@@ -822,12 +822,67 @@ static inline void enable_client_sni(php_stream *stream, php_openssl_netstream_d
822
822
/* }}} */
823
823
#endif
824
824
825
+ static int capture_peer_certs (php_stream * stream ,
826
+ php_openssl_netstream_data_t * sslsock ,
827
+ X509 * peer_cert
828
+ TSRMLS_DC )
829
+ {
830
+ zval * * val , * zcert ;
831
+ int cert_captured = 0 ;
832
+
833
+ if (SUCCESS == php_stream_context_get_option (stream -> context ,
834
+ "ssl" , "capture_peer_cert" , & val ) &&
835
+ zend_is_true (* val )
836
+ ) {
837
+ MAKE_STD_ZVAL (zcert );
838
+ ZVAL_RESOURCE (zcert , zend_list_insert (peer_cert , php_openssl_get_x509_list_id () TSRMLS_CC ));
839
+ php_stream_context_set_option (stream -> context , "ssl" , "peer_certificate" , zcert );
840
+ cert_captured = 1 ;
841
+ FREE_ZVAL (zcert );
842
+ }
843
+
844
+ if (SUCCESS == php_stream_context_get_option (stream -> context ,
845
+ "ssl" , "capture_peer_cert_chain" , & val ) &&
846
+ zend_is_true (* val )
847
+ ) {
848
+ zval * arr ;
849
+ STACK_OF (X509 ) * chain ;
850
+
851
+ MAKE_STD_ZVAL (arr );
852
+ chain = SSL_get_peer_cert_chain (sslsock -> ssl_handle );
853
+
854
+ if (chain && sk_X509_num (chain ) > 0 ) {
855
+ int i ;
856
+ array_init (arr );
857
+
858
+ for (i = 0 ; i < sk_X509_num (chain ); i ++ ) {
859
+ X509 * mycert = X509_dup (sk_X509_value (chain , i ));
860
+ MAKE_STD_ZVAL (zcert );
861
+ ZVAL_RESOURCE (zcert , zend_list_insert (mycert , php_openssl_get_x509_list_id () TSRMLS_CC ));
862
+ add_next_index_zval (arr , zcert );
863
+ }
864
+
865
+ } else {
866
+ ZVAL_NULL (arr );
867
+ }
868
+
869
+ php_stream_context_set_option (stream -> context , "ssl" , "peer_certificate_chain" , arr );
870
+ zval_dtor (arr );
871
+ efree (arr );
872
+ }
873
+
874
+ return cert_captured ;
875
+ }
876
+
825
877
static inline int php_openssl_enable_crypto (php_stream * stream ,
826
878
php_openssl_netstream_data_t * sslsock ,
827
879
php_stream_xport_crypto_param * cparam
828
880
TSRMLS_DC )
829
881
{
830
- int n , retry = 1 ;
882
+ int n ;
883
+ int retry = 1 ;
884
+ int cert_captured ;
885
+ X509 * peer_cert ;
831
886
832
887
if (cparam -> inputs .activate && !sslsock -> ssl_active ) {
833
888
struct timeval start_time ,
@@ -924,90 +979,43 @@ static inline int php_openssl_enable_crypto(php_stream *stream,
924
979
}
925
980
926
981
if (n == 1 ) {
927
- X509 * peer_cert ;
928
-
929
982
peer_cert = SSL_get_peer_certificate (sslsock -> ssl_handle );
983
+ if (peer_cert && stream -> context ) {
984
+ cert_captured = capture_peer_certs (stream , sslsock , peer_cert TSRMLS_CC );
985
+ }
930
986
931
987
if (FAILURE == php_openssl_apply_verification_policy (sslsock -> ssl_handle , peer_cert , stream TSRMLS_CC )) {
932
988
SSL_shutdown (sslsock -> ssl_handle );
933
989
n = -1 ;
934
990
} else {
935
991
sslsock -> ssl_active = 1 ;
936
992
937
- /* allow the script to capture the peer cert
938
- * and/or the certificate chain */
939
993
if (stream -> context ) {
940
- zval * * val , * zcert ;
994
+ zval * * val ;
941
995
942
- if (SUCCESS == php_stream_context_get_option (
943
- stream -> context , "ssl" ,
944
- "capture_session_meta" , & val ) &&
945
- zend_is_true ( * val ) ) {
996
+ if (SUCCESS == php_stream_context_get_option (stream -> context ,
997
+ "ssl" , "capture_session_meta" , & val ) &&
998
+ zend_is_true ( * val )
999
+ ) {
946
1000
zval * meta_arr = php_capture_ssl_session_meta (sslsock -> ssl_handle );
947
- php_stream_context_set_option (stream -> context ,
948
- "ssl" , "session_meta" ,
949
- meta_arr );
1001
+ php_stream_context_set_option (stream -> context , "ssl" , "session_meta" , meta_arr );
950
1002
zval_dtor (meta_arr );
951
1003
efree (meta_arr );
952
1004
}
953
-
954
- if (SUCCESS == php_stream_context_get_option (
955
- stream -> context , "ssl" ,
956
- "capture_peer_cert" , & val ) &&
957
- zend_is_true (* val )) {
958
- MAKE_STD_ZVAL (zcert );
959
- ZVAL_RESOURCE (zcert , zend_list_insert (peer_cert ,
960
- php_openssl_get_x509_list_id () TSRMLS_CC ));
961
- php_stream_context_set_option (stream -> context ,
962
- "ssl" , "peer_certificate" ,
963
- zcert );
964
- peer_cert = NULL ;
965
- FREE_ZVAL (zcert );
966
- }
967
-
968
- if (SUCCESS == php_stream_context_get_option (
969
- stream -> context , "ssl" ,
970
- "capture_peer_cert_chain" , & val ) &&
971
- zend_is_true (* val )) {
972
- zval * arr ;
973
- STACK_OF (X509 ) * chain ;
974
-
975
- MAKE_STD_ZVAL (arr );
976
- chain = SSL_get_peer_cert_chain (
977
- sslsock -> ssl_handle );
978
-
979
- if (chain && sk_X509_num (chain ) > 0 ) {
980
- int i ;
981
- array_init (arr );
982
-
983
- for (i = 0 ; i < sk_X509_num (chain ); i ++ ) {
984
- X509 * mycert = X509_dup (
985
- sk_X509_value (chain , i ));
986
- MAKE_STD_ZVAL (zcert );
987
- ZVAL_RESOURCE (zcert ,
988
- zend_list_insert (mycert ,
989
- php_openssl_get_x509_list_id () TSRMLS_CC ));
990
- add_next_index_zval (arr , zcert );
991
- }
992
-
993
- } else {
994
- ZVAL_NULL (arr );
995
- }
996
-
997
- php_stream_context_set_option (stream -> context ,
998
- "ssl" , "peer_certificate_chain" ,
999
- arr );
1000
- zval_dtor (arr );
1001
- efree (arr );
1002
- }
1003
1005
}
1004
1006
}
1005
-
1006
- if (peer_cert ) {
1007
- X509_free (peer_cert );
1007
+ } else if (errno == EAGAIN ) {
1008
+ n = 0 ;
1009
+ } else {
1010
+ n = -1 ;
1011
+ peer_cert = SSL_get_peer_certificate (sslsock -> ssl_handle );
1012
+ if (peer_cert && stream -> context ) {
1013
+ cert_captured = capture_peer_certs (stream , sslsock , peer_cert TSRMLS_CC );
1008
1014
}
1009
- } else {
1010
- n = errno == EAGAIN ? 0 : -1 ;
1015
+ }
1016
+
1017
+ if (n && peer_cert && cert_captured == 0 ) {
1018
+ X509_free (peer_cert );
1011
1019
}
1012
1020
1013
1021
return n ;
@@ -1017,6 +1025,7 @@ static inline int php_openssl_enable_crypto(php_stream *stream,
1017
1025
SSL_shutdown (sslsock -> ssl_handle );
1018
1026
sslsock -> ssl_active = 0 ;
1019
1027
}
1028
+
1020
1029
return -1 ;
1021
1030
}
1022
1031
0 commit comments