Skip to content
This repository has been archived by the owner on Apr 22, 2023. It is now read-only.

Commit

Permalink
tls: x509 certificate subject parsing fail
Browse files Browse the repository at this point in the history
Fixes #1568.
  • Loading branch information
koichik committed Aug 30, 2011
1 parent d8f7a86 commit 6f60683
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 20 deletions.
8 changes: 4 additions & 4 deletions lib/tls.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,12 @@ CryptoStream.prototype.setEncoding = function(encoding) {
};


// EG '/C=US/ST=CA/L=SF/O=Joyent/OU=Node.js/CN=ca1/emailAddress=ry@clouds.org'
// Example:
// C=US\nST=CA\nL=SF\nO=Joyent\nOU=Node.js\nCN=ca1\nemailAddress=ry@clouds.org
function parseCertString(s) {
var out = {};
var parts = s.split('/');
// Note: can always skip the first one.
for (var i = 1; i < parts.length; i++) {
var parts = s.split('\n');
for (var i = 0, len = parts.length; i < len; i++) {
var sepIndex = parts[i].indexOf('=');
if (sepIndex > 0) {
var key = parts[i].slice(0, sepIndex);
Expand Down
42 changes: 26 additions & 16 deletions src/node_crypto.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@
static const char *PUBLIC_KEY_PFX = "-----BEGIN PUBLIC KEY-----";
static const int PUBLIC_KEY_PFX_LEN = strlen(PUBLIC_KEY_PFX);

static const int X509_NAME_FLAGS = ASN1_STRFLGS_ESC_CTRL
| ASN1_STRFLGS_ESC_MSB
| XN_FLAG_SEP_MULTILINE
| XN_FLAG_FN_SN;

namespace node {
namespace crypto {

Expand Down Expand Up @@ -1066,27 +1071,31 @@ Handle<Value> Connection::GetPeerCertificate(const Arguments& args) {
Local<Object> info = Object::New();
X509* peer_cert = SSL_get_peer_certificate(ss->ssl_);
if (peer_cert != NULL) {
char* subject = X509_NAME_oneline(X509_get_subject_name(peer_cert), 0, 0);
if (subject != NULL) {
info->Set(subject_symbol, String::New(subject));
OPENSSL_free(subject);
BIO* bio = BIO_new(BIO_s_mem());
BUF_MEM* mem;
if (X509_NAME_print_ex(bio, X509_get_subject_name(peer_cert), 0,
X509_NAME_FLAGS) > 0) {
BIO_get_mem_ptr(bio, &mem);
info->Set(subject_symbol, String::New(mem->data, mem->length));
}
char* issuer = X509_NAME_oneline(X509_get_issuer_name(peer_cert), 0, 0);
if (subject != NULL) {
info->Set(issuer_symbol, String::New(issuer));
OPENSSL_free(issuer);
(void) BIO_reset(bio);

if (X509_NAME_print_ex(bio, X509_get_issuer_name(peer_cert), 0,
X509_NAME_FLAGS) > 0) {
BIO_get_mem_ptr(bio, &mem);
info->Set(issuer_symbol, String::New(mem->data, mem->length));
}
char buf[256];
BIO* bio = BIO_new(BIO_s_mem());
(void) BIO_reset(bio);

ASN1_TIME_print(bio, X509_get_notBefore(peer_cert));
memset(buf, 0, sizeof(buf));
BIO_read(bio, buf, sizeof(buf) - 1);
info->Set(valid_from_symbol, String::New(buf));
BIO_get_mem_ptr(bio, &mem);
info->Set(valid_from_symbol, String::New(mem->data, mem->length));
(void) BIO_reset(bio);

ASN1_TIME_print(bio, X509_get_notAfter(peer_cert));
memset(buf, 0, sizeof(buf));
BIO_read(bio, buf, sizeof(buf) - 1);
BIO_get_mem_ptr(bio, &mem);
info->Set(valid_to_symbol, String::New(mem->data, mem->length));
BIO_free(bio);
info->Set(valid_to_symbol, String::New(buf));

unsigned int md_size, i;
unsigned char md[EVP_MAX_MD_SIZE];
Expand Down Expand Up @@ -1114,6 +1123,7 @@ Handle<Value> Connection::GetPeerCertificate(const Arguments& args) {
peer_cert, NID_ext_key_usage, NULL, NULL);
if (eku != NULL) {
Local<Array> ext_key_usage = Array::New();
char buf[256];

for (int i = 0; i < sk_ASN1_OBJECT_num(eku); i++) {
memset(buf, 0, sizeof(buf));
Expand Down
24 changes: 24 additions & 0 deletions test/fixtures/alice.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
-----BEGIN CERTIFICATE-----
MIID8DCCAtigAwIBAgIJALmw0zKhqlY1MA0GCSqGSIb3DQEBBQUAMFgxDjAMBgNV
BAMTBWFsaWNlMUYwRAYDVR0RFD11bmlmb3JtUmVzb3VyY2VJZGVudGlmaWVyOmh0
dHA6Ly9sb2NhbGhvc3Q6ODAwMC9hbGljZS5mb2FmI21lMB4XDTExMDgyNDA1NTUx
NFoXDTExMDkyMzA1NTUxNFowWDEOMAwGA1UEAxMFYWxpY2UxRjBEBgNVHREUPXVu
aWZvcm1SZXNvdXJjZUlkZW50aWZpZXI6aHR0cDovL2xvY2FsaG9zdDo4MDAwL2Fs
aWNlLmZvYWYjbWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDP4tdk
6NxAImrf5kpQVpuPvWij97H9ewFwWq0FOGONPD0JURXB89BCnhfC0+IHbTi+dhfB
DX9HY11NCoJm7juXv0uywv+7Zrlj37Q0RTedADmp237UUATRzmh7E+KZc6tHcZZ8
rPs+ZnY7TXXsh4JRRc8blTy6aEN7/iYMXhk0mIpzjTha2Gq5OqBLustBkeFnoPQS
cac6TOWbEkxg80dI5jX/qK901RRwLztrA0QDeWB+HLbkjIErdAlz5pgo1Nu3vQt6
vLdu7bBYsUa2Y2IaVBNLgmzEiZGwQJMjvbs5tLv8VYBCypb4I4vRJrkG4wWsUimM
+sR7SKHu9FFt2ZdHAgMBAAGjgbwwgbkwHQYDVR0OBBYEFA51eHepg7Tp5bi6Ao5F
B01/5+GoMIGJBgNVHSMEgYEwf4AUDnV4d6mDtOnluLoCjkUHTX/n4aihXKRaMFgx
DjAMBgNVBAMTBWFsaWNlMUYwRAYDVR0RFD11bmlmb3JtUmVzb3VyY2VJZGVudGlm
aWVyOmh0dHA6Ly9sb2NhbGhvc3Q6ODAwMC9hbGljZS5mb2FmI21lggkAubDTMqGq
VjUwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAreudH4Y7R9Vl2GJo
2xRUEwZiMj/ogomZ7B+IZtcuMIR8X2mzQ30xmPKaCy/fjbueqBroIDdxFeQ4eWZf
MD3AK/q5lJXwSInDjnn7jE9gNgLdQeCnajV0/QH+eDxIe/Alvx+RuvrDiNOudEs4
vhqv5zEaL6VEXoWVb4/cghDbynQucSpyOMmGGPYYw2zmg0nNXdQauYWDUZIaDwQ6
tM/pi2ewYubHPZdwJv5jvxTN3Z7RuuGHM+aLAZSAqSgAi0ml8PYYd2eRzXMaEI0c
eajcEvVa405aYT6dxuF1qqRDYx14As/R7O5RKCpz7wsxD6ICD/Ynv3GCUGxANQim
bcCjpg==
-----END CERTIFICATE-----
58 changes: 58 additions & 0 deletions test/simple/test-tls-peer-certificate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright Joyent, Inc. and other Node contributors.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to permit
// persons to whom the Software is furnished to do so, subject to the
// following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

if (!process.versions.openssl) {
console.error("Skipping because node compiled without OpenSSL.");
process.exit(0);
}

var common = require('../common');
var assert = require('assert');
var tls = require('tls');
var fs = require('fs');
var util = require('util');
var join = require('path').join;
var spawn = require('child_process').spawn;

var options = {
key: fs.readFileSync(join(common.fixturesDir, 'agent.key')),
cert: fs.readFileSync(join(common.fixturesDir, 'alice.crt'))
};
var verified = false;

var server = tls.createServer(options, function(cleartext) {
cleartext.end('World');
});
server.listen(common.PORT, function() {
var socket = tls.connect(common.PORT, function() {
var peerCert = socket.getPeerCertificate();
common.debug(util.inspect(peerCert));
assert.equal(peerCert.subject.subjectAltName,
'uniformResourceIdentifier:http://localhost:8000/alice.foaf#me');
verified = true;
server.close();
});
socket.end('Hello');
});

process.on('exit', function() {
assert.ok(verified);
});

0 comments on commit 6f60683

Please sign in to comment.