@@ -517,46 +517,35 @@ int SSL_CTX_get_issuer(SSL_CTX* ctx, X509* cert, X509** issuer) {
517
517
}
518
518
519
519
520
- // Read a file that contains our certificate in "PEM" format,
521
- // possibly followed by a sequence of CA certificates that should be
522
- // sent to the peer in the Certificate message.
523
- //
524
- // Taken from OpenSSL - editted for style.
525
520
int SSL_CTX_use_certificate_chain (SSL_CTX* ctx,
526
- BIO* in,
521
+ X509* x,
522
+ STACK_OF (X509)* extra_certs,
527
523
X509** cert,
528
524
X509** issuer) {
529
- int ret = 0 ;
530
- X509* x = nullptr ;
525
+ CHECK_EQ (*issuer, nullptr ) ;
526
+ CHECK_EQ (*cert, nullptr ) ;
531
527
532
- x = PEM_read_bio_X509_AUX (in, nullptr , CryptoPemCallback, nullptr );
533
-
534
- if (x == nullptr ) {
535
- SSLerr (SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
536
- goto end;
537
- }
538
-
539
- ret = SSL_CTX_use_certificate (ctx, x);
528
+ int ret = SSL_CTX_use_certificate (ctx, x);
540
529
541
530
if (ret) {
542
531
// If we could set up our certificate, now proceed to
543
532
// the CA certificates.
544
- X509 *ca;
545
533
int r;
546
- unsigned long err;
547
534
548
535
if (ctx->extra_certs != nullptr ) {
549
536
sk_X509_pop_free (ctx->extra_certs , X509_free);
550
537
ctx->extra_certs = nullptr ;
551
538
}
552
539
553
- while ((ca = PEM_read_bio_X509 (in, nullptr , CryptoPemCallback, nullptr ))) {
540
+ for (int i = 0 ; i < sk_X509_num (extra_certs); i++) {
541
+ X509* ca = sk_X509_value (extra_certs, i);
542
+
554
543
// NOTE: Increments reference count on `ca`
555
544
r = SSL_CTX_add1_chain_cert (ctx, ca);
556
545
557
546
if (!r) {
558
- X509_free (ca);
559
547
ret = 0 ;
548
+ *issuer = nullptr ;
560
549
goto end;
561
550
}
562
551
// Note that we must not free r if it was successfully
@@ -567,17 +556,8 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
567
556
// Find issuer
568
557
if (*issuer != nullptr || X509_check_issued (ca, x) != X509_V_OK)
569
558
continue ;
570
- *issuer = ca;
571
- }
572
559
573
- // When the while loop ends, it's usually just EOF.
574
- err = ERR_peek_last_error ();
575
- if (ERR_GET_LIB (err) == ERR_LIB_PEM &&
576
- ERR_GET_REASON (err) == PEM_R_NO_START_LINE) {
577
- ERR_clear_error ();
578
- } else {
579
- // some real error
580
- ret = 0 ;
560
+ *issuer = ca;
581
561
}
582
562
}
583
563
@@ -590,13 +570,88 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
590
570
// no need to free `store`
591
571
} else {
592
572
// Increment issuer reference count
593
- CRYPTO_add (&(*issuer)->references , 1 , CRYPTO_LOCK_X509);
573
+ *issuer = X509_dup (*issuer);
574
+ if (*issuer == nullptr ) {
575
+ ret = 0 ;
576
+ goto end;
577
+ }
594
578
}
595
579
}
596
580
597
581
end:
582
+ if (ret && x != nullptr ) {
583
+ *cert = X509_dup (x);
584
+ if (*cert == nullptr )
585
+ ret = 0 ;
586
+ }
587
+ return ret;
588
+ }
589
+
590
+
591
+ // Read a file that contains our certificate in "PEM" format,
592
+ // possibly followed by a sequence of CA certificates that should be
593
+ // sent to the peer in the Certificate message.
594
+ //
595
+ // Taken from OpenSSL - edited for style.
596
+ int SSL_CTX_use_certificate_chain (SSL_CTX* ctx,
597
+ BIO* in,
598
+ X509** cert,
599
+ X509** issuer) {
600
+ X509* x = nullptr ;
601
+
602
+ // Just to ensure that `ERR_peek_last_error` below will return only errors
603
+ // that we are interested in
604
+ ERR_clear_error ();
605
+
606
+ x = PEM_read_bio_X509_AUX (in, nullptr , CryptoPemCallback, nullptr );
607
+
608
+ if (x == nullptr ) {
609
+ SSLerr (SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB);
610
+ return 0 ;
611
+ }
612
+
613
+ X509* extra = nullptr ;
614
+ int ret = 0 ;
615
+ unsigned long err = 0 ;
616
+
617
+ // Read extra certs
618
+ STACK_OF (X509)* extra_certs = sk_X509_new_null ();
619
+ if (extra_certs == nullptr ) {
620
+ SSLerr (SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_MALLOC_FAILURE);
621
+ goto done;
622
+ }
623
+
624
+ while ((extra = PEM_read_bio_X509 (in, nullptr , CryptoPemCallback, nullptr ))) {
625
+ if (sk_X509_push (extra_certs, extra))
626
+ continue ;
627
+
628
+ // Failure, free all certs
629
+ goto done;
630
+ }
631
+ extra = nullptr ;
632
+
633
+ // When the while loop ends, it's usually just EOF.
634
+ err = ERR_peek_last_error ();
635
+ if (ERR_GET_LIB (err) == ERR_LIB_PEM &&
636
+ ERR_GET_REASON (err) == PEM_R_NO_START_LINE) {
637
+ ERR_clear_error ();
638
+ } else {
639
+ // some real error
640
+ goto done;
641
+ }
642
+
643
+ ret = SSL_CTX_use_certificate_chain (ctx, x, extra_certs, cert, issuer);
644
+ if (!ret)
645
+ goto done;
646
+
647
+ done:
648
+ if (extra_certs != nullptr )
649
+ sk_X509_pop_free (extra_certs, X509_free);
650
+ if (extra != nullptr )
651
+ X509_free (extra);
598
652
if (x != nullptr )
599
- *cert = x;
653
+ X509_free (x);
654
+
600
655
return ret;
601
656
}
602
657
@@ -614,6 +669,16 @@ void SecureContext::SetCert(const FunctionCallbackInfo<Value>& args) {
614
669
if (!bio)
615
670
return ;
616
671
672
+ // Free previous certs
673
+ if (sc->issuer_ != nullptr ) {
674
+ X509_free (sc->issuer_ );
675
+ sc->issuer_ = nullptr ;
676
+ }
677
+ if (sc->cert_ != nullptr ) {
678
+ X509_free (sc->cert_ );
679
+ sc->cert_ = nullptr ;
680
+ }
681
+
617
682
int rv = SSL_CTX_use_certificate_chain (sc->ctx_ ,
618
683
bio,
619
684
&sc->cert_ ,
@@ -888,7 +953,7 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
888
953
PKCS12* p12 = nullptr ;
889
954
EVP_PKEY* pkey = nullptr ;
890
955
X509* cert = nullptr ;
891
- STACK_OF (X509)* extraCerts = nullptr ;
956
+ STACK_OF (X509)* extra_certs = nullptr ;
892
957
char * pass = nullptr ;
893
958
bool ret = false ;
894
959
@@ -913,28 +978,33 @@ void SecureContext::LoadPKCS12(const FunctionCallbackInfo<Value>& args) {
913
978
pass[passlen] = ' \0 ' ;
914
979
}
915
980
981
+ // Free previous certs
982
+ if (sc->issuer_ != nullptr ) {
983
+ X509_free (sc->issuer_ );
984
+ sc->issuer_ = nullptr ;
985
+ }
986
+ if (sc->cert_ != nullptr ) {
987
+ X509_free (sc->cert_ );
988
+ sc->cert_ = nullptr ;
989
+ }
990
+
916
991
if (d2i_PKCS12_bio (in, &p12) &&
917
- PKCS12_parse (p12, pass, &pkey, &cert, &extraCerts) &&
918
- SSL_CTX_use_certificate (sc->ctx_ , cert) &&
992
+ PKCS12_parse (p12, pass, &pkey, &cert, &extra_certs) &&
993
+ SSL_CTX_use_certificate_chain (sc->ctx_ ,
994
+ cert,
995
+ extra_certs,
996
+ &sc->cert_ ,
997
+ &sc->issuer_ ) &&
919
998
SSL_CTX_use_PrivateKey (sc->ctx_ , pkey)) {
920
- // set extra certs
921
- while (X509* x509 = sk_X509_pop (extraCerts)) {
922
- if (!sc->ca_store_ ) {
923
- sc->ca_store_ = X509_STORE_new ();
924
- SSL_CTX_set_cert_store (sc->ctx_ , sc->ca_store_ );
925
- }
926
-
927
- X509_STORE_add_cert (sc->ca_store_ , x509);
928
- SSL_CTX_add_client_CA (sc->ctx_ , x509);
929
- X509_free (x509);
930
- }
999
+ ret = true ;
1000
+ }
931
1001
1002
+ if (pkey != nullptr )
932
1003
EVP_PKEY_free (pkey);
1004
+ if (cert != nullptr )
933
1005
X509_free (cert);
934
- sk_X509_free (extraCerts);
935
-
936
- ret = true ;
937
- }
1006
+ if (extra_certs != nullptr )
1007
+ sk_X509_free (extra_certs);
938
1008
939
1009
PKCS12_free (p12);
940
1010
BIO_free_all (in);
0 commit comments