summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Lippai <adam.lippai@tresorit.com>2014-09-14 00:37:34 +0200
committerFedor Indutny <fedor@indutny.com>2014-09-15 17:42:20 +0400
commit11d57a535c21a64885808afd41612406ff854c69 (patch)
treed057e43786af8513fcccf11a83c51623da95bb56
parent630f0c4660f9c9fb7c6b1f032e92fc1ca238f0e9 (diff)
downloadnodejs-11d57a535c21a64885808afd41612406ff854c69.tar.gz
nodejs-11d57a535c21a64885808afd41612406ff854c69.tar.bz2
nodejs-11d57a535c21a64885808afd41612406ff854c69.zip
tls: fix encoding in certificate-related functions
Strings are treated as UTF8 instead of one-byte strings when names are processed and when OpenSSL's ..._print functions are used. This commit fixes simple/test-tls-peer-certificate-encoding test. fix #8366
-rw-r--r--src/node_crypto.cc23
-rw-r--r--test/fixtures/keys/Makefile31
-rw-r--r--test/fixtures/keys/agent5-cert.pem16
-rw-r--r--test/fixtures/keys/agent5-csr.pem12
-rw-r--r--test/fixtures/keys/agent5-key.pem15
-rw-r--r--test/fixtures/keys/agent5.cnf21
-rw-r--r--test/fixtures/keys/ca2-cert.srl2
-rw-r--r--test/simple/test-tls-peer-certificate-encoding.js62
8 files changed, 170 insertions, 12 deletions
diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index 1be2f2e42..85f18bc19 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -69,7 +69,7 @@ static const char CERTIFICATE_PFX[] = "-----BEGIN CERTIFICATE-----";
static const int CERTIFICATE_PFX_LEN = sizeof(CERTIFICATE_PFX) - 1;
static const int X509_NAME_FLAGS = ASN1_STRFLGS_ESC_CTRL
- | ASN1_STRFLGS_ESC_MSB
+ | ASN1_STRFLGS_UTF8_CONVERT
| XN_FLAG_SEP_MULTILINE
| XN_FLAG_FN_SN;
@@ -1130,7 +1130,8 @@ static Local<Object> X509ToObject(Environment* env, X509* cert) {
X509_NAME_FLAGS) > 0) {
BIO_get_mem_ptr(bio, &mem);
info->Set(env->subject_string(),
- OneByteString(env->isolate(), mem->data, mem->length));
+ String::NewFromUtf8(env->isolate(), mem->data,
+ String::kNormalString, mem->length));
}
(void) BIO_reset(bio);
@@ -1138,7 +1139,8 @@ static Local<Object> X509ToObject(Environment* env, X509* cert) {
if (X509_NAME_print_ex(bio, issuer_name, 0, X509_NAME_FLAGS) > 0) {
BIO_get_mem_ptr(bio, &mem);
info->Set(env->issuer_string(),
- OneByteString(env->isolate(), mem->data, mem->length));
+ String::NewFromUtf8(env->isolate(), mem->data,
+ String::kNormalString, mem->length));
}
(void) BIO_reset(bio);
@@ -1162,7 +1164,8 @@ static Local<Object> X509ToObject(Environment* env, X509* cert) {
BIO_get_mem_ptr(bio, &mem);
info->Set(keys[i],
- OneByteString(env->isolate(), mem->data, mem->length));
+ String::NewFromUtf8(env->isolate(), mem->data,
+ String::kNormalString, mem->length));
(void) BIO_reset(bio);
}
@@ -1176,13 +1179,15 @@ static Local<Object> X509ToObject(Environment* env, X509* cert) {
BN_print(bio, rsa->n);
BIO_get_mem_ptr(bio, &mem);
info->Set(env->modulus_string(),
- OneByteString(env->isolate(), mem->data, mem->length));
+ String::NewFromUtf8(env->isolate(), mem->data,
+ String::kNormalString, mem->length));
(void) BIO_reset(bio);
BN_print(bio, rsa->e);
BIO_get_mem_ptr(bio, &mem);
info->Set(env->exponent_string(),
- OneByteString(env->isolate(), mem->data, mem->length));
+ String::NewFromUtf8(env->isolate(), mem->data,
+ String::kNormalString, mem->length));
(void) BIO_reset(bio);
}
@@ -1198,13 +1203,15 @@ static Local<Object> X509ToObject(Environment* env, X509* cert) {
ASN1_TIME_print(bio, X509_get_notBefore(cert));
BIO_get_mem_ptr(bio, &mem);
info->Set(env->valid_from_string(),
- OneByteString(env->isolate(), mem->data, mem->length));
+ String::NewFromUtf8(env->isolate(), mem->data,
+ String::kNormalString, mem->length));
(void) BIO_reset(bio);
ASN1_TIME_print(bio, X509_get_notAfter(cert));
BIO_get_mem_ptr(bio, &mem);
info->Set(env->valid_to_string(),
- OneByteString(env->isolate(), mem->data, mem->length));
+ String::NewFromUtf8(env->isolate(), mem->data,
+ String::kNormalString, mem->length));
BIO_free_all(bio);
unsigned int md_size, i;
diff --git a/test/fixtures/keys/Makefile b/test/fixtures/keys/Makefile
index 079332920..ee667c601 100644
--- a/test/fixtures/keys/Makefile
+++ b/test/fixtures/keys/Makefile
@@ -1,4 +1,4 @@
-all: agent1-cert.pem agent2-cert.pem agent3-cert.pem agent4-cert.pem ca2-crl.pem ec-cert.pem dh512.pem dh1024.pem dh2048.pem
+all: agent1-cert.pem agent2-cert.pem agent3-cert.pem agent4-cert.pem agent5-cert.pem ca2-crl.pem ec-cert.pem dh512.pem dh1024.pem dh2048.pem
#
@@ -132,6 +132,31 @@ ca2-crl.pem: ca2-key.pem ca2-cert.pem ca2.cnf
-out ca2-crl.pem \
-passin 'pass:password'
+#
+# agent5 is signed by ca2 (client cert)
+#
+
+agent5-key.pem:
+ openssl genrsa -out agent5-key.pem 1024
+
+agent5-csr.pem: agent5.cnf agent5-key.pem
+ openssl req -new -config agent5.cnf -key agent5-key.pem -out agent5-csr.pem
+
+agent5-cert.pem: agent5-csr.pem ca2-cert.pem ca2-key.pem
+ openssl x509 -req \
+ -days 9999 \
+ -passin "pass:password" \
+ -in agent5-csr.pem \
+ -CA ca2-cert.pem \
+ -CAkey ca2-key.pem \
+ -CAcreateserial \
+ -extfile agent5.cnf \
+ -extensions ext_key_usage \
+ -out agent5-cert.pem
+
+agent5-verify: agent5-cert.pem ca2-cert.pem
+ openssl verify -CAfile ca2-cert.pem agent5-cert.pem
+
ec-key.pem:
openssl ecparam -genkey -out ec-key.pem -name prime256v1
@@ -157,7 +182,7 @@ dh2048.pem:
clean:
rm -f *.pem *.srl ca2-database.txt ca2-serial
-test: agent1-verify agent2-verify agent3-verify agent4-verify
+test: agent1-verify agent2-verify agent3-verify agent4-verify agent5-verify
-.PHONY: all clean test agent1-verify agent2-verify agent3-verify agent4-verify
+.PHONY: all clean test agent1-verify agent2-verify agent3-verify agent4-verify agent5-verify
diff --git a/test/fixtures/keys/agent5-cert.pem b/test/fixtures/keys/agent5-cert.pem
new file mode 100644
index 000000000..636aed017
--- /dev/null
+++ b/test/fixtures/keys/agent5-cert.pem
@@ -0,0 +1,16 @@
+-----BEGIN CERTIFICATE-----
+MIICgzCCAeygAwIBAgIJAO6+LOUhGhL4MA0GCSqGSIb3DQEBBQUAMHoxCzAJBgNV
+BAYTAlVTMQswCQYDVQQIEwJDQTELMAkGA1UEBxMCU0YxDzANBgNVBAoTBkpveWVu
+dDEQMA4GA1UECxMHTm9kZS5qczEMMAoGA1UEAxMDY2EyMSAwHgYJKoZIhvcNAQkB
+FhFyeUB0aW55Y2xvdWRzLm9yZzAeFw0xNDA5MTMyMjM0MThaFw00MjAxMjgyMjM0
+MThaMHQxCzAJBgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDERMA8GA1UECgwI
+VHJlc29yaXQxFjAUBgNVBAMMDcOBZMOhbSBMaXBwYWkxJzAlBgkqhkiG9w0BCQEW
+GGFkYW0ubGlwcGFpQHRyZXNvcml0LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAw
+gYkCgYEAtrYJnvw24liDRWrfRDp/aBRwAK3xoaJ99YBCj7U8955GJvsoN21q6ZiD
+gT+/7K+HA5gxLXTngrSCTzbk8qfGTD+Gco5WoOK7ubm5R4ePlGrT+yCMaUQBKzX7
+3s3f0rxuAI5F2qCtIJAS/K6Nk3v6C60DyK/rudnY/+d8dFQf2gECAwEAAaMXMBUw
+EwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADgYEAC+QBFRXhCWq3
+BLogUKBPl9TWeu13aPkhMFo29ZZB4G2KCoKWUgHZyJ3Q/Dx40QA+PCrqmKxNHyUx
+oEzol97MwB8Q4puv4BC3m8Zkgu/7z7CFH5LMh/shIjDT+kveGFUscqPzjHykeBhP
+2/4042bED6KYhNw+f3DlN+Y1mBYKEuk=
+-----END CERTIFICATE-----
diff --git a/test/fixtures/keys/agent5-csr.pem b/test/fixtures/keys/agent5-csr.pem
new file mode 100644
index 000000000..a40b2206f
--- /dev/null
+++ b/test/fixtures/keys/agent5-csr.pem
@@ -0,0 +1,12 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIB2TCCAUICAQAwdDELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MREw
+DwYDVQQKDAhUcmVzb3JpdDEWMBQGA1UEAwwNw4Fkw6FtIExpcHBhaTEnMCUGCSqG
+SIb3DQEJARYYYWRhbS5saXBwYWlAdHJlc29yaXQuY29tMIGfMA0GCSqGSIb3DQEB
+AQUAA4GNADCBiQKBgQC2tgme/DbiWINFat9EOn9oFHAArfGhon31gEKPtTz3nkYm
++yg3bWrpmIOBP7/sr4cDmDEtdOeCtIJPNuTyp8ZMP4Zyjlag4ru5ublHh4+UatP7
+IIxpRAErNfvezd/SvG4AjkXaoK0gkBL8ro2Te/oLrQPIr+u52dj/53x0VB/aAQID
+AQABoCUwIwYJKoZIhvcNAQkHMRYMFEEgY2hhbGxlbmdlIHBhc3N3b3JkMA0GCSqG
+SIb3DQEBBQUAA4GBAAoVh5wdSi58RJrwy4xaXeZwrRUeCEfNf66AhAr16fa7AxMZ
+7XCMGVYTCcPxsFaagYptWYigYOP3vC89i1dm29PjUwRvyTvkSQ+o/8Cjs+BESeG2
+HrmK7b7xQjXCUwUXfHW7bnqVsTXcX1QfSztWKZANgETITD0MsGjh6Cdv+6ze
+-----END CERTIFICATE REQUEST-----
diff --git a/test/fixtures/keys/agent5-key.pem b/test/fixtures/keys/agent5-key.pem
new file mode 100644
index 000000000..d9ee12e4d
--- /dev/null
+++ b/test/fixtures/keys/agent5-key.pem
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQC2tgme/DbiWINFat9EOn9oFHAArfGhon31gEKPtTz3nkYm+yg3
+bWrpmIOBP7/sr4cDmDEtdOeCtIJPNuTyp8ZMP4Zyjlag4ru5ublHh4+UatP7IIxp
+RAErNfvezd/SvG4AjkXaoK0gkBL8ro2Te/oLrQPIr+u52dj/53x0VB/aAQIDAQAB
+AoGAbB+X2/THifT1YhwXmenAQdhuW4iUSKG/RowrV53aQXLxctoId5yRu0Ec+Vy/
+eBJ7pJ3o5EydQFUQFE6Y+BxfFPogncoTu7U8I5S38aBDaL5teX8DzaDqLvcqU7GF
+s+nOACcCErQ2BcpasTkKBFzzrpJtAes2jVzpsfa48JZtc70CQQDe0uUtlKR7tatL
+sugU7OfRoeV1c/tHWp/5HODY0ZeMYvbNw6SqebKeBts26rJNGn4b4LgJs/TTT3qz
+ux6a0ex3AkEA0eo22zaBVjZcygfIfEW9tyfGT1eHgfE/DHcaPHekwgwltoo2gEkU
+hzWy7n09MTkM2Zw6RBz6yvbdJ80/T8UjRwJBALfPJPqauazLSgjiBozseLb3ZD+l
+c02DNp/a8KgrDWbjZFCM6VMvnOa7JS6CIJ92ET2R/H8UkguWbtPAshhovzUCQQC8
+uU8SbQGBKiToOnEkUWtMhMUFRlN9HxEpOtdqr8J/933cjIyNb6a2HTA+vHhMjdcg
+uhWkcU2FNscEZsJaDIo3AkAOnbQTW1w4WjkV92B+EH6dQfS3wdCFVDUYM+POcwfQ
+7HNtjmk1XeMTkGLlyinyFe2nARfXXzMmyRYP8o2m9uCf
+-----END RSA PRIVATE KEY-----
diff --git a/test/fixtures/keys/agent5.cnf b/test/fixtures/keys/agent5.cnf
new file mode 100644
index 000000000..1958e21cf
--- /dev/null
+++ b/test/fixtures/keys/agent5.cnf
@@ -0,0 +1,21 @@
+[ req ]
+string_mask = utf8only
+utf8 = yes
+default_bits = 1024
+days = 999
+distinguished_name = req_distinguished_name
+attributes = req_attributes
+prompt = no
+
+[ req_distinguished_name ]
+C = HU
+L = Budapest
+O = Tresorit
+CN = Ádám Lippai
+emailAddress = adam.lippai@tresorit.com
+
+[ req_attributes ]
+challengePassword = A challenge password
+
+[ ext_key_usage ]
+extendedKeyUsage = clientAuth
diff --git a/test/fixtures/keys/ca2-cert.srl b/test/fixtures/keys/ca2-cert.srl
index 1821c066a..82ebc5da1 100644
--- a/test/fixtures/keys/ca2-cert.srl
+++ b/test/fixtures/keys/ca2-cert.srl
@@ -1 +1 @@
-EEBE2CE5211A12F7
+EEBE2CE5211A12F8
diff --git a/test/simple/test-tls-peer-certificate-encoding.js b/test/simple/test-tls-peer-certificate-encoding.js
new file mode 100644
index 000000000..288236a93
--- /dev/null
+++ b/test/simple/test-tls-peer-certificate-encoding.js
@@ -0,0 +1,62 @@
+// 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, 'keys', 'agent5-key.pem')),
+ cert: fs.readFileSync(join(common.fixturesDir, 'keys', 'agent5-cert.pem')),
+ ca: [ fs.readFileSync(join(common.fixturesDir, 'keys', 'ca2-cert.pem')) ]
+};
+var verified = false;
+
+var server = tls.createServer(options, function(cleartext) {
+ cleartext.end('World');
+});
+server.listen(common.PORT, function() {
+ var socket = tls.connect({
+ port: common.PORT,
+ rejectUnauthorized: false
+ }, function() {
+ var peerCert = socket.getPeerCertificate();
+
+ common.debug(util.inspect(peerCert));
+ assert.equal(peerCert.subject.CN, 'Ádám Lippai');
+ verified = true;
+ server.close();
+ });
+ socket.end('Hello');
+});
+
+process.on('exit', function() {
+ assert.ok(verified);
+});