@@ -1326,6 +1326,74 @@ PHP_FUNCTION(openssl_x509_check_private_key)
1326
1326
}
1327
1327
/* }}} */
1328
1328
1329
+ /* Special handling of subjectAltName, see CVE-2013-4073
1330
+ * Christian Heimes
1331
+ */
1332
+
1333
+ static int openssl_x509v3_subjectAltName (BIO * bio , X509_EXTENSION * extension )
1334
+ {
1335
+ GENERAL_NAMES * names ;
1336
+ const X509V3_EXT_METHOD * method = NULL ;
1337
+ long i , length , num ;
1338
+ const unsigned char * p ;
1339
+
1340
+ method = X509V3_EXT_get (extension );
1341
+ if (method == NULL ) {
1342
+ return -1 ;
1343
+ }
1344
+
1345
+ p = extension -> value -> data ;
1346
+ length = extension -> value -> length ;
1347
+ if (method -> it ) {
1348
+ names = (GENERAL_NAMES * )(ASN1_item_d2i (NULL , & p , length ,
1349
+ ASN1_ITEM_ptr (method -> it )));
1350
+ } else {
1351
+ names = (GENERAL_NAMES * )(method -> d2i (NULL , & p , length ));
1352
+ }
1353
+ if (names == NULL ) {
1354
+ return -1 ;
1355
+ }
1356
+
1357
+ num = sk_GENERAL_NAME_num (names );
1358
+ for (i = 0 ; i < num ; i ++ ) {
1359
+ GENERAL_NAME * name ;
1360
+ ASN1_STRING * as ;
1361
+ name = sk_GENERAL_NAME_value (names , i );
1362
+ switch (name -> type ) {
1363
+ case GEN_EMAIL :
1364
+ BIO_puts (bio , "email:" );
1365
+ as = name -> d .rfc822Name ;
1366
+ BIO_write (bio , ASN1_STRING_data (as ),
1367
+ ASN1_STRING_length (as ));
1368
+ break ;
1369
+ case GEN_DNS :
1370
+ BIO_puts (bio , "DNS:" );
1371
+ as = name -> d .dNSName ;
1372
+ BIO_write (bio , ASN1_STRING_data (as ),
1373
+ ASN1_STRING_length (as ));
1374
+ break ;
1375
+ case GEN_URI :
1376
+ BIO_puts (bio , "URI:" );
1377
+ as = name -> d .uniformResourceIdentifier ;
1378
+ BIO_write (bio , ASN1_STRING_data (as ),
1379
+ ASN1_STRING_length (as ));
1380
+ break ;
1381
+ default :
1382
+ /* use builtin print for GEN_OTHERNAME, GEN_X400,
1383
+ * GEN_EDIPARTY, GEN_DIRNAME, GEN_IPADD and GEN_RID
1384
+ */
1385
+ GENERAL_NAME_print (bio , name );
1386
+ }
1387
+ /* trailing ', ' except for last element */
1388
+ if (i < (num - 1 )) {
1389
+ BIO_puts (bio , ", " );
1390
+ }
1391
+ }
1392
+ sk_GENERAL_NAME_pop_free (names , GENERAL_NAME_free );
1393
+
1394
+ return 0 ;
1395
+ }
1396
+
1329
1397
/* {{{ proto array openssl_x509_parse(mixed x509 [, bool shortnames=true])
1330
1398
Returns an array of the fields/values of the CERT */
1331
1399
PHP_FUNCTION (openssl_x509_parse )
@@ -1422,15 +1490,29 @@ PHP_FUNCTION(openssl_x509_parse)
1422
1490
1423
1491
1424
1492
for (i = 0 ; i < X509_get_ext_count (cert ); i ++ ) {
1493
+ int nid ;
1425
1494
extension = X509_get_ext (cert , i );
1426
- if (OBJ_obj2nid (X509_EXTENSION_get_object (extension )) != NID_undef ) {
1495
+ nid = OBJ_obj2nid (X509_EXTENSION_get_object (extension ));
1496
+ if (nid != NID_undef ) {
1427
1497
extname = (char * )OBJ_nid2sn (OBJ_obj2nid (X509_EXTENSION_get_object (extension )));
1428
1498
} else {
1429
1499
OBJ_obj2txt (buf , sizeof (buf )- 1 , X509_EXTENSION_get_object (extension ), 1 );
1430
1500
extname = buf ;
1431
1501
}
1432
1502
bio_out = BIO_new (BIO_s_mem ());
1433
- if (X509V3_EXT_print (bio_out , extension , 0 , 0 )) {
1503
+ if (nid == NID_subject_alt_name ) {
1504
+ if (openssl_x509v3_subjectAltName (bio_out , extension ) == 0 ) {
1505
+ add_assoc_stringl (subitem , extname , bio_buf -> data , bio_buf -> length , 1 );
1506
+ } else {
1507
+ zval_dtor (return_value );
1508
+ if (certresource == -1 && cert ) {
1509
+ X509_free (cert );
1510
+ }
1511
+ BIO_free (bio_out );
1512
+ RETURN_FALSE ;
1513
+ }
1514
+ }
1515
+ else if (X509V3_EXT_print (bio_out , extension , 0 , 0 )) {
1434
1516
BIO_get_mem_ptr (bio_out , & bio_buf );
1435
1517
add_assoc_stringl (subitem , extname , bio_buf -> data , bio_buf -> length , 1 );
1436
1518
} else {
0 commit comments