Skip to content

Commit 5dcace0

Browse files
committed
Fixed bug #68879 (IP Address fields in subjectAltNames not used)
1 parent ca766e0 commit 5dcace0

File tree

4 files changed

+109
-22
lines changed

4 files changed

+109
-22
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
socket timeouts). (Brad Broerman)
3737
. Fixed bug #68920 (use strict peer_fingerprint input checks)
3838
(Daniel Lowrey)
39+
. Fixed bug #68879 (IP Address fields in subjectAltNames not used)
40+
(Daniel Lowrey)
3941

4042
- pgsql:
4143
. Fixed bug #68638 (pg_update() fails to store infinite values).

ext/openssl/tests/bug68879.pem

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
-----BEGIN ENCRYPTED PRIVATE KEY-----
2+
MIICxjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIuw/AFD7RWcMCAggA
3+
MBQGCCqGSIb3DQMHBAh98F6GmaGn1ASCAoBpzaFxyttEhyh4dhMjarJIqTz24DjO
4+
yZnp1K5qthejSYx2P28uUsh+gQOh6F2jbVAq++eAWkTBGuc4pWhhoT7nY8vhf0Y0
5+
6yTlVrTxuI/8MNo/lfa0xE/+ZD4B5zp0hQxfij4GTd8l6V/kpXMgiYD1JmIXArm7
6+
sucn+9XV3RucsTBpeIJ1nLEDfpbyEWqNfhoyskQ+S3I6HkMgELI9JpsO6OR9fh1Q
7+
ttdoYxBU+YjoDYcSWRGkTGrJFeGGhTQzz+L2ijgoqNWDSfrLBoQR1bqNVUuw6gcE
8+
9PpA/vpRlxcHbUNNkOWft+4e0tV3I2EqscEcsYeNbd2Ta4yu7f6pk4/Kxn40wrQ8
9+
6Ss9GZylghaFth2xppL/vpmGaCC7FqpZRh+NKqjlcBobIkwyRcsQrPHB0CYLPHA4
10+
yak/dNTY8L5K8Rtd5XG3+E41CoDF6ssNY0Kw7l9kAn/neDVh+WnQkWIiWPmq210a
11+
p4L/uiXRK7aYi+UqKJ5+svayNw2w1dkqpbeejwLq2F1+ek/447JFPVJcvP8Nm7sr
12+
04Mcg+ZHusZdjiWEv4W6CBq8o6eF2JdhfpSDgPkHwiZ/EarHfx0vcYIMJhlEQBmk
13+
a/XsZPk2wnamKSPfJautO3MIus0M6SniWF6eDA4/AZzSjXV8Vc0unb6lc+Nc8tJa
14+
6MU1soTsmki/YraCmQswqpL+kXFZVeHuLowOC5oH+CimQoscmiZ9tBvpnYo6XwEZ
15+
S9jZRIBQ77oMku+rlMPfz2FURgVXZpEfrGmxKvA5Vt3ojrYfTwwD2YqZHVcm39zy
16+
iKqA1qVt7A2A90ILMAzYnN0VRE4SO3yIDN1ZBp5OOY61AduPrhpaHl81
17+
-----END ENCRYPTED PRIVATE KEY-----
18+
-----BEGIN CERTIFICATE-----
19+
MIICkTCCAfqgAwIBAgIJAPbIVRT31Al1MA0GCSqGSIb3DQEBCwUAMFgxCzAJBgNV
20+
BAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQg
21+
Q29tcGFueSBMdGQxFDASBgNVBAMMC3BocCB0ZXN0IGNhMB4XDTE1MDMwNTA0NTQx
22+
NVoXDTI1MDMwMjA0NTQxNVowUjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlNDMRUw
23+
EwYDVQQHDAxNeXJ0bGUgQmVhY2gxDDAKBgNVBAsMA1BIUDERMA8GA1UEAwwIdGVz
24+
dC5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKp5gxUbKvY5eFwZJti0
25+
6d6YBo400Or6M+bLfIMnz5C1WQ7dMfiQpeFLpSIlOIaFqyrqkeeR9k5dsx1K9FOu
26+
PAJ4+lmWA4R93RpdJFz8kmQoNu3P59JMATXi8wvNBIrN/Vc08NT0wBRImeyQSVHd
27+
UcFIXBEbBM0dQsPKQ1k8n5WDAgMBAAGjaTBnMAkGA1UdEwQCMAAwCwYDVR0PBAQD
28+
AgXgME0GA1UdEQRGMESCCHRlc3QuY29tggx3d3cudGVzdC5jb22CEnN1YmRvbWFp
29+
bi50ZXN0LmNvbYcQAAAAAAAAAAAAAP//CgIAAYcECgIAATANBgkqhkiG9w0BAQsF
30+
AAOBgQBZ4TptNXV85gNj3wcB5feWFcwKO8cN4hwnhrbqiHN280r9O/g1CQiLmB4K
31+
2txrJt06UNCnvWse7CdvsN14wu6rRGRk/+7M36NBw5ERkAzp5HXgZUWVdMl3YltB
32+
PpqbLhGGrkVn7/jW2FdAxfax7qaGDYgC3qcQNfiK6K92SPxV7Q==
33+
-----END CERTIFICATE-----

ext/openssl/tests/bug68879.phpt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--TEST--
2+
Bug #68879: Match IP address fields in subjectAltName checks
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded("openssl")) die("skip openssl not loaded");
6+
if (!function_exists("proc_open")) die("skip no proc_open");
7+
--FILE--
8+
<?php
9+
$serverCode = <<<'CODE'
10+
$serverUri = "ssl://127.0.0.1:64321";
11+
$serverFlags = STREAM_SERVER_BIND | STREAM_SERVER_LISTEN;
12+
$serverCtx = stream_context_create(['ssl' => [
13+
'local_cert' => __DIR__ . '/bug68879.pem',
14+
'passphrase' => 'elephpant',
15+
]]);
16+
17+
$server = stream_socket_server($serverUri, $errno, $errstr, $serverFlags, $serverCtx);
18+
phpt_notify();
19+
20+
stream_socket_accept($server, 30);
21+
CODE;
22+
23+
$clientCode = <<<'CODE'
24+
$serverUri = "ssl://127.0.0.1:64321";
25+
$clientFlags = STREAM_CLIENT_CONNECT;
26+
$clientCtx = stream_context_create(['ssl' => [
27+
'verify_peer' => false,
28+
'verify_peer_name' => true,
29+
'peer_name' => '10.2.0.1',
30+
]]);
31+
32+
phpt_wait();
33+
34+
var_dump(stream_socket_client($serverUri, $errno, $errstr, 30, $clientFlags, $clientCtx));
35+
CODE;
36+
37+
include 'ServerClientTestCase.inc';
38+
ServerClientTestCase::getInstance()->run($clientCode, $serverCode);
39+
--EXPECTF--
40+
resource(%d) of type (stream)
41+

ext/openssl/xp_ssl.c

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -370,40 +370,51 @@ static zend_bool matches_wildcard_name(const char *subjectname, const char *cert
370370
}
371371
/* }}} */
372372

373-
static zend_bool matches_san_list(X509 *peer, const char *subject_name TSRMLS_DC) /* {{{ */
373+
static zend_bool matches_san_list(X509 *peer, const char *subject_name) /* {{{ */
374374
{
375-
int i, san_name_len;
376-
zend_bool is_match = 0;
375+
int i;
377376
unsigned char *cert_name = NULL;
377+
char ipbuffer[64];
378378

379379
GENERAL_NAMES *alt_names = X509_get_ext_d2i(peer, NID_subject_alt_name, 0, 0);
380380
int alt_name_count = sk_GENERAL_NAME_num(alt_names);
381381

382382
for (i = 0; i < alt_name_count; i++) {
383383
GENERAL_NAME *san = sk_GENERAL_NAME_value(alt_names, i);
384-
if (san->type != GEN_DNS) {
385-
/* we only care about DNS names */
386-
continue;
387-
}
388-
389-
san_name_len = ASN1_STRING_length(san->d.dNSName);
390-
ASN1_STRING_to_UTF8(&cert_name, san->d.dNSName);
391-
392-
/* prevent null byte poisoning */
393-
if (san_name_len != strlen((const char*)cert_name)) {
394-
php_error_docref(NULL TSRMLS_CC, E_WARNING, "Peer SAN entry is malformed");
395-
} else {
396-
is_match = matches_wildcard_name(subject_name, (const char *)cert_name);
397-
}
398384

399-
OPENSSL_free(cert_name);
385+
if (san->type == GEN_DNS) {
386+
ASN1_STRING_to_UTF8(&cert_name, san->d.dNSName);
387+
if (ASN1_STRING_length(san->d.dNSName) != strlen((const char*)cert_name)) {
388+
OPENSSL_free(cert_name);
389+
/* prevent null-byte poisoning*/
390+
continue;
391+
}
400392

401-
if (is_match) {
402-
break;
393+
if (matches_wildcard_name(subject_name, (const char *)cert_name)) {
394+
OPENSSL_free(cert_name);
395+
return 1;
396+
}
397+
OPENSSL_free(cert_name);
398+
} else if (san->type == GEN_IPADD) {
399+
if (san->d.iPAddress->length == 4) {
400+
sprintf(ipbuffer, "%d.%d.%d.%d",
401+
san->d.iPAddress->data[0],
402+
san->d.iPAddress->data[1],
403+
san->d.iPAddress->data[2],
404+
san->d.iPAddress->data[3]
405+
);
406+
if (strcasecmp(subject_name, (const char*)ipbuffer) == 0) {
407+
return 1;
408+
}
409+
}
410+
/* No, we aren't bothering to check IPv6 addresses. Why?
411+
* Because IP SAN names are officially deprecated and are
412+
* not allowed by CAs starting in 2015. Deal with it.
413+
*/
403414
}
404415
}
405416

406-
return is_match;
417+
return 0;
407418
}
408419
/* }}} */
409420

@@ -515,7 +526,7 @@ static int apply_peer_verification_policy(SSL *ssl, X509 *peer, php_stream *stre
515526
}
516527

517528
if (peer_name) {
518-
if (matches_san_list(peer, peer_name TSRMLS_CC)) {
529+
if (matches_san_list(peer, peer_name)) {
519530
return SUCCESS;
520531
} else if (matches_common_name(peer, peer_name TSRMLS_CC)) {
521532
return SUCCESS;

0 commit comments

Comments
 (0)