|
44 | 44 | #undef X509_NAME
|
45 | 45 | #undef X509_CERT_PAIR
|
46 | 46 | #undef X509_EXTENSIONS
|
| 47 | +#else |
| 48 | +#include <arpa/inet.h> |
47 | 49 | #endif
|
48 | 50 |
|
49 | 51 | /* Flags for determining allowed stream crypto methods */
|
|
110 | 112 | #define PHP_X509_NAME_ENTRY_TO_UTF8(ne, i, out) \
|
111 | 113 | ASN1_STRING_to_UTF8(&out, X509_NAME_ENTRY_get_data(X509_NAME_get_entry(ne, i)))
|
112 | 114 |
|
| 115 | +/* Used for IPv6 Address peer verification */ |
| 116 | +#define EXPAND_IPV6_ADDRESS(_str, _bytes) \ |
| 117 | + do { \ |
| 118 | + snprintf(_str, 39, "%X:%X:%X:%X:%X:%X:%X:%X", \ |
| 119 | + _bytes[0] << 8 | _bytes[1], \ |
| 120 | + _bytes[2] << 8 | _bytes[3], \ |
| 121 | + _bytes[4] << 8 | _bytes[5], \ |
| 122 | + _bytes[6] << 8 | _bytes[7], \ |
| 123 | + _bytes[8] << 8 | _bytes[9], \ |
| 124 | + _bytes[10] << 8 | _bytes[11], \ |
| 125 | + _bytes[12] << 8 | _bytes[13], \ |
| 126 | + _bytes[14] << 8 | _bytes[15] \ |
| 127 | + ); \ |
| 128 | + } while(0) |
| 129 | + |
113 | 130 | #if PHP_OPENSSL_API_VERSION < 0x10100
|
114 | 131 | static RSA *php_openssl_tmp_rsa_cb(SSL *s, int is_export, int keylength);
|
115 | 132 | #endif
|
@@ -416,11 +433,18 @@ static bool php_openssl_matches_san_list(X509 *peer, const char *subject_name) /
|
416 | 433 | {
|
417 | 434 | int i, len;
|
418 | 435 | unsigned char *cert_name = NULL;
|
419 |
| - char ipbuffer[64]; |
| 436 | + char ipbuffer[64], ipv6_expanded[40]; |
| 437 | + unsigned char ipv6[16]; |
420 | 438 |
|
421 | 439 | GENERAL_NAMES *alt_names = X509_get_ext_d2i(peer, NID_subject_alt_name, 0, 0);
|
422 | 440 | int alt_name_count = sk_GENERAL_NAME_num(alt_names);
|
423 | 441 |
|
| 442 | + /* detect if subject name is an IPv6 address and expand once if required */ |
| 443 | + ipv6_expanded[0] = 0; |
| 444 | + if (inet_pton(AF_INET6,subject_name,&ipv6)) { |
| 445 | + EXPAND_IPV6_ADDRESS(ipv6_expanded, ipv6); |
| 446 | + } |
| 447 | + |
424 | 448 | for (i = 0; i < alt_name_count; i++) {
|
425 | 449 | GENERAL_NAME *san = sk_GENERAL_NAME_value(alt_names, i);
|
426 | 450 |
|
@@ -456,13 +480,17 @@ static bool php_openssl_matches_san_list(X509 *peer, const char *subject_name) /
|
456 | 480 | if (strcasecmp(subject_name, (const char*)ipbuffer) == 0) {
|
457 | 481 | sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free);
|
458 | 482 |
|
| 483 | + return 1; |
| 484 | + } |
| 485 | + } else if (san->d.ip->length == 16 && strlen(ipv6_expanded) >= 15) { /* shortest expanded IPv6 address is 0:0:0:0:0:0:0:0 */ |
| 486 | + ipbuffer[0] = 0; |
| 487 | + EXPAND_IPV6_ADDRESS(ipbuffer, san->d.iPAddress->data); |
| 488 | + if (strcasecmp((const char*)ipv6_expanded, (const char*)ipbuffer) == 0) { |
| 489 | + sk_GENERAL_NAME_pop_free(alt_names, GENERAL_NAME_free); |
| 490 | + |
459 | 491 | return 1;
|
460 | 492 | }
|
461 | 493 | }
|
462 |
| - /* No, we aren't bothering to check IPv6 addresses. Why? |
463 |
| - * Because IP SAN names are officially deprecated and are |
464 |
| - * not allowed by CAs starting in 2015. Deal with it. |
465 |
| - */ |
466 | 494 | }
|
467 | 495 | }
|
468 | 496 |
|
|
0 commit comments