@@ -1672,7 +1672,7 @@ PHP_FUNCTION(openssl_x509_export)
1672
1672
}
1673
1673
/* }}} */
1674
1674
1675
- int php_openssl_x509_fingerprint (X509 * peer , const char * method , int raw , char * * out , int * out_len )
1675
+ static int php_openssl_x509_fingerprint (X509 * peer , const char * method , int raw , char * * out , int * out_len )
1676
1676
{
1677
1677
unsigned char md [EVP_MAX_MD_SIZE ];
1678
1678
const EVP_MD * mdtype ;
@@ -1699,6 +1699,61 @@ int php_openssl_x509_fingerprint(X509 *peer, const char *method, int raw, char *
1699
1699
return 1 ;
1700
1700
}
1701
1701
1702
+ static int php_x509_fingerprint_cmp (X509 * peer , const char * method , const char * expected )
1703
+ {
1704
+ char * fingerprint ;
1705
+ int fingerprint_len ;
1706
+ int result = -1 ;
1707
+
1708
+ if (php_openssl_x509_fingerprint (peer , method , 0 , & fingerprint , & fingerprint_len )) {
1709
+ result = strcmp (expected , fingerprint );
1710
+ efree (fingerprint );
1711
+ }
1712
+
1713
+ return result ;
1714
+ }
1715
+
1716
+ static int php_x509_fingerprint_match (X509 * peer , zval * * val )
1717
+ {
1718
+ if (Z_TYPE_PP (val ) == IS_STRING ) {
1719
+ const char * method = NULL ;
1720
+
1721
+ switch (Z_STRLEN_PP (val )) {
1722
+ case 32 :
1723
+ method = "md5" ;
1724
+ break ;
1725
+
1726
+ case 40 :
1727
+ method = "sha1" ;
1728
+ break ;
1729
+ }
1730
+
1731
+ return method && php_x509_fingerprint_cmp (peer , method , Z_STRVAL_PP (val )) == 0 ;
1732
+ } else if (Z_TYPE_PP (val ) == IS_ARRAY ) {
1733
+ HashPosition pos ;
1734
+ zval * * current ;
1735
+ char * key ;
1736
+ uint key_len ;
1737
+ ulong key_index ;
1738
+
1739
+ for (zend_hash_internal_pointer_reset_ex (Z_ARRVAL_PP (val ), & pos );
1740
+ zend_hash_get_current_data_ex (Z_ARRVAL_PP (val ), (void * * )& current , & pos ) == SUCCESS ;
1741
+ zend_hash_move_forward_ex (Z_ARRVAL_PP (val ), & pos )
1742
+ ) {
1743
+ int key_type = zend_hash_get_current_key_ex (Z_ARRVAL_PP (val ), & key , & key_len , & key_index , 0 , & pos );
1744
+
1745
+ if (key_type == HASH_KEY_IS_STRING
1746
+ && Z_TYPE_PP (current ) == IS_STRING
1747
+ && php_x509_fingerprint_cmp (peer , key , Z_STRVAL_PP (current )) != 0
1748
+ ) {
1749
+ return 0 ;
1750
+ }
1751
+ }
1752
+ return 1 ;
1753
+ }
1754
+ return 0 ;
1755
+ }
1756
+
1702
1757
PHP_FUNCTION (openssl_x509_fingerprint )
1703
1758
{
1704
1759
X509 * cert ;
@@ -1709,7 +1764,7 @@ PHP_FUNCTION(openssl_x509_fingerprint)
1709
1764
int method_len ;
1710
1765
1711
1766
char * fingerprint ;
1712
- char * fingerprint_len ;
1767
+ int fingerprint_len ;
1713
1768
1714
1769
if (zend_parse_parameters (ZEND_NUM_ARGS () TSRMLS_CC , "Z|sb" , & zcert , & method , & method_len , & raw_output ) == FAILURE ) {
1715
1770
return ;
@@ -4932,30 +4987,14 @@ int php_openssl_apply_verification_policy(SSL *ssl, X509 *peer, php_stream *stre
4932
4987
4933
4988
/* if the cert passed the usual checks, apply our own local policies now */
4934
4989
4935
- if (GET_VER_OPT ("peer_fingerprint" ) && Z_TYPE_PP (val ) == IS_STRING ) {
4936
- char * fingerprint ;
4937
- int fingerprint_len ;
4938
- const char * method = NULL ;
4939
-
4940
- switch (Z_STRLEN_PP (val )) {
4941
- case 32 :
4942
- method = "md5" ;
4943
- break ;
4944
-
4945
- case 40 :
4946
- method = "sha1" ;
4947
- break ;
4948
- }
4949
-
4950
- if (method && php_openssl_x509_fingerprint (peer , method , 0 , & fingerprint , & fingerprint_len )) {
4951
- int match = strcmp (Z_STRVAL_PP (val ), fingerprint ) == 0 ;
4952
-
4953
- efree (fingerprint );
4954
-
4955
- if (!match ) {
4956
- php_error_docref (NULL TSRMLS_CC , E_WARNING , "Peer fingerprint `%s` not matched" , Z_STRVAL_PP (val ));
4990
+ if (GET_VER_OPT ("peer_fingerprint" )) {
4991
+ if (Z_TYPE_PP (val ) == IS_STRING || Z_TYPE_PP (val ) == IS_ARRAY ) {
4992
+ if (!php_x509_fingerprint_match (peer , val )) {
4993
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "Peer fingerprint doesn't match" );
4957
4994
return FAILURE ;
4958
4995
}
4996
+ } else {
4997
+ php_error_docref (NULL TSRMLS_CC , E_WARNING , "Expected peer fingerprint must be a string or an array" );
4959
4998
}
4960
4999
}
4961
5000
0 commit comments