From 081c8e9d92b27eddbb3600c59f8d58d7afa4b229 Mon Sep 17 00:00:00 2001 From: Daniel Lowrey Date: Tue, 11 Feb 2014 06:42:29 -0700 Subject: [PATCH] Add 'capture_session_meta' context option --- ext/openssl/tests/session_meta_capture.phpt | 73 +++++++++++++++++++++ ext/openssl/xp_ssl.c | 37 +++++++++++ 2 files changed, 110 insertions(+) create mode 100644 ext/openssl/tests/session_meta_capture.phpt diff --git a/ext/openssl/tests/session_meta_capture.phpt b/ext/openssl/tests/session_meta_capture.phpt new file mode 100644 index 0000000000..8ef0f873c9 --- /dev/null +++ b/ext/openssl/tests/session_meta_capture.phpt @@ -0,0 +1,73 @@ +--TEST-- +Capture SSL session meta array in stream context +--SKIPIF-- + [ + 'local_cert' => __DIR__ . '/bug54992.pem', + 'allow_self_signed' => true +]]); +$server = stream_socket_server('ssl://127.0.0.1:64321', $errno, $errstr, $flags, $ctx); + +$pid = pcntl_fork(); +if ($pid == -1) { + die('could not fork'); +} else if ($pid) { + + // Base SSL context values + $sslCtxVars = array( + 'verify_peer' => TRUE, + 'cafile' => __DIR__ . '/bug54992-ca.pem', + 'CN_match' => 'bug54992.local', // common name from the server's "local_cert" PEM file + 'capture_session_meta' => TRUE + ); + + // SSLv3 + $ctxCopy = $sslCtxVars; + $ctxCopy['crypto_method'] = STREAM_CRYPTO_METHOD_SSLv3_CLIENT; + $ctx = stream_context_create(array('ssl' => $ctxCopy)); + stream_socket_client("ssl://127.0.0.1:64321", $errno, $errstr, 1, STREAM_CLIENT_CONNECT, $ctx); + $meta = stream_context_get_options($ctx)['ssl']['session_meta']; + var_dump($meta['protocol']); + + // TLSv1 + $ctxCopy = $sslCtxVars; + $ctxCopy['crypto_method'] = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT; + $ctx = stream_context_create(array('ssl' => $ctxCopy)); + stream_socket_client("ssl://127.0.0.1:64321", $errno, $errstr, 1, STREAM_CLIENT_CONNECT, $ctx); + $meta = stream_context_get_options($ctx)['ssl']['session_meta']; + var_dump($meta['protocol']); + + // TLSv1.1 + $ctxCopy = $sslCtxVars; + $ctxCopy['crypto_method'] = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT; + $ctx = stream_context_create(array('ssl' => $ctxCopy)); + stream_socket_client("ssl://127.0.0.1:64321", $errno, $errstr, 1, STREAM_CLIENT_CONNECT, $ctx); + $meta = stream_context_get_options($ctx)['ssl']['session_meta']; + var_dump($meta['protocol']); + + // TLSv1.2 + $ctxCopy = $sslCtxVars; + $ctxCopy['crypto_method'] = STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT; + $ctx = stream_context_create(array('ssl' => $ctxCopy)); + stream_socket_client("ssl://127.0.0.1:64321", $errno, $errstr, 1, STREAM_CLIENT_CONNECT, $ctx); + $meta = stream_context_get_options($ctx)['ssl']['session_meta']; + var_dump($meta['protocol']); + +} else { + @pcntl_wait($status); + @stream_socket_accept($server, 1); + @stream_socket_accept($server, 1); + @stream_socket_accept($server, 1); + @stream_socket_accept($server, 1); +} +--EXPECTF-- +string(5) "SSLv3" +string(5) "TLSv1" +string(7) "TLSv1.1" +string(7) "TLSv1.2" diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index 99995b6814..aa1d50e64d 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -456,6 +456,31 @@ static inline int php_openssl_setup_crypto(php_stream *stream, return 0; } +static zval *php_capture_ssl_session_meta(SSL *ssl_handle) +{ + zval *meta_arr; + char *proto_str; + long proto = SSL_version(ssl_handle); + const SSL_CIPHER *cipher = SSL_get_current_cipher(ssl_handle); + + switch (proto) { + case TLS1_2_VERSION: proto_str = "TLSv1.2"; break; + case TLS1_1_VERSION: proto_str = "TLSv1.1"; break; + case TLS1_VERSION: proto_str = "TLSv1"; break; + case SSL3_VERSION: proto_str = "SSLv3"; break; + case SSL2_VERSION: proto_str = "SSLv2"; break; + default: proto_str = "UNKNOWN"; + } + + MAKE_STD_ZVAL(meta_arr); + array_init(meta_arr); + add_assoc_string(meta_arr, "protocol", proto_str, 1); + add_assoc_string(meta_arr, "cipher_name", (char *) SSL_CIPHER_get_name(cipher), 1); + add_assoc_long(meta_arr, "cipher_bits", SSL_CIPHER_get_bits(cipher, NULL)); + add_assoc_string(meta_arr, "cipher_version", SSL_CIPHER_get_version(cipher), 1); + + return meta_arr; +} static inline int php_openssl_enable_crypto(php_stream *stream, php_openssl_netstream_data_t *sslsock, php_stream_xport_crypto_param *cparam TSRMLS_DC) { @@ -581,6 +606,18 @@ static inline int php_openssl_enable_crypto(php_stream *stream, php_openssl_nets if (stream->context) { zval **val, *zcert; + if (SUCCESS == php_stream_context_get_option( + stream->context, "ssl", + "capture_session_meta", &val) && + zend_is_true(*val)) { + zval *meta_arr = php_capture_ssl_session_meta(sslsock->ssl_handle); + php_stream_context_set_option(stream->context, + "ssl", "session_meta", + meta_arr); + zval_dtor(meta_arr); + efree(meta_arr); + } + if (SUCCESS == php_stream_context_get_option( stream->context, "ssl", "capture_peer_cert", &val) && -- 2.50.1