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_STRING_OR_BUFFER (val, prefix ) \
@@ -115,6 +117,12 @@ using v8::String;
115
117
using v8::Value;
116
118
117
119
120
+ struct StackOfX509Deleter {
121
+ void operator ()(STACK_OF(X509)* p) const { sk_X509_pop_free (p, X509_free); }
122
+ };
123
+
124
+ using StackOfX509 = std::unique_ptr<STACK_OF(X509), StackOfX509Deleter>;
125
+
118
126
#if OPENSSL_VERSION_NUMBER < 0x10100000L
119
127
static void RSA_get0_key (const RSA* r, const BIGNUM** n, const BIGNUM** e,
120
128
const BIGNUM** d) {
@@ -839,17 +847,15 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
839
847
int ret = 0 ;
840
848
unsigned long err = 0 ; // NOLINT(runtime/int)
841
849
842
- // Read extra certs
843
- STACK_OF (X509)* extra_certs = sk_X509_new_null ();
844
- if (extra_certs == nullptr ) {
850
+ StackOfX509 extra_certs (sk_X509_new_null ());
851
+ if (!extra_certs)
845
852
goto done;
846
- }
847
853
848
854
while ((extra = PEM_read_bio_X509 (in,
849
855
nullptr ,
850
856
NoPasswordCallback,
851
857
nullptr ))) {
852
- if (sk_X509_push (extra_certs, extra))
858
+ if (sk_X509_push (extra_certs. get () , extra))
853
859
continue ;
854
860
855
861
// Failure, free all certs
@@ -867,13 +873,11 @@ int SSL_CTX_use_certificate_chain(SSL_CTX* ctx,
867
873
goto done;
868
874
}
869
875
870
- ret = SSL_CTX_use_certificate_chain (ctx, x, extra_certs, cert, issuer);
876
+ ret = SSL_CTX_use_certificate_chain (ctx, x, extra_certs. get () , cert, issuer);
871
877
if (!ret)
872
878
goto done;
873
879
874
880
done:
875
- if (extra_certs != nullptr )
876
- sk_X509_pop_free (extra_certs, X509_free);
877
881
if (extra != nullptr )
878
882
X509_free (extra);
879
883
if (x != nullptr )
@@ -2004,14 +2008,14 @@ static Local<Object> X509ToObject(Environment* env, X509* cert) {
2004
2008
2005
2009
static Local<Object> AddIssuerChainToObject (X509** cert,
2006
2010
Local<Object> object,
2007
- STACK_OF (X509)* const peer_certs,
2011
+ StackOfX509 peer_certs,
2008
2012
Environment* const env) {
2009
2013
Local<Context> context = env->isolate ()->GetCurrentContext ();
2010
- *cert = sk_X509_delete (peer_certs, 0 );
2014
+ *cert = sk_X509_delete (peer_certs. get () , 0 );
2011
2015
for (;;) {
2012
2016
int i;
2013
- for (i = 0 ; i < sk_X509_num (peer_certs); i++) {
2014
- X509* ca = sk_X509_value (peer_certs, i);
2017
+ for (i = 0 ; i < sk_X509_num (peer_certs. get () ); i++) {
2018
+ X509* ca = sk_X509_value (peer_certs. get () , i);
2015
2019
if (X509_check_issued (ca, *cert) != X509_V_OK)
2016
2020
continue ;
2017
2021
@@ -2023,41 +2027,31 @@ static Local<Object> AddIssuerChainToObject(X509** cert,
2023
2027
X509_free (*cert);
2024
2028
2025
2029
// Delete cert and continue aggregating issuers.
2026
- *cert = sk_X509_delete (peer_certs, i);
2030
+ *cert = sk_X509_delete (peer_certs. get () , i);
2027
2031
break ;
2028
2032
}
2029
2033
2030
2034
// Issuer not found, break out of the loop.
2031
- if (i == sk_X509_num (peer_certs))
2035
+ if (i == sk_X509_num (peer_certs. get () ))
2032
2036
break ;
2033
2037
}
2034
- sk_X509_pop_free (peer_certs, X509_free);
2035
2038
return object;
2036
2039
}
2037
2040
2038
2041
2039
- static bool CloneSSLCerts (X509** cert,
2040
- const STACK_OF (X509)* const ssl_certs,
2041
- STACK_OF (X509)** peer_certs) {
2042
- *peer_certs = sk_X509_new (nullptr );
2043
- bool result = true ;
2042
+ static StackOfX509 CloneSSLCerts (X509** cert,
2043
+ const STACK_OF (X509)* const ssl_certs) {
2044
+ StackOfX509 peer_certs (sk_X509_new (nullptr ));
2044
2045
if (*cert != nullptr )
2045
- sk_X509_push (* peer_certs, *cert);
2046
+ sk_X509_push (peer_certs. get () , *cert);
2046
2047
for (int i = 0 ; i < sk_X509_num (ssl_certs); i++) {
2047
2048
*cert = X509_dup (sk_X509_value (ssl_certs, i));
2048
- if (*cert == nullptr ) {
2049
- result = false ;
2050
- break ;
2051
- }
2052
- if (!sk_X509_push (*peer_certs, *cert)) {
2053
- result = false ;
2054
- break ;
2055
- }
2056
- }
2057
- if (!result) {
2058
- sk_X509_pop_free (*peer_certs, X509_free);
2049
+ if (*cert == nullptr )
2050
+ return StackOfX509 ();
2051
+ if (!sk_X509_push (peer_certs.get (), *cert))
2052
+ return StackOfX509 ();
2059
2053
}
2060
- return result ;
2054
+ return peer_certs ;
2061
2055
}
2062
2056
2063
2057
@@ -2091,7 +2085,6 @@ void SSLWrap<Base>::GetPeerCertificate(
2091
2085
Base* w;
2092
2086
ASSIGN_OR_RETURN_UNWRAP (&w, args.Holder ());
2093
2087
Environment* env = w->ssl_env ();
2094
- Local<Context> context = env->context ();
2095
2088
2096
2089
ClearErrorOnReturn clear_error_on_return;
2097
2090
@@ -2103,23 +2096,25 @@ void SSLWrap<Base>::GetPeerCertificate(
2103
2096
// contains the `peer_certificate`, but on server it doesn't.
2104
2097
X509* cert = w->is_server () ? SSL_get_peer_certificate (w->ssl_ ) : nullptr ;
2105
2098
STACK_OF (X509)* ssl_certs = SSL_get_peer_cert_chain (w->ssl_ );
2106
- STACK_OF (X509)* peer_certs = nullptr ;
2107
2099
if (cert == nullptr && (ssl_certs == nullptr || sk_X509_num (ssl_certs) == 0 ))
2108
2100
goto done;
2109
2101
2110
2102
// Short result requested.
2111
2103
if (args.Length () < 1 || !args[0 ]->IsTrue ()) {
2112
- result = X509ToObject (env,
2113
- cert == nullptr ? sk_X509_value (ssl_certs, 0 ) : cert);
2104
+ X509* target_cert = cert;
2105
+ if (target_cert == nullptr )
2106
+ target_cert = sk_X509_value (ssl_certs, 0 );
2107
+ result = X509ToObject (env, target_cert);
2114
2108
goto done;
2115
2109
}
2116
2110
2117
- if (CloneSSLCerts (&cert, ssl_certs, &peer_certs )) {
2111
+ if (auto peer_certs = CloneSSLCerts (&cert, ssl_certs)) {
2118
2112
// First and main certificate.
2119
- cert = sk_X509_value (peer_certs, 0 );
2113
+ cert = sk_X509_value (peer_certs. get () , 0 );
2120
2114
result = X509ToObject (env, cert);
2121
2115
2122
- issuer_chain = AddIssuerChainToObject (&cert, result, peer_certs, env);
2116
+ issuer_chain =
2117
+ AddIssuerChainToObject (&cert, result, std::move (peer_certs), env);
2123
2118
issuer_chain = GetLastIssuedCert (&cert, w->ssl_ , issuer_chain, env);
2124
2119
// Last certificate should be self-signed.
2125
2120
if (X509_check_issued (cert, cert) == X509_V_OK)
@@ -3184,25 +3179,23 @@ inline CheckResult CheckWhitelistedServerCert(X509_STORE_CTX* ctx) {
3184
3179
unsigned char hash[CNNIC_WHITELIST_HASH_LEN];
3185
3180
unsigned int hashlen = CNNIC_WHITELIST_HASH_LEN;
3186
3181
3187
- STACK_OF (X509)* chain = X509_STORE_CTX_get1_chain (ctx);
3188
- CHECK_NE (chain, nullptr );
3189
- CHECK_GT (sk_X509_num (chain), 0 );
3182
+ StackOfX509 chain ( X509_STORE_CTX_get1_chain (ctx) );
3183
+ CHECK (chain);
3184
+ CHECK_GT (sk_X509_num (chain. get () ), 0 );
3190
3185
3191
3186
// Take the last cert as root at the first time.
3192
- X509* root_cert = sk_X509_value (chain, sk_X509_num (chain)-1 );
3187
+ X509* root_cert = sk_X509_value (chain. get () , sk_X509_num (chain. get () )-1 );
3193
3188
X509_NAME* root_name = X509_get_subject_name (root_cert);
3194
3189
3195
3190
if (!IsSelfSigned (root_cert)) {
3196
- root_cert = FindRoot (chain);
3191
+ root_cert = FindRoot (chain. get () );
3197
3192
CHECK_NE (root_cert, nullptr );
3198
3193
root_name = X509_get_subject_name (root_cert);
3199
3194
}
3200
3195
3201
- X509* leaf_cert = sk_X509_value (chain, 0 );
3202
- if (!CheckStartComOrWoSign (root_name, leaf_cert)) {
3203
- sk_X509_pop_free (chain, X509_free);
3196
+ X509* leaf_cert = sk_X509_value (chain.get (), 0 );
3197
+ if (!CheckStartComOrWoSign (root_name, leaf_cert))
3204
3198
return CHECK_CERT_REVOKED;
3205
- }
3206
3199
3207
3200
// When the cert is issued from either CNNNIC ROOT CA or CNNNIC EV
3208
3201
// ROOT CA, check a hash of its leaf cert if it is in the whitelist.
@@ -3215,13 +3208,10 @@ inline CheckResult CheckWhitelistedServerCert(X509_STORE_CTX* ctx) {
3215
3208
void * result = bsearch (hash, WhitelistedCNNICHashes,
3216
3209
arraysize (WhitelistedCNNICHashes),
3217
3210
CNNIC_WHITELIST_HASH_LEN, compar);
3218
- if (result == nullptr ) {
3219
- sk_X509_pop_free (chain, X509_free);
3211
+ if (result == nullptr )
3220
3212
return CHECK_CERT_REVOKED;
3221
- }
3222
3213
}
3223
3214
3224
- sk_X509_pop_free (chain, X509_free);
3225
3215
return CHECK_OK;
3226
3216
}
3227
3217
0 commit comments