mirror of
https://github.com/php/php-src.git
synced 2024-09-22 02:17:32 +00:00
Add stream_socket_crypto_info() function
This commit is contained in:
parent
3ff36c265f
commit
13acb7ec65
@ -1603,6 +1603,89 @@ static zend_array *capture_session_meta(SSL *ssl_handle) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int php_openssl_crypto_info(php_stream *stream,
|
||||
php_openssl_netstream_data_t *sslsock,
|
||||
php_stream_xport_crypto_param *cparam
|
||||
) /* {{{ */
|
||||
{
|
||||
zval *zresult;
|
||||
const SSL_CIPHER *cipher;
|
||||
char *cipher_name, *cipher_version, *crypto_protocol;
|
||||
int cipher_bits;
|
||||
int needs_array_return;
|
||||
|
||||
if (!sslsock->ssl_active) {
|
||||
php_error_docref(NULL, E_WARNING, "SSL/TLS not currently enabled for this stream");
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
zresult = cparam->inputs.zresult;
|
||||
needs_array_return = (cparam->inputs.infotype == STREAM_CRYPTO_INFO_ALL) ? 1 : 0;
|
||||
|
||||
if (cparam->inputs.infotype & STREAM_CRYPTO_INFO_CIPHER) {
|
||||
cipher = SSL_get_current_cipher(sslsock->ssl_handle);
|
||||
|
||||
if (cparam->inputs.infotype & STREAM_CRYPTO_INFO_CIPHER_NAME) {
|
||||
cipher_name = (char *)SSL_CIPHER_get_name(cipher);
|
||||
if (!needs_array_return) {
|
||||
ZVAL_STRING(zresult, cipher_name);
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (cparam->inputs.infotype & STREAM_CRYPTO_INFO_CIPHER_BITS) {
|
||||
cipher_bits = SSL_CIPHER_get_bits(cipher, NULL);
|
||||
if (!needs_array_return) {
|
||||
ZVAL_LONG(zresult, cipher_bits);
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (cparam->inputs.infotype & STREAM_CRYPTO_INFO_CIPHER_VERSION) {
|
||||
cipher_version = (char *)SSL_CIPHER_get_version(cipher);
|
||||
if (!needs_array_return) {
|
||||
ZVAL_STRING(zresult, cipher_version);
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cparam->inputs.infotype & STREAM_CRYPTO_INFO_PROTOCOL) {
|
||||
switch (SSL_version(sslsock->ssl_handle)) {
|
||||
#ifdef HAVE_TLS12
|
||||
case TLS1_2_VERSION: crypto_protocol = "TLSv1.2"; break;
|
||||
#endif
|
||||
#ifdef HAVE_TLS11
|
||||
case TLS1_1_VERSION: crypto_protocol = "TLSv1.1"; break;
|
||||
#endif
|
||||
case TLS1_VERSION: crypto_protocol = "TLSv1"; break;
|
||||
#ifdef HAVE_SSL3
|
||||
case SSL3_VERSION: crypto_protocol = "SSLv3"; break;
|
||||
#endif
|
||||
#ifdef HAVE_SSL2
|
||||
case SSL2_VERSION: crypto_protocol = "SSLv2"; break;
|
||||
#endif
|
||||
default: crypto_protocol = "UNKNOWN";
|
||||
}
|
||||
|
||||
if (!needs_array_return) {
|
||||
ZVAL_STRING(zresult, crypto_protocol);
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we're still here we need to return an array with everything */
|
||||
array_init(zresult);
|
||||
add_assoc_string(zresult, "protocol", crypto_protocol);
|
||||
add_assoc_string(zresult, "cipher_name", cipher_name);
|
||||
add_assoc_long(zresult, "cipher_bits", cipher_bits);
|
||||
add_assoc_string(zresult, "cipher_version", cipher_version);
|
||||
Z_ARR_P(zresult);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int capture_peer_certs(php_stream *stream, php_openssl_netstream_data_t *sslsock, X509 *peer_cert) /* {{{ */
|
||||
{
|
||||
zval *val, zcert;
|
||||
@ -2207,6 +2290,11 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val
|
||||
cparam->outputs.returncode = php_openssl_enable_crypto(stream, sslsock, cparam);
|
||||
return PHP_STREAM_OPTION_RETURN_OK;
|
||||
break;
|
||||
case STREAM_XPORT_CRYPTO_OP_INFO:
|
||||
return (php_openssl_crypto_info(stream, sslsock, cparam) == SUCCESS)
|
||||
? PHP_STREAM_OPTION_RETURN_OK
|
||||
: PHP_STREAM_OPTION_RETURN_ERR;
|
||||
break;
|
||||
default:
|
||||
/* fall through */
|
||||
break;
|
||||
|
@ -2103,6 +2103,11 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_stream_socket_enable_crypto, 0, 0, 2)
|
||||
ZEND_ARG_INFO(0, sessionstream)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
ZEND_BEGIN_ARG_INFO(arginfo_stream_socket_crypto_info, 0)
|
||||
ZEND_ARG_INFO(0, stream)
|
||||
ZEND_ARG_INFO(0, infotype)
|
||||
ZEND_END_ARG_INFO()
|
||||
|
||||
#ifdef HAVE_SHUTDOWN
|
||||
ZEND_BEGIN_ARG_INFO(arginfo_stream_socket_shutdown, 0)
|
||||
ZEND_ARG_INFO(0, stream)
|
||||
@ -3086,6 +3091,7 @@ const zend_function_entry basic_functions[] = { /* {{{ */
|
||||
PHP_FE(stream_socket_recvfrom, arginfo_stream_socket_recvfrom)
|
||||
PHP_FE(stream_socket_sendto, arginfo_stream_socket_sendto)
|
||||
PHP_FE(stream_socket_enable_crypto, arginfo_stream_socket_enable_crypto)
|
||||
PHP_FE(stream_socket_crypto_info, arginfo_stream_socket_crypto_info)
|
||||
#ifdef HAVE_SHUTDOWN
|
||||
PHP_FE(stream_socket_shutdown, arginfo_stream_socket_shutdown)
|
||||
#endif
|
||||
|
@ -231,6 +231,11 @@ PHP_MINIT_FUNCTION(file)
|
||||
REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLSv1_1_SERVER", STREAM_CRYPTO_METHOD_TLSv1_1_SERVER, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("STREAM_CRYPTO_METHOD_TLSv1_2_SERVER", STREAM_CRYPTO_METHOD_TLSv1_2_SERVER, CONST_CS|CONST_PERSISTENT);
|
||||
|
||||
REGISTER_LONG_CONSTANT("STREAM_CRYPTO_INFO_PROTOCOL", STREAM_CRYPTO_INFO_PROTOCOL, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("STREAM_CRYPTO_INFO_CIPHER_NAME", STREAM_CRYPTO_INFO_CIPHER_NAME, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("STREAM_CRYPTO_INFO_CIPHER_BITS", STREAM_CRYPTO_INFO_CIPHER_BITS, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("STREAM_CRYPTO_INFO_CIPHER_VERSION", STREAM_CRYPTO_INFO_CIPHER_VERSION, CONST_CS|CONST_PERSISTENT);
|
||||
|
||||
REGISTER_LONG_CONSTANT("STREAM_SHUT_RD", STREAM_SHUT_RD, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("STREAM_SHUT_WR", STREAM_SHUT_WR, CONST_CS|CONST_PERSISTENT);
|
||||
REGISTER_LONG_CONSTANT("STREAM_SHUT_RDWR", STREAM_SHUT_RDWR, CONST_CS|CONST_PERSISTENT);
|
||||
|
@ -1485,6 +1485,45 @@ PHP_FUNCTION(stream_socket_enable_crypto)
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto int stream_socket_crypto_info(resource stream [, int infotype])
|
||||
Retrieve information about the stream's crypto session */
|
||||
PHP_FUNCTION(stream_socket_crypto_info)
|
||||
{
|
||||
zval *zstream = NULL;
|
||||
php_stream *stream = NULL;
|
||||
zend_long infotype = 0;
|
||||
|
||||
if (zend_parse_parameters(ZEND_NUM_ARGS(), "r|l", &zstream, &infotype) == FAILURE) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
php_stream_from_zval(stream, zstream);
|
||||
|
||||
if (infotype == 0) {
|
||||
infotype = STREAM_CRYPTO_INFO_ALL;
|
||||
} else {
|
||||
switch (infotype) {
|
||||
case STREAM_CRYPTO_INFO_CIPHER_NAME:
|
||||
case STREAM_CRYPTO_INFO_CIPHER_BITS:
|
||||
case STREAM_CRYPTO_INFO_CIPHER_VERSION:
|
||||
case STREAM_CRYPTO_INFO_CIPHER:
|
||||
case STREAM_CRYPTO_INFO_PROTOCOL:
|
||||
case STREAM_CRYPTO_INFO_ALL:
|
||||
break;
|
||||
default:
|
||||
php_error_docref(NULL, E_WARNING, "unknown crypto info type");
|
||||
RETURN_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (php_stream_xport_crypto_info(stream, infotype, return_value) != PHP_STREAM_OPTION_RETURN_OK) {
|
||||
RETURN_FALSE;
|
||||
}
|
||||
|
||||
/* return_value populated by php_stream_xport_crypto_info() upon success */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ proto string stream_resolve_include_path(string filename)
|
||||
Determine what file will be opened by calls to fopen() with a relative path */
|
||||
PHP_FUNCTION(stream_resolve_include_path)
|
||||
|
@ -57,6 +57,7 @@ PHP_FUNCTION(stream_filter_prepend);
|
||||
PHP_FUNCTION(stream_filter_append);
|
||||
PHP_FUNCTION(stream_filter_remove);
|
||||
PHP_FUNCTION(stream_socket_enable_crypto);
|
||||
PHP_FUNCTION(stream_socket_crypto_info);
|
||||
PHP_FUNCTION(stream_socket_shutdown);
|
||||
PHP_FUNCTION(stream_resolve_include_path);
|
||||
PHP_FUNCTION(stream_is_local);
|
||||
|
@ -183,15 +183,28 @@ typedef enum {
|
||||
STREAM_CRYPTO_METHOD_ANY_SERVER = ((1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5))
|
||||
} php_stream_xport_crypt_method_t;
|
||||
|
||||
typedef enum {
|
||||
STREAM_CRYPTO_INFO_CIPHER_NAME = 1,
|
||||
STREAM_CRYPTO_INFO_CIPHER_BITS = 2,
|
||||
STREAM_CRYPTO_INFO_CIPHER_VERSION = 4,
|
||||
STREAM_CRYPTO_INFO_CIPHER = 5,
|
||||
STREAM_CRYPTO_INFO_PROTOCOL = 8,
|
||||
STREAM_CRYPTO_INFO_ALPN_PROTOCOL = 16,
|
||||
STREAM_CRYPTO_INFO_ALL = 63
|
||||
} php_stream_xport_crypt_info_t;
|
||||
|
||||
/* These functions provide crypto support on the underlying transport */
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
PHPAPI int php_stream_xport_crypto_setup(php_stream *stream, php_stream_xport_crypt_method_t crypto_method, php_stream *session_stream);
|
||||
PHPAPI int php_stream_xport_crypto_enable(php_stream *stream, int activate);
|
||||
PHPAPI int php_stream_xport_crypto_info(php_stream *stream, zend_long infotype, zval *zresult);
|
||||
END_EXTERN_C()
|
||||
|
||||
typedef struct _php_stream_xport_crypto_param {
|
||||
struct {
|
||||
zval *zresult;
|
||||
int infotype;
|
||||
php_stream *session;
|
||||
int activate;
|
||||
php_stream_xport_crypt_method_t method;
|
||||
@ -201,7 +214,8 @@ typedef struct _php_stream_xport_crypto_param {
|
||||
} outputs;
|
||||
enum {
|
||||
STREAM_XPORT_CRYPTO_OP_SETUP,
|
||||
STREAM_XPORT_CRYPTO_OP_ENABLE
|
||||
STREAM_XPORT_CRYPTO_OP_ENABLE,
|
||||
STREAM_XPORT_CRYPTO_OP_INFO
|
||||
} op;
|
||||
} php_stream_xport_crypto_param;
|
||||
|
||||
|
@ -390,6 +390,25 @@ PHPAPI int php_stream_xport_crypto_enable(php_stream *stream, int activate)
|
||||
return ret;
|
||||
}
|
||||
|
||||
PHPAPI int php_stream_xport_crypto_info(php_stream *stream, zend_long infotype, zval *zresult)
|
||||
{
|
||||
php_stream_xport_crypto_param param;
|
||||
int ret;
|
||||
|
||||
memset(¶m, 0, sizeof(param));
|
||||
param.op = STREAM_XPORT_CRYPTO_OP_INFO;
|
||||
param.inputs.zresult = zresult;
|
||||
param.inputs.infotype = infotype;
|
||||
|
||||
ret = php_stream_set_option(stream, PHP_STREAM_OPTION_CRYPTO_API, 0, ¶m);
|
||||
|
||||
if (ret != PHP_STREAM_OPTION_RETURN_OK) {
|
||||
php_error_docref("streams.crypto", E_WARNING, "this stream does not support SSL/crypto");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Similar to recv() system call; read data from the stream, optionally
|
||||
* peeking, optionally retrieving OOB data */
|
||||
PHPAPI int php_stream_xport_recvfrom(php_stream *stream, char *buf, size_t buflen,
|
||||
|
Loading…
Reference in New Issue
Block a user