|
30 | 30 | #include <openssl/nid.h>
|
31 | 31 | #include <openssl/pem.h>
|
32 | 32 | #include <openssl/pool.h>
|
| 33 | +#include <openssl/rand.h> |
33 | 34 | #include <openssl/x509.h>
|
34 | 35 | #include <openssl/x509v3.h>
|
35 | 36 |
|
@@ -1945,6 +1946,26 @@ TEST(X509Test, TestCRL) {
|
1945 | 1946 | ASSERT_EQ(nullptr, X509_OBJECT_get0_X509_CRL(&invalidCRL));
|
1946 | 1947 | }
|
1947 | 1948 |
|
| 1949 | +TEST(X509Test, TestX509GettersSetters) { |
| 1950 | + bssl::UniquePtr<X509_OBJECT> obj(X509_OBJECT_new()); |
| 1951 | + bssl::UniquePtr<X509> x509(CertFromPEM(kCRLTestRoot)); |
| 1952 | + bssl::UniquePtr<X509_CRL> crl(CRLFromPEM(kBasicCRL)); |
| 1953 | + |
| 1954 | + ASSERT_TRUE(obj); |
| 1955 | + ASSERT_TRUE(x509); |
| 1956 | + ASSERT_TRUE(crl); |
| 1957 | + |
| 1958 | + EXPECT_EQ(0, X509_OBJECT_get0_X509(obj.get())); |
| 1959 | + EXPECT_EQ(0, X509_OBJECT_get0_X509_CRL(obj.get())); |
| 1960 | + EXPECT_EQ(0, X509_OBJECT_set1_X509(nullptr, x509.get())); |
| 1961 | + EXPECT_EQ(0, X509_OBJECT_set1_X509_CRL(nullptr, crl.get())); |
| 1962 | + |
| 1963 | + EXPECT_EQ(1, X509_OBJECT_set1_X509(obj.get(), x509.get())); |
| 1964 | + EXPECT_EQ(x509.get(), X509_OBJECT_get0_X509(obj.get())); |
| 1965 | + EXPECT_EQ(1, X509_OBJECT_set1_X509_CRL(obj.get(), crl.get())); |
| 1966 | + EXPECT_EQ(crl.get(), X509_OBJECT_get0_X509_CRL(obj.get())); |
| 1967 | +} |
| 1968 | + |
1948 | 1969 | TEST(X509Test, ManyNamesAndConstraints) {
|
1949 | 1970 | bssl::UniquePtr<X509> many_constraints(CertFromPEM(
|
1950 | 1971 | GetTestData("crypto/x509/test/many_constraints.pem").c_str()));
|
@@ -5022,12 +5043,44 @@ TEST(X509Test, AddDuplicates) {
|
5022 | 5043 | ASSERT_TRUE(a);
|
5023 | 5044 | ASSERT_TRUE(b);
|
5024 | 5045 |
|
| 5046 | + // To begin, add the certs to the store. Subsequent adds will be duplicative. |
5025 | 5047 | EXPECT_TRUE(X509_STORE_add_cert(store.get(), a.get()));
|
5026 | 5048 | EXPECT_TRUE(X509_STORE_add_cert(store.get(), b.get()));
|
5027 |
| - EXPECT_TRUE(X509_STORE_add_cert(store.get(), a.get())); |
5028 |
| - EXPECT_TRUE(X509_STORE_add_cert(store.get(), b.get())); |
5029 |
| - EXPECT_TRUE(X509_STORE_add_cert(store.get(), a.get())); |
5030 |
| - EXPECT_TRUE(X509_STORE_add_cert(store.get(), b.get())); |
| 5049 | + |
| 5050 | + // Half the threads add duplicate certs, the other half take a lock and |
| 5051 | + // look them up to exercise un/locking functions. |
| 5052 | + const size_t kNumThreads = 10; |
| 5053 | + std::vector<std::thread> threads; |
| 5054 | + for (size_t i = 0; i < kNumThreads/2; i++) { |
| 5055 | + threads.emplace_back([&] { |
| 5056 | + // Sleep with some jitter to offset thread execution |
| 5057 | + uint8_t sleep_buf[1]; |
| 5058 | + ASSERT_TRUE(RAND_bytes(sleep_buf, sizeof(sleep_buf))); |
| 5059 | + std::this_thread::sleep_for(std::chrono::microseconds(1 + (sleep_buf[0] % 5))); |
| 5060 | + EXPECT_TRUE(X509_STORE_add_cert(store.get(), a.get())); |
| 5061 | + EXPECT_TRUE(X509_STORE_add_cert(store.get(), b.get())); |
| 5062 | + }); |
| 5063 | + threads.emplace_back([&] { |
| 5064 | + uint8_t sleep_buf[1]; |
| 5065 | + ASSERT_TRUE(RAND_bytes(sleep_buf, sizeof(sleep_buf))); |
| 5066 | + ASSERT_TRUE(X509_STORE_lock(store.get())); |
| 5067 | + // Sleep after taking the lock to cause contention. Sleep longer than the |
| 5068 | + // adder half of threads to ensure we hold the lock while they contend |
| 5069 | + // for it. |X509_OBJECT_retrieve_by_subject| is called because it doesn't |
| 5070 | + // take a lock on the store, thus avoiding deadlock. |
| 5071 | + std::this_thread::sleep_for(std::chrono::microseconds(11 + (sleep_buf[0] % 5))); |
| 5072 | + EXPECT_TRUE(X509_OBJECT_retrieve_by_subject( |
| 5073 | + store->objs, X509_LU_X509, X509_get_subject_name(a.get()) |
| 5074 | + )); |
| 5075 | + EXPECT_TRUE(X509_OBJECT_retrieve_by_subject( |
| 5076 | + store->objs, X509_LU_X509, X509_get_subject_name(b.get()) |
| 5077 | + )); |
| 5078 | + ASSERT_TRUE(X509_STORE_unlock(store.get())); |
| 5079 | + }); |
| 5080 | + } |
| 5081 | + for (auto &thread : threads) { |
| 5082 | + thread.join(); |
| 5083 | + } |
5031 | 5084 |
|
5032 | 5085 | EXPECT_EQ(sk_X509_OBJECT_num(X509_STORE_get0_objects(store.get())), 2u);
|
5033 | 5086 | }
|
|
0 commit comments