/* OpenSSL includes */
#include <openssl/evp.h>
+#include <openssl/bn.h>
+#include <openssl/rsa.h>
+#include <openssl/dsa.h>
+#include <openssl/dh.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/crypto.h>
if ((req->priv_key = EVP_PKEY_new()) != NULL) {
switch(req->priv_key_type) {
case OPENSSL_KEYTYPE_RSA:
- if (EVP_PKEY_assign_RSA(req->priv_key, RSA_generate_key(req->priv_key_bits, 0x10001, NULL, NULL))) {
- return_val = req->priv_key;
+ {
+ RSA* rsaparam;
+#if OPENSSL_VERSION_NUMBER < 0x10002000L
+ /* OpenSSL 1.0.2 deprecates RSA_generate_key */
+ rsaparam = (RSA*)RSA_generate_key(req->priv_key_bits, RSA_F4, NULL, NULL);
+#else
+ {
+ BIGNUM *bne = (BIGNUM *)BN_new();
+ if (BN_set_word(bne, RSA_F4) != 1) {
+ BN_free(bne);
+ php_error_docref(NULL, E_WARNING, "failed setting exponent");
+ return NULL;
+ }
+ rsaparam = RSA_new();
+ RSA_generate_key_ex(rsaparam, req->priv_key_bits, bne, NULL);
+ BN_free(bne);
+ }
+#endif
+ if (rsaparam && EVP_PKEY_assign_RSA(req->priv_key, rsaparam)) {
+ return_val = req->priv_key;
+ }
}
break;
#if !defined(NO_DSA) && defined(HAVE_DSA_DEFAULT_METHOD)
case OPENSSL_KEYTYPE_DSA:
{
- DSA *dsapar = DSA_generate_parameters(req->priv_key_bits, NULL, 0, NULL, NULL, NULL, NULL);
- if (dsapar) {
- DSA_set_method(dsapar, DSA_get_default_method());
- if (DSA_generate_key(dsapar)) {
- if (EVP_PKEY_assign_DSA(req->priv_key, dsapar)) {
+ DSA* dsaparam;
+#if OPENSSL_VERSION_NUMBER < 0x10002000L
+ dsaparam = DSA_generate_parameters(req->priv_key_bits, NULL, 0, NULL, NULL, NULL, NULL);
+#else
+ DSA_generate_parameters_ex(dsaparam, req->priv_key_bits, NULL, 0, NULL, NULL, NULL);
+#endif
+ if (dsaparam) {
+ DSA_set_method(dsaparam, DSA_get_default_method());
+ if (DSA_generate_key(dsaparam)) {
+ if (EVP_PKEY_assign_DSA(req->priv_key, dsaparam)) {
return_val = req->priv_key;
}
} else {
- DSA_free(dsapar);
+ DSA_free(dsaparam);
}
}
}
#if !defined(NO_DH)
case OPENSSL_KEYTYPE_DH:
{
- DH *dhpar = DH_generate_parameters(req->priv_key_bits, 2, NULL, NULL);
int codes = 0;
-
- if (dhpar) {
- DH_set_method(dhpar, DH_get_default_method());
- if (DH_check(dhpar, &codes) && codes == 0 && DH_generate_key(dhpar)) {
- if (EVP_PKEY_assign_DH(req->priv_key, dhpar)) {
+ DH *dhparam;
+#if OPENSSL_VERSION_NUMBER < 0x10002000L
+ dhparam = DH_generate_parameters(req->priv_key_bits, 2, NULL, NULL);
+#else
+ DH_generate_parameters_ex(dhparam, req->priv_key_bits, 2, NULL);
+#endif
+ if (dhparam) {
+ DH_set_method(dhparam, DH_get_default_method());
+ if (DH_check(dhparam, &codes) && codes == 0 && DH_generate_key(dhparam)) {
+ if (EVP_PKEY_assign_DH(req->priv_key, dhparam)) {
return_val = req->priv_key;
}
} else {
- DH_free(dhpar);
+ DH_free(dhparam);
}
}
}
#include "php_openssl.h"
#include "php_network.h"
#include <openssl/ssl.h>
+#include <openssl/rsa.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include <openssl/err.h>
#include <sys/select.h>
#endif
+/* OpenSSL 1.0.2 removes SSLv2 support entirely*/
+#if OPENSSL_VERSION_NUMBER < 0x10002000L && !defined(OPENSSL_NO_SSL2)
+#define HAVE_SSL2 1
+#endif
+
+#ifndef OPENSSL_NO_SSL3
+#define HAVE_SSL3 1
+#endif
+
+#if OPENSSL_VERSION_NUMBER >= 0x10001001L
+#define HAVE_TLS11 1
+#define HAVE_TLS12 1
+#endif
+
#if !defined(OPENSSL_NO_ECDH) && OPENSSL_VERSION_NUMBER >= 0x0090800fL
#define HAVE_ECDH 1
#endif
-#if OPENSSL_VERSION_NUMBER >= 0x00908070L && !defined(OPENSSL_NO_TLSEXT)
-#define HAVE_SNI 1
+#if !defined(OPENSSL_NO_TLSEXT)
+#if OPENSSL_VERSION_NUMBER >= 0x00908070L
+#define HAVE_TLS_SNI 1
#endif
+#endif
+
/* Flags for determining allowed stream crypto methods */
#define STREAM_CRYPTO_IS_CLIENT (1<<0)
static const SSL_METHOD *php_select_crypto_method(zend_long method_value, int is_client) /* {{{ */
{
if (method_value == STREAM_CRYPTO_METHOD_SSLv2) {
-#ifndef OPENSSL_NO_SSL2
- return is_client ? SSLv2_client_method() : SSLv2_server_method();
+#ifdef HAVE_SSL2
+ return is_client ? (SSL_METHOD *)SSLv2_client_method() : (SSL_METHOD *)SSLv2_server_method();
#else
php_error_docref(NULL, E_WARNING,
- "SSLv2 support is not compiled into the OpenSSL library PHP is linked against");
+ "SSLv2 unavailable in the OpenSSL library against which PHP is linked");
return NULL;
#endif
} else if (method_value == STREAM_CRYPTO_METHOD_SSLv3) {
-#ifndef OPENSSL_NO_SSL3
+#ifdef HAVE_SSL3
return is_client ? SSLv3_client_method() : SSLv3_server_method();
#else
php_error_docref(NULL, E_WARNING,
- "SSLv3 support is not compiled into the OpenSSL library PHP is linked against");
+ "SSLv3 unavailable in the OpenSSL library against which PHP is linked");
return NULL;
#endif
} else if (method_value == STREAM_CRYPTO_METHOD_TLSv1_0) {
return is_client ? TLSv1_client_method() : TLSv1_server_method();
} else if (method_value == STREAM_CRYPTO_METHOD_TLSv1_1) {
-#if OPENSSL_VERSION_NUMBER >= 0x10001001L
+#ifdef HAVE_TLS11
return is_client ? TLSv1_1_client_method() : TLSv1_1_server_method();
#else
php_error_docref(NULL, E_WARNING,
- "TLSv1.1 support is not compiled into the OpenSSL library PHP is linked against");
+ "TLSv1.1 unavailable in the OpenSSL library against which PHP is linked");
return NULL;
#endif
} else if (method_value == STREAM_CRYPTO_METHOD_TLSv1_2) {
-#if OPENSSL_VERSION_NUMBER >= 0x10001001L
+#ifdef HAVE_TLS12
return is_client ? TLSv1_2_client_method() : TLSv1_2_server_method();
#else
php_error_docref(NULL, E_WARNING,
- "TLSv1.2 support is not compiled into the OpenSSL library PHP is linked against");
+ "TLSv1.2 unavailable in the OpenSSL library against which PHP is linked");
return NULL;
#endif
} else {
rsa_key_size = 2048;
}
- rsa = RSA_generate_key(rsa_key_size, RSA_F4, NULL, NULL);
+#if OPENSSL_VERSION_NUMBER < 0x10002000L
+ /* OpenSSL 1.0.2 deprecates RSA_generate_key */
+ rsa = (RSA*)RSA_generate_key(rsa_key_size, RSA_F4, NULL, NULL);
+#else
+ {
+ BIGNUM *bne = (BIGNUM *)BN_new();
+ if (BN_set_word(bne, RSA_F4) != 1) {
+ BN_free(bne);
+ return FAILURE;
+ }
+ rsa = RSA_new();
+ RSA_generate_key_ex(rsa, rsa_key_size, bne, NULL);
+ BN_free(bne);
+ }
+#endif
if (!SSL_CTX_set_tmp_rsa(ctx, rsa)) {
php_error_docref(NULL, E_WARNING, "Failed setting RSA key");
}
/* }}} */
-#ifdef HAVE_SNI
+#ifdef HAVE_TLS_SNI
static int server_sni_callback(SSL *ssl_handle, int *al, void *arg) /* {{{ */
{
php_stream *stream;
return FAILURE;
}
}
+
if (FAILURE == set_local_cert(sslsock->ctx, stream)) {
return FAILURE;
}
handle_ssl_error(stream, 0, 1);
}
-#ifdef HAVE_SNI
+#ifdef HAVE_TLS_SNI
/* Enable server-side SNI */
if (sslsock->is_client == 0 && enable_server_sni(stream, sslsock) == FAILURE) {
return FAILURE;
const SSL_CIPHER *cipher = SSL_get_current_cipher(ssl_handle);
switch (proto) {
-#if OPENSSL_VERSION_NUMBER >= 0x10001001L
- case TLS1_2_VERSION: proto_str = "TLSv1.2"; break;
- case TLS1_1_VERSION: proto_str = "TLSv1.1"; break;
+#ifdef HAVE_TLS12
+ case TLS1_2_VERSION:
+ proto_str = "TLSv1.2";
+ break;
+#endif
+#ifdef HAVE_TLS11
+ case TLS1_1_VERSION:
+ proto_str = "TLSv1.1";
+ break;
+#endif
+ case TLS1_VERSION:
+ proto_str = "TLSv1";
+ break;
+#ifdef HAVE_SSL3
+ case SSL3_VERSION:
+ proto_str = "SSLv3";
+ break;
+#endif
+#ifdef HAVE_SSL2
+ case SSL2_VERSION:
+ proto_str = "SSLv2";
+ break;
#endif
- 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";
}
int blocked = sslsock->s.is_blocked,
has_timeout = 0;
-#ifdef HAVE_SNI
+#ifdef HAVE_TLS_SNI
if (sslsock->is_client) {
enable_client_sni(stream, sslsock);
}
if (PHP_STREAM_CONTEXT(stream)) {
zval *val;
-
if (NULL != (val = php_stream_context_get_option(PHP_STREAM_CONTEXT(stream),
- "ssl", "capture_session_meta")) &&
- zend_is_true(val)
+ "ssl", "capture_session_meta")) && zend_is_true(val)
) {
zval meta_arr;
ZVAL_ARR(&meta_arr, capture_session_meta(sslsock->ssl_handle));
n = 0;
} else {
n = -1;
+ /* We want to capture the peer cert even if verification fails*/
peer_cert = SSL_get_peer_certificate(sslsock->ssl_handle);
if (peer_cert && PHP_STREAM_CONTEXT(stream)) {
cert_captured = capture_peer_certs(stream, sslsock, peer_cert);
sslsock->enable_on_connect = 1;
sslsock->method = get_crypto_method(context, STREAM_CRYPTO_METHOD_ANY_CLIENT);
} else if (strncmp(proto, "sslv2", protolen) == 0) {
-#ifdef OPENSSL_NO_SSL2
- php_error_docref(NULL, E_WARNING, "SSLv2 support is not compiled into the OpenSSL library PHP is linked against");
- return NULL;
-#else
+#ifdef HAVE_SSL2
sslsock->enable_on_connect = 1;
sslsock->method = STREAM_CRYPTO_METHOD_SSLv2_CLIENT;
+#else
+ php_error_docref(NULL, E_WARNING, "SSLv2 support is not compiled into the OpenSSL library against which PHP is linked");
+ return NULL;
#endif
} else if (strncmp(proto, "sslv3", protolen) == 0) {
-#ifdef OPENSSL_NO_SSL3
- php_error_docref(NULL, E_WARNING, "SSLv3 support is not compiled into the OpenSSL library PHP is linked against");
- return NULL;
-#else
+#ifdef HAVE_SSL3
sslsock->enable_on_connect = 1;
sslsock->method = STREAM_CRYPTO_METHOD_SSLv3_CLIENT;
+#else
+ php_error_docref(NULL, E_WARNING, "SSLv3 support is not compiled into the OpenSSL library against which PHP is linked");
+ return NULL;
#endif
} else if (strncmp(proto, "tls", protolen) == 0) {
sslsock->enable_on_connect = 1;
sslsock->enable_on_connect = 1;
sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT;
} else if (strncmp(proto, "tlsv1.1", protolen) == 0) {
-#if OPENSSL_VERSION_NUMBER >= 0x10001001L
+#ifdef HAVE_TLS11
sslsock->enable_on_connect = 1;
sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
#else
- php_error_docref(NULL, E_WARNING, "TLSv1.1 support is not compiled into the OpenSSL library PHP is linked against");
+ php_error_docref(NULL, E_WARNING, "TLSv1.1 support is not compiled into the OpenSSL library against which PHP is linked");
return NULL;
#endif
} else if (strncmp(proto, "tlsv1.2", protolen) == 0) {
-#if OPENSSL_VERSION_NUMBER >= 0x10001001L
+#ifdef HAVE_TLS12
sslsock->enable_on_connect = 1;
sslsock->method = STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
#else
- php_error_docref(NULL, E_WARNING, "TLSv1.2 support is not compiled into the OpenSSL library PHP is linked against");
+ php_error_docref(NULL, E_WARNING, "TLSv1.2 support is not compiled into the OpenSSL library against which PHP is linked");
return NULL;
#endif
}