Last active
June 18, 2019 18:47
-
-
Save flotwig/12b2f070fd627f48fa7681802e6c36de to your computer and use it in GitHub Desktop.
node.js client certificate experiments
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const assert = require('assert') | |
const Bluebird = require('bluebird') | |
const certyCb = require('certy') | |
const https = require('https') | |
const rp = require('request-promise') | |
const certy = Bluebird.promisifyAll(certyCb) | |
certy.createAsync() | |
.then((certs) => { | |
const { serverKey, serverCert, clientCert, clientKey, ca } = certs | |
const server = https.createServer({ | |
key: serverKey, | |
cert: serverCert, | |
ca, | |
requestCert: true, | |
rejectUnauthorized: true, | |
}, (req, res) => { | |
res.writeHead(200) | |
res.end('hello world\n') | |
}) | |
server.listen() | |
const { port } = server.address() | |
const baseOptions = { | |
cert: clientCert, | |
key: clientKey, | |
ca, | |
rejectUnauthorized: false, | |
resolveWithFullResponse: true, | |
} | |
// try normal pki | |
return rp.get(Object.assign({ | |
url: `https://localhost:${port}/`, | |
}, baseOptions)) | |
.then((res) => { | |
assert(res.statusCode === 200) | |
// try sending pki to a server that doesn't use it | |
return rp.get(Object.assign({ | |
url: 'https://google.com/', | |
}, baseOptions)) | |
}) | |
.then((res) => { | |
assert(res.statusCode === 200) | |
// ditto | |
return rp.get(Object.assign({ | |
url: 'https://example.com/', | |
}, baseOptions)) | |
}) | |
.then((res) => { | |
assert(res.statusCode === 200) | |
// try to send it to an http origin | |
return rp.get(Object.assign({ | |
url: 'http://example.com/', | |
}, baseOptions)) | |
}) | |
.then((res) => { | |
assert(res.statusCode === 200) | |
// don't send a cert and key but the server wants one, should err | |
return rp.get(Object.assign({}, baseOptions, { | |
url: `https://localhost:${port}/`, | |
cert: undefined, | |
key: undefined, | |
})) | |
.then(() => { | |
throw new Error('should not reach') | |
}) | |
.catch((e) => { | |
assert(e.message.includes('handshake failure')) | |
}) | |
}) | |
.then(() => { | |
// sending an array of certs and keys, only one of which matches | |
// this FAILS - probably the biggest question to adding this in Cypress will be | |
// how to send the correct cert/key for each request | |
return Bluebird.join( | |
certy.createAsync(), | |
certy.createAsync(), | |
(certs2, certs3) => { | |
return rp.get(Object.assign({}, baseOptions, { | |
url: `https://localhost:${port}/`, | |
cert: [clientCert, certs3.clientCert, certs2.clientCert], | |
key: [clientKey, certs3.clientKey, certs2.clientKey], | |
})) | |
} | |
) | |
}) | |
.then(() => { | |
server.close() | |
}) | |
}) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment