Skip to content

Commit 0ac60d6

Browse files
twosenikic
andauthored
Micro optimizations for xp_ssl.c (#7447)
If certfile/private_key points to a file that doesn't exist, it throw a warning and return failure now. Also fixed sni_server tests. Co-authored-by: Nikita Popov <[email protected]>
1 parent abe05b1 commit 0ac60d6

File tree

3 files changed

+30
-39
lines changed

3 files changed

+30
-39
lines changed

ext/openssl/tests/sni_server.phpt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ if (!function_exists("proc_open")) die("skip no proc_open");
1111
$serverCode = <<<'CODE'
1212
$flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN;
1313
$ctx = stream_context_create(['ssl' => [
14-
'local_cert' => __DIR__ . '/domain1.pem',
1514
'SNI_server_certs' => [
1615
"cs.php.net" => __DIR__ . "/sni_server_cs.pem",
1716
"uk.php.net" => __DIR__ . "/sni_server_uk.pem",

ext/openssl/tests/sni_server_key_cert.phpt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ if (!function_exists("proc_open")) die("skip no proc_open");
1111
$serverCode = <<<'CODE'
1212
$flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN;
1313
$ctx = stream_context_create(['ssl' => [
14-
'local_cert' => __DIR__ . '/domain1.pem',
1514
'SNI_server_certs' => [
1615
"cs.php.net" => [
1716
'local_cert' => __DIR__ . "/sni_server_cs_cert.pem",

ext/openssl/xp_ssl.c

Lines changed: 30 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -897,35 +897,30 @@ static int php_openssl_set_local_cert(SSL_CTX *ctx, php_stream *stream) /* {{{ *
897897
char resolved_path_buff[MAXPATHLEN];
898898
const char *private_key = NULL;
899899

900-
if (VCWD_REALPATH(certfile, resolved_path_buff)) {
901-
/* a certificate to use for authentication */
902-
if (SSL_CTX_use_certificate_chain_file(ctx, resolved_path_buff) != 1) {
903-
php_error_docref(NULL, E_WARNING,
904-
"Unable to set local cert chain file `%s'; Check that your cafile/capath "
905-
"settings include details of your certificate and its issuer",
906-
certfile);
907-
return FAILURE;
908-
}
909-
GET_VER_OPT_STRING("local_pk", private_key);
910-
911-
if (private_key) {
912-
char resolved_path_buff_pk[MAXPATHLEN];
913-
if (VCWD_REALPATH(private_key, resolved_path_buff_pk)) {
914-
if (SSL_CTX_use_PrivateKey_file(ctx, resolved_path_buff_pk, SSL_FILETYPE_PEM) != 1) {
915-
php_error_docref(NULL, E_WARNING, "Unable to set private key file `%s'", resolved_path_buff_pk);
916-
return FAILURE;
917-
}
918-
}
919-
} else {
920-
if (SSL_CTX_use_PrivateKey_file(ctx, resolved_path_buff, SSL_FILETYPE_PEM) != 1) {
921-
php_error_docref(NULL, E_WARNING, "Unable to set private key file `%s'", resolved_path_buff);
922-
return FAILURE;
923-
}
924-
}
900+
if (!VCWD_REALPATH(certfile, resolved_path_buff)) {
901+
php_error_docref(NULL, E_WARNING, "Unable to get real path of certificate file `%s'", certfile);
902+
return FAILURE;
903+
}
904+
/* a certificate to use for authentication */
905+
if (SSL_CTX_use_certificate_chain_file(ctx, resolved_path_buff) != 1) {
906+
php_error_docref(NULL, E_WARNING,
907+
"Unable to set local cert chain file `%s'; Check that your cafile/capath "
908+
"settings include details of your certificate and its issuer",
909+
certfile);
910+
return FAILURE;
911+
}
925912

926-
if (!SSL_CTX_check_private_key(ctx)) {
927-
php_error_docref(NULL, E_WARNING, "Private key does not match certificate!");
928-
}
913+
GET_VER_OPT_STRING("local_pk", private_key);
914+
if (private_key && !VCWD_REALPATH(private_key, resolved_path_buff)) {
915+
php_error_docref(NULL, E_WARNING, "Unable to get real path of private key file `%s'", private_key);
916+
return FAILURE;
917+
}
918+
if (SSL_CTX_use_PrivateKey_file(ctx, resolved_path_buff, SSL_FILETYPE_PEM) != 1) {
919+
php_error_docref(NULL, E_WARNING, "Unable to set private key file `%s'", resolved_path_buff);
920+
return FAILURE;
921+
}
922+
if (!SSL_CTX_check_private_key(ctx)) {
923+
php_error_docref(NULL, E_WARNING, "Private key does not match certificate!");
929924
}
930925
}
931926

@@ -1614,11 +1609,16 @@ int php_openssl_setup_crypto(php_stream *stream,
16141609
/* We need to do slightly different things based on client/server method
16151610
* so lets remember which method was selected */
16161611
sslsock->is_client = cparam->inputs.method & STREAM_CRYPTO_IS_CLIENT;
1617-
method_flags = ((cparam->inputs.method >> 1) << 1);
1612+
method_flags = cparam->inputs.method & ~STREAM_CRYPTO_IS_CLIENT;
16181613

16191614
method = sslsock->is_client ? SSLv23_client_method() : SSLv23_server_method();
16201615
sslsock->ctx = SSL_CTX_new(method);
16211616

1617+
if (sslsock->ctx == NULL) {
1618+
php_error_docref(NULL, E_WARNING, "SSL context creation failure");
1619+
return FAILURE;
1620+
}
1621+
16221622
GET_VER_OPT_LONG("min_proto_version", min_version);
16231623
GET_VER_OPT_LONG("max_proto_version", max_version);
16241624
method_flags = php_openssl_get_proto_version_flags(method_flags, min_version, max_version);
@@ -1628,11 +1628,6 @@ int php_openssl_setup_crypto(php_stream *stream,
16281628
ssl_ctx_options = SSL_OP_ALL;
16291629
#endif
16301630

1631-
if (sslsock->ctx == NULL) {
1632-
php_error_docref(NULL, E_WARNING, "SSL context creation failure");
1633-
return FAILURE;
1634-
}
1635-
16361631
if (GET_VER_OPT("no_ticket") && zend_is_true(val)) {
16371632
ssl_ctx_options |= SSL_OP_NO_TICKET;
16381633
}
@@ -2293,9 +2288,7 @@ static inline int php_openssl_tcp_sockop_accept(php_stream *stream, php_openssl_
22932288

22942289
if (xparam->outputs.client && sock->enable_on_connect) {
22952290
/* remove the client bit */
2296-
if (sock->method & STREAM_CRYPTO_IS_CLIENT) {
2297-
sock->method = ((sock->method >> 1) << 1);
2298-
}
2291+
sock->method &= ~STREAM_CRYPTO_IS_CLIENT;
22992292

23002293
clisockdata->method = sock->method;
23012294

0 commit comments

Comments
 (0)