diff options
author | Daniel Lowrey <rdlowrey@php.net> | 2014-03-05 10:50:23 -0500 |
---|---|---|
committer | Daniel Lowrey <rdlowrey@php.net> | 2014-03-05 10:03:33 -0700 |
commit | fad14e3180b17127496c95fe7f0a4b1ca4f36196 (patch) | |
tree | 563d06c3eb14ecece42b3fa0915a2288ae2ad5fa /ext/openssl | |
parent | 020e161966db1603f28df9baa33141ae59067243 (diff) | |
download | php-git-fad14e3180b17127496c95fe7f0a4b1ca4f36196.tar.gz |
Add encrypted server SNI support
- New "SNI_server_certs" context option maps host names to
appropriate certs should client handshakes advertise the
SNI extension:
$ctx = stream_context_create(["ssl" => [
"local_cert" => "/path/to/cert.pem",
"SNI_server_certs" => [
"domain1.com" => "/path/to/domain1.pem",
"*.domain2.com" => "/path/to/domain2.pem",
"domain3.com" => "/path/to/domain3.pem"
]
]]);
- Prefixing a "*." will utilize the matching cert if a client
requests the primary host name or any subdomain thereof. So
in the above example our "domain2.pem" will be used for both
requests to "domain2.com" -and- "subdomain.domain2.com"
- The "SNI_server_certs" ctx option has no effect for client
streams.
- SNI support is enabled by default as of 5.6 for both servers
and clients. Servers must specify the "SNI_server_certs" array
to actually use the SNI extension, though.
- If the `"SNI_enabled" => false` ctx option is also passed then
"SNI_server_certs" has no effect.
- While supporting SNI by itself is enough to successfully
negotiate the TLS handshake with many clients, servers MUST
still specify a "local_cert" ctx option or run the risk of
connection failures from clients that do not support the SNI
extension.
Diffstat (limited to 'ext/openssl')
-rw-r--r-- | ext/openssl/tests/sni_server.phpt | 60 | ||||
-rw-r--r-- | ext/openssl/tests/sni_server_ca.pem | 63 | ||||
-rw-r--r-- | ext/openssl/tests/sni_server_domain1.pem | 82 | ||||
-rw-r--r-- | ext/openssl/tests/sni_server_domain2.pem | 82 | ||||
-rw-r--r-- | ext/openssl/tests/sni_server_domain3.pem | 82 | ||||
-rw-r--r-- | ext/openssl/xp_ssl.c | 147 |
6 files changed, 516 insertions, 0 deletions
diff --git a/ext/openssl/tests/sni_server.phpt b/ext/openssl/tests/sni_server.phpt new file mode 100644 index 0000000000..d44a69f549 --- /dev/null +++ b/ext/openssl/tests/sni_server.phpt @@ -0,0 +1,60 @@ +--TEST-- +sni_server +--SKIPIF-- +<?php +if (!extension_loaded("openssl")) die("skip openssl not loaded"); +--FILE-- +<?php +$serverCode = <<<'CODE' + $flags = STREAM_SERVER_BIND|STREAM_SERVER_LISTEN; + $ctx = stream_context_create(['ssl' => [ + 'local_cert' => __DIR__ . '/domain1.pem', + 'SNI_server_certs' => [ + "domain1.com" => __DIR__ . "/sni_server_domain1.pem", + "domain2.com" => __DIR__ . "/sni_server_domain2.pem", + "domain3.com" => __DIR__ . "/sni_server_domain3.pem" + ] + ]]); + + $server = stream_socket_server('tls://127.0.0.1:64321', $errno, $errstr, $flags, $ctx); + phpt_notify(); + + for ($i=0; $i < 3; $i++) { + @stream_socket_accept($server, 3); + } +CODE; + +$clientCode = <<<'CODE' + $flags = STREAM_CLIENT_CONNECT; + $ctxArr = [ + 'cafile' => __DIR__ . '/sni_server_ca.pem', + 'capture_peer_cert' => true + ]; + + phpt_wait(); + + $ctxArr['peer_name'] = 'domain1.com'; + $ctx = stream_context_create(['ssl' => $ctxArr]); + $client = stream_socket_client("tls://127.0.0.1:64321", $errno, $errstr, 1, $flags, $ctx); + $cert = stream_context_get_options($ctx)['ssl']['peer_certificate']; + var_dump(openssl_x509_parse($cert)['subject']['CN']); + + $ctxArr['peer_name'] = 'domain2.com'; + $ctx = stream_context_create(['ssl' => $ctxArr]); + $client = @stream_socket_client("tls://127.0.0.1:64321", $errno, $errstr, 1, $flags, $ctx); + $cert = stream_context_get_options($ctx)['ssl']['peer_certificate']; + var_dump(openssl_x509_parse($cert)['subject']['CN']); + + $ctxArr['peer_name'] = 'domain3.com'; + $ctx = stream_context_create(['ssl' => $ctxArr]); + $client = @stream_socket_client("tls://127.0.0.1:64321", $errno, $errstr, 1, $flags, $ctx); + $cert = stream_context_get_options($ctx)['ssl']['peer_certificate']; + var_dump(openssl_x509_parse($cert)['subject']['CN']); +CODE; + +include 'ServerClientTestCase.inc'; +ServerClientTestCase::getInstance()->run($clientCode, $serverCode); +--EXPECTF-- +string(%d) "domain1.com" +string(%d) "domain2.com" +string(%d) "domain3.com" diff --git a/ext/openssl/tests/sni_server_ca.pem b/ext/openssl/tests/sni_server_ca.pem new file mode 100644 index 0000000000..f840802c29 --- /dev/null +++ b/ext/openssl/tests/sni_server_ca.pem @@ -0,0 +1,63 @@ +-----BEGIN CERTIFICATE----- +MIIFPjCCAyYCAQEwDQYJKoZIhvcNAQEFBQAwWTELMAkGA1UEBhMCVVMxCzAJBgNV +BAgMAlNDMRUwEwYDVQQHDAxNeXJ0bGUgQmVhY2gxEjAQBgNVBAoMCXBocC50ZXN0 +czESMBAGA1UEAwwJcGhwLnRlc3RzMB4XDTE0MDMwNTE0MTg1M1oXDTI0MDMwMjE0 +MTg1M1owcTELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlNDMRUwEwYDVQQHDAxNeXJ0 +bGUgQmVhY2gxHjAcBgNVBAoMFXBocC50ZXN0cyBzdWJvcmRpbmF0ZTEeMBwGA1UE +AwwVcGhwLnRlc3RzLnN1Ym9yZGluYXRlMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEA4rmcz5M0B2Td+0g8+pmGT0IBCxZTVL14xKA1yLeY+6eshdNiRAIR +8m5sI21AirtAh7mJziA2Q4C/1bRvY9VI/0yxXRP20aicNmhEvFVAvQCxmAkg8hIm +WwDiNLw+4HpAkQInpd8exjExhvanUgAz6tq8w6CL2BqquiwQPVIf5HHMHjomz1gz +iZEs6CRE5YMdUd7ZSx+MHl6ww3WYwW/XHDPzAUIe8uhOT+yA8lVLFAac3+lyjA6g +zMPYG5SrqE6/+yZYDVx2WhVMjJq8d+N6hnIkhZeJyZo2T0G7/pSGIwaVsceIJ/8/ +6km8p4Dn2Pq75F8RZW5iz0MnSqKqSH/ANP71UuinpcVfnyg0ajy7J+cNMDC3gNPC +L0b13qRhRsjNYdyOR7Aj5uQgCegDVipMGLIa+5Vxnzinc059/81QttbsrF2Ll96y +lQk46zhyMOOTnVuX/6k2iFnNUNouXiFlEYPdxRAOJtcOL650F7wTtWolNAyEsRyH +sv3wDXAFXp8b+B/Be1i1yfomP6VnXQMls6RR00qBtc8qEVAMddYihAv5MWa6vXSc ++PA3dBJJBmBJeesqR2PC8kgs+CeGJfUS3VRcUmUKBWz+dMvHPSSiQebwg+Za3xz8 +l3WWPMVWwFUviyv8pw+AB30d5m/akB/r7a1f2FJjwg1P7atkZzz0/SUCAwEAATAN +BgkqhkiG9w0BAQUFAAOCAgEATP38i4XRo2if8SZLqg/kdZQ/B7ER5PpOS0YkMgp+ +g1dLpUrjthIFJ96s9akxO4Bq1NUnt/Ms/8RgTHlM8xF3HuXBt6C6MjeIL9keg0rz +D3dObstOGhqYrUpEhcCaG9mtWQ4G7n86e1/zKTIORAPBD1LPvp6nIzJGNU5DwPeR +u+RK1/DCUBNk1YHrhxj6AevagVozTEeZ2F5AQK9B78MG1fXezN5q5ubLyJZG673q +G1+rhigUrK2xoJzE+DDWlhrVt2nkdzK+rlP63Y9I/XUH76OT4kuLXqttnbWfuvCr +mVt5st+nx24hGmd9yaiKPsUFPlbSfhwzstGreGlsdWIYKzCwnXX6niVMBdKwrRfa +PBnmZbG3YYcMflWLcMUscCqvlPDn9fQS6uwKT6xcEDIou6a8KpQpEgo9k+KUpX2Z +DpyFkDGEeYR2qENlblEoPpkBITWq68tY4jjkHETh1spgDisIzZFkFcupSIrcIaXb +T05gv3POWqb8soejrxMBQHQwkHkZNHcaOBPTJMRG3UTkRbI/UN77oOjCk7/tWa0B +GDEF2eMQ8bpTChQsr4pfIqaHjx4NVdLlZ4OfVoGlKISmMYjU+bVIYZibRNZg/GYP +fUs9sB8ZSRTFvsOHtL5hoD/BYhPIQ5g2fkDsYdfQZIMPQidO+R9lOvMQUgPy/gGd +JzA= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFhTCCA22gAwIBAgIJAMJT3RVinFnaMA0GCSqGSIb3DQEBBQUAMFkxCzAJBgNV +BAYTAlVTMQswCQYDVQQIDAJTQzEVMBMGA1UEBwwMTXlydGxlIEJlYWNoMRIwEAYD +VQQKDAlwaHAudGVzdHMxEjAQBgNVBAMMCXBocC50ZXN0czAeFw0xNDAzMDUxNDE1 +NDBaFw0yNDAzMDIxNDE1NDBaMFkxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJTQzEV +MBMGA1UEBwwMTXlydGxlIEJlYWNoMRIwEAYDVQQKDAlwaHAudGVzdHMxEjAQBgNV +BAMMCXBocC50ZXN0czCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAM1G +jKhUktyuMjqqUSHW5pq+sR53S2E79fCqQq+Gom0NV/KdL5VAkwa3HBFzy+t0z6gE +9wVP6h+AdVU0b9BEb9bEuaDVpW7kwclNLXtRVPw5BN3amLs0ukPoZqoBQVhjfg2p +4qqYBpHBi6U7ltdEHApsBVxYsxGJz+g0NkF4oSlZt+M07jscNexXqpd1m08b9dp/ +nbIR6GLyQ6fSqIXJR7ImvBew2LE8WhFt9ldzzA0cEmr3NQcUXuS4fO8mRNIF+9dJ +f/M9myn6NlCl/eO+YBVSLOp+J72wKLo2LT/C4zbSj2bhc24ui66olzVOCe/97V76 +xusTDKXwagcMxNJD6lZIjZsl5VS9/SYpECj63cGTu5OE6UP6ZyBKZsaX4ZpmklhH +PTMfCTGOtK9MazStM7YtDLSTO3O0yGZXRd0uHcPXM+H2lHqpM90GfGNNdIzS8h7p +hFmocpnHQLVN9SKbrgv9Rt+QbGpBwYH6NFtcwJRiNU9cabez2dcaXWs8+Okvxb7/ +Azvs0jv6d4Y05iIQ4uyJeBOfAuc0UyoG/y+XrGko/8omrTUnAUQtKD/1ymTs+yjb +YNZ6dw5Q5w/FbgL6pMNNOcDgl37mGKFzpRqkUHbOhDZTEUlzYyvtn84t7rbC5g2u +y+KFo3/S4qJheyRfl5FANFTUlxv4vMvMnuaHcJxvAgMBAAGjUDBOMB0GA1UdDgQW +BBRQ95jPSVj20YO2Eq2+wnknOpCjqjAfBgNVHSMEGDAWgBRQ95jPSVj20YO2Eq2+ +wnknOpCjqjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4ICAQCaYxaA9H8O +J55kLRzzgLV56yc+MhowAqOAOjD4J20aWbkRQIwUMIi6xnCwRRnwjuscPFOSF6P+ +Bn3kdVX+KhzFLNRhAk1qjEGjwSVLPKJSKJSdwOmrvCkSsIcbASxSXQkz714LkFAL +hZ9cs4QD+/JVEPazgqjBwtlu3hwwuGAxwHNAKWeFaXpOJu9UerwfBmF090L0uBND +QJAqDyCZRaQp4Re6qH3iQhxyERlAwCNIRSV2cWHJP0HmWye76Z2aehp96fKTo5Cd +NXW3GKGSpmZeZgY8MZVyzUau1c83+nHJCYO0jhFyZjO4XMJ+cce0a2H8iIhox5fY +ZBEuxYN6cPkdvDbFRQU+e+KO1jjyumNWentW57DDPihpgZ3f3Gf5xtUjnHTC5VKT +chW9ujq18Hk4JWL5uyF+5am5Qm4YdjhhZ1TtGHNjoZGpHV0Tf4h5AcDG4Zr6TCmM +3Rw952ytcMtZKZzBq2ZWC3lKpBPPzihAgwzgflVvi0BLP9Ek98oMxq22pymHEHY8 +ivfm+t4rRY6JMl7DxDcARvWoKujrJy2JUUm50vT5D2GG8xYwYr9XKgD8rP36qCjC +B+1l+upz+37r9U12uWfjPsRjyphGbN8ZZAkjSSZQU2snogxaKOvWZb+2M/rajdek +BSQ9sUZ6sNXnTkyYon6iH6WULvmSTgBGnQ== +-----END CERTIFICATE----- diff --git a/ext/openssl/tests/sni_server_domain1.pem b/ext/openssl/tests/sni_server_domain1.pem new file mode 100644 index 0000000000..f00857bda8 --- /dev/null +++ b/ext/openssl/tests/sni_server_domain1.pem @@ -0,0 +1,82 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJKAIBAAKCAgEAnCaINvfTx7v+DUMD5zJLg+8lEJsxGt7OQjEmFkEUmwrXz1I5 +E29rckBS/lCNG6NvEG6uNtxgXoz6cLlOwL9cdHGSKPDOYHGa7JN+EGiMnScZLNc9 +ao1ouvLdBa5lv6zcoCu6YPw95AnZ6PHEHj8mFckWtmFjV16/diB1SR9wDpIwye7m +nJlVRUAMzrABVNDaPUqqj8G+xr02Mo6pTX1wGHgQyTR/pNOHZGiDDBXeWNDuEBNv +TYtBWXXXMrGC36HTSR+KMlDjFfmCTb+y0s8ILT7Pagx6LFoun99SbhXQtrwC/0sU +R5tyqOrgVj1dbuKSWuSaiWYMJZXaFKkndkCTQLiPCDltHOd7ppYmRt848WqKTbjO +Vhpjxjhu4rfHw3ynhQNC50N/jiViKBcpptQhX4cMNltXsJXI0hr6dWI2/6r7op9j +2uxOHthznLejsHcGmW62F8wpUZxAT8yuvTcEMzx+HjdLyBu+N/t7BHKk4+nIAN8G +266mT4BjSLHcdny4J8UrVoBvDeW7oQkdvhluIomabGJg3wknnjY9/QbsiCAcR05H +Z2IEremU9Vm3uogAwBBWk2YTEuIuNbm8TAHqfTj1PkxXRE6YTL907fFZMcw/+3nO +YERqS4FV5OvNqoNILWxl0dBYaBrtRwhMEYZFDK5jDc1OtolpF07s45JwbakCAwEA +AQKCAgASxm9KbLICKhB597zYZ6u8yVxjisV0vaV/P/mcY2be3YblXrWOKK96pVFV +UsoksJoCF8zKu+S6eakDNMTLWDb9qUoxsgKehgpit7lIr8l4e+MDCT5ROX+GOv1o +WXfSfC5q89cNIkcuzCBvaeJy4JTruaoJc9xF/RZ4VZ7ElAsdNWa4YQlJewZNtU3U +7ES8tgAHrpqjfmA59TY3DgA9WP/JcWZTSwSuBOEaqZZYNajudPCq7itL35qT7x9Y +8Q8TZJnLCQfM1Pz4/28zegE+Z7ZL+mlmDuoBuzYv8uIuamEWF7UkjRp7Ia2/sb4X +oHlDg+qlEyehrat4OXRnV49vIIST64cxQw3v9mGZr1mCxyrfGbRvPw99CSwjdCju +LSuzYlr5w/ZVKsVGKB1mvowxzKJ89Njhdv+QlHpqrodSgCTFzm2A6dwoEQ9bQFd/ +OH7pG9YOu5jf66MFnV60AiImGBZCP7B3thJgmCBhjSau2cmDSUGFLwZswoue2y7u +Goh5sCOq8MAcFkm5CyXkAQbDIptGs7XGipJBbpZEXBo1fnVPQnz/Ien9Mv8ZxeAW +busJD5aPMZZ9GwLuRfoGEa7PEO4409zHc07hA22kxv6yb1nNyuTNcXG2myIP5MdO +rHLFuDcQ+2adBmpmJGYXmak73eamYzCZOMEOLYSLAwYNFpOIgQKCAQEAytAdhSFa +goKLWCR5NcXvMSjAblWqMn5qAG0KroIISrOIgWamiDE6Xsqrg6H/aRETyelO5Xyi +TxHnhYzge0VUAXJK3megyKbXCWwIJyym14gKXppvgNmvKs7hM6tp00+UYYUGWj1u +2Mw3ae6oCyQIx2GYGUVTRyIbtz/u0Nfc0cJJ/OB91Q7Ab/GEVv70hvN3QBLab4OK +37BtXE26dorHLAAC2SWwDbaD6A7NxHW5M9JpQHdtYvhNwS6lBVxSlFjmA7jBXrxH +vT/8TJG4b5f9d85JGvURwX3DW1bUO/vVMEdp5RE1gHLo5q+IKQSH7OeVfJQeavyA +OXC2+UIcsOdMPQKCAQEAxRm5xTchHfhTFusfggVjRwp0fKxCGw7LL4xLO6G3nqTX +5WX2XWc/VB7uSJVq1b4dwiUJxVnmYWL/FcC3OeAQZh2BnkEJoPF4re7neN/8BOHB +sHpn8+O8a5XF5XumvodSgwoBj0dPTdRRvK8OreyMjhoMwC5OrOWeYgfCkg4UUeax +Mjta7j3B/wzu/SQcLOkVW9Y/B6FsC5ZIbNPhFJQ/h9q4aFw421AWnJ98FRSGDT22 +cynII9nA8OhNh8YXEJz4FRYs4GelbUNBe98BEh7cVOEuqK/7L7wXpmmC64yhP1ro +37WJ9LDZbYqLriGsMZV23/knvPOk0Mqd8dTgderh3QKCAQB3zXHyp14ow+Z+HaWA +DzkZB+KMCoxsIWKKd98ccHFndyAGmFV9E99QCVZBfps6PD09Q1U4mGPkY0YpDKu6 +BZz28cWqFPrULEHQLgGu6mBv5suBUKbXLT+dAPHkrLfpfBPBe2viOHHXHOMK71BS +rGmHJW5MVzg3R72phNmUgj7NpYBBIXcTORCRz9AF97sIUJ87uSdRQhnxwu0G3l9s +ENRQeH02Ol4B67OFi+Ee0Q+ivgMwcpuqH9UGbYBLZ1rciJruzd9kD8Is17Q4oseZ +G+Y9NBzZELT5YEnbFbJu8Hbhev3hs0WwZ7COPFgpKqUEW1Rhb7l8J0WzKJLdMKF0 +Gl1dAoIBAD3mVGdRZv8oi7+4285TrtgSun6lAqXIwZsPLllt8mLKVlte6D5xPHxI +soDtG/5AlMvyId1u3GFdW8sTGPf+HGhVf+2Zc1KuQz4st1lIzrchx1iLOLZpoTUQ +dnQZn0Za7Vjl/ZNny8ofkgP13mBU19eQ6sw4PtEh09npofuInG0UTDYAWhBUKObW +wv+RJaAdG24aHPVihrIk4l37NMbnwAQEdsGfpOOLhW5uz+M27NqftPr59jb8HhIK +gr7PQVMgWPEWY8WeB2AHLTufz5BHTN8DUUn86qAVLEBBBrK/Gazx+gy30LmeCMrU +JgXr4U45KHoyn35B7lL8LxpRxqSBvakCggEBAJBaYCI/2uWAF+sGQLt0rg25jnLo +iuY45pshPCoxjONwYh0vnjsr00nyyN56ipPRITETMnQh/thGYJmj0O+5dO+0fkfB +iHP9MxOxqVpMYff9Q4As+mtmC1/9UPSN8hRxyUuNwL0rNt/tq7u3muo5XT0rRWwV +SjnMMjfK98i4b3xBpFPn8wrenhK3EVsx0hCyWg3NgmhTNh2OaK31FPiQAwOM7XXS +55sQLO2XTPa663GNavzECmzZxYiRrk6TCEYp8jDofBw0aT+Mq8fp7kwgwX7l2lfK +XQzGJ+CxJCdMyWhLlXGkIhG8G2W4/3tqyIp2+JlXk6/3CD6ovOqy0rhnpA8= +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIFSDCCAzACAQEwDQYJKoZIhvcNAQEFBQAwcTELMAkGA1UEBhMCVVMxCzAJBgNV +BAgMAlNDMRUwEwYDVQQHDAxNeXJ0bGUgQmVhY2gxHjAcBgNVBAoMFXBocC50ZXN0 +cyBzdWJvcmRpbmF0ZTEeMBwGA1UEAwwVcGhwLnRlc3RzLnN1Ym9yZGluYXRlMB4X +DTE0MDMwNTE0MjgwOFoXDTI0MDMwMjE0MjgwOFowYzELMAkGA1UEBhMCVVMxFTAT +BgNVBAgMDE15cnRsZSBCZWFjaDELMAkGA1UEBwwCU0MxGjAYBgNVBAoMEWRvbWFp +bjEgdGVzdCBjZXJ0MRQwEgYDVQQDDAtkb21haW4xLmNvbTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAJwmiDb308e7/g1DA+cyS4PvJRCbMRrezkIxJhZB +FJsK189SORNva3JAUv5QjRujbxBurjbcYF6M+nC5TsC/XHRxkijwzmBxmuyTfhBo +jJ0nGSzXPWqNaLry3QWuZb+s3KArumD8PeQJ2ejxxB4/JhXJFrZhY1dev3YgdUkf +cA6SMMnu5pyZVUVADM6wAVTQ2j1Kqo/Bvsa9NjKOqU19cBh4EMk0f6TTh2RogwwV +3ljQ7hATb02LQVl11zKxgt+h00kfijJQ4xX5gk2/stLPCC0+z2oMeixaLp/fUm4V +0La8Av9LFEebcqjq4FY9XW7iklrkmolmDCWV2hSpJ3ZAk0C4jwg5bRzne6aWJkbf +OPFqik24zlYaY8Y4buK3x8N8p4UDQudDf44lYigXKabUIV+HDDZbV7CVyNIa+nVi +Nv+q+6KfY9rsTh7Yc5y3o7B3BpluthfMKVGcQE/Mrr03BDM8fh43S8gbvjf7ewRy +pOPpyADfBtuupk+AY0ix3HZ8uCfFK1aAbw3lu6EJHb4ZbiKJmmxiYN8JJ542Pf0G +7IggHEdOR2diBK3plPVZt7qIAMAQVpNmExLiLjW5vEwB6n049T5MV0ROmEy/dO3x +WTHMP/t5zmBEakuBVeTrzaqDSC1sZdHQWGga7UcITBGGRQyuYw3NTraJaRdO7OOS +cG2pAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAJ3pMaMcWaW5TJ1QV58npS/F7Ao7 +mciFMQ+KiQ6E5TJ/S37EfR/r5+mqQodM6Zvs07x4k2HdwcuI0cdpddLKfIH2znDW +pJY1nEKI9W/pz9pEj3TBu9M3QAPzWVwYyBaJzVJGIll1yYVQVNGneHF8YpWQo+Ow +yg97x1220oUSAlJ9zUwwls6QjJCo95PcClV9ZK6A+H17v+kwzBco7DwGhoxy3s+n +D9+LjDa5Z6yk7Y1h+I4kIExenjuXT1wgQatruR8MBl8MX+KKeAi4neRdCBiDceHs +zzO0f+IBNiF1J8THokV81i7DMbsHRGv28r3rcQpalDK9/rcBRVXUl0Kw8ZDQJLaS +C1EuAcqw8TgvZOAhw431EpZW7Beek4xvrwTSzrF1XhlbD/1Jm8YAjGQyO138qzq2 +p40NRXgGL3rT6LEDcUVjL9D2z/7Tu7G9g17vleEzBC13ILnAOg/UFsZ4BuGNCnxa +3PiJ7QaDBL0UA4uUuXjVgGTFzeDaTJbNCybcTKI7rD4zAa/4d05364gA3S1XJU66 +tH24Z3ncMBrh1GrsX4z6vLkNyb7m2wBqWBuyuVidm7rPcMGoggbrAsIP5vPjIMdg +GR+ghPgzhJsbEg/WoSxv8+oljAJT2I1A53ulJaL4w6S/Ku1yEQ01Xk4vZEBJHAAw +TJxrq625wwS0cKQd +-----END CERTIFICATE----- diff --git a/ext/openssl/tests/sni_server_domain2.pem b/ext/openssl/tests/sni_server_domain2.pem new file mode 100644 index 0000000000..4acc355352 --- /dev/null +++ b/ext/openssl/tests/sni_server_domain2.pem @@ -0,0 +1,82 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIFSDCCAzACAQIwDQYJKoZIhvcNAQEFBQAwcTELMAkGA1UEBhMCVVMxCzAJBgNV +BAgMAlNDMRUwEwYDVQQHDAxNeXJ0bGUgQmVhY2gxHjAcBgNVBAoMFXBocC50ZXN0 +cyBzdWJvcmRpbmF0ZTEeMBwGA1UEAwwVcGhwLnRlc3RzLnN1Ym9yZGluYXRlMB4X +DTE0MDMwNTE0MzAzMVoXDTI0MDMwMjE0MzAzMVowYzELMAkGA1UEBhMCVVMxCzAJ +BgNVBAgMAlNDMRUwEwYDVQQHDAxNeXJ0bGUgQmVhY2gxGjAYBgNVBAoMEWRvbWFp +bjIgdGVzdCBjZXJ0MRQwEgYDVQQDDAtkb21haW4yLmNvbTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAOdrgSdbb+KLIdxlKnYgUtNRY5zp83ZDQf4wJPpt +AR+g4iiU9I0er7Kc7rbjyJ9Ba1RO1dddqOFzoWIsYxnwJeqgP7Of5hNCYMNgYyJ4 +L3sxXqnbJdYNmdAeQpwimTMvw7gcrLNxF4wPbrjqxAWpwMBPi61BH5k0AbT2Z4Jf +RZ9UwKpGAOFAa/3TrUjEpmpv3c+ppK5RFjVGasLhQoEEdhjK019Mw/W715Q+TL8o +utQ1HOWEURmM4jCtCskg6MIGuYyKq1LebLy2hyHTlx3zCY43LQ/ptxTa34gublzf +Vmw2fSyJygpmv52Y4UR5MFBEx5LC/C/4cwjWN5ZPWOKTCAoTeynTDGL2pwA21Tnk +ae0RgPftFpyst7thAsoAgyfuMPiGWBnhqdN+RzeFpw+lm22gquxr3UPOBG51rrN0 +//UJQNbhqxG5sqxS7EDYolUFG4ViQwJ0Ney3GPa59E60Iw+IU14Lif6NVzYYlT3d +czZpt/uR97cKeCZDHO28o0XCspdm8z4dT1WTWNVuCLArb7zm9+IOu47bUJa/y9N8 +ApqPjrwWPXWwdQq8ViUCSewTSQa9GeB2MnIVKQCjNuLmPCDDkmmJYcVpyiwljkwb +29Itigeo7TMgVBeadN3biZGYSgIeYvf/MjOjxMKt4bCcoKNsieIsCNHj9+9lHbIr +UrpDAgMBAAEwDQYJKoZIhvcNAQEFBQADggIBAAzy1BUPLBK3+230sILn9iJV+7DJ +1pFOTBdChTn8UrCzP8NrhQ7TNyNuwETcjxOMZ0IYc9SBUZgQV2RZrGM4Ek2dV2so +Z+HzQ9UsAl31t8bL1uSBH4lspAeSAIq8HyLK52JxZ4yBK8ID2e7oHzbqY58Xcfzn +4WlA54XYNI1+gj6bBTP7lXLz40H9lcPTHDsed3usYYWtfH/ncIW0rw9/fK1P6aTO +680lOaLFB26Z3ygGiJXbfmcnIjEmbpgWLfcPOoIBFrDmkiHqo31UT1WBxQ16c4yw +DwO+DY5KK6adI1j5PWUmT/8vwlsO2CEtq4DOKfB51ggG9NyciCw+vJXP4Ec30IiX +5TNWNwpg+ex44ICScSF6ew4hS2tO59VFBvDaa/2nFhEOG0iECN0537v10vOxgaVr +kHlCgJtgCwUbKrfVTA2FogXRDIBJ1aOZiA7kIPPSqdTH49HwieH55Q5kfi7xak5y +tSijrFw70vZOf3ORErmXEAZFqQgPuK4KlvTMom7z9QnNq4L579DeGUdBhLYGXJzP +8WcMXRlQ7XUT6TQaSTDwDYlWcxcZ584seK4rVCLT2jyChEWSLR2K29hZ0eNVQt43 +3Xxz9hExGS/oELv53zPqp10w/0ZKlFQc5Wa4kEkjBz5R8VzzWuelxarqNAH6m9Du +i3jyxtHS869PHMU3 +-----END CERTIFICATE----- diff --git a/ext/openssl/tests/sni_server_domain3.pem b/ext/openssl/tests/sni_server_domain3.pem new file mode 100644 index 0000000000..9f80b717a2 --- /dev/null +++ b/ext/openssl/tests/sni_server_domain3.pem @@ -0,0 +1,82 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- +-----BEGIN CERTIFICATE----- +MIIFTzCCAzcCAQIwDQYJKoZIhvcNAQEFBQAwcTELMAkGA1UEBhMCVVMxCzAJBgNV +BAgMAlNDMRUwEwYDVQQHDAxNeXJ0bGUgQmVhY2gxHjAcBgNVBAoMFXBocC50ZXN0 +cyBzdWJvcmRpbmF0ZTEeMBwGA1UEAwwVcGhwLnRlc3RzLnN1Ym9yZGluYXRlMB4X +DTE0MDMwNTE0MzA0M1oXDTI0MDMwMjE0MzA0M1owajELMAkGA1UEBhMCVVMxCzAJ +BgNVBAgMAlNDMRUwEwYDVQQHDAxNeXJ0bGUgQmVhY2gxITAfBgNVBAoMGEludGVy +bmV0IFdpZGdpdHMgUHR5IEx0ZDEUMBIGA1UEAwwLZG9tYWluMy5jb20wggIiMA0G +CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCu5H20GpgEO8HUN8wSFwVJxFsoQtH4 +AsXhrQQb996s58XJzgeBZLulxO7Oq2moY0hnFCRH7JyiwI3dlpfaC65uENq0sIYQ +iCeEV7LOO0sXA7JdkNvWyiTP4tt6p1t5xmX6b72PLIPff+OK35a1N3IVqbo2D3WP +m4ALTMIHwryVrZO5nfeBW2IznVHSLMofYpKeg/pMgQ1QI20FbqnU/FN8KZvGZTn2 +wpKRfgz/tCOZbdW3NYD0S/f5zo4W92FrbgKEqYVuzqRm31O05uilWuIw57c6cp8Y +4Dx14jJUugaBs50LJVtkhYiYCH51UQKfGnmcYwctFfNsbBxPLYLzLXfmph3l3lFB +5zZXf68uTQhj6Nqvykuj08KyqDKPS95qMDkIvxw68vVZpFEtRUkLGSOci+f70Vtl +5l8w7TJ+zPPtKPe5DuQSRbDwU8e9NdhqbbliYu6H1pNKG6tHdZF5QNrZCxom8jfn +jTKtM369VhUEUiZ1Wf19DbY7K6LVpkzu8B0hsD8oDU2oEPsS5iLAHzv8kbbPkYWc +GfKsn+VBWm7aX9zv/JT2FEAQOiVzSe6Bi8walXJ9qEI5p53Wvfny0bmgrhMDvbbN +5QRyBfTWs2SjsEgdUJFi7QhbZn1JVAwScMnAX/Ne2uS0uMdcEqU59FYfhW8jHI1v +EY5BD8etxaT34QIDAQABMA0GCSqGSIb3DQEBBQUAA4ICAQDUel0pS4vCng3sQ2ab +U4bSTDiiyR09TUlX54eaHrQFnnJAXxnHdu9S2xlizaGgkUHqQ7P6HXiMn5rl2GTw +7uLcV2CoapceuX3HK+Iiy5r4phXtylmkUT737jR32Rib/jH7swkdPLDcnbI2J2Cs +I1LIlCiuaJagu0q2liRnJOkdZQd1Rz3w9I/WHECxS9SAnaQsF4LbXabXObVeRrtq +qiNoDbC0Q9c4RquVtbdjm4vP6eCjnqck/0Tq8ceq7Hg5hu3Q0scg3mEK+7cyp19X +Y+/nCg8SZe+7LxewJ7GgqRgnDiHgfO5Nu4jhuZh72LA1mtIS+dU/cDVf8kxLiusG +UlJKDwJ14Jh7LAKdRorqGFqNi8R5zEaCIcuSWvUfNl9TzOXlRj6c4lP8eixWG4FD +CiHkv7jXsz8AYZcKy7IqsXVdnem+8PoKmBzhtngNX86W9JgQ65vLwsT4kdWHMfU0 +zEZrHZ3+qcmL5GUXI7r3uQQmp0RcNQV57X6bLRG4PaCMxuTv6JJ3Bi+qqX4vVWPL +K1Au3W5UiJ3XPVllxSynA6lcUvVw/PoNLaV21sskxwJDtLwbSAH3DS0JQQSZzesj +hGayf3SOVU1n84lTuc84KEgM+zaxGzqfShUadlLMKBS+w+8j8N+qBjUi08UOUKa7 +OAES8tCv7DK0Mi21rLXMadYwlw== +-----END CERTIFICATE----- diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index ad3d92d0dc..e251d2124a 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -77,6 +77,12 @@ extern int php_openssl_get_x509_list_id(void); php_stream_ops php_openssl_socket_ops; +/* Certificate contexts used for server-side SNI selection */ +typedef struct _php_openssl_sni_cert_t { + char *name; + SSL_CTX *ctx; +} php_openssl_sni_cert_t; + /* Provides leaky bucket handhsake renegotiation rate-limiting */ typedef struct _php_openssl_handshake_bucket_t { long prev_handshake; @@ -1168,6 +1174,131 @@ static int set_server_specific_opts(php_stream *stream, SSL_CTX *ctx TSRMLS_DC) /* }}} */ #ifdef HAVE_SNI +static int server_sni_callback(SSL *ssl_handle, int *al, void *arg) /* {{{ */ +{ + php_stream *stream; + php_openssl_netstream_data_t *sslsock; + unsigned i; + const char *server_name; + + server_name = SSL_get_servername(ssl_handle, TLSEXT_NAMETYPE_host_name); + + if (!server_name) { + return SSL_TLSEXT_ERR_NOACK; + } + + stream = (php_stream*)SSL_get_ex_data(ssl_handle, php_openssl_get_ssl_stream_data_index()); + sslsock = (php_openssl_netstream_data_t*)stream->abstract; + + if (!(sslsock->sni_cert_count && sslsock->sni_certs)) { + return SSL_TLSEXT_ERR_NOACK; + } + + for (i=0; i < sslsock->sni_cert_count; i++) { + if (matches_wildcard_name(server_name, sslsock->sni_certs[i].name)) { + SSL_set_SSL_CTX(ssl_handle, sslsock->sni_certs[i].ctx); + return SSL_TLSEXT_ERR_OK; + } + } + + return SSL_TLSEXT_ERR_NOACK; +} +/* }}} */ + +static int enable_server_sni(php_stream *stream, php_openssl_netstream_data_t *sslsock TSRMLS_DC) +{ + zval **val; + zval **current; + char *key; + uint key_len; + ulong key_index; + int key_type; + HashPosition pos; + int i = 0; + char resolved_path_buff[MAXPATHLEN]; + SSL_CTX *ctx; + + /* If the stream ctx disables SNI we're finished here */ + if (GET_VER_OPT("SNI_enabled") && !zend_is_true(*val)) { + return SUCCESS; + } + + /* If no SNI cert array is specified we're finished here */ + if (!GET_VER_OPT("SNI_server_certs")) { + return SUCCESS; + } + + if (Z_TYPE_PP(val) != IS_ARRAY) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "SNI_server_certs requires an array mapping host names to cert paths" + ); + return FAILURE; + } + + sslsock->sni_cert_count = zend_hash_num_elements(Z_ARRVAL_PP(val)); + if (sslsock->sni_cert_count == 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "SNI_server_certs host cert array must not be empty" + ); + return FAILURE; + } + + sslsock->sni_certs = (php_openssl_sni_cert_t*)safe_pemalloc(sslsock->sni_cert_count, + sizeof(php_openssl_sni_cert_t), 0, php_stream_is_persistent(stream) + ); + + for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(val), &pos); + zend_hash_get_current_data_ex(Z_ARRVAL_PP(val), (void **)¤t, &pos) == SUCCESS; + zend_hash_move_forward_ex(Z_ARRVAL_PP(val), &pos) + ) { + key_type = zend_hash_get_current_key_ex(Z_ARRVAL_PP(val), &key, &key_len, &key_index, 0, &pos); + if (key_type != HASH_KEY_IS_STRING) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "SNI_server_certs array requires string host name keys" + ); + return FAILURE; + } + + if (VCWD_REALPATH(Z_STRVAL_PP(current), resolved_path_buff)) { + /* The hello method is not inherited by SSL structs when assigning a new context + * inside the SNI callback, so the just use SSLv23 */ + ctx = SSL_CTX_new(SSLv23_server_method()); + + if (SSL_CTX_use_certificate_chain_file(ctx, resolved_path_buff) != 1) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "failed setting local cert chain file `%s'; " \ + "check that your cafile/capath settings include " \ + "details of your certificate and its issuer", + resolved_path_buff + ); + SSL_CTX_free(ctx); + return FAILURE; + } else if (SSL_CTX_use_PrivateKey_file(ctx, resolved_path_buff, SSL_FILETYPE_PEM) != 1) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "failed setting private key from file `%s'", + resolved_path_buff + ); + SSL_CTX_free(ctx); + return FAILURE; + } else { + sslsock->sni_certs[i].name = pestrdup(key, php_stream_is_persistent(stream)); + sslsock->sni_certs[i].ctx = ctx; + ++i; + } + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "failed setting local cert chain file `%s'; file not found", + Z_STRVAL_PP(current) + ); + return FAILURE; + } + } + + SSL_CTX_set_tlsext_servername_callback(sslsock->ctx, server_sni_callback); + + return SUCCESS; +} + static void enable_client_sni(php_stream *stream, php_openssl_netstream_data_t *sslsock) /* {{{ */ { zval **val; @@ -1311,6 +1442,13 @@ int php_openssl_setup_crypto(php_stream *stream, handle_ssl_error(stream, 0, 1 TSRMLS_CC); } +#ifdef HAVE_SNI + /* Enable server-side SNI */ + if (sslsock->is_client == 0 && enable_server_sni(stream, sslsock TSRMLS_CC) == FAILURE) { + return FAILURE; + } +#endif + /* Enable server-side handshake renegotiation rate-limiting */ if (sslsock->is_client == 0) { init_server_reneg_limit(stream, sslsock); @@ -1687,6 +1825,15 @@ static int php_openssl_sockop_close(php_stream *stream, int close_handle TSRMLS_ } } + if (sslsock->sni_certs) { + for (i=0; i<sslsock->sni_cert_count; i++) { + SSL_CTX_free(sslsock->sni_certs[i].ctx); + pefree(sslsock->sni_certs[i].name, php_stream_is_persistent(stream)); + } + pefree(sslsock->sni_certs, php_stream_is_persistent(stream)); + sslsock->sni_certs = NULL; + } + if (sslsock->url_name) { pefree(sslsock->url_name, php_stream_is_persistent(stream)); } |