@@ -1398,6 +1398,74 @@ PHP_FUNCTION(openssl_x509_check_private_key)
1398
1398
}
1399
1399
/* }}} */
1400
1400
1401
+ /* Special handling of subjectAltName, see CVE-2013-4073
1402
+ * Christian Heimes
1403
+ */
1404
+
1405
+ static int openssl_x509v3_subjectAltName (BIO * bio , X509_EXTENSION * extension )
1406
+ {
1407
+ GENERAL_NAMES * names ;
1408
+ const X509V3_EXT_METHOD * method = NULL ;
1409
+ long i , length , num ;
1410
+ const unsigned char * p ;
1411
+
1412
+ method = X509V3_EXT_get (extension );
1413
+ if (method == NULL ) {
1414
+ return -1 ;
1415
+ }
1416
+
1417
+ p = extension -> value -> data ;
1418
+ length = extension -> value -> length ;
1419
+ if (method -> it ) {
1420
+ names = (GENERAL_NAMES * )(ASN1_item_d2i (NULL , & p , length ,
1421
+ ASN1_ITEM_ptr (method -> it )));
1422
+ } else {
1423
+ names = (GENERAL_NAMES * )(method -> d2i (NULL , & p , length ));
1424
+ }
1425
+ if (names == NULL ) {
1426
+ return -1 ;
1427
+ }
1428
+
1429
+ num = sk_GENERAL_NAME_num (names );
1430
+ for (i = 0 ; i < num ; i ++ ) {
1431
+ GENERAL_NAME * name ;
1432
+ ASN1_STRING * as ;
1433
+ name = sk_GENERAL_NAME_value (names , i );
1434
+ switch (name -> type ) {
1435
+ case GEN_EMAIL :
1436
+ BIO_puts (bio , "email:" );
1437
+ as = name -> d .rfc822Name ;
1438
+ BIO_write (bio , ASN1_STRING_data (as ),
1439
+ ASN1_STRING_length (as ));
1440
+ break ;
1441
+ case GEN_DNS :
1442
+ BIO_puts (bio , "DNS:" );
1443
+ as = name -> d .dNSName ;
1444
+ BIO_write (bio , ASN1_STRING_data (as ),
1445
+ ASN1_STRING_length (as ));
1446
+ break ;
1447
+ case GEN_URI :
1448
+ BIO_puts (bio , "URI:" );
1449
+ as = name -> d .uniformResourceIdentifier ;
1450
+ BIO_write (bio , ASN1_STRING_data (as ),
1451
+ ASN1_STRING_length (as ));
1452
+ break ;
1453
+ default :
1454
+ /* use builtin print for GEN_OTHERNAME, GEN_X400,
1455
+ * GEN_EDIPARTY, GEN_DIRNAME, GEN_IPADD and GEN_RID
1456
+ */
1457
+ GENERAL_NAME_print (bio , name );
1458
+ }
1459
+ /* trailing ', ' except for last element */
1460
+ if (i < (num - 1 )) {
1461
+ BIO_puts (bio , ", " );
1462
+ }
1463
+ }
1464
+ sk_GENERAL_NAME_pop_free (names , GENERAL_NAME_free );
1465
+
1466
+ return 0 ;
1467
+ }
1468
+
1401
1469
/* {{{ proto array openssl_x509_parse(mixed x509 [, bool shortnames=true])
1402
1470
Returns an array of the fields/values of the CERT */
1403
1471
PHP_FUNCTION (openssl_x509_parse )
@@ -1494,15 +1562,29 @@ PHP_FUNCTION(openssl_x509_parse)
1494
1562
1495
1563
1496
1564
for (i = 0 ; i < X509_get_ext_count (cert ); i ++ ) {
1565
+ int nid ;
1497
1566
extension = X509_get_ext (cert , i );
1498
- if (OBJ_obj2nid (X509_EXTENSION_get_object (extension )) != NID_undef ) {
1567
+ nid = OBJ_obj2nid (X509_EXTENSION_get_object (extension ));
1568
+ if (nid != NID_undef ) {
1499
1569
extname = (char * )OBJ_nid2sn (OBJ_obj2nid (X509_EXTENSION_get_object (extension )));
1500
1570
} else {
1501
1571
OBJ_obj2txt (buf , sizeof (buf )- 1 , X509_EXTENSION_get_object (extension ), 1 );
1502
1572
extname = buf ;
1503
1573
}
1504
1574
bio_out = BIO_new (BIO_s_mem ());
1505
- if (X509V3_EXT_print (bio_out , extension , 0 , 0 )) {
1575
+ if (nid == NID_subject_alt_name ) {
1576
+ if (openssl_x509v3_subjectAltName (bio_out , extension ) == 0 ) {
1577
+ add_assoc_stringl (subitem , extname , bio_buf -> data , bio_buf -> length , 1 );
1578
+ } else {
1579
+ zval_dtor (return_value );
1580
+ if (certresource == -1 && cert ) {
1581
+ X509_free (cert );
1582
+ }
1583
+ BIO_free (bio_out );
1584
+ RETURN_FALSE ;
1585
+ }
1586
+ }
1587
+ else if (X509V3_EXT_print (bio_out , extension , 0 , 0 )) {
1506
1588
BIO_get_mem_ptr (bio_out , & bio_buf );
1507
1589
add_assoc_stringl (subitem , extname , bio_buf -> data , bio_buf -> length , 1 );
1508
1590
} else {
0 commit comments