Skip to content

Commit ea0578e

Browse files
committed
Merge branch 'ssl-streams-crypto-method' of https://github.com/mj/php-src
* 'ssl-streams-crypto-method' of https://github.com/mj/php-src: Add unit test that covers setting the crypto method. Streams for ssl:// transports can now be configured to use a specific crypto method (SSLv3, SSLv2 etc.) by calling
2 parents 8300ced + 047877e commit ea0578e

File tree

3 files changed

+139
-1
lines changed

3 files changed

+139
-1
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIC5jCCAk+gAwIBAgIBADANBgkqhkiG9w0BAQQFADBcMQswCQYDVQQGEwJBVTET
3+
MBEGA1UECBMKUXVlZW5zbGFuZDEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQx
4+
HDAaBgNVBAMTE1Rlc3QgUENBICgxMDI0IGJpdCkwHhcNOTkxMjAyMjEzNTQ4WhcN
5+
MDUwNzExMjEzNTQ4WjBcMQswCQYDVQQGEwJBVTETMBEGA1UECBMKUXVlZW5zbGFu
6+
ZDEaMBgGA1UEChMRQ3J5cHRTb2Z0IFB0eSBMdGQxHDAaBgNVBAMTE1Rlc3QgUENB
7+
ICgxMDI0IGJpdCkwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJ2haT/f5Zwy
8+
V+MiuSDjSR62adBoSiBB7Usty44lXqsp9RICw+DCCxpsn/CfxPEDXLLd4olsWXc6
9+
JRcxGynbYmnzk+Z6aIPPJQhK3CTvaqGnWKZsA1m+WaUIUqJCuNTK4N+7hMAGaf6S
10+
S3e9HVgEQ4a34gXJ7VQFVIBNV1EnZRWHAgMBAAGjgbcwgbQwHQYDVR0OBBYEFE0R
11+
aEcrj18q1dw+G6nJbsTWR213MIGEBgNVHSMEfTB7gBRNEWhHK49fKtXcPhupyW7E
12+
1kdtd6FgpF4wXDELMAkGA1UEBhMCQVUxEzARBgNVBAgTClF1ZWVuc2xhbmQxGjAY
13+
BgNVBAoTEUNyeXB0U29mdCBQdHkgTHRkMRwwGgYDVQQDExNUZXN0IFBDQSAoMTAy
14+
NCBiaXQpggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAUa8B3pho
15+
+Mvxeq9HsEzJxHIFQla05S5J/e/V+DQTYoKiRFchKPrDAdrzYSEvP3h4QJEtsNqQ
16+
JfOxg5M42uLFq7aPGWkF6ZZqZsYS+zA9IVT14g7gNA6Ne+5QtJqQtH9HA24st0T0
17+
Tga/lZ9M2ovImovaxSL/kRHbpCWcqWVxpOw=
18+
-----END CERTIFICATE-----
19+
-----BEGIN RSA PRIVATE KEY-----
20+
MIICXAIBAAKBgQCdoWk/3+WcMlfjIrkg40ketmnQaEogQe1LLcuOJV6rKfUSAsPg
21+
wgsabJ/wn8TxA1yy3eKJbFl3OiUXMRsp22Jp85PmemiDzyUIStwk72qhp1imbANZ
22+
vlmlCFKiQrjUyuDfu4TABmn+kkt3vR1YBEOGt+IFye1UBVSATVdRJ2UVhwIDAQAB
23+
AoGAba4fTtuap5l7/8ZsbE7Z1O32KJY4ZcOZukLOLUUhXxXduT+FTgGWujc0/rgc
24+
z9qYCLlNZHOouMYTgtSfYvuMuLZ11VIt0GYH+nRioLShE59Yy+zCRyC+gPigS1kz
25+
xvo14AsOIPYV14Tk/SsHyq6E0eTk7VzaIE197giiINUERPECQQDSKmtPTh/lRKw7
26+
HSZSM0I1mFWn/1zqrAbontRQY5w98QWIOe5qmzYyFbPXYT3d9BzlsMyhgiRNoBbD
27+
yvohSHXJAkEAwAHx6ezAZeWWzD5yXD36nyjpkVCw7Tk7TSmOceLJMWt1QcrCfqlS
28+
xA5jjpQ6Z8suU5DdtWAryM2sAir1WisYzwJAd6Zcx56jvAQ3xcPXsE6scBTVFzrj
29+
7FqZ6E+cclPzfLQ+QQsyOBE7bpI6e/FJppY26XGZXo3YGzV8IGXrt40oOQJALETG
30+
h86EFXo3qGOFbmsDy4pdP5nBERCu8X1xUCSfintiD4c2DInxgS5oGclnJeMcjTvL
31+
QjQoJCX3UJCi/OUO1QJBAKgcDHWjMvt+l1pjJBsSEZ0HX9AAIIVx0RQmbFGS+F2Q
32+
hhu5l77WnnZOQ9vvhV5u7NPCUF9nhU3jh60qWWO8mkc=
33+
-----END RSA PRIVATE KEY-----
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
--TEST--
2+
Specific crypto method for ssl:// transports.
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('openssl')) die('skip, openssl required');
6+
if (!extension_loaded('pcntl')) die('skip, pcntl required');
7+
?>
8+
--FILE--
9+
<?php
10+
function client($port, $method) {
11+
$ctx = stream_context_create();
12+
stream_context_set_option($ctx, 'ssl', 'crypto_method', $method);
13+
14+
$fp = @fopen('https://127.0.0.1:' . $port . '/', 'r', false, $ctx);
15+
if ($fp) {
16+
fpassthru($fp);
17+
fclose($fp);
18+
}
19+
}
20+
21+
function server($port, $transport) {
22+
$context = stream_context_create();
23+
24+
stream_context_set_option($context, 'ssl', 'local_cert', dirname(__FILE__) . '/streams_crypto_method.pem');
25+
stream_context_set_option($context, 'ssl', 'allow_self_signed', true);
26+
stream_context_set_option($context, 'ssl', 'verify_peer', false);
27+
28+
$server = stream_socket_server($transport . '127.0.0.1:' . $port, $errno, $errstr, STREAM_SERVER_BIND|STREAM_SERVER_LISTEN, $context);
29+
30+
$client = @stream_socket_accept($server);
31+
32+
if ($client) {
33+
$in = '';
34+
while (!preg_match('/\r?\n\r?\n/', $in)) {
35+
$in .= fread($client, 2048);
36+
}
37+
38+
$response = <<<EOS
39+
HTTP/1.1 200 OK
40+
Content-Type: text/plain
41+
Content-Length: 13
42+
Connection: close
43+
44+
Hello World!
45+
46+
EOS;
47+
48+
fwrite($client, $response);
49+
fclose($client);
50+
exit();
51+
}
52+
}
53+
54+
$port1 = rand(15000, 16000);
55+
$port2 = rand(16001, 17000);
56+
57+
$pid1 = pcntl_fork();
58+
$pid2 = pcntl_fork();
59+
60+
if ($pid1 == 0 && $pid2 != 0) {
61+
server($port1, 'sslv3://');
62+
exit;
63+
}
64+
65+
if ($pid1 != 0 && $pid2 == 0) {
66+
server($port2, 'sslv3://');
67+
exit;
68+
}
69+
70+
client($port1, STREAM_CRYPTO_METHOD_SSLv3_CLIENT);
71+
client($port2, STREAM_CRYPTO_METHOD_SSLv2_CLIENT);
72+
73+
pcntl_waitpid($pid1, $status);
74+
pcntl_waitpid($pid2, $status);
75+
?>
76+
--EXPECTF--
77+
Hello World!

ext/openssl/xp_ssl.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,29 @@ php_stream_ops php_openssl_socket_ops = {
853853
php_openssl_sockop_set_option,
854854
};
855855

856+
static int get_crypto_method(php_stream_context *ctx) {
857+
if (ctx) {
858+
zval **val = NULL;
859+
long crypto_method;
860+
861+
if (php_stream_context_get_option(ctx, "ssl", "crypto_method", &val) == SUCCESS) {
862+
convert_to_long_ex(val);
863+
crypto_method = (long)Z_LVAL_PP(val);
864+
865+
switch (crypto_method) {
866+
case STREAM_CRYPTO_METHOD_SSLv2_CLIENT:
867+
case STREAM_CRYPTO_METHOD_SSLv3_CLIENT:
868+
case STREAM_CRYPTO_METHOD_SSLv23_CLIENT:
869+
case STREAM_CRYPTO_METHOD_TLS_CLIENT:
870+
return crypto_method;
871+
}
872+
873+
}
874+
}
875+
876+
return STREAM_CRYPTO_METHOD_SSLv23_CLIENT;
877+
}
878+
856879
static char * get_sni(php_stream_context *ctx, const char *resourcename, size_t resourcenamelen, int is_persistent TSRMLS_DC) {
857880

858881
php_url *url;
@@ -939,7 +962,12 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, size_t protolen,
939962

940963
if (strncmp(proto, "ssl", protolen) == 0) {
941964
sslsock->enable_on_connect = 1;
942-
sslsock->method = STREAM_CRYPTO_METHOD_SSLv23_CLIENT;
965+
966+
/* General ssl:// transports can use a number
967+
* of crypto methods. The actual methhod can be
968+
* provided in the streams context options.
969+
*/
970+
sslsock->method = get_crypto_method(context);
943971
} else if (strncmp(proto, "sslv2", protolen) == 0) {
944972
#ifdef OPENSSL_NO_SSL2
945973
php_error_docref(NULL TSRMLS_CC, E_WARNING, "SSLv2 support is not compiled into the OpenSSL library PHP is linked against");

0 commit comments

Comments
 (0)