Merge pull request #18062 from spray/w/15687-enable-endpoint-verification
#18059 #15687 Enable https hostname verification
This commit is contained in:
commit
d89b9e19b1
17 changed files with 440 additions and 20 deletions
39
akka-http-core/src/main/resources/keys/README
Normal file
39
akka-http-core/src/main/resources/keys/README
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
Keys for running Tls tests using the `ExampleHttpContexts`
|
||||
----------------------------------------------------------
|
||||
|
||||
Instructions adapted from
|
||||
|
||||
* http://datacenteroverlords.com/2012/03/01/creating-your-own-ssl-certificate-authority/
|
||||
* http://security.stackexchange.com/questions/9600/how-to-use-openssl-generated-keys-in-java
|
||||
|
||||
|
||||
# Create a rootCA key:
|
||||
|
||||
openssl genrsa -out rootCA.key 2048
|
||||
|
||||
# Self-sign CA:
|
||||
|
||||
openssl req -x509 -new -nodes -key rootCA.key -days 3560 -out rootCA.crt
|
||||
|
||||
# Create server key:
|
||||
|
||||
openssl genrsa -out device.key 2048
|
||||
|
||||
# Create server CSR:
|
||||
|
||||
openssl req -new -key server.key -out server.csr
|
||||
|
||||
# Create server certificate:
|
||||
|
||||
openssl x509 -req -in server.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out server.crt -days 3560
|
||||
|
||||
# Create certificate chain:
|
||||
|
||||
cat server.crt rootCA.crt > chain.pem
|
||||
|
||||
# Convert certificate and key to pkcs12 (you need to provide a password manually, `ExampleHttpContexts`
|
||||
# expects the password to be "abcdef"):
|
||||
|
||||
openssl pkcs12 -export -name servercrt -in chain.pem -inkey server.key -out server.p12
|
||||
|
||||
|
||||
40
akka-http-core/src/main/resources/keys/chain.pem
Normal file
40
akka-http-core/src/main/resources/keys/chain.pem
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDITCCAgkCCQCo8H6OcPrArzANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB
|
||||
VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
|
||||
cyBQdHkgTHRkMB4XDTE1MDcyMzA5NTEyMloXDTI1MDQyMTA5NTEyMlowYDELMAkG
|
||||
A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
|
||||
IFdpZGdpdHMgUHR5IEx0ZDEZMBcGA1UEAwwQYWtrYS5leGFtcGxlLm9yZzCCASIw
|
||||
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANMy/wgrSYVhVtu9OGbo2rSKauiz
|
||||
5V56X4uCqtCHF9UeHtnVtFLCBMa+pimOS+UyUAT4mbBsxW22BhoNUBZ15KPxltyD
|
||||
yEsqNCKwWGxL3r8AXQtze2MEpTl22Lvp/iCTXO1vbML/+9r3uqUjw/AAP9HwF9Wd
|
||||
j/yOrs6q8WE4sfc48iOj6N60/h2pRfn2WNJmo9W9FLC53NznixfsG5oN6Jmb9RM+
|
||||
fMHYXLfL/Vt6NrgVX1uqHt9HvuoxfNKhhXE5VU8bNfFfzPYvIt4aZXGxO15vEqsq
|
||||
OaZ7YJyKr1oFfJC8LmE5xPa3GHToCqmkdMXQK38mpslMQWlQLYnmkS5Qzv8CAwEA
|
||||
ATANBgkqhkiG9w0BAQsFAAOCAQEAEPDd1gAF9q2LtoZqTdcwmeBjdbT7n0WDRSuI
|
||||
BzQ/qKjvymwpFKQ0pZSPUyaw2qfRRiTQ/QTbqYep2mhvl5n+gW3ifTp83zgTGKH/
|
||||
3sDlX0HPSCBYCDy2gP/AOIgV/57ADMpEkTlz8yyLMH+pLDAoNFIPwy7blAkq+ULQ
|
||||
y6TfEBmZXoemSaIh5tRnexCD+pTvL4MRrGlBEoxdejDnIAt4n6BxmF0b4hKg8uta
|
||||
UvivA85lBKzWUoR/Vam5/SC8jtcyLt9RThRcNSj6zP6s5d+o+8PLznrSEadAtfD9
|
||||
0q+t4TYF81tClEEgGruVPNL4WIpDniOfw9AJgQNVJGfy5TKY1Q==
|
||||
-----END CERTIFICATE-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDXTCCAkWgAwIBAgIJANYwx08wP3STMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
|
||||
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
||||
aWRnaXRzIFB0eSBMdGQwHhcNMTUwNzIzMDk0ODI2WhcNMjUwNDIxMDk0ODI2WjBF
|
||||
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
|
||||
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||
CgKCAQEArk0K/Rn7uND2YGFBks5Sok1WvNdHQccPESEw2hNVF32ExAhbBXCrFaIl
|
||||
Io0q4eYSbypeauEjDXB/NJXurEefL8ONXK62erJDKKQ0aTTYqsVifoNYA9ORWoGE
|
||||
XhtAfOx4xvzr6vF1e3kz0PB/A4ftn0vvVygYnf/2E2bQZgaw8dXP5lIGasEzzigB
|
||||
LX/qTEW/vBOL98Rxp6JvjwvYMbPSZGwNwSz+tI5W2psdE1Mga2Qnsv3j+STWlD9v
|
||||
+JlgdN8r3PyR1sl3jC7gCj3AaOhv4RbAbqjwnZ9nrckx16PFiMtJiVRea7CQXN7g
|
||||
191EVujQnlg1LOhiSMKwVsuoXr08ywIDAQABo1AwTjAdBgNVHQ4EFgQU2THI/ilU
|
||||
M0xds3vZlV4CvhAZ1d8wHwYDVR0jBBgwFoAU2THI/ilUM0xds3vZlV4CvhAZ1d8w
|
||||
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAK9LO0HyIi0xbTISsc+A5
|
||||
LQyZowgRAGqsNNmni7NKDXauPLZrCfDVhvo/FPP1XSFShXo7ARvro9lul4AJlkNN
|
||||
VgX0gbWtkiAx0uLqlbMsC6imj2L9boRse7mzI/Ymem5SNTn9GUnlMiZ74rca9UT4
|
||||
Dk9YytrT4FSpomiL6z8Xj604W3RuLSdEfpfcn3Jh2tFSZ9hyLwB7ATUTA/yuj1SU
|
||||
G1gmoPMvlnPzNj2lIqyIdQxGdxt+L3mFO20CxBkeieWqQuNptpjwptliFjkZJJZP
|
||||
wQlx9qLLvs/eFC2AUWj+hbsl37PuARR9hoeqbKRcUjwGtaXOqikrvX1qzPc2+ij9
|
||||
/w==
|
||||
-----END CERTIFICATE-----
|
||||
21
akka-http-core/src/main/resources/keys/rootCA.crt
Normal file
21
akka-http-core/src/main/resources/keys/rootCA.crt
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDXTCCAkWgAwIBAgIJANYwx08wP3STMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
|
||||
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
||||
aWRnaXRzIFB0eSBMdGQwHhcNMTUwNzIzMDk0ODI2WhcNMjUwNDIxMDk0ODI2WjBF
|
||||
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
|
||||
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||
CgKCAQEArk0K/Rn7uND2YGFBks5Sok1WvNdHQccPESEw2hNVF32ExAhbBXCrFaIl
|
||||
Io0q4eYSbypeauEjDXB/NJXurEefL8ONXK62erJDKKQ0aTTYqsVifoNYA9ORWoGE
|
||||
XhtAfOx4xvzr6vF1e3kz0PB/A4ftn0vvVygYnf/2E2bQZgaw8dXP5lIGasEzzigB
|
||||
LX/qTEW/vBOL98Rxp6JvjwvYMbPSZGwNwSz+tI5W2psdE1Mga2Qnsv3j+STWlD9v
|
||||
+JlgdN8r3PyR1sl3jC7gCj3AaOhv4RbAbqjwnZ9nrckx16PFiMtJiVRea7CQXN7g
|
||||
191EVujQnlg1LOhiSMKwVsuoXr08ywIDAQABo1AwTjAdBgNVHQ4EFgQU2THI/ilU
|
||||
M0xds3vZlV4CvhAZ1d8wHwYDVR0jBBgwFoAU2THI/ilUM0xds3vZlV4CvhAZ1d8w
|
||||
DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAK9LO0HyIi0xbTISsc+A5
|
||||
LQyZowgRAGqsNNmni7NKDXauPLZrCfDVhvo/FPP1XSFShXo7ARvro9lul4AJlkNN
|
||||
VgX0gbWtkiAx0uLqlbMsC6imj2L9boRse7mzI/Ymem5SNTn9GUnlMiZ74rca9UT4
|
||||
Dk9YytrT4FSpomiL6z8Xj604W3RuLSdEfpfcn3Jh2tFSZ9hyLwB7ATUTA/yuj1SU
|
||||
G1gmoPMvlnPzNj2lIqyIdQxGdxt+L3mFO20CxBkeieWqQuNptpjwptliFjkZJJZP
|
||||
wQlx9qLLvs/eFC2AUWj+hbsl37PuARR9hoeqbKRcUjwGtaXOqikrvX1qzPc2+ij9
|
||||
/w==
|
||||
-----END CERTIFICATE-----
|
||||
27
akka-http-core/src/main/resources/keys/rootCA.key
Normal file
27
akka-http-core/src/main/resources/keys/rootCA.key
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEArk0K/Rn7uND2YGFBks5Sok1WvNdHQccPESEw2hNVF32ExAhb
|
||||
BXCrFaIlIo0q4eYSbypeauEjDXB/NJXurEefL8ONXK62erJDKKQ0aTTYqsVifoNY
|
||||
A9ORWoGEXhtAfOx4xvzr6vF1e3kz0PB/A4ftn0vvVygYnf/2E2bQZgaw8dXP5lIG
|
||||
asEzzigBLX/qTEW/vBOL98Rxp6JvjwvYMbPSZGwNwSz+tI5W2psdE1Mga2Qnsv3j
|
||||
+STWlD9v+JlgdN8r3PyR1sl3jC7gCj3AaOhv4RbAbqjwnZ9nrckx16PFiMtJiVRe
|
||||
a7CQXN7g191EVujQnlg1LOhiSMKwVsuoXr08ywIDAQABAoIBAQCSXAEpLMNRmq33
|
||||
mlMMqhF7VcPKyF5+Xl9Je/xgcjFWi0CLt5Ruyf/vJ3tVOwLSM3YxQHuN9cSQSXGX
|
||||
P3rt0SpbWjJ+q/pwpvV7z/5uhUCWjS46m6GxfNsmC3GR8AJDo/F67fBQFTcYWlrn
|
||||
TLrqxR4EUCgGoJWjPsZr3j6KHX5BYmzyTuJFBzxxipK42hnJQ7tMB8l6/5r4nRka
|
||||
d6SGFpJDkyhO+Wl0sBXjxHu1E4g8asI061jEOhcROV1Dk4hp1CYhd8TBj//6FSBC
|
||||
ttsIe2gxT0fk8bnNC78FuO0CUTCj4hFOWP7apr/NhLlxypu+4hj17NMhlptRvGxz
|
||||
6pPlMVDJAoGBANPVTS5nkJpMyczA5vaHsyTF/nwunogwHVeVYsQQ3Bed28Ldp7gr
|
||||
Dr4hgYFvGkEmlLvWOleHvGISuD3lHLd112LcPyLFMRrs8wX9vWTueZGYj5KDLS3C
|
||||
i3GaYMqqYbuiFY1QYprF36zRQkLMKUiOomE2+baCasbhluAqqx32KEKvAoGBANKk
|
||||
cG0X0svJ/TTQIE5nfDtKePDUA7wEPYGrQOO4vKKZUlytVhf+gEcYr575bPjkTl1h
|
||||
5jrrhr4OWpFDmRyBpi7wB95Fe93Df+0o4KmiNtsioZsi/MA5Tga2rAZPBBuZ9+5l
|
||||
alYl0fTo5PR3fOXJJoJ+w7+QI4N/9TGuBJoiEl6lAoGBAM8XapsBOIcApxB7TdCa
|
||||
HXLH9eDlmqq9jxH+w022xdR4yU2acMtFnOYXz4oAWgRzeVihOOw1kN+4OVKZWBer
|
||||
JuRJOZf+e+E84OFsjOnNkh/arBGqGFLyLGzlZdb79wv+i19ZxOxWojNLaKHxAjMi
|
||||
7nBn1Hyux0CjbmK8lAl4iyeVAoGAT6r4BprTFFaiGN56yYykVPx2v4dAnlTwOmHe
|
||||
GgLd/ZWFrB23CT4toDY6/iKST5Rx+ymy3SgFf06IfJaXi0uR4gDQyQV4sshlUvp5
|
||||
9k6u9rSjcLyL4dwKoclnSL+L6zCRsC3VSR3myf1n0vp6V6J7mTF+sa4/cFXuE8sg
|
||||
XHd0gS0CgYAXNDcF+zYoSmbfdG7uM7qOPQwNRbr0pHvAg0NmtM9JOj8gZPoaeAy3
|
||||
3jEk9AMQrK0MNsRynAoMkhy+7WOU6TNLvyxXAKGZffOmABzSB9LEFgHkVPutl5/i
|
||||
wL2pE1SoG2QwSqFYGv+rHgIpREJzDTNwbmSbl/Za50JrIZ3OFfTMDQ==
|
||||
-----END RSA PRIVATE KEY-----
|
||||
19
akka-http-core/src/main/resources/keys/server.crt
Normal file
19
akka-http-core/src/main/resources/keys/server.crt
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
-----BEGIN CERTIFICATE-----
|
||||
MIIDITCCAgkCCQCo8H6OcPrArzANBgkqhkiG9w0BAQsFADBFMQswCQYDVQQGEwJB
|
||||
VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0
|
||||
cyBQdHkgTHRkMB4XDTE1MDcyMzA5NTEyMloXDTI1MDQyMTA5NTEyMlowYDELMAkG
|
||||
A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0
|
||||
IFdpZGdpdHMgUHR5IEx0ZDEZMBcGA1UEAwwQYWtrYS5leGFtcGxlLm9yZzCCASIw
|
||||
DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANMy/wgrSYVhVtu9OGbo2rSKauiz
|
||||
5V56X4uCqtCHF9UeHtnVtFLCBMa+pimOS+UyUAT4mbBsxW22BhoNUBZ15KPxltyD
|
||||
yEsqNCKwWGxL3r8AXQtze2MEpTl22Lvp/iCTXO1vbML/+9r3uqUjw/AAP9HwF9Wd
|
||||
j/yOrs6q8WE4sfc48iOj6N60/h2pRfn2WNJmo9W9FLC53NznixfsG5oN6Jmb9RM+
|
||||
fMHYXLfL/Vt6NrgVX1uqHt9HvuoxfNKhhXE5VU8bNfFfzPYvIt4aZXGxO15vEqsq
|
||||
OaZ7YJyKr1oFfJC8LmE5xPa3GHToCqmkdMXQK38mpslMQWlQLYnmkS5Qzv8CAwEA
|
||||
ATANBgkqhkiG9w0BAQsFAAOCAQEAEPDd1gAF9q2LtoZqTdcwmeBjdbT7n0WDRSuI
|
||||
BzQ/qKjvymwpFKQ0pZSPUyaw2qfRRiTQ/QTbqYep2mhvl5n+gW3ifTp83zgTGKH/
|
||||
3sDlX0HPSCBYCDy2gP/AOIgV/57ADMpEkTlz8yyLMH+pLDAoNFIPwy7blAkq+ULQ
|
||||
y6TfEBmZXoemSaIh5tRnexCD+pTvL4MRrGlBEoxdejDnIAt4n6BxmF0b4hKg8uta
|
||||
UvivA85lBKzWUoR/Vam5/SC8jtcyLt9RThRcNSj6zP6s5d+o+8PLznrSEadAtfD9
|
||||
0q+t4TYF81tClEEgGruVPNL4WIpDniOfw9AJgQNVJGfy5TKY1Q==
|
||||
-----END CERTIFICATE-----
|
||||
27
akka-http-core/src/main/resources/keys/server.key
Normal file
27
akka-http-core/src/main/resources/keys/server.key
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEA0zL/CCtJhWFW2704ZujatIpq6LPlXnpfi4Kq0IcX1R4e2dW0
|
||||
UsIExr6mKY5L5TJQBPiZsGzFbbYGGg1QFnXko/GW3IPISyo0IrBYbEvevwBdC3N7
|
||||
YwSlOXbYu+n+IJNc7W9swv/72ve6pSPD8AA/0fAX1Z2P/I6uzqrxYTix9zjyI6Po
|
||||
3rT+HalF+fZY0maj1b0UsLnc3OeLF+wbmg3omZv1Ez58wdhct8v9W3o2uBVfW6oe
|
||||
30e+6jF80qGFcTlVTxs18V/M9i8i3hplcbE7Xm8Sqyo5pntgnIqvWgV8kLwuYTnE
|
||||
9rcYdOgKqaR0xdArfyamyUxBaVAtieaRLlDO/wIDAQABAoIBADfqTXkVNM7aWYut
|
||||
yiv8xEJ+TxWy4ywjS/58psq0qYukANj9alNqyKbxvL5NzSwuKN9YDiCWe6KzSWRG
|
||||
WAjKR7Fb+ewB+9pinxD8DT0GzT9WUkwA1A8AINpY68K8jaqEOVsnX+00prJvWfv0
|
||||
vyBggIUNgtHseD2ObRuMSIHL59oivxoBKmeRqFl26PCq+m6Dp1SsMwL8NE02rfUu
|
||||
uVW0zSz0/A5ZK90l8St3N78Puw/qicvfrI4PrGi4kLKW9UKJKP5FzfPF7Kf9itVA
|
||||
1VB3gd8Gs98vRnzHwZlwgjyAQkePzS/iEQid9uRA/Xys5ozcT1arYM00t3I7ZEUg
|
||||
GJTKHBECgYEA+K/M6smzPrTAi0BEuI1NCb3zfxkjbBhC0cco9U4VIuhYVU+7Ukre
|
||||
zi5yI+BQR8MPbftSeeosXV6eQaq04pKCrHWF+ql+3Io9Hojghd/EnNCOtGxjTGmI
|
||||
Px8G7byeIr4+QyP+JSEdsVBfIEEQ9BJ8Up84RibsMfWcKe6ntzAMEmkCgYEA2Wj6
|
||||
DqPisPp4WwGi8bSvSRZsF3h3xu0saml+ug28j+b3kOa99Uz49kCi99sacJArYOWv
|
||||
Dn+DPl2K2/lwYO0bfyXwWaLp8pd/MAmwhKZ2+qvoUnkZJFRU3yrUoPp7CURZSbcG
|
||||
aD7IKotFH7wutqj8pZ50y8VGqKVACenhRSAH2ScCgYAuX7IJslUfg1tIXFK0S30r
|
||||
LOXENK7bUGbdcZMcs1PTr5oRRo362YVU02prcD/oMeKlsrD9lQJy4tsGCcwzV/jQ
|
||||
KhYy2PqUK58cG5AqxsCGMYn68R9PN3q1spZ7LKocdndr08FnsRY1Y3Rpslhz+yJ9
|
||||
0b0Pr+BprJBTbXKPAYGuyQKBgAJFu59djSgGZi2lVburBM4Bwv13z+CvZ/Bwy9dL
|
||||
/3WNl3bXQpMGy+9e+5UVoDAfAaUQoYTIRmnndmUYNVl+APSSQ/Hb5xAXD0hEQakR
|
||||
SFsUYuhBxcaAbyap/vDzzUdqhHhlxlZemZ8AN6e+Qsq793APuO7MUBHBMGsqG6Wq
|
||||
UQqvAoGAINEINXhFXp2qVRDBUY57rRtpjQHajeNTMChgWTg30owfVNBY4evjRj8f
|
||||
9XDuUkTumYcDcnOKmX3L6n9rg4noHlfNvxmn9pmG9vP0mG0MEOOxSxXFHVIuBw10
|
||||
wdTb0WE/i3FhyufdaRHLGhPAMQjaCeFSV3sMxMHuNePvCxnKD3E=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
BIN
akka-http-core/src/main/resources/keys/server.p12
Normal file
BIN
akka-http-core/src/main/resources/keys/server.p12
Normal file
Binary file not shown.
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2015 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package akka.http.impl.util
|
||||
|
||||
import java.lang.reflect.{ InvocationTargetException, Method }
|
||||
import javax.net.ssl.SSLParameters
|
||||
|
||||
import scala.util.control.NonFatal
|
||||
|
||||
/**
|
||||
* INTERNAL API
|
||||
*
|
||||
* Enables accessing SslParameters even if compiled against Java 6.
|
||||
*/
|
||||
private[http] object Java6Compat {
|
||||
/**
|
||||
* Returns true if setting the algorithm was successful.
|
||||
*/
|
||||
def setEndpointIdentificationAlgorithm(parameters: SSLParameters, algorithm: String): Boolean =
|
||||
setEndpointIdentificationAlgorithmFunction(parameters, algorithm)
|
||||
|
||||
private[this] val setEndpointIdentificationAlgorithmFunction: (SSLParameters, String) ⇒ Boolean = {
|
||||
def unsupported: (SSLParameters, String) ⇒ Boolean = (_, _) ⇒ false
|
||||
|
||||
def callReflectively(m: Method) =
|
||||
(params: SSLParameters, algorithm: String) ⇒
|
||||
try {
|
||||
m.invoke(params, algorithm)
|
||||
true
|
||||
} catch {
|
||||
case ite: InvocationTargetException ⇒ throw ite.getTargetException
|
||||
}
|
||||
|
||||
try {
|
||||
val m = classOf[SSLParameters].getMethod("setEndpointIdentificationAlgorithm", classOf[java.lang.String])
|
||||
|
||||
val candidate =
|
||||
if (m.getReturnType == Void.TYPE && m.getParameterTypes.toSeq == Seq(classOf[java.lang.String])) {
|
||||
if (!m.isAccessible) m.setAccessible(true)
|
||||
callReflectively(m)
|
||||
} else unsupported
|
||||
|
||||
// probe so that we can be sure a reflective problem only turns up once
|
||||
// here during construction
|
||||
candidate(new SSLParameters(), "https")
|
||||
candidate
|
||||
} catch {
|
||||
case NonFatal(_) ⇒ unsupported
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -146,4 +146,6 @@ package util {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private[http] class ReadTheDocumentationException(message: String) extends RuntimeException(message)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import akka.event.LoggingAdapter
|
|||
import akka.http._
|
||||
import akka.http.impl.engine.client._
|
||||
import akka.http.impl.engine.server._
|
||||
import akka.http.impl.util.StreamUtils
|
||||
import akka.http.impl.util.{ ReadTheDocumentationException, Java6Compat, StreamUtils }
|
||||
import akka.http.scaladsl.model._
|
||||
import akka.http.scaladsl.model.headers.Host
|
||||
import akka.http.scaladsl.util.FastFuture
|
||||
|
|
@ -186,7 +186,7 @@ class HttpExt(config: Config)(implicit system: ActorSystem) extends akka.actor.E
|
|||
log: LoggingAdapter): Flow[HttpRequest, HttpResponse, Future[OutgoingConnection]] = {
|
||||
val hostHeader = if (port == (if (httpsContext.isEmpty) 80 else 443)) Host(host) else Host(host, port)
|
||||
val layer = clientLayer(hostHeader, settings, log)
|
||||
val tlsStage = sslTlsStage(httpsContext, Client)
|
||||
val tlsStage = sslTlsStage(httpsContext, Client, Some(host -> port))
|
||||
val transportFlow = Tcp().outgoingConnection(new InetSocketAddress(host, port), localAddress,
|
||||
settings.socketOptions, halfClose = true, settings.connectingTimeout, settings.idleTimeout)
|
||||
|
||||
|
|
@ -391,13 +391,25 @@ class HttpExt(config: Config)(implicit system: ActorSystem) extends akka.actor.E
|
|||
synchronized {
|
||||
_defaultClientHttpsContext match {
|
||||
case null ⇒
|
||||
val ctx = HttpsContext(SSLContext.getDefault)
|
||||
val ctx = createDefaultClientHttpsContext
|
||||
_defaultClientHttpsContext = ctx
|
||||
ctx
|
||||
case ctx ⇒ ctx
|
||||
}
|
||||
}
|
||||
|
||||
private def createDefaultClientHttpsContext: HttpsContext = {
|
||||
val defaultCtx = SSLContext.getDefault
|
||||
|
||||
val params = new SSLParameters
|
||||
if (!Java6Compat.setEndpointIdentificationAlgorithm(params, "https"))
|
||||
throw new ReadTheDocumentationException(
|
||||
"Cannot enable HTTPS hostname verification on Java 6. See the " +
|
||||
"\"Client-Side HTTPS Support\" section in the documentation")
|
||||
|
||||
HttpsContext(defaultCtx, sslParameters = Some(params))
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default client-side [[HttpsContext]].
|
||||
*/
|
||||
|
|
@ -470,9 +482,9 @@ class HttpExt(config: Config)(implicit system: ActorSystem) extends akka.actor.E
|
|||
private def effectiveHttpsContext(ctx: Option[HttpsContext]): Option[HttpsContext] =
|
||||
ctx orElse Some(defaultClientHttpsContext)
|
||||
|
||||
private def sslTlsStage(httpsContext: Option[HttpsContext], role: Role) =
|
||||
private[http] def sslTlsStage(httpsContext: Option[HttpsContext], role: Role, hostInfo: Option[(String, Int)] = None) =
|
||||
httpsContext match {
|
||||
case Some(hctx) ⇒ SslTls(hctx.sslContext, hctx.firstSession, role)
|
||||
case Some(hctx) ⇒ SslTls(hctx.sslContext, hctx.firstSession, role, hostInfo = hostInfo)
|
||||
case None ⇒ SslTlsPlacebo.forScala
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2015 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package akka.http.impl.engine.client
|
||||
|
||||
import org.scalatest.concurrent.PatienceConfiguration.Timeout
|
||||
import org.scalatest.concurrent.ScalaFutures
|
||||
|
||||
import akka.stream.ActorMaterializer
|
||||
import akka.stream.io._
|
||||
import akka.stream.scaladsl._
|
||||
import akka.stream.testkit.AkkaSpec
|
||||
|
||||
import akka.http.impl.util._
|
||||
|
||||
import akka.http.scaladsl.{ HttpsContext, Http }
|
||||
import akka.http.scaladsl.model.{ StatusCodes, HttpResponse, HttpRequest }
|
||||
import akka.http.scaladsl.model.headers.Host
|
||||
import org.scalatest.time.{ Span, Seconds }
|
||||
|
||||
import scala.concurrent.Future
|
||||
|
||||
class TlsEndpointVerificationSpec extends AkkaSpec("""
|
||||
#akka.loggers = []
|
||||
akka.loglevel = DEBUG
|
||||
akka.io.tcp.trace-logging = off
|
||||
akka.io.tcp.windows-connection-abort-workaround-enabled=auto""") with ScalaFutures {
|
||||
implicit val materializer = ActorMaterializer()
|
||||
val timeout = Timeout(Span(3, Seconds))
|
||||
|
||||
"The client implementation" should {
|
||||
"not accept certificates signed by unknown CA" in {
|
||||
val pipe = pipeline(Http().defaultClientHttpsContext, hostname = "akka.example.org") // default context doesn't include custom CA
|
||||
|
||||
whenReady(pipe(HttpRequest(uri = "https://akka.example.org/")).failed, timeout) { e ⇒
|
||||
e shouldBe an[Exception]
|
||||
}
|
||||
}
|
||||
"accept certificates signed by known CA" in {
|
||||
val pipe = pipeline(ExampleHttpContexts.exampleClientContext, hostname = "akka.example.org") // example context does include custom CA
|
||||
|
||||
whenReady(pipe(HttpRequest(uri = "https://akka.example.org/")), timeout) { response ⇒
|
||||
response.status shouldEqual StatusCodes.OK
|
||||
}
|
||||
}
|
||||
"not accept certificates for foreign hosts" in {
|
||||
val pipe = pipeline(ExampleHttpContexts.exampleClientContext, hostname = "hijack.de") // example context does include custom CA
|
||||
|
||||
whenReady(pipe(HttpRequest(uri = "https://hijack.de/")).failed, timeout) { e ⇒
|
||||
e shouldBe an[Exception]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def pipeline(clientContext: HttpsContext, hostname: String): HttpRequest ⇒ Future[HttpResponse] = req ⇒
|
||||
Source.single(req).via(pipelineFlow(clientContext, hostname)).runWith(Sink.head)
|
||||
|
||||
def pipelineFlow(clientContext: HttpsContext, hostname: String): Flow[HttpRequest, HttpResponse, Unit] = {
|
||||
val handler: HttpRequest ⇒ HttpResponse = _ ⇒ HttpResponse()
|
||||
|
||||
val serverSideTls = Http().sslTlsStage(Some(ExampleHttpContexts.exampleServerContext), Server)
|
||||
val clientSideTls = Http().sslTlsStage(Some(clientContext), Client, Some(hostname -> 8080))
|
||||
|
||||
val server =
|
||||
Http().serverLayer()
|
||||
.atop(serverSideTls)
|
||||
.reversed
|
||||
.join(Flow[HttpRequest].map(handler))
|
||||
|
||||
val client =
|
||||
Http().clientLayer(Host(hostname, 8080))
|
||||
.atop(clientSideTls)
|
||||
|
||||
client.join(server)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2015 Typesafe Inc. <http://www.typesafe.com>
|
||||
*/
|
||||
|
||||
package akka.http.impl.util
|
||||
|
||||
import java.io.InputStream
|
||||
import java.security.{ SecureRandom, KeyStore }
|
||||
import java.security.cert.{ CertificateFactory, Certificate }
|
||||
import javax.net.ssl.{ SSLParameters, SSLContext, TrustManagerFactory, KeyManagerFactory }
|
||||
|
||||
import akka.http.scaladsl.HttpsContext
|
||||
|
||||
/**
|
||||
* These are HTTPS example configurations that take key material from the resources/key folder.
|
||||
*/
|
||||
object ExampleHttpContexts {
|
||||
val exampleServerContext = {
|
||||
val ks = KeyStore.getInstance("PKCS12")
|
||||
ks.load(resourceStream("keys/server.p12"), "abcdef".toCharArray)
|
||||
|
||||
val keyManagerFactory = KeyManagerFactory.getInstance("SunX509")
|
||||
keyManagerFactory.init(ks, "abcdef".toCharArray)
|
||||
|
||||
val context = SSLContext.getInstance("TLS")
|
||||
context.init(keyManagerFactory.getKeyManagers, null, new SecureRandom)
|
||||
|
||||
HttpsContext(context)
|
||||
}
|
||||
val exampleClientContext = {
|
||||
val certStore = KeyStore.getInstance(KeyStore.getDefaultType)
|
||||
certStore.load(null, null)
|
||||
certStore.setCertificateEntry("ca", loadX509Certificate("keys/rootCA.crt"))
|
||||
|
||||
val certManagerFactory = TrustManagerFactory.getInstance("SunX509")
|
||||
certManagerFactory.init(certStore)
|
||||
|
||||
val context = SSLContext.getInstance("TLS")
|
||||
context.init(null, certManagerFactory.getTrustManagers, new SecureRandom)
|
||||
|
||||
val params = new SSLParameters()
|
||||
Java6Compat.setEndpointIdentificationAlgorithm(params, "https")
|
||||
HttpsContext(context, sslParameters = Some(params))
|
||||
}
|
||||
|
||||
def resourceStream(resourceName: String): InputStream = {
|
||||
val is = getClass.getClassLoader.getResourceAsStream(resourceName)
|
||||
require(is ne null, s"Resource $resourceName not found")
|
||||
is
|
||||
}
|
||||
|
||||
def loadX509Certificate(resourceName: String): Certificate =
|
||||
CertificateFactory.getInstance("X.509").generateCertificate(resourceStream(resourceName))
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue