Skip to content

Commit db9d305

Browse files
committed
src: modify SecureContext::SetCACert to not use root_certs
1 parent 8253290 commit db9d305

File tree

1 file changed

+54
-3
lines changed

1 file changed

+54
-3
lines changed

src/crypto/crypto_context.cc

+54-3
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,47 @@ X509_STORE* GetOrCreateRootCertStore() {
6060
return store;
6161
}
6262

63+
64+
// copies an X509_STORE object, including the certificates and crls it contains.
65+
X509_STORE* CopyX509Store (X509_STORE* src) {
66+
// create a new X509_STORE
67+
X509_STORE* dest = X509_STORE_new();
68+
69+
if (*system_cert_path != '\0') {
70+
ERR_set_mark();
71+
X509_STORE_load_locations(dest, system_cert_path, nullptr);
72+
ERR_pop_to_mark();
73+
}
74+
75+
if (per_process::cli_options->ssl_openssl_cert_store) {
76+
CHECK_EQ(1, X509_STORE_set_default_paths(dest));
77+
}
78+
79+
// copy flags
80+
X509_STORE_set1_param(dest, X509_STORE_get0_param(src));
81+
82+
// get the certificates and crls from the source store
83+
STACK_OF(X509_OBJECT)* objs = X509_STORE_get0_objects(src);
84+
for (int i = 0; i < sk_X509_OBJECT_num(objs); i++) {
85+
X509_OBJECT* obj = sk_X509_OBJECT_value(objs, i);
86+
int type = X509_OBJECT_get_type(obj);
87+
if (type == X509_LU_X509) {
88+
// copy certs
89+
X509* x509 = X509_OBJECT_get0_X509(obj);
90+
X509_up_ref(x509);
91+
X509_STORE_add_cert(dest, x509);
92+
} else if (type == X509_LU_CRL) {
93+
// copy crls
94+
X509_CRL* crl = X509_OBJECT_get0_X509_CRL(obj);
95+
X509_CRL_up_ref(crl);
96+
X509_STORE_add_crl(dest, crl);
97+
}
98+
}
99+
100+
return dest;
101+
}
102+
103+
63104
// Takes a string or buffer and loads it into a BIO.
64105
// Caller responsible for BIO_free_all-ing the returned object.
65106
BIOPointer LoadBIO(Environment* env, Local<Value> v) {
@@ -785,9 +826,19 @@ void SecureContext::SetCACert(const BIOPointer& bio) {
785826
if (!bio) return;
786827
while (X509Pointer x509 = X509Pointer(PEM_read_bio_X509_AUX(
787828
bio.get(), nullptr, NoPasswordCallback, nullptr))) {
788-
CHECK_EQ(1,
789-
X509_STORE_add_cert(GetCertStoreOwnedByThisSecureContext(),
790-
x509.get()));
829+
// Avoid calling GetCertStoreOwnedByThisSecureContext() in SetCACert method
830+
// because it will create X509_STORE based on root_certs (more than 150) and is very slow
831+
832+
if (!own_cert_store_cache_) {
833+
// Is cert_store here a globally shared root cert store? There are two possibilities
834+
// 1. AddRootCerts has been called, and cert_store is a globally shared root cert store
835+
// 2. AddRootCerts has not been called, and cert_store is the default cert store of OpenSSL
836+
// Directly creating a new store is not a correct implementation of copy on write
837+
SSL_CTX_set_cert_store(ctx_.get(), own_cert_store_cache_ = CopyX509Store(SSL_CTX_get_cert_store(ctx_.get())));
838+
// No need to call X509_STORE_free manually, SSL_CTX_set_cert_store will take over the ownership of X509_STORE
839+
}
840+
841+
CHECK_EQ(1, X509_STORE_add_cert(own_cert_store_cache_, x509.get()));
791842
CHECK_EQ(1, SSL_CTX_add_client_CA(ctx_.get(), x509.get()));
792843
}
793844
}

0 commit comments

Comments
 (0)