summaryrefslogtreecommitdiff
path: root/doc/api/https.md
diff options
context:
space:
mode:
authorHannes Magnusson <hannes.magnusson@creditkarma.com>2018-02-14 09:35:10 -0800
committerRuben Bridgewater <ruben@bridgewater.de>2018-02-22 11:22:14 +0100
commit6aab9e1eed68b10e027b87795285b34eafdcf229 (patch)
tree645d19ba276ab6a8e0824ec2bc9fcadcc530d7e2 /doc/api/https.md
parent853f0bdf1908f754a0e7a7486339e79578c2c68b (diff)
downloadandroid-node-v8-6aab9e1eed68b10e027b87795285b34eafdcf229.tar.gz
android-node-v8-6aab9e1eed68b10e027b87795285b34eafdcf229.tar.bz2
android-node-v8-6aab9e1eed68b10e027b87795285b34eafdcf229.zip
crypto: add docs & tests for cert.pubkey & cert.fingerprint256
Include example on how to pin certificate and/or public key PR-URL: https://github.com/nodejs/node/pull/17690 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
Diffstat (limited to 'doc/api/https.md')
-rw-r--r--doc/api/https.md92
1 files changed, 92 insertions, 0 deletions
diff --git a/doc/api/https.md b/doc/api/https.md
index 58e62ccced..da4dbb22ab 100644
--- a/doc/api/https.md
+++ b/doc/api/https.md
@@ -251,6 +251,98 @@ const req = https.request(options, (res) => {
});
```
+Example pinning on certificate fingerprint, or the public key (similar to `pin-sha256`):
+
+```js
+const tls = require('tls');
+const https = require('https');
+const crypto = require('crypto');
+
+function sha256(s) {
+ return crypto.createHash('sha256').update(s).digest('base64');
+}
+const options = {
+ hostname: 'github.com',
+ port: 443,
+ path: '/',
+ method: 'GET',
+ checkServerIdentity: function(host, cert) {
+ // Make sure the certificate is issued to the host we are connected to
+ const err = tls.checkServerIdentity(host, cert);
+ if (err) {
+ return err;
+ }
+
+ // Pin the public key, similar to HPKP pin-sha25 pinning
+ const pubkey256 = 'pL1+qb9HTMRZJmuC/bB/ZI9d302BYrrqiVuRyW+DGrU=';
+ if (sha256(cert.pubkey) !== pubkey256) {
+ const msg = 'Certificate verification error: ' +
+ `The public key of '${cert.subject.CN}' ` +
+ 'does not match our pinned fingerprint';
+ return new Error(msg);
+ }
+
+ // Pin the exact certificate, rather then the pub key
+ const cert256 = '25:FE:39:32:D9:63:8C:8A:FC:A1:9A:29:87:' +
+ 'D8:3E:4C:1D:98:DB:71:E4:1A:48:03:98:EA:22:6A:BD:8B:93:16';
+ if (cert.fingerprint256 !== cert256) {
+ const msg = 'Certificate verification error: ' +
+ `The certificate of '${cert.subject.CN}' ` +
+ 'does not match our pinned fingerprint';
+ return new Error(msg);
+ }
+
+ // This loop is informational only.
+ // Print the certificate and public key fingerprints of all certs in the
+ // chain. Its common to pin the public key of the issuer on the public
+ // internet, while pinning the public key of the service in sensitive
+ // environments.
+ do {
+ console.log('Subject Common Name:', cert.subject.CN);
+ console.log(' Certificate SHA256 fingerprint:', cert.fingerprint256);
+
+ hash = crypto.createHash('sha256');
+ console.log(' Public key ping-sha256:', sha256(cert.pubkey));
+
+ lastprint256 = cert.fingerprint256;
+ cert = cert.issuerCertificate;
+ } while (cert.fingerprint256 !== lastprint256);
+
+ },
+};
+
+options.agent = new https.Agent(options);
+const req = https.request(options, (res) => {
+ console.log('All OK. Server matched our pinned cert or public key');
+ console.log('statusCode:', res.statusCode);
+ // Print the HPKP values
+ console.log('headers:', res.headers['public-key-pins']);
+
+ res.on('data', (d) => {});
+});
+
+req.on('error', (e) => {
+ console.error(e.message);
+});
+req.end();
+
+```
+ Outputs for example:
+```text
+Subject Common Name: github.com
+ Certificate SHA256 fingerprint: 25:FE:39:32:D9:63:8C:8A:FC:A1:9A:29:87:D8:3E:4C:1D:98:DB:71:E4:1A:48:03:98:EA:22:6A:BD:8B:93:16
+ Public key ping-sha256: pL1+qb9HTMRZJmuC/bB/ZI9d302BYrrqiVuRyW+DGrU=
+Subject Common Name: DigiCert SHA2 Extended Validation Server CA
+ Certificate SHA256 fingerprint: 40:3E:06:2A:26:53:05:91:13:28:5B:AF:80:A0:D4:AE:42:2C:84:8C:9F:78:FA:D0:1F:C9:4B:C5:B8:7F:EF:1A
+ Public key ping-sha256: RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho=
+Subject Common Name: DigiCert High Assurance EV Root CA
+ Certificate SHA256 fingerprint: 74:31:E5:F4:C3:C1:CE:46:90:77:4F:0B:61:E0:54:40:88:3B:A9:A0:1E:D0:0B:A6:AB:D7:80:6E:D3:B1:18:CF
+ Public key ping-sha256: WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18=
+All OK. Server matched our pinned cert or public key
+statusCode: 200
+headers: max-age=0; pin-sha256="WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="; pin-sha256="RRM1dGqnDFsCJXBTHky16vi1obOlCgFFn/yOhI/y+ho="; pin-sha256="k2v657xBsOVe1PQRwOsHsw3bsGT2VzIqz5K+59sNQws="; pin-sha256="K87oWBWM9UZfyddvDfoxL+8lpNyoUB2ptGtn0fv6G2Q="; pin-sha256="IQBnNBEiFuhj+8x6X8XLgh01V9Ic5/V3IRQLNFFc7v4="; pin-sha256="iie1VXtL7HzAMF+/PVPR9xzT80kQxdZeJ+zduCB3uj0="; pin-sha256="LvRiGEjRqfzurezaWuj8Wie2gyHMrW5Q06LspMnox7A="; includeSubDomains
+```
+
[`Agent`]: #https_class_https_agent
[`URL`]: url.html#url_the_whatwg_url_api
[`http.Agent`]: http.html#http_class_http_agent