Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add missing HTTPS options that were not being passed to tunnel (@brichard19) #1383

Merged
merged 4 commits into from Feb 2, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
43 changes: 33 additions & 10 deletions request.js
Expand Up @@ -163,17 +163,22 @@ function constructTunnelOptions(request) {
var proxy = request.proxy

var tunnelOptions = {
proxy: {
host: proxy.hostname,
port: +proxy.port,
proxyAuth: proxy.auth,
headers: request.proxyHeaders
proxy : {
host : proxy.hostname,
port : +proxy.port,
proxyAuth : proxy.auth,
headers : request.proxyHeaders
},
rejectUnauthorized: request.rejectUnauthorized,
headers: request.headers,
ca: request.ca,
cert: request.cert,
key: request.key
headers : request.headers,
ca : request.ca,
cert : request.cert,
key : request.key,
passphrase : request.passphrase,
pfx : request.pfx,
ciphers : request.ciphers,
rejectUnauthorized : request.rejectUnauthorized,
secureOptions : request.secureOptions,
secureProtocol : request.secureProtocol
}

return tunnelOptions
Expand Down Expand Up @@ -794,6 +799,14 @@ Request.prototype.getNewAgent = function () {
options.cert = self.cert
}

if (self.pfx) {
options.pfx = self.pfx
}

if (self.passphrase) {
options.passphrase = self.passphrase
}

var poolKey = ''

// different types of agents are in different pools
Expand Down Expand Up @@ -824,9 +837,19 @@ Request.prototype.getNewAgent = function () {
}

if (options.cert) {
if (poolKey) {
poolKey += ':'
}
poolKey += options.cert.toString('ascii') + options.key.toString('ascii')
}

if (options.pfx) {
if (poolKey) {
poolKey += ':'
}
poolKey += options.pfx.toString('ascii')
}

if (options.ciphers) {
if (poolKey) {
poolKey += ':'
Expand Down
4 changes: 3 additions & 1 deletion tests/server.js
Expand Up @@ -34,7 +34,9 @@ exports.createSSLServer = function(port, opts) {
}

for (i in options) {
options[i] = fs.readFileSync(options[i])
if (i !== 'requestCert' && i !== 'rejectUnauthorized') {
options[i] = fs.readFileSync(options[i])
}
}

var s = https.createServer(options, function (req, resp) {
Expand Down
30 changes: 30 additions & 0 deletions tests/ssl/ca/client-enc.key
@@ -0,0 +1,30 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,E95AEBB470632DA50EC1ABAB7F2D7A2A

FDVPpWyXyUn3f+mYpHyQIWa2bnqfnzffLjrZky938WSL43hHL5XmqXXcgemQsoeb
abz68jYpVfDicvcgHprv40c69ZAKv1lmN11P9mHzRmI6HHo1oaQ2Sn13UHxX425W
NZ8IBREbSxm65a5zBYFLQXamNVBkR1z5EIoU/1FJz5CY9TAlmWYrybtUVHbc7V4S
GiiyD0Cm5fyg/436p9bcZPvXxalep9903eWd5kl1A+WO05Sin1Ilk5OVCFLMIiuM
yq4MCtONumDdIWoiSGT488P+/eMe5gfxYGseNR0AEWHYIM+Fptd2qxj9QM6CO6Pc
8EDoPs5zUXitCsTKR1tsNI7WnldMnQGf5J4SG2X5jXX3fyX534bbEBkA/CtkkdCa
A4rjrbBpMpijnq6yEsOxMOE9pqvJsWtBVdVtFtw/bx+oBKD3S2IUn3DVhSFjs62R
OSsWCT8zY0B8+EwXBPQjmfjAU/dq21ot3jxvy5fl627wM1TuEnsrqMiGxZe5mkXJ
wg9Y0c6K4Qwr5bbYIf7WvsMoKj0PfU9NRBUymSdZnaFlNSe5RguBCokaYD9/Kn9E
wyf5AKlI3LrdUk+9AmOKKmejPCzPBaGnhZjpFLLbV2pCkT3pRlrnGk5zvEKLKTdx
MjYzBxxbbBqAk5VHwN5t7D0aPerVPHsyt2bfBC2FWQAbpil70O2KHe90UbAh2VpZ
ofcx0ta6nUGTz5htcLZXsE0TR6d1bcdtXhtyxONo3kNDfNsfYlHmzQJpf9FTOKVG
EKQZ5M9OqMTzzVHysWu3DfN4x4Z6nNoXjDckWyv5bhpazZU2Puq2zgliiXORd30D
xVSuCkNeaw0DbeHd0CDL3Hn3W3ElevS7yHwKgG8OOntb4iVOzwx8nw0B/8O4OBoh
xB3EKu8eCfenkX9+smAz6ZE+ahgT7Jc0wsknekyInhWBR6JmmROy+DrCxwrntq8X
7zcoMLNFx7k6XnXo3u1MTo5rWVtsVZki+O3vCnxep0txkDoVXSSMW7aQMaUG7w68
SXav16s14DuKpQVA6pSQRWG1spdiR2leOxvvzaFaKcnTRWKDeyqJMRf2cKqtrl+0
Qg21folVaQlWT24P1f0d9tXGCtVzhvSBvHkomrSnCiHYzXtQLA9Cacqf4FN+vFx1
ZxZQtv/9tFFBh0PE3EtHPdLM5KZLQuqL3jMHIWGwl+U5hQ9SlNi5239W9NWrY9Iu
ZCf5QW39orW5sH9EOk4eFwrGovY1tCJlboj6sxOoNncW9Iz/Z1q0xm6J4FV94W7+
vaz5EXSVr4egYnJHgxEvA3XGKO2s99DFU3A2PcwkCTHDgi/UatOE8IckgPseXCsQ
I8uRzwSZO/q+kWEfb3c6PJb/wxgKYbMGqaw4Qlyg3DwjKBUbAv3gXd9rv1JvVhrP
I1LTr2MLYsDErbaj2F0KUW/XTYEHWlAQ2X4pDcq9bRBosqnJhYclW56w9d0WS10H
71J5a4Bk5qVun2mkCQIGcsONQxmVkGUYuQ/7Dag7noN8B5qZV5HljJBMQSpmDS1v
QxkMI5pPM/AptRl2jRYd8laluxM33fqP0/nFBM9ghDn8mU1BAVfMqPPv0gz446Kl
-----END RSA PRIVATE KEY-----
20 changes: 20 additions & 0 deletions tests/ssl/ca/client.cnf
@@ -0,0 +1,20 @@
[ req ]
default_bits = 1024
days = 3650
distinguished_name = req_distinguished_name
attributes = req_attributes
prompt = no
output_password = password

[ req_distinguished_name ]
C = US
ST = CA
L = Oakland
O = request
OU = request@localhost
CN = TestClient
emailAddress = do.not@email.me

[ req_attributes ]
challengePassword = password challenge

20 changes: 20 additions & 0 deletions tests/ssl/ca/client.crt
@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDLjCCApcCCQCt9iAWqkDJwzANBgkqhkiG9w0BAQUFADCBojELMAkGA1UEBhMC
VVMxCzAJBgNVBAgTAkNBMRAwDgYDVQQHEwdPYWtsYW5kMRAwDgYDVQQKEwdyZXF1
ZXN0MSYwJAYDVQQLEx1yZXF1ZXN0IENlcnRpZmljYXRlIEF1dGhvcml0eTESMBAG
A1UEAxMJcmVxdWVzdENBMSYwJAYJKoZIhvcNAQkBFhdtaWtlYWxAbWlrZWFscm9n
ZXJzLmNvbTAeFw0xNTAxMjYyMTAxMjNaFw0xNTAyMjUyMTAxMjNaMIGPMQswCQYD
VQQGEwJVUzELMAkGA1UECBMCQ0ExEDAOBgNVBAcTB09ha2xhbmQxEDAOBgNVBAoT
B3JlcXVlc3QxGjAYBgNVBAsUEXJlcXVlc3RAbG9jYWxob3N0MRMwEQYDVQQDEwpU
ZXN0Q2xpZW50MR4wHAYJKoZIhvcNAQkBFg9kby5ub3RAZW1haWwubWUwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDJDnEzgWpgsEyQcMQnkTTm7uFNKYOM
76RID4bdK2pHbFlW4ZEWC//RFee4XkAzI4Yqa0thSaQBlm/ZrQD5w82XlHNUMtAu
CJPfIMGKUYSBv8L26Bj23X8Hju1n8bdvyqAmLh0rvLvHF0g8AitpiQvn+DAhnV7A
st5a87mUbCoBtETmnOZ1HQk8eIJ+3kZ0WaTmJy3WY8lP+LA64qLOC7kpIKkeBJUT
ndnedd8gnq87Ale1XwLILUxN1hEfbBXLG2qxr8YDyUzntQMAEDNwJP8ikCcm8Yia
+Ftp7vuioVtwR9G4lTn+3LYwDV2mki2IAjZ0bTVowJXFu6Aw9uLmm9NpAgMBAAEw
DQYJKoZIhvcNAQEFBQADgYEAsmRaJf+axYufn9vLB5nh94vRsMSSLe5ARrWl0btT
BZil51V0zvBwU502AVjxhzYmWGwEJuuChsnOv3rf/km5EmDo/yYN1ZEIZZEKGPQ1
U7GMMJkrT1aBplPI/97CjuZkJYhBKpXMvi0yb4leJfYIORSyegPsDOEpaKMKDcDO
QWw=
-----END CERTIFICATE-----
18 changes: 18 additions & 0 deletions tests/ssl/ca/client.csr
@@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE REQUEST-----
MIIC+DCCAeACAQAwgY8xCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEQMA4GA1UE
BxMHT2FrbGFuZDEQMA4GA1UEChMHcmVxdWVzdDEaMBgGA1UECxQRcmVxdWVzdEBs
b2NhbGhvc3QxEzARBgNVBAMTClRlc3RDbGllbnQxHjAcBgkqhkiG9w0BCQEWD2Rv
Lm5vdEBlbWFpbC5tZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMkO
cTOBamCwTJBwxCeRNObu4U0pg4zvpEgPht0rakdsWVbhkRYL/9EV57heQDMjhipr
S2FJpAGWb9mtAPnDzZeUc1Qy0C4Ik98gwYpRhIG/wvboGPbdfweO7Wfxt2/KoCYu
HSu8u8cXSDwCK2mJC+f4MCGdXsCy3lrzuZRsKgG0ROac5nUdCTx4gn7eRnRZpOYn
LdZjyU/4sDrios4LuSkgqR4ElROd2d513yCerzsCV7VfAsgtTE3WER9sFcsbarGv
xgPJTOe1AwAQM3Ak/yKQJybxiJr4W2nu+6KhW3BH0biVOf7ctjANXaaSLYgCNnRt
NWjAlcW7oDD24uab02kCAwEAAaAjMCEGCSqGSIb3DQEJBzEUExJwYXNzd29yZCBj
aGFsbGVuZ2UwDQYJKoZIhvcNAQELBQADggEBACEqC+TJTli7enf064IaIbaJvN2+
KyHgOmWvjI3B/Sswb2E8gm2d5epPTH1BD62wv2TowHI9NvRwa6MVb1xrdDs5WAck
EDvw9hUlv+9t5OXQXd0LmAzFVga3EjYCSdECKjiyTP71irBjmnxAYI/2cqE39xfw
rGLXI1qOs+ivptaCAIJeHkNjf/z6EHQJE9F6OyGI6Mhg8GcoufI5xfV8FXjy8RBd
Cz7uLocFxiQk9lwNwfL0ki5nrSWJOaa/1rY0q/sK/yHFLfapXEcE70vVr/hf05B/
w8q4LgqU2PCELrFb0JKpT1L3lSXe17+AeYk2fi/SbHyVe53VY6rep/Y9yQ8=
-----END CERTIFICATE REQUEST-----
27 changes: 27 additions & 0 deletions tests/ssl/ca/client.key
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAyQ5xM4FqYLBMkHDEJ5E05u7hTSmDjO+kSA+G3StqR2xZVuGR
Fgv/0RXnuF5AMyOGKmtLYUmkAZZv2a0A+cPNl5RzVDLQLgiT3yDBilGEgb/C9ugY
9t1/B47tZ/G3b8qgJi4dK7y7xxdIPAIraYkL5/gwIZ1ewLLeWvO5lGwqAbRE5pzm
dR0JPHiCft5GdFmk5ict1mPJT/iwOuKizgu5KSCpHgSVE53Z3nXfIJ6vOwJXtV8C
yC1MTdYRH2wVyxtqsa/GA8lM57UDABAzcCT/IpAnJvGImvhbae77oqFbcEfRuJU5
/ty2MA1dppItiAI2dG01aMCVxbugMPbi5pvTaQIDAQABAoIBAB27wQn47Z529Bu4
UYn4c3ZjhXY/2XCSUB1IDo3OydzeLSgoG6jDBYYKU0Z0ydHGQyUq0O8GUPbbJJdw
emB1kIYGMjgVe6wTIKsy0Ox/ubTmgxK4qFh50Ttw67MfkB08PgrnbvD07GA5FTmq
qHjnB5e6oIOYHlcpHLEesic9B8lQeHWvCDdmoSS/qSw3t/GR02rlQjE/tEwMDGSl
sDbm/3SgWBFDiNuZsewP3rq+ZaK0BQ2g9BDZjTXQEdyuqEfqZg1idx5UIYUBlaHD
qoT6DxQdhZVk5+DIABHSRhK0InegxtQTVXOwR7HeJFtyu4QqLcfS3RVr8fiv3kx4
8uoCngECgYEA4vMj6keOPkvHzWLCd8mzdHtQ8Iq+LstSqjYrw/Wu4vYNCbY2bHTD
ZTJYKRy7R81+PXTLZaOSPVVj/gGg/89dO/xX8RYIm/FuRMTqTA45x1dWbjyHAURS
HDlWhNb2ht853XZnrnvup8HH3cuFy9Ep6oF+ffje/Lw6mSrtftR3QnkCgYEA4srP
Jg7y1TR/vSSJk+OMzlnqEtyo8ZVwO+I3UrtvKIOXJM3gsqCwDFhkAL/ROLMZL94o
27+Ov4kNZRWJ3y/Cdlj82amFGzhVdwmP3hFlJDC+Rf4bkkgtkTwn1uo/qoXE/OZO
rhYPdZkeWT/43O+kXn2+ucD/F2H+XCv8hG20XHECgYEAqGmXmE4bTz06+r2z4+KI
ygKMsMO0l9MH+AmU9qkFa6T9TdyqjFclfJ4cb/3DOGhUqtRV74mvhtYsCp041TwT
SuVaeSxJnTdPBbc+ysuvsq6sE8fUw2rop8sg2hkO/kz+ispH7GJJWrHhWESkd/gy
a7RGosKg7tnbfjgt33VZPrkCgYBc5dBWeZcUqE2Oz5GfR31c5U3Rbhux4ZG4peAd
fnN49/YIeGCLKvESDX7hI7Fy9UHi7rBz2xKA+IXJGzp/dpPEYI0qJ5tDXB7+BKeu
whdY7LJz/zOSBwjLTgXPreJoWiUnprsh6h1pAVCCJIcvEOaWYhGnCxwymsxTOx1T
rZBMsQKBgQCnhZUI01EAMhMihdABW4WEGqLyQ0y395ebD7j5eq0RxTJs1151Skx2
in8Ut0u9K0r4MUHh1tQU+JRbmWm/uFHI7uksW5e59mfFvGs0ioGuKecy60Giieod
BgqAfzyAmodwrvPgPaBOaPCYLVDnmeM1QYH6G4DiMzpc0dJOBneZ/Q==
-----END RSA PRIVATE KEY-----
23 changes: 23 additions & 0 deletions tests/ssl/ca/gen-client.sh
@@ -0,0 +1,23 @@
#!/bin/sh

# Adapted from:
# http://nodejs.org/api/tls.html
# https://github.com/joyent/node/blob/master/test/fixtures/keys/Makefile

# Create a private key
openssl genrsa -out client.key 2048

# Create a certificate signing request
openssl req -new -sha256 -key client.key -out client.csr -config client.cnf

# Use the CSR and the CA key (previously generated) to create a certificate
openssl x509 -req \
-in client.csr \
-CA ca.crt \
-CAkey ca.key \
-set_serial 0x`cat ca.srl` \
-passin 'pass:password' \
-out client.crt

# Encrypt with password
openssl rsa -aes128 -in client.key -out client-enc.key -passout 'password'
63 changes: 61 additions & 2 deletions tests/test-tunnel.js
Expand Up @@ -14,10 +14,20 @@ var server = require('./server')
var events = []
, caFile = path.resolve(__dirname, 'ssl/ca/ca.crt')
, ca = fs.readFileSync(caFile)
, clientCert = fs.readFileSync(path.resolve(__dirname, 'ssl/ca/client.crt'))
, clientKey = fs.readFileSync(path.resolve(__dirname, 'ssl/ca/client-enc.key'))
, clientPassword = 'password'
, sslOpts = {
key : path.resolve(__dirname, 'ssl/ca/localhost.key'),
cert : path.resolve(__dirname, 'ssl/ca/localhost.crt')
}
, mutualSSLOpts = {
key : path.resolve(__dirname, 'ssl/ca/localhost.key'),
cert : path.resolve(__dirname, 'ssl/ca/localhost.crt'),
ca : caFile,
requestCert : true,
rejectUnauthorized : true
}

// this is needed for 'https over http, tunnel=false' test
// from https://github.com/coolaj86/node-ssl-root-cas/blob/v1.1.9-beta/ssl-root-cas.js#L4267-L4281
Expand All @@ -27,11 +37,13 @@ httpsOpts.ca.push(ca)

var s = server.createServer()
, ss = server.createSSLServer(null, sslOpts)
, ss2 = server.createSSLServer(ss.port + 1, mutualSSLOpts)

// XXX when tunneling https over https, connections get left open so the server
// doesn't want to close normally (and same issue with http server on v0.8.x)
destroyable(s)
destroyable(ss)
destroyable(ss2)

function event() {
events.push(util.format.apply(null, arguments))
Expand Down Expand Up @@ -87,11 +99,14 @@ function setListeners(server, type) {

setListeners(s, 'http')
setListeners(ss, 'https')
setListeners(ss2, 'https')

tape('setup', function(t) {
s.listen(s.port, function() {
ss.listen(ss.port, function() {
t.end()
ss2.listen(ss2.port, 'localhost', function() {
t.end()
})
})
})
})
Expand Down Expand Up @@ -405,10 +420,54 @@ runTest('https->https over http, tunnel=default', {
])


// MUTUAL HTTPS OVER HTTP

runTest('mutual https over http, tunnel=true', {
url : ss2.url,
proxy : s.url,
tunnel : true,
cert : clientCert,
key : clientKey,
passphrase : clientPassword
}, [
'http connect to localhost:' + ss2.port,
'https response',
'200 https ok'
])

// XXX causes 'Error: socket hang up'
// runTest('mutual https over http, tunnel=false', {
// url : ss2.url,
// proxy : s.url,
// tunnel : false,
// cert : clientCert,
// key : clientKey,
// passphrase : clientPassword
// }, [
// 'http connect to localhost:' + ss2.port,
// 'https response',
// '200 https ok'
// ])

runTest('mutual https over http, tunnel=default', {
url : ss2.url,
proxy : s.url,
cert : clientCert,
key : clientKey,
passphrase : clientPassword
}, [
'http connect to localhost:' + ss2.port,
'https response',
'200 https ok'
])


tape('cleanup', function(t) {
s.destroy(function() {
ss.destroy(function() {
t.end()
ss2.destroy(function() {
t.end()
})
})
})
})