}
/* }}} */
-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;
- const unsigned char *alpn_proto = NULL;
- unsigned int alpn_proto_len = 0;
- 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_ALPN_PROTOCOL) {
-#ifdef HAVE_TLS_ALPN
- SSL_get0_alpn_selected(sslsock->ssl_handle, &alpn_proto, &alpn_proto_len);
-#endif
- if (!needs_array_return) {
- if (alpn_proto_len > 0) {
- ZVAL_STRINGL(zresult, (const char*)alpn_proto, alpn_proto_len);
- }
- return SUCCESS;
- }
- }
-
- 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);
- if (alpn_proto) {
- add_assoc_stringl(zresult, "alpn_protocol", (char *) alpn_proto, alpn_proto_len);
- }
-
- return SUCCESS;
-}
-/* }}} */
-
static int capture_peer_certs(php_stream *stream, php_openssl_netstream_data_t *sslsock, X509 *peer_cert) /* {{{ */
{
zval *val, zcert;
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;
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)
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
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_CRYPTO_INFO_ALPN_PROTOCOL", STREAM_CRYPTO_INFO_ALPN_PROTOCOL, 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);
}
/* }}} */
-/* {{{ 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_ALPN_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)
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);
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;
} outputs;
enum {
STREAM_XPORT_CRYPTO_OP_SETUP,
- STREAM_XPORT_CRYPTO_OP_ENABLE,
- STREAM_XPORT_CRYPTO_OP_INFO
+ STREAM_XPORT_CRYPTO_OP_ENABLE
} op;
} php_stream_xport_crypto_param;
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,