From d163b5ebfc4e696f066e8675aa11d688c4cedecd Mon Sep 17 00:00:00 2001 From: chenximin <ximin.chen@rokid.com> Date: Tue, 28 Nov 2017 11:45:10 +0800 Subject: [PATCH 01/10] fix verify crash caused by invalid cert format --- src/x509.cc | 101 ++++++++++++++++++++++------------------------------ 1 file changed, 43 insertions(+), 58 deletions(-) diff --git a/src/x509.cc b/src/x509.cc index f2c8167..a836301 100644 --- a/src/x509.cc +++ b/src/x509.cc @@ -58,68 +58,53 @@ NAN_METHOD(verify) { X509_STORE *store = NULL; X509_STORE_CTX *verify_ctx = NULL; X509 *cert = NULL; - BIO *cert_bio = BIO_new(BIO_s_file()); - - // create store - store = X509_STORE_new(); - if (store == NULL) { - X509_STORE_free(store); - BIO_free_all(cert_bio); - Nan::ThrowError("Failed to create X509 certificate store."); - } - - verify_ctx = X509_STORE_CTX_new(); - - if (verify_ctx == NULL) { - X509_STORE_free(store); - BIO_free_all(cert_bio); - Nan::ThrowError("Failed to create X509 verification context."); - } - - // load file in BIO - int ret = BIO_read_filename(cert_bio, cert_path.c_str()); - if (ret != 1) { - X509_STORE_free(store); - X509_free(cert); - BIO_free_all(cert_bio); - X509_STORE_CTX_free(verify_ctx); - Nan::ThrowError("Error reading file"); - } - - // read from BIO - cert = PEM_read_bio_X509(cert_bio, NULL, 0, NULL); - if (cert == NULL) { - X509_STORE_free(store); - X509_free(cert); - X509_STORE_CTX_free(verify_ctx); - BIO_free_all(cert_bio); - Nan::ThrowError("Failed to load cert"); - } - - // load CA bundle - ret = X509_STORE_load_locations(store, ca_bundlestr.c_str(), NULL); - if (ret != 1) { - X509_STORE_free(store); - X509_free(cert); - BIO_free_all(cert_bio); - X509_STORE_CTX_free(verify_ctx); - Nan::ThrowError("Error loading CA chain file"); - } - - // verify - X509_STORE_CTX_init(verify_ctx, store, cert, NULL); - ret = X509_verify_cert(verify_ctx); - - if (ret <= 0) { - Nan::ThrowError(X509_verify_cert_error_string(verify_ctx->error)); - } - + BIO *cert_bio = NULL; + const char *error = NULL; + + do { + store = X509_STORE_new(); + if (store == NULL) { + error = "Failed to create X509 certificate store."; + break; + } + verify_ctx = X509_STORE_CTX_new(); + if (verify_ctx == NULL) { + error = "Failed to create X509 verification context."; + break; + } + cert_bio = BIO_new(BIO_s_file()); + int ret = BIO_read_filename(cert_bio, cert_path.c_str()); + if (ret != 1) { + error = "Error reading file"; + break; + } + cert = PEM_read_bio_X509(cert_bio, NULL, 0, NULL); + if (cert == NULL) { + error = "Failed to load cert"; + break; + } + ret = X509_STORE_load_locations(store, ca_bundlestr.c_str(), NULL); + if (ret != 1) { + error = "Error loading CA chain file"; + break; + } + X509_STORE_CTX_init(verify_ctx, store, cert, NULL); + ret = X509_verify_cert(verify_ctx); + if (ret <= 0) { + error = X509_verify_cert_error_string(verify_ctx->error); + break; + } + } while(0); + X509_STORE_free(store); X509_free(cert); X509_STORE_CTX_free(verify_ctx); BIO_free_all(cert_bio); - - info.GetReturnValue().Set(Nan::New(true)); + if (error != NULL) { + Nan::ThrowError(error); + } else { + info.GetReturnValue().Set(Nan::New(true)); + } } From 748b3c203b1301e60efc40a110fae8234c4dd059 Mon Sep 17 00:00:00 2001 From: chenximin <ximin.chen@rokid.com> Date: Tue, 28 Nov 2017 22:13:52 +0800 Subject: [PATCH 02/10] add test case for invalid cert format --- test/test.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/test/test.js b/test/test.js index c364fdc..c230876 100644 --- a/test/test.js +++ b/test/test.js @@ -38,3 +38,19 @@ x509.verify( assert.throws(assert.ifError.bind(null, err), /ENOENT/) } ); + +x509.verify( + path.join(__dirname, 'certs/equifax.crt'), + path.join(__dirname, '/test.js'), + function(err, result) { + assert.notStrictEqual(err, null); + } +); + +x509.verify( + path.join(__dirname, '/test.js'), + path.join(__dirname, 'CA_chains/enduser-example.com.chain'), + function(err, result) { + assert.notStrictEqual(err, null); + } +); \ No newline at end of file From 327f6a49b80a350edb1cdeaa2da0926c42d10b06 Mon Sep 17 00:00:00 2001 From: chenximin <ximin.chen@rokid.com> Date: Tue, 28 Nov 2017 22:42:54 +0800 Subject: [PATCH 03/10] update test case for invalid cert format --- test/test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test.js b/test/test.js index c230876..c98818d 100644 --- a/test/test.js +++ b/test/test.js @@ -43,7 +43,7 @@ x509.verify( path.join(__dirname, 'certs/equifax.crt'), path.join(__dirname, '/test.js'), function(err, result) { - assert.notStrictEqual(err, null); + assert.throws(assert.ifError.bind(null, err), /Error loading CA chain file/) } ); @@ -51,6 +51,6 @@ x509.verify( path.join(__dirname, '/test.js'), path.join(__dirname, 'CA_chains/enduser-example.com.chain'), function(err, result) { - assert.notStrictEqual(err, null); + assert.throws(assert.ifError.bind(null, err), /Failed to load cert/) } ); \ No newline at end of file From 9c32c21b501ff9da8e56df1396677103902f1631 Mon Sep 17 00:00:00 2001 From: chenximin <ximin.chen@rokid.com> Date: Mon, 18 Dec 2017 11:15:41 +0800 Subject: [PATCH 04/10] implement verify from string --- include/x509.h | 2 ++ index.js | 13 ++++++++ src/addon.cc | 4 +++ src/x509.cc | 67 +++++++++++++++++++++++++++++++++++++++- test/test.crt | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++ test/test.js | 32 +++++++++++++++++++ 6 files changed, 201 insertions(+), 1 deletion(-) create mode 100644 test/test.crt diff --git a/include/x509.h b/include/x509.h index ce1198b..11c31a4 100644 --- a/include/x509.h +++ b/include/x509.h @@ -24,9 +24,11 @@ NAN_METHOD(get_subject); NAN_METHOD(get_issuer); NAN_METHOD(parse_cert); NAN_METHOD(verify); +NAN_METHOD(verifyFromStr); Local<Value> try_parse(const std::string& dataString); Local<Value> verify(const std::string& dataString); +Local<Value> verifyFromStr(const std::string& dataString); Local<Value> parse_date(ASN1_TIME *date); Local<Value> parse_serial(ASN1_INTEGER *serial); Local<Object> parse_name(X509_NAME *subject); diff --git a/index.js b/index.js index 539a76c..35e8aa6 100644 --- a/index.js +++ b/index.js @@ -6,6 +6,19 @@ exports.getAltNames = x509.getAltNames; exports.getSubject = x509.getSubject; exports.getIssuer = x509.getIssuer; +exports.verifyFromStr = function(certStr, CABundleStr, cb) { + let caughtErr = null; + try { + x509.verifyFromStr(certStr, CABundleStr); + } + catch (verificationError) { + caughtErr = verificationError; + } + finally { + cb(caughtErr); + } +}; + exports.verify = function(certPath, CABundlePath, cb) { if (!certPath) { throw new TypeError('Certificate path is required'); diff --git a/src/addon.cc b/src/addon.cc index f0aab0c..47c2bed 100644 --- a/src/addon.cc +++ b/src/addon.cc @@ -10,6 +10,10 @@ void init(Local<Object> exports) { Nan::Set(exports, Nan::New<String>("version").ToLocalChecked(), Nan::New<String>(VERSION).ToLocalChecked()); + + Nan::Set(exports, + Nan::New<String>("verifyFromStr").ToLocalChecked(), + Nan::New<FunctionTemplate>(verifyFromStr)->GetFunction()); Nan::Set(exports, Nan::New<String>("verify").ToLocalChecked(), diff --git a/src/x509.cc b/src/x509.cc index a836301..de2fcbf 100644 --- a/src/x509.cc +++ b/src/x509.cc @@ -46,7 +46,72 @@ std::string parse_args(const Nan::FunctionCallbackInfo<v8::Value>& info) { return *String::Utf8Value(info[0]->ToString()); } - +NAN_METHOD(verifyFromStr) { + Nan::HandleScope scope; + OpenSSL_add_all_algorithms(); + std::string cert_str = *String::Utf8Value(info[0]->ToString()); + std::string ca_str = *String::Utf8Value(info[1]->ToString()); + + X509_STORE *store = NULL; + X509_STORE_CTX *verify_ctx = NULL; + X509 *ca_cert = NULL; + BIO *ca_bio = NULL; + X509 *cert = NULL; + BIO *cert_bio = NULL; + const char *error = NULL; + do { + store = X509_STORE_new(); + if (store == NULL) { + error = "Failed to create X509 certificate store."; + break; + } + verify_ctx = X509_STORE_CTX_new(); + if (verify_ctx == NULL) { + error = "Failed to create X509 verification context."; + break; + } + cert_bio = BIO_new(BIO_s_mem()); + size_t ret = BIO_puts(cert_bio, cert_str.c_str()); + if (ret != cert_str.length()) { + error = "Error reading cert content"; + break; + } + cert = PEM_read_bio_X509(cert_bio, NULL, 0, NULL); + if (cert == NULL) { + error = "Failed to load cert"; + break; + } + ca_bio = BIO_new(BIO_s_mem()); + ret = BIO_puts(ca_bio, ca_str.c_str()); + if (ret != ca_str.length()) { + error = "Error reading ca content"; + break; + } + ca_cert = PEM_read_bio_X509(ca_bio, NULL, 0, NULL); + if (ca_cert == NULL) { + error = "Failed to load ca"; + break; + } + X509_STORE_CTX_init(verify_ctx, store, ca_cert, NULL); + X509_STORE_add_cert(store, cert); + ret = X509_verify_cert(verify_ctx); + if (ret < 1) { + error = X509_verify_cert_error_string(verify_ctx->error); + break; + } + } while(0); + X509_STORE_free(store); + X509_STORE_CTX_free(verify_ctx); + X509_free(ca_cert); + BIO_free_all(ca_bio); + X509_free(cert); + BIO_free_all(cert_bio); + if (error != NULL) { + Nan::ThrowError(error); + } else { + info.GetReturnValue().Set(Nan::New(true)); + } +} NAN_METHOD(verify) { Nan::HandleScope scope; diff --git a/test/test.crt b/test/test.crt new file mode 100644 index 0000000..ef48d6f --- /dev/null +++ b/test/test.crt @@ -0,0 +1,84 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 4 (0x4) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=CN, ST=Hangzhou, L=Hangzhou, O=Rokid, OU=homebase, CN=Rokid + Validity + Not Before: Dec 13 13:57:27 2017 GMT + Not After : Dec 13 13:57:27 2018 GMT + Subject: C=CN, ST=sss, O=zzz, OU=ddd, CN=ttt + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + Public-Key: (2048 bit) + Modulus: + 00:a1:91:5e:39:ce:04:73:3c:db:5e:67:f8:c5:a8: + e0:63:e0:df:ab:21:54:0d:89:d7:63:04:68:ae:1a: + f5:1c:46:20:77:a3:41:9c:aa:a3:6d:58:dd:07:43: + c6:3f:81:cc:24:c2:85:59:10:99:c6:bb:a9:34:6d: + 70:c6:cf:63:57:5d:65:b8:42:ec:05:51:52:7a:b0: + 5f:d6:09:60:9f:ae:47:28:af:97:94:76:b7:4b:77: + 97:31:ec:eb:d2:a9:08:4f:0b:b0:54:6a:bd:40:9d: + cb:13:05:2d:2f:b2:51:3e:ff:42:54:89:53:92:96: + e8:3a:7d:d6:8d:42:55:72:e3:5f:51:e2:ee:64:0c: + 76:c0:38:e8:5c:86:09:ef:d5:57:92:2f:e8:fd:f4: + 84:b9:57:41:7a:4c:0c:23:c9:9e:10:17:a3:70:d8: + 43:1c:39:18:9b:92:4a:e4:01:1c:f4:0c:3d:a6:7a: + bf:02:93:ab:57:3d:16:a5:f9:21:fd:e2:15:d5:ab: + de:46:cf:bf:ad:32:de:96:01:3a:fc:f5:50:9b:cb: + 51:c3:97:c4:13:73:59:61:da:6d:1e:06:9a:c8:11: + 14:c2:52:78:59:65:fe:0f:c1:fe:66:5e:47:47:04: + ca:57:7b:7d:b0:0d:1c:91:44:fb:29:ae:8a:ea:27: + 3a:31 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Basic Constraints: + CA:FALSE + Netscape Comment: + OpenSSL Generated Certificate + X509v3 Subject Key Identifier: + 21:28:5D:C7:BB:E1:30:B8:BD:0C:84:F8:98:49:CF:3F:6D:B1:48:4D + X509v3 Authority Key Identifier: + DirName:/C=CN/ST=Hangzhou/L=Hangzhou/O=Rokid/OU=homebase/CN=Rokid + serial:94:4E:2C:AE:6B:DA:31:6B + + Signature Algorithm: sha1WithRSAEncryption + 13:83:55:67:e4:b3:4c:7e:91:92:79:e5:5a:c8:b3:d3:b6:05: + c4:74:ff:6b:82:b8:2b:51:40:d1:b7:6d:2f:0d:f0:c5:65:44: + 05:8f:eb:31:ce:a0:64:6e:02:fe:25:75:ce:24:6d:8d:93:9d: + d2:fb:f9:89:d5:e7:09:fd:09:de:cf:91:c8:ab:0b:ad:ad:12: + be:55:8d:83:ce:8c:77:f1:40:f1:b8:cc:ae:74:90:18:8b:f3: + 42:51:ab:47:21:52:8a:3d:d8:de:3a:b9:2b:6e:0d:9e:33:c7: + 9c:52:33:15:8b:99:38:d6:d5:27:d8:b4:03:28:d6:de:dc:2b: + 19:73:61:fa:8e:3a:43:83:c8:3b:79:0b:23:2a:ed:2f:d1:eb: + 22:5b:00:ac:00:6a:89:04:dc:79:fa:29:42:53:af:b0:9e:fe: + 15:2a:31:06:35:ef:38:88:71:50:c8:6e:20:57:dd:a1:bf:93: + 94:49:26:9b:1a:f3:4b:79:75:53:e0:1c:87:a9:2c:cc:78:61: + cb:ee:56:55:1d:08:9a:36:fd:8e:33:a9:f0:a3:f3:c4:85:de: + a8:94:a1:cd:ee:38:99:84:f8:8e:a8:b2:19:c9:b3:f9:5e:3e: + 24:03:ab:c8:9b:6f:f0:1d:9f:55:47:12:4f:18:53:ed:01:07: + 8f:0c:01:90 +-----BEGIN CERTIFICATE----- +MIIEBTCCAu2gAwIBAgIBBDANBgkqhkiG9w0BAQUFADBmMQswCQYDVQQGEwJDTjER +MA8GA1UECAwISGFuZ3pob3UxETAPBgNVBAcMCEhhbmd6aG91MQ4wDAYDVQQKDAVS +b2tpZDERMA8GA1UECwwIaG9tZWJhc2UxDjAMBgNVBAMMBVJva2lkMB4XDTE3MTIx +MzEzNTcyN1oXDTE4MTIxMzEzNTcyN1owRTELMAkGA1UEBhMCQ04xDDAKBgNVBAgM +A3NzczEMMAoGA1UECgwDenp6MQwwCgYDVQQLDANkZGQxDDAKBgNVBAMMA3R0dDCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKGRXjnOBHM8215n+MWo4GPg +36shVA2J12MEaK4a9RxGIHejQZyqo21Y3QdDxj+BzCTChVkQmca7qTRtcMbPY1dd +ZbhC7AVRUnqwX9YJYJ+uRyivl5R2t0t3lzHs69KpCE8LsFRqvUCdyxMFLS+yUT7/ +QlSJU5KW6Dp91o1CVXLjX1Hi7mQMdsA46FyGCe/VV5Iv6P30hLlXQXpMDCPJnhAX +o3DYQxw5GJuSSuQBHPQMPaZ6vwKTq1c9FqX5If3iFdWr3kbPv60y3pYBOvz1UJvL +UcOXxBNzWWHabR4GmsgRFMJSeFll/g/B/mZeR0cEyld7fbANHJFE+ymuiuonOjEC +AwEAAaOB3jCB2zAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdl +bmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUIShdx7vhMLi9DIT4mEnPP22x +SE0wgYAGA1UdIwR5MHehaqRoMGYxCzAJBgNVBAYTAkNOMREwDwYDVQQIDAhIYW5n +emhvdTERMA8GA1UEBwwISGFuZ3pob3UxDjAMBgNVBAoMBVJva2lkMREwDwYDVQQL +DAhob21lYmFzZTEOMAwGA1UEAwwFUm9raWSCCQCUTiyua9oxazANBgkqhkiG9w0B +AQUFAAOCAQEAE4NVZ+SzTH6RknnlWsiz07YFxHT/a4K4K1FA0bdtLw3wxWVEBY/r +Mc6gZG4C/iV1ziRtjZOd0vv5idXnCf0J3s+RyKsLra0SvlWNg86Md/FA8bjMrnSQ +GIvzQlGrRyFSij3Y3jq5K24NnjPHnFIzFYuZONbVJ9i0AyjW3twrGXNh+o46Q4PI +O3kLIyrtL9HrIlsArABqiQTcefopQlOvsJ7+FSoxBjXvOIhxUMhuIFfdob+TlEkm +mxrzS3l1U+Ach6kszHhhy+5WVR0Imjb9jjOp8KPzxIXeqJShze44mYT4jqiyGcmz ++V4+JAOryJtv8B2fVUcSTxhT7QEHjwwBkA== +-----END CERTIFICATE----- diff --git a/test/test.js b/test/test.js index c98818d..2cf8708 100644 --- a/test/test.js +++ b/test/test.js @@ -53,4 +53,36 @@ x509.verify( function(err, result) { assert.throws(assert.ifError.bind(null, err), /Failed to load cert/) } +); + +x509.verifyFromStr( + fs.readFileSync(path.join(__dirname, 'certs/enduser-example.com.crt')), + fs.readFileSync(path.join(__dirname, 'CA_chains/enduser-example.com.chain')), + function(err, result) { + assert.strictEqual(err, null) + } +); + +x509.verifyFromStr( + fs.readFileSync(path.join(__dirname, 'certs/acaline.com.crt')), + fs.readFileSync(path.join(__dirname, 'CA_chains/enduser-example.com.chain')), + function(err, result) { + assert.throws(assert.ifError.bind(null, err), /self signed certificate/) + } +); + +x509.verifyFromStr( + fs.readFileSync(path.join(__dirname, 'test.js')), + fs.readFileSync(path.join(__dirname, 'CA_chains/enduser-example.com.chain')), + function(err, result) { + assert.throws(assert.ifError.bind(null, err), /Failed to load cert/) + } +); + +x509.verifyFromStr( + fs.readFileSync(path.join(__dirname, 'certs/acaline.com.crt')), + fs.readFileSync(path.join(__dirname, 'test.js')), + function(err, result) { + assert.throws(assert.ifError.bind(null, err), /Failed to load ca/) + } ); \ No newline at end of file From 3d6b34f8f756d159ba77f9ea9cdcc28b4bc44c84 Mon Sep 17 00:00:00 2001 From: chenximin <ximin.chen@rokid.com> Date: Mon, 18 Dec 2017 11:23:34 +0800 Subject: [PATCH 05/10] Update README.md --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index 6a49152..606a5bc 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,21 @@ x509.verify( ``` +#### x509.verifyFromStr(`certStr`, `caStr`, function(err, result){ /*...*/}) + +It is the same with verify. + +```js +const x509 = require('x509'); + +x509.verify( + path.readFileSync(__dirname + '/certs/user.com.crt'), + path.readFileSync(__dirname + 'enduser-example.com.chain'), + function(err, result){ /*...*/} +); + +``` + ## Examples Checking the date to make sure the certificate is active: ```js From 354a3511a83b9caf0cef19a0a9fafc6f9fe0755a Mon Sep 17 00:00:00 2001 From: qile222 <chhxxc@gmail.com> Date: Mon, 18 Dec 2017 11:28:20 +0800 Subject: [PATCH 06/10] Delete test.crt --- test/test.crt | 84 --------------------------------------------------- 1 file changed, 84 deletions(-) delete mode 100644 test/test.crt diff --git a/test/test.crt b/test/test.crt deleted file mode 100644 index ef48d6f..0000000 --- a/test/test.crt +++ /dev/null @@ -1,84 +0,0 @@ -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 4 (0x4) - Signature Algorithm: sha1WithRSAEncryption - Issuer: C=CN, ST=Hangzhou, L=Hangzhou, O=Rokid, OU=homebase, CN=Rokid - Validity - Not Before: Dec 13 13:57:27 2017 GMT - Not After : Dec 13 13:57:27 2018 GMT - Subject: C=CN, ST=sss, O=zzz, OU=ddd, CN=ttt - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (2048 bit) - Modulus: - 00:a1:91:5e:39:ce:04:73:3c:db:5e:67:f8:c5:a8: - e0:63:e0:df:ab:21:54:0d:89:d7:63:04:68:ae:1a: - f5:1c:46:20:77:a3:41:9c:aa:a3:6d:58:dd:07:43: - c6:3f:81:cc:24:c2:85:59:10:99:c6:bb:a9:34:6d: - 70:c6:cf:63:57:5d:65:b8:42:ec:05:51:52:7a:b0: - 5f:d6:09:60:9f:ae:47:28:af:97:94:76:b7:4b:77: - 97:31:ec:eb:d2:a9:08:4f:0b:b0:54:6a:bd:40:9d: - cb:13:05:2d:2f:b2:51:3e:ff:42:54:89:53:92:96: - e8:3a:7d:d6:8d:42:55:72:e3:5f:51:e2:ee:64:0c: - 76:c0:38:e8:5c:86:09:ef:d5:57:92:2f:e8:fd:f4: - 84:b9:57:41:7a:4c:0c:23:c9:9e:10:17:a3:70:d8: - 43:1c:39:18:9b:92:4a:e4:01:1c:f4:0c:3d:a6:7a: - bf:02:93:ab:57:3d:16:a5:f9:21:fd:e2:15:d5:ab: - de:46:cf:bf:ad:32:de:96:01:3a:fc:f5:50:9b:cb: - 51:c3:97:c4:13:73:59:61:da:6d:1e:06:9a:c8:11: - 14:c2:52:78:59:65:fe:0f:c1:fe:66:5e:47:47:04: - ca:57:7b:7d:b0:0d:1c:91:44:fb:29:ae:8a:ea:27: - 3a:31 - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Basic Constraints: - CA:FALSE - Netscape Comment: - OpenSSL Generated Certificate - X509v3 Subject Key Identifier: - 21:28:5D:C7:BB:E1:30:B8:BD:0C:84:F8:98:49:CF:3F:6D:B1:48:4D - X509v3 Authority Key Identifier: - DirName:/C=CN/ST=Hangzhou/L=Hangzhou/O=Rokid/OU=homebase/CN=Rokid - serial:94:4E:2C:AE:6B:DA:31:6B - - Signature Algorithm: sha1WithRSAEncryption - 13:83:55:67:e4:b3:4c:7e:91:92:79:e5:5a:c8:b3:d3:b6:05: - c4:74:ff:6b:82:b8:2b:51:40:d1:b7:6d:2f:0d:f0:c5:65:44: - 05:8f:eb:31:ce:a0:64:6e:02:fe:25:75:ce:24:6d:8d:93:9d: - d2:fb:f9:89:d5:e7:09:fd:09:de:cf:91:c8:ab:0b:ad:ad:12: - be:55:8d:83:ce:8c:77:f1:40:f1:b8:cc:ae:74:90:18:8b:f3: - 42:51:ab:47:21:52:8a:3d:d8:de:3a:b9:2b:6e:0d:9e:33:c7: - 9c:52:33:15:8b:99:38:d6:d5:27:d8:b4:03:28:d6:de:dc:2b: - 19:73:61:fa:8e:3a:43:83:c8:3b:79:0b:23:2a:ed:2f:d1:eb: - 22:5b:00:ac:00:6a:89:04:dc:79:fa:29:42:53:af:b0:9e:fe: - 15:2a:31:06:35:ef:38:88:71:50:c8:6e:20:57:dd:a1:bf:93: - 94:49:26:9b:1a:f3:4b:79:75:53:e0:1c:87:a9:2c:cc:78:61: - cb:ee:56:55:1d:08:9a:36:fd:8e:33:a9:f0:a3:f3:c4:85:de: - a8:94:a1:cd:ee:38:99:84:f8:8e:a8:b2:19:c9:b3:f9:5e:3e: - 24:03:ab:c8:9b:6f:f0:1d:9f:55:47:12:4f:18:53:ed:01:07: - 8f:0c:01:90 ------BEGIN CERTIFICATE----- -MIIEBTCCAu2gAwIBAgIBBDANBgkqhkiG9w0BAQUFADBmMQswCQYDVQQGEwJDTjER -MA8GA1UECAwISGFuZ3pob3UxETAPBgNVBAcMCEhhbmd6aG91MQ4wDAYDVQQKDAVS -b2tpZDERMA8GA1UECwwIaG9tZWJhc2UxDjAMBgNVBAMMBVJva2lkMB4XDTE3MTIx -MzEzNTcyN1oXDTE4MTIxMzEzNTcyN1owRTELMAkGA1UEBhMCQ04xDDAKBgNVBAgM -A3NzczEMMAoGA1UECgwDenp6MQwwCgYDVQQLDANkZGQxDDAKBgNVBAMMA3R0dDCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKGRXjnOBHM8215n+MWo4GPg -36shVA2J12MEaK4a9RxGIHejQZyqo21Y3QdDxj+BzCTChVkQmca7qTRtcMbPY1dd -ZbhC7AVRUnqwX9YJYJ+uRyivl5R2t0t3lzHs69KpCE8LsFRqvUCdyxMFLS+yUT7/ -QlSJU5KW6Dp91o1CVXLjX1Hi7mQMdsA46FyGCe/VV5Iv6P30hLlXQXpMDCPJnhAX -o3DYQxw5GJuSSuQBHPQMPaZ6vwKTq1c9FqX5If3iFdWr3kbPv60y3pYBOvz1UJvL -UcOXxBNzWWHabR4GmsgRFMJSeFll/g/B/mZeR0cEyld7fbANHJFE+ymuiuonOjEC -AwEAAaOB3jCB2zAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdl -bmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUIShdx7vhMLi9DIT4mEnPP22x -SE0wgYAGA1UdIwR5MHehaqRoMGYxCzAJBgNVBAYTAkNOMREwDwYDVQQIDAhIYW5n -emhvdTERMA8GA1UEBwwISGFuZ3pob3UxDjAMBgNVBAoMBVJva2lkMREwDwYDVQQL -DAhob21lYmFzZTEOMAwGA1UEAwwFUm9raWSCCQCUTiyua9oxazANBgkqhkiG9w0B -AQUFAAOCAQEAE4NVZ+SzTH6RknnlWsiz07YFxHT/a4K4K1FA0bdtLw3wxWVEBY/r -Mc6gZG4C/iV1ziRtjZOd0vv5idXnCf0J3s+RyKsLra0SvlWNg86Md/FA8bjMrnSQ -GIvzQlGrRyFSij3Y3jq5K24NnjPHnFIzFYuZONbVJ9i0AyjW3twrGXNh+o46Q4PI -O3kLIyrtL9HrIlsArABqiQTcefopQlOvsJ7+FSoxBjXvOIhxUMhuIFfdob+TlEkm -mxrzS3l1U+Ach6kszHhhy+5WVR0Imjb9jjOp8KPzxIXeqJShze44mYT4jqiyGcmz -+V4+JAOryJtv8B2fVUcSTxhT7QEHjwwBkA== ------END CERTIFICATE----- From 46b1dd77b64b6b2b78764453caabb5227d5bcd6e Mon Sep 17 00:00:00 2001 From: chenximin <ximin.chen@rokid.com> Date: Mon, 18 Dec 2017 11:47:21 +0800 Subject: [PATCH 07/10] Replace var with let --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 35e8aa6..7251753 100644 --- a/index.js +++ b/index.js @@ -7,7 +7,7 @@ exports.getSubject = x509.getSubject; exports.getIssuer = x509.getIssuer; exports.verifyFromStr = function(certStr, CABundleStr, cb) { - let caughtErr = null; + var caughtErr = null; try { x509.verifyFromStr(certStr, CABundleStr); } From 90be4221c350cd007ae53c68ff21e29625b20677 Mon Sep 17 00:00:00 2001 From: chenximin <ximin.chen@rokid.com> Date: Wed, 27 Jun 2018 15:35:44 +0800 Subject: [PATCH 08/10] optmize code style; add test case; check args --- README.md | 2 +- include/x509.h | 4 ++-- index.js | 26 +++++++++++++++++++------- src/addon.cc | 4 ++-- src/x509.cc | 2 +- test/test.js | 19 ++++++++++++++++++- 6 files changed, 43 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 606a5bc..c8eff2b 100644 --- a/README.md +++ b/README.md @@ -137,7 +137,7 @@ x509.verify( ``` -#### x509.verifyFromStr(`certStr`, `caStr`, function(err, result){ /*...*/}) +#### x509.verifyFromStr(`certStr`, `CABundleStr`, function(err, result){ /*...*/}) It is the same with verify. diff --git a/include/x509.h b/include/x509.h index 11c31a4..0eb05c1 100644 --- a/include/x509.h +++ b/include/x509.h @@ -24,11 +24,11 @@ NAN_METHOD(get_subject); NAN_METHOD(get_issuer); NAN_METHOD(parse_cert); NAN_METHOD(verify); -NAN_METHOD(verifyFromStr); +NAN_METHOD(verify_from_str); Local<Value> try_parse(const std::string& dataString); Local<Value> verify(const std::string& dataString); -Local<Value> verifyFromStr(const std::string& dataString); +Local<Value> verify_from_str(const std::string& dataString); Local<Value> parse_date(ASN1_TIME *date); Local<Value> parse_serial(ASN1_INTEGER *serial); Local<Object> parse_name(X509_NAME *subject); diff --git a/index.js b/index.js index 7251753..58f7ab5 100644 --- a/index.js +++ b/index.js @@ -7,14 +7,27 @@ exports.getSubject = x509.getSubject; exports.getIssuer = x509.getIssuer; exports.verifyFromStr = function(certStr, CABundleStr, cb) { + if (typeof cb !== 'function') { + throw new Error('cb should be function') + } + if (certStr instanceof Buffer) { + certStr = certStr.toString() + } else if (typeof certStr !== 'string') { + cb(new Error('certStr should be string or buffer')) + return + } + if (CABundleStr instanceof Buffer) { + CABundleStr = CABundleStr.toString() + } else if (typeof CABundleStr !== 'string') { + cb(new Error('CABundleStr should be string or buffer')) + return + } var caughtErr = null; try { - x509.verifyFromStr(certStr, CABundleStr); - } - catch (verificationError) { + x509.verify_from_str(certStr, CABundleStr); + } catch (verificationError) { caughtErr = verificationError; - } - finally { + } finally { cb(caughtErr); } }; @@ -42,8 +55,7 @@ exports.verify = function(certPath, CABundlePath, cb) { try { x509.verify(certPath, CABundlePath); cb(null); - } - catch (verificationError) { + } catch (verificationError) { cb(verificationError); } }); diff --git a/src/addon.cc b/src/addon.cc index 47c2bed..faf0a47 100644 --- a/src/addon.cc +++ b/src/addon.cc @@ -12,8 +12,8 @@ void init(Local<Object> exports) { Nan::New<String>(VERSION).ToLocalChecked()); Nan::Set(exports, - Nan::New<String>("verifyFromStr").ToLocalChecked(), - Nan::New<FunctionTemplate>(verifyFromStr)->GetFunction()); + Nan::New<String>("verify_from_str").ToLocalChecked(), + Nan::New<FunctionTemplate>(verify_from_str)->GetFunction()); Nan::Set(exports, Nan::New<String>("verify").ToLocalChecked(), diff --git a/src/x509.cc b/src/x509.cc index de2fcbf..a6fdecf 100644 --- a/src/x509.cc +++ b/src/x509.cc @@ -46,7 +46,7 @@ std::string parse_args(const Nan::FunctionCallbackInfo<v8::Value>& info) { return *String::Utf8Value(info[0]->ToString()); } -NAN_METHOD(verifyFromStr) { +NAN_METHOD(verify_from_str) { Nan::HandleScope scope; OpenSSL_add_all_algorithms(); std::string cert_str = *String::Utf8Value(info[0]->ToString()); diff --git a/test/test.js b/test/test.js index 2cf8708..2fb854c 100644 --- a/test/test.js +++ b/test/test.js @@ -85,4 +85,21 @@ x509.verifyFromStr( function(err, result) { assert.throws(assert.ifError.bind(null, err), /Failed to load ca/) } -); \ No newline at end of file +); + +x509.verifyFromStr( + 123456, + fs.readFileSync(path.join(__dirname, 'CA_chains/enduser-example.com.chain')), + function(err, result) { + assert.throws(assert.ifError.bind(null, err), /certStr should be string or buffer/) + } +) + +try { + x509.verifyFromStr( + fs.readFileSync(path.join(__dirname, 'certs/acaline.com.crt')), + fs.readFileSync(path.join(__dirname, 'CA_chains/enduser-example.com.chain')) + ) +} catch (err) { + assert.throws(assert.ifError.bind(null, err), /cb should be function/) +} \ No newline at end of file From 22e520ccbf20d4d0dd0d01d5e478fcbc0311e6d8 Mon Sep 17 00:00:00 2001 From: chenximin <ximin.chen@rokid.com> Date: Thu, 26 Jul 2018 21:55:16 +0800 Subject: [PATCH 09/10] fix style --- index.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/index.js b/index.js index 58f7ab5..c97c232 100644 --- a/index.js +++ b/index.js @@ -8,19 +8,19 @@ exports.getIssuer = x509.getIssuer; exports.verifyFromStr = function(certStr, CABundleStr, cb) { if (typeof cb !== 'function') { - throw new Error('cb should be function') + throw new Error('cb should be function'); } if (certStr instanceof Buffer) { - certStr = certStr.toString() + certStr = certStr.toString(); } else if (typeof certStr !== 'string') { - cb(new Error('certStr should be string or buffer')) - return + cb(new Error('certStr should be string or buffer')); + return; } if (CABundleStr instanceof Buffer) { - CABundleStr = CABundleStr.toString() + CABundleStr = CABundleStr.toString(); } else if (typeof CABundleStr !== 'string') { - cb(new Error('CABundleStr should be string or buffer')) - return + cb(new Error('CABundleStr should be string or buffer')); + return; } var caughtErr = null; try { From de6fbd9c550b62b07da639b1d8511acd00aa3cbc Mon Sep 17 00:00:00 2001 From: chenximin <ximin.chen@rokid.com> Date: Thu, 20 Dec 2018 15:30:32 +0800 Subject: [PATCH 10/10] lint fix --- README.md | 2 +- index.js | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index c8eff2b..177bd48 100644 --- a/README.md +++ b/README.md @@ -137,7 +137,7 @@ x509.verify( ``` -#### x509.verifyFromStr(`certStr`, `CABundleStr`, function(err, result){ /*...*/}) +#### x509.verifyFromStr(`certStr`, `caBundleStr`, function(err, result){ /*...*/}) It is the same with verify. diff --git a/index.js b/index.js index c97c232..35e1aff 100644 --- a/index.js +++ b/index.js @@ -6,7 +6,7 @@ exports.getAltNames = x509.getAltNames; exports.getSubject = x509.getSubject; exports.getIssuer = x509.getIssuer; -exports.verifyFromStr = function(certStr, CABundleStr, cb) { +exports.verifyFromStr = function(certStr, caBundleStr, cb) { if (typeof cb !== 'function') { throw new Error('cb should be function'); } @@ -16,15 +16,15 @@ exports.verifyFromStr = function(certStr, CABundleStr, cb) { cb(new Error('certStr should be string or buffer')); return; } - if (CABundleStr instanceof Buffer) { - CABundleStr = CABundleStr.toString(); - } else if (typeof CABundleStr !== 'string') { - cb(new Error('CABundleStr should be string or buffer')); + if (caBundleStr instanceof Buffer) { + caBundleStr = caBundleStr.toString(); + } else if (typeof caBundleStr !== 'string') { + cb(new Error('caBundleStr should be string or buffer')); return; } var caughtErr = null; try { - x509.verify_from_str(certStr, CABundleStr); + x509.verify_from_str(certStr, caBundleStr); } catch (verificationError) { caughtErr = verificationError; } finally {