| // Copyright 2018 The BoringSSL Authors | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // https://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| #include "test_state.h" | |
| #include <openssl/ssl.h> | |
| #include "../../crypto/internal.h" | |
| #include "../internal.h" | |
| using namespace bssl; | |
| static CRYPTO_once_t g_once = CRYPTO_ONCE_INIT; | |
| static int g_state_index = 0; | |
| // Some code treats the zero time special, so initialize the clock to a | |
| // non-zero time. | |
| static timeval g_clock = { 1234, 1234 }; | |
| static void TestStateExFree(void *parent, void *ptr, CRYPTO_EX_DATA *ad, | |
| int index, long argl, void *argp) { | |
| delete ((TestState *)ptr); | |
| } | |
| static bool InitGlobals() { | |
| CRYPTO_once(&g_once, [] { | |
| g_state_index = | |
| SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, TestStateExFree); | |
| }); | |
| return g_state_index >= 0; | |
| } | |
| struct timeval *GetClock() { | |
| return &g_clock; | |
| } | |
| void AdvanceClock(unsigned seconds) { | |
| g_clock.tv_sec += seconds; | |
| } | |
| bool SetTestState(SSL *ssl, std::unique_ptr<TestState> state) { | |
| if (!InitGlobals()) { | |
| return false; | |
| } | |
| // `SSL_set_ex_data` takes ownership of `state` only on success. | |
| if (SSL_set_ex_data(ssl, g_state_index, state.get()) == 1) { | |
| state.release(); | |
| return true; | |
| } | |
| return false; | |
| } | |
| TestState *GetTestState(const SSL *ssl) { | |
| if (!InitGlobals()) { | |
| return nullptr; | |
| } | |
| return static_cast<TestState *>(SSL_get_ex_data(ssl, g_state_index)); | |
| } | |
| static void ssl_ctx_add_session(SSL_SESSION *session, void *void_param) { | |
| SSL_CTX *ctx = reinterpret_cast<SSL_CTX *>(void_param); | |
| UniquePtr<SSL_SESSION> new_session = SSL_SESSION_dup( | |
| session, SSL_SESSION_INCLUDE_NONAUTH | SSL_SESSION_INCLUDE_TICKET); | |
| if (new_session != nullptr) { | |
| SSL_CTX_add_session(ctx, new_session.get()); | |
| } | |
| } | |
| void CopySessions(SSL_CTX *dst, const SSL_CTX *src) { | |
| lh_SSL_SESSION_doall_arg(FromOpaque(src)->sessions, ssl_ctx_add_session, dst); | |
| } |