1*b1cdbd2cSJim Jagielski------------------------------------------------------------------------ 2*b1cdbd2cSJim Jagielskir1699925 | breser | 2014-08-04 11:04:00 -0700 (Mon, 04 Aug 2014) | 5 lines 3*b1cdbd2cSJim Jagielski 4*b1cdbd2cSJim JagielskiOn the 1.3.x branch: 5*b1cdbd2cSJim Jagielski 6*b1cdbd2cSJim JagielskiMerge changes from trunk: 7*b1cdbd2cSJim Jagielski- r2392: Handle NUL bytes in fields of X.509 certs. 8*b1cdbd2cSJim Jagielski 9*b1cdbd2cSJim Jagielski------------------------------------------------------------------------ 10*b1cdbd2cSJim JagielskiIndex: misc/build/serf-1.2.1/buckets/ssl_buckets.c 11*b1cdbd2cSJim Jagielski=================================================================== 12*b1cdbd2cSJim Jagielski--- misc/serf-1.2.1/buckets/ssl_buckets.c (revision 1699924) 13*b1cdbd2cSJim Jagielski+++ misc/build/serf-1.2.1/buckets/ssl_buckets.c (revision 1699925) 14*b1cdbd2cSJim Jagielski@@ -202,6 +202,8 @@ 15*b1cdbd2cSJim Jagielski }; 16*b1cdbd2cSJim Jagielski 17*b1cdbd2cSJim Jagielski static void disable_compression(serf_ssl_context_t *ssl_ctx); 18*b1cdbd2cSJim Jagielski+static char * 19*b1cdbd2cSJim Jagielski+ pstrdup_escape_nul_bytes(const char *buf, int len, apr_pool_t *pool); 20*b1cdbd2cSJim Jagielski 21*b1cdbd2cSJim Jagielski #if SSL_VERBOSE 22*b1cdbd2cSJim Jagielski /* Log all ssl alerts that we receive from the server. */ 23*b1cdbd2cSJim Jagielski@@ -427,6 +429,81 @@ 24*b1cdbd2cSJim Jagielski #endif 25*b1cdbd2cSJim Jagielski }; 26*b1cdbd2cSJim Jagielski 27*b1cdbd2cSJim Jagielski+typedef enum san_copy_t { 28*b1cdbd2cSJim Jagielski+ EscapeNulAndCopy = 0, 29*b1cdbd2cSJim Jagielski+ ErrorOnNul = 1, 30*b1cdbd2cSJim Jagielski+} san_copy_t; 31*b1cdbd2cSJim Jagielski+ 32*b1cdbd2cSJim Jagielski+ 33*b1cdbd2cSJim Jagielski+static apr_status_t 34*b1cdbd2cSJim Jagielski+get_subject_alt_names(apr_array_header_t **san_arr, X509 *ssl_cert, 35*b1cdbd2cSJim Jagielski+ san_copy_t copy_action, apr_pool_t *pool) 36*b1cdbd2cSJim Jagielski+{ 37*b1cdbd2cSJim Jagielski+ STACK_OF(GENERAL_NAME) *names; 38*b1cdbd2cSJim Jagielski+ 39*b1cdbd2cSJim Jagielski+ /* assert: copy_action == ErrorOnNul || (san_arr && pool) */ 40*b1cdbd2cSJim Jagielski+ 41*b1cdbd2cSJim Jagielski+ /* Get subjectAltNames */ 42*b1cdbd2cSJim Jagielski+ names = X509_get_ext_d2i(ssl_cert, NID_subject_alt_name, NULL, NULL); 43*b1cdbd2cSJim Jagielski+ if (names) { 44*b1cdbd2cSJim Jagielski+ int names_count = sk_GENERAL_NAME_num(names); 45*b1cdbd2cSJim Jagielski+ int name_idx; 46*b1cdbd2cSJim Jagielski+ 47*b1cdbd2cSJim Jagielski+ if (san_arr) 48*b1cdbd2cSJim Jagielski+ *san_arr = apr_array_make(pool, names_count, sizeof(char*)); 49*b1cdbd2cSJim Jagielski+ for (name_idx = 0; name_idx < names_count; name_idx++) { 50*b1cdbd2cSJim Jagielski+ char *p = NULL; 51*b1cdbd2cSJim Jagielski+ GENERAL_NAME *nm = sk_GENERAL_NAME_value(names, name_idx); 52*b1cdbd2cSJim Jagielski+ 53*b1cdbd2cSJim Jagielski+ switch (nm->type) { 54*b1cdbd2cSJim Jagielski+ case GEN_DNS: 55*b1cdbd2cSJim Jagielski+ if (copy_action == ErrorOnNul && 56*b1cdbd2cSJim Jagielski+ strlen(nm->d.ia5->data) != nm->d.ia5->length) 57*b1cdbd2cSJim Jagielski+ return SERF_ERROR_SSL_CERT_FAILED; 58*b1cdbd2cSJim Jagielski+ if (san_arr && *san_arr) 59*b1cdbd2cSJim Jagielski+ p = pstrdup_escape_nul_bytes((const char *)nm->d.ia5->data, 60*b1cdbd2cSJim Jagielski+ nm->d.ia5->length, 61*b1cdbd2cSJim Jagielski+ pool); 62*b1cdbd2cSJim Jagielski+ break; 63*b1cdbd2cSJim Jagielski+ default: 64*b1cdbd2cSJim Jagielski+ /* Don't know what to do - skip. */ 65*b1cdbd2cSJim Jagielski+ break; 66*b1cdbd2cSJim Jagielski+ } 67*b1cdbd2cSJim Jagielski+ 68*b1cdbd2cSJim Jagielski+ if (p) { 69*b1cdbd2cSJim Jagielski+ APR_ARRAY_PUSH(*san_arr, char*) = p; 70*b1cdbd2cSJim Jagielski+ } 71*b1cdbd2cSJim Jagielski+ } 72*b1cdbd2cSJim Jagielski+ sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free); 73*b1cdbd2cSJim Jagielski+ } 74*b1cdbd2cSJim Jagielski+ 75*b1cdbd2cSJim Jagielski+ return APR_SUCCESS; 76*b1cdbd2cSJim Jagielski+} 77*b1cdbd2cSJim Jagielski+ 78*b1cdbd2cSJim Jagielski+static apr_status_t validate_cert_hostname(X509 *server_cert, apr_pool_t *pool) 79*b1cdbd2cSJim Jagielski+{ 80*b1cdbd2cSJim Jagielski+ char buf[1024]; 81*b1cdbd2cSJim Jagielski+ int length; 82*b1cdbd2cSJim Jagielski+ apr_status_t ret; 83*b1cdbd2cSJim Jagielski+ 84*b1cdbd2cSJim Jagielski+ ret = get_subject_alt_names(NULL, server_cert, ErrorOnNul, NULL); 85*b1cdbd2cSJim Jagielski+ if (ret) { 86*b1cdbd2cSJim Jagielski+ return ret; 87*b1cdbd2cSJim Jagielski+ } else { 88*b1cdbd2cSJim Jagielski+ /* Fail if the subject's CN field contains \0 characters. */ 89*b1cdbd2cSJim Jagielski+ X509_NAME *subject = X509_get_subject_name(server_cert); 90*b1cdbd2cSJim Jagielski+ if (!subject) 91*b1cdbd2cSJim Jagielski+ return SERF_ERROR_SSL_CERT_FAILED; 92*b1cdbd2cSJim Jagielski+ 93*b1cdbd2cSJim Jagielski+ length = X509_NAME_get_text_by_NID(subject, NID_commonName, buf, 1024); 94*b1cdbd2cSJim Jagielski+ if (length != -1) 95*b1cdbd2cSJim Jagielski+ if (strlen(buf) != length) 96*b1cdbd2cSJim Jagielski+ return SERF_ERROR_SSL_CERT_FAILED; 97*b1cdbd2cSJim Jagielski+ } 98*b1cdbd2cSJim Jagielski+ 99*b1cdbd2cSJim Jagielski+ return APR_SUCCESS; 100*b1cdbd2cSJim Jagielski+} 101*b1cdbd2cSJim Jagielski+ 102*b1cdbd2cSJim Jagielski static int 103*b1cdbd2cSJim Jagielski validate_server_certificate(int cert_valid, X509_STORE_CTX *store_ctx) 104*b1cdbd2cSJim Jagielski { 105*b1cdbd2cSJim Jagielski@@ -435,6 +512,7 @@ 106*b1cdbd2cSJim Jagielski X509 *server_cert; 107*b1cdbd2cSJim Jagielski int err, depth; 108*b1cdbd2cSJim Jagielski int failures = 0; 109*b1cdbd2cSJim Jagielski+ apr_status_t status; 110*b1cdbd2cSJim Jagielski 111*b1cdbd2cSJim Jagielski ssl = X509_STORE_CTX_get_ex_data(store_ctx, 112*b1cdbd2cSJim Jagielski SSL_get_ex_data_X509_STORE_CTX_idx()); 113*b1cdbd2cSJim Jagielski@@ -475,6 +553,11 @@ 114*b1cdbd2cSJim Jagielski } 115*b1cdbd2cSJim Jagielski } 116*b1cdbd2cSJim Jagielski 117*b1cdbd2cSJim Jagielski+ /* Validate hostname */ 118*b1cdbd2cSJim Jagielski+ status = validate_cert_hostname(server_cert, ctx->pool); 119*b1cdbd2cSJim Jagielski+ if (status) 120*b1cdbd2cSJim Jagielski+ failures |= SERF_SSL_CERT_UNKNOWN_FAILURE; 121*b1cdbd2cSJim Jagielski+ 122*b1cdbd2cSJim Jagielski /* Check certificate expiry dates. */ 123*b1cdbd2cSJim Jagielski if (X509_cmp_current_time(X509_get_notBefore(server_cert)) >= 0) { 124*b1cdbd2cSJim Jagielski failures |= SERF_SSL_CERT_NOTYETVALID; 125*b1cdbd2cSJim Jagielski@@ -485,7 +568,6 @@ 126*b1cdbd2cSJim Jagielski 127*b1cdbd2cSJim Jagielski if (ctx->server_cert_callback && 128*b1cdbd2cSJim Jagielski (depth == 0 || failures)) { 129*b1cdbd2cSJim Jagielski- apr_status_t status; 130*b1cdbd2cSJim Jagielski serf_ssl_certificate_t *cert; 131*b1cdbd2cSJim Jagielski apr_pool_t *subpool; 132*b1cdbd2cSJim Jagielski 133*b1cdbd2cSJim Jagielski@@ -512,7 +594,6 @@ 134*b1cdbd2cSJim Jagielski 135*b1cdbd2cSJim Jagielski if (ctx->server_cert_chain_callback 136*b1cdbd2cSJim Jagielski && (depth == 0 || failures)) { 137*b1cdbd2cSJim Jagielski- apr_status_t status; 138*b1cdbd2cSJim Jagielski STACK_OF(X509) *chain; 139*b1cdbd2cSJim Jagielski const serf_ssl_certificate_t **certs; 140*b1cdbd2cSJim Jagielski int certs_len; 141*b1cdbd2cSJim Jagielski@@ -1461,7 +1542,50 @@ 142*b1cdbd2cSJim Jagielski 143*b1cdbd2cSJim Jagielski /* Functions to read a serf_ssl_certificate structure. */ 144*b1cdbd2cSJim Jagielski 145*b1cdbd2cSJim Jagielski-/* Creates a hash_table with keys (E, CN, OU, O, L, ST and C). */ 146*b1cdbd2cSJim Jagielski+/* Takes a counted length string and escapes any NUL bytes so that 147*b1cdbd2cSJim Jagielski+ * it can be used as a C string. NUL bytes are escaped as 3 characters 148*b1cdbd2cSJim Jagielski+ * "\00" (that's a literal backslash). 149*b1cdbd2cSJim Jagielski+ * The returned string is allocated in POOL. 150*b1cdbd2cSJim Jagielski+ */ 151*b1cdbd2cSJim Jagielski+static char * 152*b1cdbd2cSJim Jagielski+pstrdup_escape_nul_bytes(const char *buf, int len, apr_pool_t *pool) 153*b1cdbd2cSJim Jagielski+{ 154*b1cdbd2cSJim Jagielski+ int i, nul_count = 0; 155*b1cdbd2cSJim Jagielski+ char *ret; 156*b1cdbd2cSJim Jagielski+ 157*b1cdbd2cSJim Jagielski+ /* First determine if there are any nul bytes in the string. */ 158*b1cdbd2cSJim Jagielski+ for (i = 0; i < len; i++) { 159*b1cdbd2cSJim Jagielski+ if (buf[i] == '\0') 160*b1cdbd2cSJim Jagielski+ nul_count++; 161*b1cdbd2cSJim Jagielski+ } 162*b1cdbd2cSJim Jagielski+ 163*b1cdbd2cSJim Jagielski+ if (nul_count == 0) { 164*b1cdbd2cSJim Jagielski+ /* There aren't so easy case to just copy the string */ 165*b1cdbd2cSJim Jagielski+ ret = apr_pstrdup(pool, buf); 166*b1cdbd2cSJim Jagielski+ } else { 167*b1cdbd2cSJim Jagielski+ /* There are so we have to replace nul bytes with escape codes 168*b1cdbd2cSJim Jagielski+ * Proper length is the length of the original string, plus 169*b1cdbd2cSJim Jagielski+ * 2 times the number of nulls (for two digit hex code for 170*b1cdbd2cSJim Jagielski+ * the value) + the trailing null. */ 171*b1cdbd2cSJim Jagielski+ char *pos; 172*b1cdbd2cSJim Jagielski+ ret = pos = apr_palloc(pool, len + 2 * nul_count + 1); 173*b1cdbd2cSJim Jagielski+ for (i = 0; i < len; i++) { 174*b1cdbd2cSJim Jagielski+ if (buf[i] != '\0') { 175*b1cdbd2cSJim Jagielski+ *(pos++) = buf[i]; 176*b1cdbd2cSJim Jagielski+ } else { 177*b1cdbd2cSJim Jagielski+ *(pos++) = '\\'; 178*b1cdbd2cSJim Jagielski+ *(pos++) = '0'; 179*b1cdbd2cSJim Jagielski+ *(pos++) = '0'; 180*b1cdbd2cSJim Jagielski+ } 181*b1cdbd2cSJim Jagielski+ } 182*b1cdbd2cSJim Jagielski+ *pos = '\0'; 183*b1cdbd2cSJim Jagielski+ } 184*b1cdbd2cSJim Jagielski+ 185*b1cdbd2cSJim Jagielski+ return ret; 186*b1cdbd2cSJim Jagielski+} 187*b1cdbd2cSJim Jagielski+ 188*b1cdbd2cSJim Jagielski+/* Creates a hash_table with keys (E, CN, OU, O, L, ST and C). Any NUL bytes in 189*b1cdbd2cSJim Jagielski+ these fields in the certificate will be escaped as \00. */ 190*b1cdbd2cSJim Jagielski static apr_hash_t * 191*b1cdbd2cSJim Jagielski convert_X509_NAME_to_table(X509_NAME *org, apr_pool_t *pool) 192*b1cdbd2cSJim Jagielski { 193*b1cdbd2cSJim Jagielski@@ -1474,37 +1598,44 @@ 194*b1cdbd2cSJim Jagielski NID_commonName, 195*b1cdbd2cSJim Jagielski buf, 1024); 196*b1cdbd2cSJim Jagielski if (ret != -1) 197*b1cdbd2cSJim Jagielski- apr_hash_set(tgt, "CN", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf)); 198*b1cdbd2cSJim Jagielski+ apr_hash_set(tgt, "CN", APR_HASH_KEY_STRING, 199*b1cdbd2cSJim Jagielski+ pstrdup_escape_nul_bytes(buf, ret, pool)); 200*b1cdbd2cSJim Jagielski ret = X509_NAME_get_text_by_NID(org, 201*b1cdbd2cSJim Jagielski NID_pkcs9_emailAddress, 202*b1cdbd2cSJim Jagielski buf, 1024); 203*b1cdbd2cSJim Jagielski if (ret != -1) 204*b1cdbd2cSJim Jagielski- apr_hash_set(tgt, "E", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf)); 205*b1cdbd2cSJim Jagielski+ apr_hash_set(tgt, "E", APR_HASH_KEY_STRING, 206*b1cdbd2cSJim Jagielski+ pstrdup_escape_nul_bytes(buf, ret, pool)); 207*b1cdbd2cSJim Jagielski ret = X509_NAME_get_text_by_NID(org, 208*b1cdbd2cSJim Jagielski NID_organizationalUnitName, 209*b1cdbd2cSJim Jagielski buf, 1024); 210*b1cdbd2cSJim Jagielski if (ret != -1) 211*b1cdbd2cSJim Jagielski- apr_hash_set(tgt, "OU", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf)); 212*b1cdbd2cSJim Jagielski+ apr_hash_set(tgt, "OU", APR_HASH_KEY_STRING, 213*b1cdbd2cSJim Jagielski+ pstrdup_escape_nul_bytes(buf, ret, pool)); 214*b1cdbd2cSJim Jagielski ret = X509_NAME_get_text_by_NID(org, 215*b1cdbd2cSJim Jagielski NID_organizationName, 216*b1cdbd2cSJim Jagielski buf, 1024); 217*b1cdbd2cSJim Jagielski if (ret != -1) 218*b1cdbd2cSJim Jagielski- apr_hash_set(tgt, "O", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf)); 219*b1cdbd2cSJim Jagielski+ apr_hash_set(tgt, "O", APR_HASH_KEY_STRING, 220*b1cdbd2cSJim Jagielski+ pstrdup_escape_nul_bytes(buf, ret, pool)); 221*b1cdbd2cSJim Jagielski ret = X509_NAME_get_text_by_NID(org, 222*b1cdbd2cSJim Jagielski NID_localityName, 223*b1cdbd2cSJim Jagielski buf, 1024); 224*b1cdbd2cSJim Jagielski if (ret != -1) 225*b1cdbd2cSJim Jagielski- apr_hash_set(tgt, "L", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf)); 226*b1cdbd2cSJim Jagielski+ apr_hash_set(tgt, "L", APR_HASH_KEY_STRING, 227*b1cdbd2cSJim Jagielski+ pstrdup_escape_nul_bytes(buf, ret, pool)); 228*b1cdbd2cSJim Jagielski ret = X509_NAME_get_text_by_NID(org, 229*b1cdbd2cSJim Jagielski NID_stateOrProvinceName, 230*b1cdbd2cSJim Jagielski buf, 1024); 231*b1cdbd2cSJim Jagielski if (ret != -1) 232*b1cdbd2cSJim Jagielski- apr_hash_set(tgt, "ST", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf)); 233*b1cdbd2cSJim Jagielski+ apr_hash_set(tgt, "ST", APR_HASH_KEY_STRING, 234*b1cdbd2cSJim Jagielski+ pstrdup_escape_nul_bytes(buf, ret, pool)); 235*b1cdbd2cSJim Jagielski ret = X509_NAME_get_text_by_NID(org, 236*b1cdbd2cSJim Jagielski NID_countryName, 237*b1cdbd2cSJim Jagielski buf, 1024); 238*b1cdbd2cSJim Jagielski if (ret != -1) 239*b1cdbd2cSJim Jagielski- apr_hash_set(tgt, "C", APR_HASH_KEY_STRING, apr_pstrdup(pool, buf)); 240*b1cdbd2cSJim Jagielski+ apr_hash_set(tgt, "C", APR_HASH_KEY_STRING, 241*b1cdbd2cSJim Jagielski+ pstrdup_escape_nul_bytes(buf, ret, pool)); 242*b1cdbd2cSJim Jagielski 243*b1cdbd2cSJim Jagielski return tgt; 244*b1cdbd2cSJim Jagielski } 245*b1cdbd2cSJim Jagielski@@ -1550,7 +1681,7 @@ 246*b1cdbd2cSJim Jagielski unsigned int md_size, i; 247*b1cdbd2cSJim Jagielski unsigned char md[EVP_MAX_MD_SIZE]; 248*b1cdbd2cSJim Jagielski BIO *bio; 249*b1cdbd2cSJim Jagielski- STACK_OF(GENERAL_NAME) *names; 250*b1cdbd2cSJim Jagielski+ apr_array_header_t *san_arr; 251*b1cdbd2cSJim Jagielski 252*b1cdbd2cSJim Jagielski /* sha1 fingerprint */ 253*b1cdbd2cSJim Jagielski if (X509_digest(cert->ssl_cert, EVP_sha1(), md, &md_size)) { 254*b1cdbd2cSJim Jagielski@@ -1595,33 +1726,9 @@ 255*b1cdbd2cSJim Jagielski BIO_free(bio); 256*b1cdbd2cSJim Jagielski 257*b1cdbd2cSJim Jagielski /* Get subjectAltNames */ 258*b1cdbd2cSJim Jagielski- names = X509_get_ext_d2i(cert->ssl_cert, NID_subject_alt_name, NULL, NULL); 259*b1cdbd2cSJim Jagielski- if (names) { 260*b1cdbd2cSJim Jagielski- int names_count = sk_GENERAL_NAME_num(names); 261*b1cdbd2cSJim Jagielski- 262*b1cdbd2cSJim Jagielski- apr_array_header_t *san_arr = apr_array_make(pool, names_count, 263*b1cdbd2cSJim Jagielski- sizeof(char*)); 264*b1cdbd2cSJim Jagielski+ if (!get_subject_alt_names(&san_arr, cert->ssl_cert, EscapeNulAndCopy, pool)) 265*b1cdbd2cSJim Jagielski apr_hash_set(tgt, "subjectAltName", APR_HASH_KEY_STRING, san_arr); 266*b1cdbd2cSJim Jagielski- for (i = 0; i < names_count; i++) { 267*b1cdbd2cSJim Jagielski- char *p = NULL; 268*b1cdbd2cSJim Jagielski- GENERAL_NAME *nm = sk_GENERAL_NAME_value(names, i); 269*b1cdbd2cSJim Jagielski 270*b1cdbd2cSJim Jagielski- switch (nm->type) { 271*b1cdbd2cSJim Jagielski- case GEN_DNS: 272*b1cdbd2cSJim Jagielski- p = apr_pstrmemdup(pool, (const char *)nm->d.ia5->data, 273*b1cdbd2cSJim Jagielski- nm->d.ia5->length); 274*b1cdbd2cSJim Jagielski- break; 275*b1cdbd2cSJim Jagielski- default: 276*b1cdbd2cSJim Jagielski- /* Don't know what to do - skip. */ 277*b1cdbd2cSJim Jagielski- break; 278*b1cdbd2cSJim Jagielski- } 279*b1cdbd2cSJim Jagielski- if (p) { 280*b1cdbd2cSJim Jagielski- APR_ARRAY_PUSH(san_arr, char*) = p; 281*b1cdbd2cSJim Jagielski- } 282*b1cdbd2cSJim Jagielski- } 283*b1cdbd2cSJim Jagielski- sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free); 284*b1cdbd2cSJim Jagielski- } 285*b1cdbd2cSJim Jagielski- 286*b1cdbd2cSJim Jagielski return tgt; 287*b1cdbd2cSJim Jagielski } 288*b1cdbd2cSJim Jagielski 289*b1cdbd2cSJim Jagielski------------------------------------------------------------------------ 290*b1cdbd2cSJim Jagielskir1699931 | breser | 2014-08-05 19:24:00 -0700 (Tue, 05 Aug 2014) | 6 lines 291*b1cdbd2cSJim Jagielski 292*b1cdbd2cSJim JagielskiOn the 1.3.x branch: 293*b1cdbd2cSJim Jagielski 294*b1cdbd2cSJim JagielskiMerge changes from trunk: 295*b1cdbd2cSJim Jagielski- r2398: Initialize san_arr when we're expected to fill it. 296*b1cdbd2cSJim Jagielski 297*b1cdbd2cSJim Jagielski 298*b1cdbd2cSJim Jagielski------------------------------------------------------------------------ 299*b1cdbd2cSJim JagielskiIndex: misc/build/serf-1.2.1/buckets/ssl_buckets.c 300*b1cdbd2cSJim Jagielski=================================================================== 301*b1cdbd2cSJim Jagielski--- misc/serf-1.2.1/buckets/ssl_buckets.c (revision 1699930) 302*b1cdbd2cSJim Jagielski+++ misc/build/serf-1.2.1/buckets/ssl_buckets.c (revision 1699931) 303*b1cdbd2cSJim Jagielski@@ -443,6 +443,10 @@ 304*b1cdbd2cSJim Jagielski 305*b1cdbd2cSJim Jagielski /* assert: copy_action == ErrorOnNul || (san_arr && pool) */ 306*b1cdbd2cSJim Jagielski 307*b1cdbd2cSJim Jagielski+ if (san_arr) { 308*b1cdbd2cSJim Jagielski+ *san_arr = NULL; 309*b1cdbd2cSJim Jagielski+ } 310*b1cdbd2cSJim Jagielski+ 311*b1cdbd2cSJim Jagielski /* Get subjectAltNames */ 312*b1cdbd2cSJim Jagielski names = X509_get_ext_d2i(ssl_cert, NID_subject_alt_name, NULL, NULL); 313*b1cdbd2cSJim Jagielski if (names) { 314