diff --git a/doc/api/tls.markdown b/doc/api/tls.markdown index 7cb4b982d2c..d3dad295c8b 100644 --- a/doc/api/tls.markdown +++ b/doc/api/tls.markdown @@ -573,7 +573,8 @@ Example: CN: 'localhost' }, valid_from: 'Nov 11 09:52:22 2009 GMT', valid_to: 'Nov 6 09:52:22 2029 GMT', - fingerprint: '2A:7A:C2:DD:E5:F9:CC:53:72:35:99:7A:02:5A:71:38:52:EC:8A:DF' } + fingerprint: '2A:7A:C2:DD:E5:F9:CC:53:72:35:99:7A:02:5A:71:38:52:EC:8A:DF', + serialNumber: 'B9B0D332A1AA5635' } If the peer does not provide a certificate, it returns `null` or an empty object. diff --git a/src/env.h b/src/env.h index 81286842ac5..5cf414b5dc1 100644 --- a/src/env.h +++ b/src/env.h @@ -111,6 +111,7 @@ namespace node { V(rdev_string, "rdev") \ V(rename_string, "rename") \ V(rss_string, "rss") \ + V(serial_number_string, "serialNumber") \ V(servername_string, "servername") \ V(session_id_string, "sessionId") \ V(should_keep_alive_string, "shouldKeepAlive") \ diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 4f6f17edb57..f1d3bd44980 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -1066,6 +1066,17 @@ void SSLWrap::GetPeerCertificate( info->Set(env->ext_key_usage_string(), ext_key_usage); } + if (ASN1_INTEGER* serial_number = X509_get_serialNumber(peer_cert)) { + if (BIGNUM* bn = ASN1_INTEGER_to_BN(serial_number, NULL)) { + if (char* buf = BN_bn2hex(bn)) { + info->Set(env->serial_number_string(), + OneByteString(node_isolate, buf)); + OPENSSL_free(buf); + } + BN_free(bn); + } + } + X509_free(peer_cert); } diff --git a/test/simple/test-tls-peer-certificate.js b/test/simple/test-tls-peer-certificate.js index 2f0b7279730..8b0418e11f4 100644 --- a/test/simple/test-tls-peer-certificate.js +++ b/test/simple/test-tls-peer-certificate.js @@ -50,6 +50,7 @@ server.listen(common.PORT, function() { common.debug(util.inspect(peerCert)); assert.equal(peerCert.subject.subjectAltName, 'uniformResourceIdentifier:http://localhost:8000/alice.foaf#me'); + assert.equal(peerCert.serialNumber, 'B9B0D332A1AA5635'); verified = true; server.close(); });