Skip to content

Commit

Permalink
Change default settings for future requirements + EV Fix
Browse files Browse the repository at this point in the history
changed the default settings:
keyBitsize set to 2048 (befor: 1024)
Hash set to SHA256 (befor: SHA1)

readCertificateInfo return now a `san` object {dns, ip} if the csr/cert
have san entries.

readCertificateInfo returns now EV Cert informations

README.md updated
  • Loading branch information
Dexus committed Mar 27, 2014
1 parent 8eed789 commit 0e017e0
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 29 deletions.
10 changes: 6 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Use `createPrivateKey` for creating private keys

Where

* **keyBitsize** is an optional size of the key, defaults to 1024 (bit)
* **keyBitsize** is an optional size of the key, defaults to 2048 (bit)
* **callback** is a callback function with an error object and `{key}`

### Create a Certificate Signing Request
Expand All @@ -71,8 +71,8 @@ Where
Possible options are the following

* **clientKey** is an optional client key to use
* **keyBitsize** - if `clientKey` is undefined, bit size to use for generating a new key (defaults to 1024)
* **hash** is a hash function to use (either `md5` or `sha1`, defaults to `sha1`)
* **keyBitsize** - if `clientKey` is undefined, bit size to use for generating a new key (defaults to 2048)
* **hash** is a hash function to use (either `md5`, `sha1` or `sha256`, defaults to `sha256`)
* **country** is a CSR country field
* **state** is a CSR state field
* **locality** is a CSR locality field
Expand Down Expand Up @@ -123,7 +123,9 @@ Use `readCertificateInfo` for reading subject data from a certificate or a CSR
Where

* **certificate** is a PEM encoded CSR or a certificate
* **callback** is a callback function with an error object and `{country, state, locality, organization, organizationUnit, commonName, emailAddress, validity{start, end} }`
* **callback** is a callback function with an error object and `{country, state, locality, organization, organizationUnit, commonName, emailAddress, validity{start, end}, san{dns, ip}? }`

? *san* is only present if the CSR or certificate has SAN entries.

### Get fingerprint

Expand Down
71 changes: 46 additions & 25 deletions lib/pem.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ module.exports.getModulus = getModulus;
/**
* Creates a private key
*
* @param {Number} [keyBitsize=1024] Size of the key, defaults to 1024bit
* @param {Number} [keyBitsize=2048] Size of the key, defaults to 2048bit
* @param {Function} callback Callback function with an error object and {key}
*/
function createPrivateKey(keyBitsize, callback){
Expand All @@ -28,7 +28,7 @@ function createPrivateKey(keyBitsize, callback){
keyBitsize = undefined;
}

keyBitsize = Number(keyBitsize) || 1024;
keyBitsize = Number(keyBitsize) || 2048;

var params = ["genrsa",
"-rand",
Expand All @@ -52,8 +52,8 @@ function createPrivateKey(keyBitsize, callback){
*
* @param {Object} [options] Optional options object
* @param {String} [options.clientKey] Optional client key to use
* @param {Number} [options.keyBitsize] If clientKey is undefined, bit size to use for generating a new key (defaults to 1024)
* @param {String} [options.hash] Hash function to use (either md5 or sha1, defaults to sha1)
* @param {Number} [options.keyBitsize] If clientKey is undefined, bit size to use for generating a new key (defaults to 2048)
* @param {String} [options.hash] Hash function to use (either md5 sha1 or sha256, defaults to sha256)
* @param {String} [options.country] CSR country field
* @param {String} [options.state] CSR state field
* @param {String} [options.locality] CSR locality field
Expand All @@ -72,18 +72,18 @@ function createCSR(options, callback){
}

options = options || {};

// http://stackoverflow.com/questions/14089872/why-does-node-js-accept-ip-addresses-in-certificates-only-for-san-not-for-cn
if (options.commonName && (net.isIPv4(options.commonName) || net.isIPv6(options.commonName))) {
if (!options.altNames) {
options.altNames = [options.commonName]
} else if (options.altNames.indexOf(options.commonName) == -1) {
options.altNames = options.altNames.concat([options.commonName])
}
}
}

if(!options.clientKey){
createPrivateKey(options.keyBitsize || 1024, function(error, keyData){
createPrivateKey(options.keyBitsize || 2048, function(error, keyData){
if(error){
return callback(error);
}
Expand All @@ -95,7 +95,7 @@ function createCSR(options, callback){

var params = ["req",
"-new",
"-" + (options.hash || "sha1"),
"-" + (options.hash || "sha256"),
"-subj",
generateCSRSubject(options),
"-key",
Expand Down Expand Up @@ -185,7 +185,7 @@ function createCertificate(options, callback){
if(options.selfSigned){
options.serviceKey = options.clientKey;
}else{
createPrivateKey(options.keyBitsize || 1024, function(error, keyData){
createPrivateKey(options.keyBitsize || 2048, function(error, keyData){
if(error){
return callback(error);
}
Expand Down Expand Up @@ -382,49 +382,47 @@ function getFingerprint(certificate, callback){
function fetchCertificateData(certData, callback){
certData = (certData || "").toString();

var subject, extra, tmp, certValues = {};
var subject,subject2, extra, tmp, certValues = {};
var validity = {};

if((subject = certData.match(/Subject:([^\n]*)\n/)) && subject.length>1){
subject2 = linebrakes(subject[1]+'\n');
subject = subject[1];
extra = subject.split("/");
subject = extra.shift()+"\n";
extra = extra.join("/")+"\n";

// country
tmp = subject.match(/\sC=([^,\n].*?)[,\n]/);
tmp = subject2.match(/\sC=([^\n].*?)[\n]/);
certValues.country = tmp && tmp[1] || "";
// state
tmp = subject.match(/\sST=([^,\n].*?)[,\n]/);
tmp = subject2.match(/\sST=([^\n].*?)[\n]/);
certValues.state = tmp && tmp[1] || "";
// locality
tmp = subject.match(/\sL=([^,\n].*?)[,\n]/);
tmp = subject2.match(/\sL=([^\n].*?)[\n]/);
certValues.locality = tmp && tmp[1] || "";
// organization
tmp = subject.match(/\sO=([^,\n].*?)[,\n]/);
tmp = subject2.match(/\sO=([^\n].*?)[\n]/);
certValues.organization = tmp && tmp[1] || "";
// unit
tmp = subject.match(/\sOU=([^,\n].*?)[,\n]/);
tmp = subject2.match(/\sOU=([^\n].*?)[\n]/);
certValues.organizationUnit = tmp && tmp[1] || "";
// common name
tmp = subject.match(/\sCN=([^,\n].*?)[,\n]/);
tmp = subject2.match(/\sCN=([^\n].*?)[\n]/);
certValues.commonName = tmp && tmp[1] || "";
//email
tmp = extra.match(/emailAddress=([^,\n\/].*?)[,\n\/]/);
tmp = extra.match(/emailAddress=([^\n\/].*?)[\n\/]/);
certValues.emailAddress = tmp && tmp[1] || "";
}
}
if((san = certData.match(/X509v3 Subject Alternative Name: \n([^\n]*)\n/)) && san.length>1){
san = san[1].trim()+'\n';
extra = subject.split("/");
subject = extra.shift()+"\n";
extra = extra.join("/")+"\n";

certValues.san = {};
// country
tmp = preg_match_all('DNS:([^,\n].*?)[,\n]',san);
certValues.SAN_DNS = tmp || "";
certValues.san.dns = tmp || "";
// country
tmp = preg_match_all('IP Address:([^,\n].*?)[,\n\s]',san);
certValues.SAN_IP = tmp || "";
certValues.san.ip = tmp || "";
}
if ((tmp = certData.match(/Not Before\s?:\s?([^\n]*)\n/)) && tmp.length>1)
validity.start = Date.parse(tmp && tmp[1] || "");
Expand All @@ -436,6 +434,29 @@ function fetchCertificateData(certData, callback){
callback(null, certValues);
}



function linebrakes (content){
var helper_x, p,subject;
helper_x = content.replace(/(C|L|O|OU|ST|CN)=/g, "\n$1=");
helper_x = preg_match_all('((C|L|O|OU|ST|CN)=[^\n].*)',helper_x);
for(p in helper_x){
subject = helper_x[p].trim();
content = subject.split("/");
subject = content.shift();
helper_x[p] = rtrim(subject,',');
}
return " " + helper_x.join('\n') + "\n";
}

function rtrim(str, charlist) {
charlist = !charlist ? ' \\s\u00A0' : (charlist + '')
.replace(/([\[\]\(\)\.\?\/\*\{\}\+\$\^\:])/g, '\\$1');
var re = new RegExp('[' + charlist + ']+$', 'g');
return (str + '')
.replace(re, '');
}

function preg_match_all(regex, haystack) {
var globalRegex = new RegExp(regex, 'g');
var globalMatch = haystack.match(globalRegex);
Expand Down Expand Up @@ -604,4 +625,4 @@ function execOpenSSL(params, searchStr, tmpfiles, callback){
return callback(new Error(searchStr + " not found from openssl output:\n---stdout---\n" + stdout + "\n---stderr---\n" + stderr + "\ncode: " + code + "\nsignal: " + signal));
}
});
}
}

0 comments on commit 0e017e0

Please sign in to comment.