@@ -121,6 +121,7 @@ const char* const root_certs[] = {
121
121
};
122
122
123
123
X509_STORE* root_cert_store;
124
+ std::vector<X509*>* root_certs_vector;
124
125
125
126
// Just to generate static methods
126
127
template class SSLWrap <TLSWrap>;
@@ -402,8 +403,6 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
402
403
SSL_SESS_CACHE_NO_AUTO_CLEAR);
403
404
SSL_CTX_sess_set_get_cb (sc->ctx_ , SSLWrap<Connection>::GetSessionCallback);
404
405
SSL_CTX_sess_set_new_cb (sc->ctx_ , SSLWrap<Connection>::NewSessionCallback);
405
-
406
- sc->ca_store_ = nullptr ;
407
406
}
408
407
409
408
@@ -672,8 +671,52 @@ void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) {
672
671
}
673
672
674
673
674
+ #if OPENSSL_VERSION_NUMBER < 0x10100000L && !defined(OPENSSL_IS_BORINGSSL)
675
+ // This section contains OpenSSL 1.1.0 functions reimplemented for OpenSSL
676
+ // 1.0.2 so that the following code can be written without lots of #if lines.
677
+
678
+ static int X509_STORE_up_ref (X509_STORE* store) {
679
+ CRYPTO_add (&store->references , 1 , CRYPTO_LOCK_X509_STORE);
680
+ return 1 ;
681
+ }
682
+
683
+ static int X509_up_ref (X509* cert) {
684
+ CRYPTO_add (&cert->references , 1 , CRYPTO_LOCK_X509);
685
+ return 1 ;
686
+ }
687
+ #endif // OPENSSL_VERSION_NUMBER < 0x10100000L && !OPENSSL_IS_BORINGSSL
688
+
689
+
690
+ static X509_STORE* NewRootCertStore () {
691
+ if (!root_certs_vector) {
692
+ root_certs_vector = new std::vector<X509*>;
693
+
694
+ for (size_t i = 0 ; i < arraysize (root_certs); i++) {
695
+ BIO* bp = NodeBIO::NewFixed (root_certs[i], strlen (root_certs[i]));
696
+ X509 *x509 = PEM_read_bio_X509 (bp, nullptr , CryptoPemCallback, nullptr );
697
+ BIO_free (bp);
698
+
699
+ if (x509 == nullptr ) {
700
+ // Parse errors from the built-in roots are fatal.
701
+ abort ();
702
+ return nullptr ;
703
+ }
704
+
705
+ root_certs_vector->push_back (x509);
706
+ }
707
+ }
708
+
709
+ X509_STORE* store = X509_STORE_new ();
710
+ for (auto & cert : *root_certs_vector) {
711
+ X509_up_ref (cert);
712
+ X509_STORE_add_cert (store, cert);
713
+ }
714
+
715
+ return store;
716
+ }
717
+
718
+
675
719
void SecureContext::AddCACert (const FunctionCallbackInfo<Value>& args) {
676
- bool newCAStore = false ;
677
720
Environment* env = Environment::GetCurrent (args);
678
721
679
722
SecureContext* sc;
@@ -685,26 +728,24 @@ void SecureContext::AddCACert(const FunctionCallbackInfo<Value>& args) {
685
728
return env->ThrowTypeError (" CA certificate argument is mandatory" );
686
729
}
687
730
688
- if (!sc-> ca_store_ ) {
689
- sc-> ca_store_ = X509_STORE_new ();
690
- newCAStore = true ;
731
+ BIO* bio = LoadBIO (env, args[ 0 ]);
732
+ if (!bio) {
733
+ return ;
691
734
}
692
735
693
- unsigned cert_count = 0 ;
694
- if (BIO* bio = LoadBIO (env, args[0 ])) {
695
- while (X509* x509 =
696
- PEM_read_bio_X509 (bio, nullptr , CryptoPemCallback, nullptr )) {
697
- X509_STORE_add_cert (sc->ca_store_ , x509);
698
- SSL_CTX_add_client_CA (sc->ctx_ , x509);
699
- X509_free (x509);
700
- cert_count += 1 ;
736
+ X509_STORE* cert_store = SSL_CTX_get_cert_store (sc->ctx_ );
737
+ while (X509* x509 =
738
+ PEM_read_bio_X509 (bio, nullptr , CryptoPemCallback, nullptr )) {
739
+ if (cert_store == root_cert_store) {
740
+ cert_store = NewRootCertStore ();
741
+ SSL_CTX_set_cert_store (sc->ctx_ , cert_store);
701
742
}
702
- BIO_free_all (bio);
743
+ X509_STORE_add_cert (cert_store, x509);
744
+ SSL_CTX_add_client_CA (sc->ctx_ , x509);
745
+ X509_free (x509);
703
746
}
704
747
705
- if (cert_count > 0 && newCAStore) {
706
- SSL_CTX_set_cert_store (sc->ctx_ , sc->ca_store_ );
707
- }
748
+ BIO_free_all (bio);
708
749
}
709
750
710
751
@@ -725,57 +766,43 @@ void SecureContext::AddCRL(const FunctionCallbackInfo<Value>& args) {
725
766
if (!bio)
726
767
return ;
727
768
728
- X509_CRL *x509 =
769
+ X509_CRL* crl =
729
770
PEM_read_bio_X509_CRL (bio, nullptr , CryptoPemCallback, nullptr );
730
771
731
- if (x509 == nullptr ) {
772
+ if (crl == nullptr ) {
773
+ return env->ThrowError (" Failed to parse CRL" );
732
774
BIO_free_all (bio);
733
775
return ;
734
776
}
735
777
736
- X509_STORE_add_crl (sc->ca_store_ , x509);
737
- X509_STORE_set_flags (sc->ca_store_ , X509_V_FLAG_CRL_CHECK |
738
- X509_V_FLAG_CRL_CHECK_ALL);
778
+ X509_STORE* cert_store = SSL_CTX_get_cert_store (sc->ctx_ );
779
+ if (cert_store == root_cert_store) {
780
+ cert_store = NewRootCertStore ();
781
+ SSL_CTX_set_cert_store (sc->ctx_ , cert_store);
782
+ }
783
+
784
+ X509_STORE_add_crl (cert_store, crl);
785
+ X509_STORE_set_flags (cert_store,
786
+ X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
787
+
739
788
BIO_free_all (bio);
740
- X509_CRL_free (x509 );
789
+ X509_CRL_free (crl );
741
790
}
742
791
743
792
744
-
745
793
void SecureContext::AddRootCerts (const FunctionCallbackInfo<Value>& args) {
746
794
SecureContext* sc;
747
795
ASSIGN_OR_RETURN_UNWRAP (&sc, args.Holder ());
748
796
ClearErrorOnReturn clear_error_on_return;
749
797
(void ) &clear_error_on_return; // Silence compiler warning.
750
798
751
- CHECK_EQ (sc->ca_store_ , nullptr );
752
-
753
799
if (!root_cert_store) {
754
- root_cert_store = X509_STORE_new ();
755
-
756
- for (size_t i = 0 ; i < arraysize (root_certs); i++) {
757
- BIO* bp = NodeBIO::NewFixed (root_certs[i], strlen (root_certs[i]));
758
- if (bp == nullptr ) {
759
- return ;
760
- }
761
-
762
- X509 *x509 = PEM_read_bio_X509 (bp, nullptr , CryptoPemCallback, nullptr );
763
- if (x509 == nullptr ) {
764
- BIO_free_all (bp);
765
- return ;
766
- }
767
-
768
- X509_STORE_add_cert (root_cert_store, x509);
769
-
770
- BIO_free_all (bp);
771
- X509_free (x509);
772
- }
800
+ root_cert_store = NewRootCertStore ();
773
801
}
774
802
775
- sc->ca_store_ = root_cert_store;
776
803
// Increment reference count so global store is not deleted along with CTX.
777
- CRYPTO_add (& root_cert_store-> references , 1 , CRYPTO_LOCK_X509_STORE );
778
- SSL_CTX_set_cert_store (sc->ctx_ , sc-> ca_store_ );
804
+ X509_STORE_up_ref ( root_cert_store);
805
+ SSL_CTX_set_cert_store (sc->ctx_ , root_cert_store );
779
806
}
780
807
781
808
@@ -985,6 +1012,8 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
985
1012
sc->cert_ = nullptr ;
986
1013
}
987
1014
1015
+ X509_STORE* cert_store = SSL_CTX_get_cert_store (sc->ctx_ );
1016
+
988
1017
if (d2i_PKCS12_bio (in, &p12) &&
989
1018
PKCS12_parse (p12, pass, &pkey, &cert, &extra_certs) &&
990
1019
SSL_CTX_use_certificate_chain (sc->ctx_ ,
@@ -997,11 +1026,11 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
997
1026
for (int i = 0 ; i < sk_X509_num (extra_certs); i++) {
998
1027
X509* ca = sk_X509_value (extra_certs, i);
999
1028
1000
- if (!sc-> ca_store_ ) {
1001
- sc-> ca_store_ = X509_STORE_new ();
1002
- SSL_CTX_set_cert_store (sc->ctx_ , sc-> ca_store_ );
1029
+ if (cert_store == root_cert_store ) {
1030
+ cert_store = NewRootCertStore ();
1031
+ SSL_CTX_set_cert_store (sc->ctx_ , cert_store );
1003
1032
}
1004
- X509_STORE_add_cert (sc-> ca_store_ , ca);
1033
+ X509_STORE_add_cert (cert_store , ca);
1005
1034
SSL_CTX_add_client_CA (sc->ctx_ , ca);
1006
1035
}
1007
1036
ret = true ;
0 commit comments