@@ -298,28 +298,41 @@ static zend_bool php_x509_fingerprint_match(X509 *peer, zval *val TSRMLS_DC)
298298 }
299299
300300 return method && php_x509_fingerprint_cmp (peer , method , Z_STRVAL_P (val ) TSRMLS_CC ) == 0 ;
301+
301302 } else if (Z_TYPE_P (val ) == IS_ARRAY ) {
302303 HashPosition pos ;
303304 zval * * current ;
304305 char * key ;
305306 uint key_len ;
306307 ulong key_index ;
307308
309+ if (!zend_hash_num_elements (Z_ARRVAL_P (val ))) {
310+ php_error_docref (NULL , E_WARNING , "Invalid peer_fingerprint array; [algo => fingerprint] form required" );
311+ return 0 ;
312+ }
313+
308314 for (zend_hash_internal_pointer_reset_ex (Z_ARRVAL_P (val ), & pos );
309315 zend_hash_get_current_data_ex (Z_ARRVAL_P (val ), (void * * )& current , & pos ) == SUCCESS ;
310316 zend_hash_move_forward_ex (Z_ARRVAL_P (val ), & pos )
311317 ) {
312318 int key_type = zend_hash_get_current_key_ex (Z_ARRVAL_P (val ), & key , & key_len , & key_index , 0 , & pos );
313319
314- if (key_type == HASH_KEY_IS_STRING
315- && Z_TYPE_PP (current ) == IS_STRING
316- && php_x509_fingerprint_cmp (peer , key , Z_STRVAL_PP (current ) TSRMLS_CC ) != 0
317- ) {
320+ if (!(key_type == HASH_KEY_IS_STRING && Z_TYPE_PP (current ) == IS_STRING )) {
321+ php_error_docref (NULL , E_WARNING , "Invalid peer_fingerprint array; [algo => fingerprint] form required" );
322+ return 0 ;
323+ }
324+ if (php_x509_fingerprint_cmp (peer , key , Z_STRVAL_PP (current ) TSRMLS_CC ) != 0 ) {
318325 return 0 ;
319326 }
320327 }
328+
321329 return 1 ;
330+
331+ } else {
332+ php_error_docref (NULL , E_WARNING ,
333+ "Invalid peer_fingerprint value; fingerprint string or array of the form [algo => fingerprint] required" );
322334 }
335+
323336 return 0 ;
324337}
325338
@@ -439,7 +452,7 @@ static int apply_peer_verification_policy(SSL *ssl, X509 *peer, php_stream *stre
439452 ? zend_is_true (* val )
440453 : sslsock -> is_client ;
441454
442- must_verify_fingerprint = ( GET_VER_OPT ("peer_fingerprint" ) && zend_is_true ( * val ) );
455+ must_verify_fingerprint = GET_VER_OPT ("peer_fingerprint" );
443456
444457 if ((must_verify_peer || must_verify_peer_name || must_verify_fingerprint ) && peer == NULL ) {
445458 php_error_docref (NULL TSRMLS_CC , E_WARNING , "Could not get peer certificate" );
@@ -474,14 +487,15 @@ static int apply_peer_verification_policy(SSL *ssl, X509 *peer, php_stream *stre
474487 if (Z_TYPE_PP (val ) == IS_STRING || Z_TYPE_PP (val ) == IS_ARRAY ) {
475488 if (!php_x509_fingerprint_match (peer , * val TSRMLS_CC )) {
476489 php_error_docref (NULL TSRMLS_CC , E_WARNING ,
477- "Peer fingerprint doesn't match"
490+ "peer_fingerprint match failure "
478491 );
479492 return FAILURE ;
480493 }
481494 } else {
482495 php_error_docref (NULL TSRMLS_CC , E_WARNING ,
483496 "Expected peer fingerprint must be a string or an array"
484497 );
498+ return FAILURE ;
485499 }
486500 }
487501
@@ -1894,14 +1908,15 @@ static size_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, siz
18941908 break ;
18951909
18961910 /* Otherwise, we need to wait again (up to time_left or we get an error) */
1897- if (blocked )
1911+ if (blocked ) {
18981912 if (read ) {
18991913 php_pollfd_for (sslsock -> s .socket , (err == SSL_ERROR_WANT_WRITE ) ?
19001914 (POLLOUT |POLLPRI ) : (POLLIN |POLLPRI ), has_timeout ? & left_time : NULL );
19011915 } else {
19021916 php_pollfd_for (sslsock -> s .socket , (err == SSL_ERROR_WANT_READ ) ?
19031917 (POLLIN |POLLPRI ) : (POLLOUT |POLLPRI ), has_timeout ? & left_time : NULL );
19041918 }
1919+ }
19051920 }
19061921 /* Finally, we keep going until we got data, and an SSL_ERROR_NONE, unless we had an error. */
19071922 } while (retry );
0 commit comments