-
Notifications
You must be signed in to change notification settings - Fork 30.1k
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
tls: Add publicKey to certificate information #1725
Conversation
@@ -165,6 +165,7 @@ namespace node { | |||
V(priority_string, "priority") \ | |||
V(processed_string, "processed") \ | |||
V(prototype_string, "prototype") \ | |||
V(public_key_string, "publicKey") \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, the name of this field is Subject Public Key Info which contains not only a public key but also a key algorithm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, subjectPublicKeyInfo
is a much better name for this because that's what we actually want here.
@saarons Could you update the example in |
@shigeki Absolutely, I'll update the example for |
Added `subjectPublicKeyInfo` attribute to the peer certificate object. The attribute is a buffer containing the DER-encoded value of the SubjectPublicKeyInfo structure as described in RFC 5280. This will allow applications to retrieve the SPKI information necessary for validating HTTP public key pins according to RFC 7469. https://tools.ietf.org/html/rfc7469
@shigeki I've made the changes you've asked for and squashed the commits. |
@saarons Thanks. I made a test for https://www.google.com to check if we can obtain a right PKP as var https = require('https');
var crypto = require('crypto');
var host = 'www.google.com';
var client = https.get({
host: host,
path: '/'
}, function(res) {
var peerCert = res.socket.getPeerCertificate(true);
var spki = peerCert.issuerCertificate.subjectPublicKeyInfo;
var sha1 = crypto.createHash('sha1');
sha1.update(spki);
var spki_hashe = sha1.digest('base64');
console.log(host, ',spki_hashe:', spki_hashe);
res.resume();
}); $ ./iojs ~/pkp_https_client.js
www.google.com ,spki_hashe: Q9rWMO5T+KmAym79hfRqo3mQ4Oo= This value matches the one embedded in Chrome. So that's fine. LGTM. @indutny How is this? |
I think we already have a |
IIRC, I think we need asn1 parser to extract spki. |
Ah, you say we can make it by user module. Right. |
Exactly, there are lots of ASN.1 parsers on npm. (https://github.com/indutny/asn1.js ;) ) |
Yes, I so other properties such as modulus, exponents and whatever except raw are not necessary. I think SPKI has a very good use case to implement HPKP. Why is only SPKI exceptional? |
@shigeki I'm afraid that modulus and friends are present here for historical reasons too. The The thing about SPKI is that there are lots of extensions and information in X509 certificate. The more we map it to JS object - the more time will take the |
Oh, it is actually even worse than this :) We already export modulus and all information that is required to construct DER-encoded public key. Even without parsing the X509 certificate itself. |
I understand the reason and the current situation. From the point of policy to keep core small, we should avoid to add a new feature that can be done within user module. @saarons Sorry, I missed the point that we have raw cert data and the spki hash for HPKP can be obtained within user module via asn1parser. We should refine certificate properties to expose in future. Thanks for your work. |
@shigeki @indutny Totally understand where you guys are coming from, I was contemplating myself whether I should even write this given that are some alternatives. One of the main reasons why I feel this would be ok, is because fields like I understand there are plenty of ASN.1 parsers out there but with your own example @indutny , I can't figure out if I can just straight parse ASN.1 without having to define an Entity. I've looked at X.509 parsers on NPM but they're no better than the info we get from |
While true, it's something that can be worked around by populating the object with getters that retrieve/calculate the values on demand. (Life cycle management would be a bit of a pain, though.) |
@saarons FYI, @indutny provides us with a very nice module named It is a very easy to deal with HPKP as var https = require('https');
var crypto = require('crypto');
var rfc3280 = require('asn1.js-rfc3280');
var Certificate = rfc3280.Certificate;
var SubjectPublicKeyInfo = rfc3280.SubjectPublicKeyInfo;
var host = 'www.google.com';
var client = https.get({
port: 443,
host: host,
path: '/'
}, function(res) {
var peerCert = res.socket.getPeerCertificate(true);
var cert = Certificate.decode(peerCert.issuerCertificate.raw, 'der');
var spki = cert.tbsCertificate.subjectPublicKeyInfo;
var spki_der = SubjectPublicKeyInfo.encode(spki, 'der');
var sha1 = crypto.createHash('sha1');
sha1.update(spki_der);
var spki_hashes = sha1.digest('base64');
console.log(host, ',spki_hashe:', spki_hashes);
res.resume();
}); $ ~/github/io.js/iojs hpkp_https_client.js
www.google.com ,spki_hashe: Q9rWMO5T+KmAym79hfRqo3mQ4Oo= Please be sure to use the latest version (2.0.2 for asn1.js and 2.0.0 for asn1.js-rfc3280) since there were a few issues related to AlgorithmIdentifier.parameters. I hope it helps you. |
Added a
publicKey
attribute to peer certificate information. Theattribute contains the DER-encoded value of the public key as a buffer.
This will allow applications to retrieve the necessary information for
validating HTTP public key pins according to RFC 7469.
https://tools.ietf.org/html/rfc7469