Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
0e57409
Add Equifax root cert, an example of a cert with UTCTime formatted da…
mikelaspina Mar 7, 2014
ea2a28f
Let OpenSSL handle date parsing. This fixes date parsing for UTCTime …
mikelaspina Mar 7, 2014
f733c13
Fix whitespace.
mikelaspina Mar 8, 2014
5f14343
Merge pull request #15 from yorkie/master
yorkie Sep 14, 2014
c48d604
fix author error
yorkie Sep 14, 2014
12116d1
Merge pull request #13 from mikelaspina/fix-parse-dates
yorkie Sep 14, 2014
6ce9ba8
fix #11 but without pem stuff
yorkie Sep 14, 2014
80fdfbb
bump version to 0.1.4
yorkie Sep 14, 2014
6894c34
fix typo: package name -> x509
yorkie Sep 14, 2014
2fdd62d
Update README.md
Southern Sep 15, 2014
8e4e452
Mention x509.js
Rush Nov 24, 2014
27fcd81
Merge pull request #18 from RushPL/patch-1
yorkie Nov 25, 2014
96ed466
use nan@2.x to support nodejs4
yorkie Sep 9, 2015
68fa0a3
fix compatible
yorkie Sep 9, 2015
b178ec5
add 4.0 into ci env
yorkie Sep 9, 2015
2f53e08
doesnt support node v0.8 any more
yorkie Sep 9, 2015
cc0e166
update travis config
yorkie Sep 9, 2015
099ff4a
Merge pull request #22 from Southern/upgrade/nan
yorkie Sep 9, 2015
a51ee74
update readme
yorkie Sep 9, 2015
eaecc39
v0.2.1
yorkie Sep 9, 2015
488f9e5
[fix] git link
jcrugzz Sep 10, 2015
5b20e3a
Merge pull request #23 from Southern/jcrugzz-patch-1
yorkie Sep 10, 2015
682345d
v0.2.2
yorkie Sep 10, 2015
dd30e57
Fix README examples.
Southern Nov 3, 2015
b40ad33
Fix extra characters in the values of extensions
Southern Nov 3, 2015
0bcf012
Run trim until all \r\n chars are trimmed
Southern Nov 3, 2015
a036660
Call real_name on extension names
Southern Nov 3, 2015
6cad0bd
Add entrustVersionInfo in missing names
Southern Nov 3, 2015
cad2992
Free BIO after parsing.
Southern Nov 3, 2015
ec713a4
Remove IRC notifications in .travis.yml
Southern Nov 3, 2015
1a9d742
Allocate sizeof(char), not sizeof(char*)
Southern Nov 3, 2015
2357b0d
Fix allocation; maybe 2am coding wasn't the best.
Southern Nov 3, 2015
c2db68c
Update .travis.yml
Southern Nov 3, 2015
7724f79
Bump version: v0.2.3
Southern Nov 6, 2015
8f07dec
BIO_NOCLOSE->BIO_CLOSE in extensions
Southern Nov 6, 2015
c128a78
v8::Handle -> v8::Local, Handle is no longer a type
Southern Feb 22, 2016
4cea21a
Update .travis.yml
Southern Feb 22, 2016
bdc7d41
Bump version: 0.2.4
Southern Feb 22, 2016
65b41c3
Update README
Southern Mar 3, 2016
97fa338
deps: upgrade nan to 2.2.0 (#33)
tanuck May 13, 2016
26b2b51
bump version
yorkie May 13, 2016
b6197ef
src: fix memory leak when throwing errors in try_parse
yorkie Jun 15, 2016
a4acc34
v0.2.6
yorkie Jun 15, 2016
fced8f8
verify: basic validation against certificate authority (#38)
lambrojos Oct 3, 2016
a87d702
v0.3.0
yorkie Oct 3, 2016
034349d
Fix link to OpenSSL documentation
sonicdoe Dec 15, 2016
50a0162
Added bitSize to public key field
Dec 22, 2016
6b8e27f
Support for subject hash property of a certificate
Jan 30, 2017
b53d6ab
Fix memory leak in bindings
Jan 31, 2017
22d57be
Merge pull request #43 from pdspicer/master
Southern Feb 6, 2017
73ebcef
Merge pull request #45 from jkryl/master
Southern Feb 6, 2017
6c92f64
Merge pull request #46 from jkryl/memleak
Southern Feb 6, 2017
2044352
Merge pull request #41 from sonicdoe/patch-1
Southern Feb 6, 2017
9584ed4
v0.3.1
Southern Feb 6, 2017
8b34a62
fixes for memory and error status leaks in parse cert
astitt-ripple Feb 17, 2017
c3d7799
Merge pull request #48 from astitt-ripple/memory_leak_fixes
Southern Mar 14, 2017
380d771
Bump version: v0.3.2
Southern Mar 21, 2017
0d70254
test: update cert & chain for verify (#62)
yorkie Nov 28, 2017
75a6a3d
src: fix verify crash caused by invalid cert format (#60)
qile222 Nov 28, 2017
d7e6c43
v0.3.3: bump version
yorkie Nov 28, 2017
6033d4b
Updated version #71 with formatting corrected (#74)
mbwhite Dec 19, 2018
17b2b7a
v0.3.4: bump version
yorkie Dec 19, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@

node_modules
build
*.log
*.DS_Store
33 changes: 22 additions & 11 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,30 @@
language: node_js
os:
- linux

addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8

language: node_js
node_js:
- "0.11"
- "stable"
- "4.0"
- "0.12"
- "0.10"
- "0.8"

notifications:
email: false

irc:
channels:
- "chat.freenode.net#jitsu"
on_success: change
on_failure: change
install:
- export CXX=g++-4.8
- $CXX --version
- npm i

before_install:
- npm install -g node-gyp
- rm -rf ~/.node-gyp/

notifications:
email: false

sudo: false
63 changes: 43 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
node-x509
=========

[![Build Status](https://travis-ci.org/Southern/node-x509.svg?branch=master)](https://travis-ci.org/Southern/node-x509)

Simple X509 certificate parser.

## Installation

From NPM *(recommended)*: `npm install x.509`
From NPM *(recommended)*: `npm install x509`

Building and testing from source:
```
Expand All @@ -17,30 +19,26 @@ npm test
## Usage
Reading from a file:
```js
var x509 = require('x509');

const x509 = require('x509');
var issuer = x509.getIssuer(__dirname + '/certs/your.crt');
```

Reading from a string:
```js
var fs = require('fs'),
x509 = require('x509');

const fs = require('fs'),
x509 = require('x509');
var issuer = x509.getIssuer(fs.readFileSync('./certs/your.crt').toString());
```

## Methods
**Notes:**
- `cert` may be a filename or a raw base64 encoded PEM string in any of these methods.


#### x509.getAltNames(`cert`)
Parse certificate with `x509.parseCert` and return the alternate names.

```js
var x509 = require('x509');

const x509 = require('x509');
var altNames = x509.getAltNames(__dirname + '/certs/nodejitsu.com.crt');
/*
altNames = [ '*.nodejitsu.com', 'nodejitsu.com' ]
Expand All @@ -51,8 +49,7 @@ altNames = [ '*.nodejitsu.com', 'nodejitsu.com' ]
Parse certificate with `x509.parseCert` and return the issuer.

```js
var x509 = require('x509');

const x509 = require('x509');
var issuer = x509.getIssuer(__dirname + '/certs/nodejitsu.com.crt');
/*
issuer = { countryName: 'GB',
Expand All @@ -67,8 +64,7 @@ issuer = { countryName: 'GB',
Parse certificate with `x509.parseCert` and return the subject.

```js
var x509 = require('x509');

const x509 = require('x509');
var subject = x509.getSubject(__dirname + '/certs/nodejitsu.com.crt');
/*
subject = { countryName: 'US',
Expand All @@ -86,11 +82,10 @@ subject = { countryName: 'US',
Parse subject, issuer, valid before and after date, and alternate names from certificate.

```js
var x509 = require('x509');

const x509 = require('x509');
var cert = x509.parseCert(__dirname + '/certs/nodejitsu.com.crt');
/*
cert = { subject:
cert = { subject:
{ countryName: 'US',
postalCode: '10010',
stateOrProvinceName: 'NY',
Expand All @@ -99,7 +94,7 @@ cert = { subject:
organizationName: 'Nodejitsu',
organizationalUnitName: 'PremiumSSL Wildcard',
commonName: '*.nodejitsu.com' },
issuer:
issuer:
{ countryName: 'GB',
stateOrProvinceName: 'Greater Manchester',
localityName: 'Salford',
Expand All @@ -117,11 +112,36 @@ cert = { subject:
*/
```


#### x509.verify(`cert`, `CABundlePath`, function(err, result){ /*...*/})

Performs basic certificate validation against a bundle of ca certificates.

It accepts an error-first callback as first argument. If the error is null, then
the certificate is valid.

The error messages are the same returned by openssl: [x509_verify_cert_error_string](https://www.openssl.org/docs/man1.0.2/crypto/X509_STORE_CTX_get_error.html)


**Note:**
As now, this function only accepts absolute paths to existing files as arguments

```js
const x509 = require('x509');

x509.verify(
__dirname + '/certs/user.com.crt',
__dirname + 'enduser-example.com.chain',
function(err, result){ /*...*/}
);

```

## Examples
Checking the date to make sure the certificate is active:
```js
var x509 = require('x509'),
cert = x509.parseCert('yourcert.crt'),
const x509 = require('x509');
var cert = x509.parseCert('yourcert.crt'),
date = new Date();

if (cert.notBefore > date) {
Expand All @@ -134,4 +154,7 @@ if (cert.notAfter < date) {

## License

MIT
MIT

#### Alternative implementation / build issues
If you are suffering from hard to fix build issues, there is an alternative (pure javascript) implementation using emscripten: https://github.com/encharm/x509.js (based on node-x509, slightly different API)
7 changes: 4 additions & 3 deletions binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
'src/x509.cc'
],
'include_dirs': [
'include'
'include',
"<!(node -e \"require('nan')\")"
],
'conditions': [
[ 'OS=="win"', {
Expand All @@ -35,7 +36,7 @@
'defines': [
'uint=unsigned int',
],
'libraries': [
'libraries': [
'-l<(openssl_root)/lib/libeay32.lib',
],
'include_dirs': [
Expand All @@ -47,7 +48,7 @@
'<(node_root_dir)/deps/openssl/openssl/include'
],
}],
],
],
}
]
}
2 changes: 1 addition & 1 deletion include/addon.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@

using namespace v8;

void init(Handle<Object> exports);
void init(Local<Object> exports);

#endif
30 changes: 14 additions & 16 deletions include/x509.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
// Include header for addon version, node/v8 inclusions, etc.
#include <addon.h>
#include <node_version.h>
#include <nan.h>
#include <string>

// OpenSSL headers
#include <openssl/asn1.h>
Expand All @@ -17,23 +19,19 @@

using namespace v8;

#if NODE_VERSION_AT_LEAST(0, 11, 3) && defined(__APPLE__)
void get_altnames(const FunctionCallbackInfo<Value> &args);
void get_subject(const FunctionCallbackInfo<Value> &args);
void get_issuer(const FunctionCallbackInfo<Value> &args);
char* parse_args(const FunctionCallbackInfo<Value> &args);
void parse_cert(const FunctionCallbackInfo<Value> &args);
#else
Handle<Value> get_altnames(const Arguments &args);
Handle<Value> get_subject(const Arguments &args);
Handle<Value> get_issuer(const Arguments &args);
Handle<Value> parse_cert(const Arguments &args);
#endif
NAN_METHOD(get_altnames);
NAN_METHOD(get_subject);
NAN_METHOD(get_issuer);
NAN_METHOD(parse_cert);
NAN_METHOD(verify);

Local<Value> try_parse(const std::string& dataString);
Local<Value> verify(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);

Handle<Value> try_parse(char *data);
Handle<Value> parse_date(char *date);
Handle<Value> parse_serial(ASN1_INTEGER *serial);
Handle<Object> parse_name(X509_NAME *subject);
char* real_name(char *data);
char* trim(char *data, int len);

#endif
36 changes: 34 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,43 @@

var x509 = require('./build/Release/x509');
var fs = require('fs');

exports.version = x509.version;
exports.getAltNames = x509.getAltNames;
exports.getSubject = x509.getSubject;
exports.getIssuer = x509.getIssuer;

exports.verify = function(certPath, CABundlePath, cb) {
if (!certPath) {
throw new TypeError('Certificate path is required');
}
if (!CABundlePath) {
throw new TypeError('CA Bundle path is required');
}

fs.stat(certPath, function(certPathErr) {

if (certPathErr) {
return cb(certPathErr);
}

fs.stat(CABundlePath, function(bundlePathErr) {

if (bundlePathErr) {
return cb(bundlePathErr);
}

try {
x509.verify(certPath, CABundlePath);
cb(null);
}
catch (verificationError) {
cb(verificationError);
}
});
});
};


exports.parseCert = function(path) {
var ret = x509.parseCert(path);
var exts = {};
Expand All @@ -17,4 +49,4 @@ exports.parseCert = function(path) {
delete ret.extensions;
ret.extensions = exts;
return ret;
};
};
13 changes: 8 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
{
"name": "x.509",
"version": "0.1.1",
"name": "x509",
"version": "0.3.4",
"description": "Simple X509 certificate parser.",
"author": "Yorkie Neil <yorkiefixer@gmail.com>",
"author": "Colton Baker",
"main": "index.js",
"repository": {
"type": "git",
"url": "http://github.com/yorkie/node-x509"
"url": "git@github.com:Southern/node-x509.git"
},
"scripts": {
"test": "node test/test"
},
"license": "MIT"
"license": "MIT",
"dependencies": {
"nan": "2.12.0"
}
}
27 changes: 21 additions & 6 deletions src/addon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,27 @@

using namespace v8;

void init(Handle<Object> exports) {
exports->Set(String::NewSymbol("version"), String::New(VERSION));
exports->Set(String::NewSymbol("getAltNames"), FunctionTemplate::New(get_altnames)->GetFunction());
exports->Set(String::NewSymbol("getSubject"), FunctionTemplate::New(get_subject)->GetFunction());
exports->Set(String::NewSymbol("getIssuer"), FunctionTemplate::New(get_issuer)->GetFunction());
exports->Set(String::NewSymbol("parseCert"), FunctionTemplate::New(parse_cert)->GetFunction());
void init(Local<Object> exports) {
Nan::Set(exports,
Nan::New<String>("version").ToLocalChecked(),
Nan::New<String>(VERSION).ToLocalChecked());

Nan::Set(exports,
Nan::New<String>("verify").ToLocalChecked(),
Nan::New<FunctionTemplate>(verify)->GetFunction());

Nan::Set(exports,
Nan::New<String>("getAltNames").ToLocalChecked(),
Nan::New<FunctionTemplate>(get_altnames)->GetFunction());
Nan::Set(exports,
Nan::New<String>("getSubject").ToLocalChecked(),
Nan::New<FunctionTemplate>(get_subject)->GetFunction());
Nan::Set(exports,
Nan::New<String>("getIssuer").ToLocalChecked(),
Nan::New<FunctionTemplate>(get_issuer)->GetFunction());
Nan::Set(exports,
Nan::New<String>("parseCert").ToLocalChecked(),
Nan::New<FunctionTemplate>(parse_cert)->GetFunction());
}

NODE_MODULE(x509, init)
Loading