1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
|
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file 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 "crypto/s2n_locking.h"
#include <pthread.h>
#include "s2n_test.h"
#define LOCK_N 1
#if !(S2N_OPENSSL_VERSION_AT_LEAST(1, 1, 0))
static void *s2n_test_thread(void *arg)
{
bool *lock_was_acquired = (bool *) arg;
CRYPTO_lock(CRYPTO_LOCK, LOCK_N, NULL, 0);
*lock_was_acquired = true;
CRYPTO_lock(CRYPTO_UNLOCK, LOCK_N, NULL, 0);
return NULL;
}
static void s2n_test_locking_cb(int mode, int n, char *file, int line)
{
return;
}
int main(int argc, char **argv)
{
BEGIN_TEST();
/* Test: libcrypto locks should actually lock.
*
* If libcrypto locking is not configured properly, then
* libcrypto locks will be no-ops and will not block threads.
*/
{
/* Lock one of the libcrypto locks */
CRYPTO_lock(CRYPTO_LOCK, LOCK_N, NULL, 0);
/* Create a new thread which will try to take the lock held by this thread
* in order to set a flag.
*/
bool lock_was_acquired = false;
pthread_t thread = { 0 };
EXPECT_EQUAL(pthread_create(&thread, NULL, s2n_test_thread, &lock_was_acquired), 0);
/* Expect the flag NOT to be set because we still hold the lock */
sleep(1);
EXPECT_FALSE(lock_was_acquired);
/* Release the libcrypto lock */
CRYPTO_lock(CRYPTO_UNLOCK, LOCK_N, NULL, 0);
/* Expect the flag to be set because the new thread took the lock */
void *retval = NULL;
EXPECT_EQUAL(pthread_join(thread, &retval), 0);
EXPECT_TRUE(lock_was_acquired);
};
/* Test: basic lifecycle */
{
EXPECT_OK(s2n_locking_cleanup());
EXPECT_OK(s2n_locking_init());
};
/* Test: s2n-tls should not override locking configured by the application */
{
/* The callback should have already been set by BEGIN_TEST()
* or a later call to s2n_locking_init().
*/
EXPECT_NOT_EQUAL(CRYPTO_get_locking_callback(), NULL);
/* Manually override the existing callback.
* Applications might set their callback after calling s2n_init.
*/
CRYPTO_set_locking_callback((void (*)()) s2n_test_locking_cb);
EXPECT_EQUAL(CRYPTO_get_locking_callback(), (void (*)()) s2n_test_locking_cb);
/* Cleaning up does not affect the application-set callback */
EXPECT_OK(s2n_locking_cleanup());
EXPECT_EQUAL(CRYPTO_get_locking_callback(), (void (*)()) s2n_test_locking_cb);
/* Initializing again doesn't override the application-set callback.
* Applications might set their callback before calling s2n_init.
*/
EXPECT_OK(s2n_locking_init());
EXPECT_EQUAL(CRYPTO_get_locking_callback(), (void (*)()) s2n_test_locking_cb);
EXPECT_OK(s2n_locking_cleanup());
EXPECT_EQUAL(CRYPTO_get_locking_callback(), (void (*)()) s2n_test_locking_cb);
/* Reset the callback */
CRYPTO_set_locking_callback(NULL);
EXPECT_EQUAL(CRYPTO_get_locking_callback(), NULL);
/* Initializing now sets the missing callback */
EXPECT_OK(s2n_locking_init());
EXPECT_NOT_EQUAL(CRYPTO_get_locking_callback(), NULL);
};
END_TEST();
}
#else
int main(int argc, char **argv)
{
BEGIN_TEST();
END_TEST();
}
#endif
|