43
43
// StartComAndWoSignData.inc
44
44
#include " StartComAndWoSignData.inc"
45
45
46
- #include < algorithm>
47
46
#include < errno.h>
48
47
#include < limits.h> // INT_MAX
49
48
#include < math.h>
50
49
#include < stdlib.h>
51
50
#include < string.h>
51
+
52
+ #include < algorithm>
53
+ #include < memory>
52
54
#include < vector>
53
55
54
56
#define THROW_AND_RETURN_IF_NOT_BUFFER (val, prefix ) \
@@ -107,6 +109,12 @@ using v8::String;
107
109
using v8::Value;
108
110
109
111
112
+ struct StackOfX509Deleter {
113
+ void operator ()(STACK_OF(X509)* p) const { sk_X509_pop_free (p, X509_free); }
114
+ };
115
+
116
+ using StackOfX509 = std::unique_ptr<STACK_OF(X509), StackOfX509Deleter>;
117
+
110
118
#if OPENSSL_VERSION_NUMBER < 0x10100000L
111
119
static void RSA_get0_key (const RSA* r, const BIGNUM** n, const BIGNUM** e,
112
120
const BIGNUM** d) {
@@ -829,17 +837,15 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
829
837
int ret = 0 ;
830
838
unsigned long err = 0 ; // NOLINT(runtime/int)
831
839
832
- // Read extra certs
833
- STACK_OF (X509)* extra_certs = sk_X509_new_null ();
834
- if (extra_certs == nullptr ) {
840
+ StackOfX509 extra_certs (sk_X509_new_null ());
841
+ if (!extra_certs)
835
842
goto done;
836
- }
837
843
838
844
while ((extra = PEM_read_bio_X509 (in,
839
845
nullptr ,
840
846
NoPasswordCallback,
841
847
nullptr ))) {
842
- if (sk_X509_push (extra_certs, extra))
848
+ if (sk_X509_push (extra_certs. get () , extra))
843
849
continue ;
844
850
845
851
// Failure, free all certs
@@ -857,13 +863,11 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
857
863
goto done;
858
864
}
859
865
860
- ret = SSL_CTX_use_certificate_chain (ctx, x, extra_certs, cert, issuer);
866
+ ret = SSL_CTX_use_certificate_chain (ctx, x, extra_certs. get () , cert, issuer);
861
867
if (!ret)
862
868
goto done;
863
869
864
870
done:
865
- if (extra_certs != nullptr )
866
- sk_X509_pop_free (extra_certs, X509_free);
867
871
if (extra != nullptr )
868
872
X509_free (extra);
869
873
if (x != nullptr )
@@ -1990,14 +1994,14 @@ static Local<Object> X509ToObject(Environment* env, X509* cert) {
1990
1994
1991
1995
static Local<Object> AddIssuerChainToObject (X509** cert,
1992
1996
Local<Object> object,
1993
- STACK_OF (X509)* const peer_certs,
1997
+ StackOfX509 peer_certs,
1994
1998
Environment* const env) {
1995
1999
Local<Context> context = env->isolate ()->GetCurrentContext ();
1996
- *cert = sk_X509_delete (peer_certs, 0 );
2000
+ *cert = sk_X509_delete (peer_certs. get () , 0 );
1997
2001
for (;;) {
1998
2002
int i;
1999
- for (i = 0 ; i < sk_X509_num (peer_certs); i++) {
2000
- X509* ca = sk_X509_value (peer_certs, i);
2003
+ for (i = 0 ; i < sk_X509_num (peer_certs. get () ); i++) {
2004
+ X509* ca = sk_X509_value (peer_certs. get () , i);
2001
2005
if (X509_check_issued (ca, *cert) != X509_V_OK)
2002
2006
continue ;
2003
2007
@@ -2009,41 +2013,31 @@ static Local<Object> AddIssuerChainToObject(X509** cert,
2009
2013
X509_free (*cert);
2010
2014
2011
2015
// Delete cert and continue aggregating issuers.
2012
- *cert = sk_X509_delete (peer_certs, i);
2016
+ *cert = sk_X509_delete (peer_certs. get () , i);
2013
2017
break ;
2014
2018
}
2015
2019
2016
2020
// Issuer not found, break out of the loop.
2017
- if (i == sk_X509_num (peer_certs))
2021
+ if (i == sk_X509_num (peer_certs. get () ))
2018
2022
break ;
2019
2023
}
2020
- sk_X509_pop_free (peer_certs, X509_free);
2021
2024
return object;
2022
2025
}
2023
2026
2024
2027
2025
- static bool CloneSSLCerts (X509** cert,
2026
- const STACK_OF (X509)* const ssl_certs,
2027
- STACK_OF (X509)** peer_certs) {
2028
- *peer_certs = sk_X509_new (nullptr );
2029
- bool result = true ;
2028
+ static StackOfX509 CloneSSLCerts (X509** cert,
2029
+ const STACK_OF (X509)* const ssl_certs) {
2030
+ StackOfX509 peer_certs (sk_X509_new (nullptr ));
2030
2031
if (*cert != nullptr )
2031
- sk_X509_push (* peer_certs, *cert);
2032
+ sk_X509_push (peer_certs. get () , *cert);
2032
2033
for (int i = 0 ; i < sk_X509_num (ssl_certs); i++) {
2033
2034
*cert = X509_dup (sk_X509_value (ssl_certs, i));
2034
- if (*cert == nullptr ) {
2035
- result = false ;
2036
- break ;
2037
- }
2038
- if (!sk_X509_push (*peer_certs, *cert)) {
2039
- result = false ;
2040
- break ;
2041
- }
2042
- }
2043
- if (!result) {
2044
- sk_X509_pop_free (*peer_certs, X509_free);
2035
+ if (*cert == nullptr )
2036
+ return StackOfX509 ();
2037
+ if (!sk_X509_push (peer_certs.get (), *cert))
2038
+ return StackOfX509 ();
2045
2039
}
2046
- return result ;
2040
+ return peer_certs ;
2047
2041
}
2048
2042
2049
2043
@@ -2077,7 +2071,6 @@ void SSLWrap<Base>::GetPeerCertificate(
2077
2071
Base* w;
2078
2072
ASSIGN_OR_RETURN_UNWRAP (&w, args.Holder ());
2079
2073
Environment* env = w->ssl_env ();
2080
- Local<Context> context = env->context ();
2081
2074
2082
2075
ClearErrorOnReturn clear_error_on_return;
2083
2076
@@ -2089,23 +2082,25 @@ void SSLWrap<Base>::GetPeerCertificate(
2089
2082
// contains the `peer_certificate`, but on server it doesn't.
2090
2083
X509* cert = w->is_server () ? SSL_get_peer_certificate (w->ssl_ ) : nullptr ;
2091
2084
STACK_OF (X509)* ssl_certs = SSL_get_peer_cert_chain (w->ssl_ );
2092
- STACK_OF (X509)* peer_certs = nullptr ;
2093
2085
if (cert == nullptr && (ssl_certs == nullptr || sk_X509_num (ssl_certs) == 0 ))
2094
2086
goto done;
2095
2087
2096
2088
// Short result requested.
2097
2089
if (args.Length () < 1 || !args[0 ]->IsTrue ()) {
2098
- result = X509ToObject (env,
2099
- cert == nullptr ? sk_X509_value (ssl_certs, 0 ) : cert);
2090
+ X509* target_cert = cert;
2091
+ if (target_cert == nullptr )
2092
+ target_cert = sk_X509_value (ssl_certs, 0 );
2093
+ result = X509ToObject (env, target_cert);
2100
2094
goto done;
2101
2095
}
2102
2096
2103
- if (CloneSSLCerts (&cert, ssl_certs, &peer_certs )) {
2097
+ if (auto peer_certs = CloneSSLCerts (&cert, ssl_certs)) {
2104
2098
// First and main certificate.
2105
- cert = sk_X509_value (peer_certs, 0 );
2099
+ cert = sk_X509_value (peer_certs. get () , 0 );
2106
2100
result = X509ToObject (env, cert);
2107
2101
2108
- issuer_chain = AddIssuerChainToObject (&cert, result, peer_certs, env);
2102
+ issuer_chain =
2103
+ AddIssuerChainToObject (&cert, result, std::move (peer_certs), env);
2109
2104
issuer_chain = GetLastIssuedCert (&cert, w->ssl_ , issuer_chain, env);
2110
2105
// Last certificate should be self-signed.
2111
2106
if (X509_check_issued (cert, cert) == X509_V_OK)
@@ -2959,25 +2954,23 @@ inline CheckResult CheckWhitelistedServerCert(X509_STORE_CTX* ctx) {
2959
2954
unsigned char hash[CNNIC_WHITELIST_HASH_LEN];
2960
2955
unsigned int hashlen = CNNIC_WHITELIST_HASH_LEN;
2961
2956
2962
- STACK_OF (X509)* chain = X509_STORE_CTX_get1_chain (ctx);
2963
- CHECK_NE (chain, nullptr );
2964
- CHECK_GT (sk_X509_num (chain), 0 );
2957
+ StackOfX509 chain ( X509_STORE_CTX_get1_chain (ctx) );
2958
+ CHECK (chain);
2959
+ CHECK_GT (sk_X509_num (chain. get () ), 0 );
2965
2960
2966
2961
// Take the last cert as root at the first time.
2967
- X509* root_cert = sk_X509_value (chain, sk_X509_num (chain)-1 );
2962
+ X509* root_cert = sk_X509_value (chain. get () , sk_X509_num (chain. get () )-1 );
2968
2963
X509_NAME* root_name = X509_get_subject_name (root_cert);
2969
2964
2970
2965
if (!IsSelfSigned (root_cert)) {
2971
- root_cert = FindRoot (chain);
2966
+ root_cert = FindRoot (chain. get () );
2972
2967
CHECK_NE (root_cert, nullptr );
2973
2968
root_name = X509_get_subject_name (root_cert);
2974
2969
}
2975
2970
2976
- X509* leaf_cert = sk_X509_value (chain, 0 );
2977
- if (!CheckStartComOrWoSign (root_name, leaf_cert)) {
2978
- sk_X509_pop_free (chain, X509_free);
2971
+ X509* leaf_cert = sk_X509_value (chain.get (), 0 );
2972
+ if (!CheckStartComOrWoSign (root_name, leaf_cert))
2979
2973
return CHECK_CERT_REVOKED;
2980
- }
2981
2974
2982
2975
// When the cert is issued from either CNNNIC ROOT CA or CNNNIC EV
2983
2976
// ROOT CA, check a hash of its leaf cert if it is in the whitelist.
@@ -2990,13 +2983,10 @@ inline CheckResult CheckWhitelistedServerCert(X509_STORE_CTX* ctx) {
2990
2983
void * result = bsearch (hash, WhitelistedCNNICHashes,
2991
2984
arraysize (WhitelistedCNNICHashes),
2992
2985
CNNIC_WHITELIST_HASH_LEN, compar);
2993
- if (result == nullptr ) {
2994
- sk_X509_pop_free (chain, X509_free);
2986
+ if (result == nullptr )
2995
2987
return CHECK_CERT_REVOKED;
2996
- }
2997
2988
}
2998
2989
2999
- sk_X509_pop_free (chain, X509_free);
3000
2990
return CHECK_OK;
3001
2991
}
3002
2992
0 commit comments