@@ -298,28 +298,41 @@ static zend_bool php_x509_fingerprint_match(X509 *peer, zval *val TSRMLS_DC)
298
298
}
299
299
300
300
return method && php_x509_fingerprint_cmp (peer , method , Z_STRVAL_P (val ) TSRMLS_CC ) == 0 ;
301
+
301
302
} else if (Z_TYPE_P (val ) == IS_ARRAY ) {
302
303
HashPosition pos ;
303
304
zval * * current ;
304
305
char * key ;
305
306
uint key_len ;
306
307
ulong key_index ;
307
308
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
+
308
314
for (zend_hash_internal_pointer_reset_ex (Z_ARRVAL_P (val ), & pos );
309
315
zend_hash_get_current_data_ex (Z_ARRVAL_P (val ), (void * * )& current , & pos ) == SUCCESS ;
310
316
zend_hash_move_forward_ex (Z_ARRVAL_P (val ), & pos )
311
317
) {
312
318
int key_type = zend_hash_get_current_key_ex (Z_ARRVAL_P (val ), & key , & key_len , & key_index , 0 , & pos );
313
319
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 ) {
318
325
return 0 ;
319
326
}
320
327
}
328
+
321
329
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" );
322
334
}
335
+
323
336
return 0 ;
324
337
}
325
338
@@ -439,7 +452,7 @@ static int apply_peer_verification_policy(SSL *ssl, X509 *peer, php_stream *stre
439
452
? zend_is_true (* val )
440
453
: sslsock -> is_client ;
441
454
442
- must_verify_fingerprint = ( GET_VER_OPT ("peer_fingerprint" ) && zend_is_true ( * val ) );
455
+ must_verify_fingerprint = GET_VER_OPT ("peer_fingerprint" );
443
456
444
457
if ((must_verify_peer || must_verify_peer_name || must_verify_fingerprint ) && peer == NULL ) {
445
458
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
474
487
if (Z_TYPE_PP (val ) == IS_STRING || Z_TYPE_PP (val ) == IS_ARRAY ) {
475
488
if (!php_x509_fingerprint_match (peer , * val TSRMLS_CC )) {
476
489
php_error_docref (NULL TSRMLS_CC , E_WARNING ,
477
- "Peer fingerprint doesn't match"
490
+ "peer_fingerprint match failure "
478
491
);
479
492
return FAILURE ;
480
493
}
481
494
} else {
482
495
php_error_docref (NULL TSRMLS_CC , E_WARNING ,
483
496
"Expected peer fingerprint must be a string or an array"
484
497
);
498
+ return FAILURE ;
485
499
}
486
500
}
487
501
@@ -1894,14 +1908,15 @@ static size_t php_openssl_sockop_io(int read, php_stream *stream, char *buf, siz
1894
1908
break ;
1895
1909
1896
1910
/* Otherwise, we need to wait again (up to time_left or we get an error) */
1897
- if (blocked )
1911
+ if (blocked ) {
1898
1912
if (read ) {
1899
1913
php_pollfd_for (sslsock -> s .socket , (err == SSL_ERROR_WANT_WRITE ) ?
1900
1914
(POLLOUT |POLLPRI ) : (POLLIN |POLLPRI ), has_timeout ? & left_time : NULL );
1901
1915
} else {
1902
1916
php_pollfd_for (sslsock -> s .socket , (err == SSL_ERROR_WANT_READ ) ?
1903
1917
(POLLIN |POLLPRI ) : (POLLOUT |POLLPRI ), has_timeout ? & left_time : NULL );
1904
1918
}
1919
+ }
1905
1920
}
1906
1921
/* Finally, we keep going until we got data, and an SSL_ERROR_NONE, unless we had an error. */
1907
1922
} while (retry );
0 commit comments