Comparing version 1.13.2 to 1.14.0
@@ -0,1 +1,8 @@ | ||
# [1.14.0](https://github.com/Dexus/pem/compare/v1.13.2...v1.14.0) (2019-01-25) | ||
### Features | ||
* **package:** Support SAN Certificate from CSR ([#229](https://github.com/Dexus/pem/issues/229)) ([fa450f5](https://github.com/Dexus/pem/commit/fa450f5)) | ||
## [1.13.2](https://github.com/Dexus/pem/compare/v1.13.1...v1.13.2) (2018-10-26) | ||
@@ -2,0 +9,0 @@ |
@@ -7,2 +7,11 @@ ### Changelog | ||
#### [v1.13.2](https://github.com/Dexus/pem/compare/v1.13.1...v1.13.2) | ||
> 26 October 2018 | ||
- fix(package): security fix [`#217`](https://github.com/Dexus/pem/pull/217) | ||
- chore(release): 1.13.2 [skip ci] [`9adaa05`](https://github.com/Dexus/pem/commit/9adaa05795fc1007856e721a9345d66680f4bfa6) | ||
- Update helper.spec.js [`8e8457c`](https://github.com/Dexus/pem/commit/8e8457cd3587c0e44b213c97f815efc85c6d69c3) | ||
- Update helper.js [`174faaf`](https://github.com/Dexus/pem/commit/174faaf191ee95afa372ec8533266f99c3f2c83c) | ||
#### [v1.13.1](https://github.com/Dexus/pem/compare/v1.13.0...v1.13.1) | ||
@@ -52,3 +61,3 @@ | ||
#### [v1.12.5](https://github.com/Dexus/pem/compare/v1.12.4...v1.12.5) | ||
#### [v1.12.5](https://github.com/Dexus/pem/compare/v1.12.3...v1.12.5) | ||
@@ -61,18 +70,2 @@ > 9 April 2018 | ||
#### [v1.12.4](https://github.com/Dexus/pem/compare/v1.12.3...v1.12.4) | ||
> 4 April 2018 | ||
- fix: pin eslint-plugin-import to 2.10.0 [`#191`](https://github.com/Dexus/pem/pull/191) | ||
- chore(package): update semantic-release to version 15.1.5 [`#190`](https://github.com/Dexus/pem/pull/190) | ||
- chore(package): update cross-env to version 5.1.4 [`#189`](https://github.com/Dexus/pem/pull/189) | ||
- Update eslint-config-standard to the latest version 🚀 [`#186`](https://github.com/Dexus/pem/pull/186) | ||
- Update semantic-release to the latest version 🚀 [`#178`](https://github.com/Dexus/pem/pull/178) | ||
- Update travis-deploy-once to the latest version 🚀 [`#181`](https://github.com/Dexus/pem/pull/181) | ||
- chore(package): update cross-env to version 5.1.2 [`#180`](https://github.com/Dexus/pem/pull/180) | ||
- chore(package): update semantic-release to version 15.1.5 [`#182`](https://github.com/Dexus/pem/issues/182) | ||
- Update HISTORY.md via TravisCI [`8e89517`](https://github.com/Dexus/pem/commit/8e895178e7701e4f0fea7a5d98a41be10a4ce457) | ||
- Update aftersuccess.sh [`e64edc9`](https://github.com/Dexus/pem/commit/e64edc98eea628736eb4d0ab04add946f878a989) | ||
- Update aftersuccess.sh [`91df068`](https://github.com/Dexus/pem/commit/91df068ec55ec65cda9c62d55503f1a1ad6424d6) | ||
#### [v1.12.3](https://github.com/Dexus/pem/compare/v1.12.2...v1.12.3) | ||
@@ -85,3 +78,3 @@ | ||
#### [v1.12.2](https://github.com/Dexus/pem/compare/v1.12.1...v1.12.2) | ||
#### v1.12.2 | ||
@@ -91,10 +84,4 @@ > 8 October 2017 | ||
- fix #150: serial can now be an 20 octets string, number or hex [`#150`](https://github.com/Dexus/pem/issues/150) | ||
- fix(package): build and release #150 fix and create HISTORY after release. [`e948217`](https://github.com/Dexus/pem/commit/e948217f34157024ec629d5d1111cbcef0c94e6a) | ||
- Update HISTORY.md via TravisCI [`b58a0b2`](https://github.com/Dexus/pem/commit/b58a0b2ea8af3620337de3bf17dfebf21a5dd353) | ||
- fix(package): build and release #150 fix and create HISTORY after release. [`e948217`](https://github.com/Dexus/pem/commit/e948217f34157024ec629d5d1111cbcef0c94e6a) | ||
- chore(release-flow): change HISTORY.md only on master [`6da3254`](https://github.com/Dexus/pem/commit/6da325403b80a06d91d0cca2c46667c07414dbf5) | ||
#### v1.12.1 | ||
> 7 October 2017 | ||
- change template for docs [`10672e4`](https://github.com/Dexus/pem/commit/10672e4d2d7e0c9e856e5bc1af90c4977da2ee8b) |
175
lib/pem.js
@@ -327,2 +327,6 @@ 'use strict' | ||
if (!options.clientKey) { | ||
options.clientKey = '' | ||
} | ||
if (!options.serviceKey) { | ||
@@ -343,21 +347,26 @@ if (options.selfSigned) { | ||
var params = ['x509', | ||
'-req', | ||
'-' + (options.hash || 'sha256'), | ||
'-days', | ||
Number(options.days) || '365', | ||
'-in', | ||
'--TMPFILE--' | ||
] | ||
var tmpfiles = [options.csr] | ||
var delTempPWFiles = [] | ||
readCertificateInfo(options.csr, function (error2, data2) { | ||
if (error2) { | ||
return callback(error2) | ||
} | ||
if (options.serviceCertificate) { | ||
params.push('-CA') | ||
params.push('--TMPFILE--') | ||
params.push('-CAkey') | ||
params.push('--TMPFILE--') | ||
if (options.serial) { | ||
params.push('-set_serial') | ||
if (helper.isNumber(options.serial)) { | ||
var params = ['x509', | ||
'-req', | ||
'-' + (options.hash || 'sha256'), | ||
'-days', | ||
Number(options.days) || '365', | ||
'-in', | ||
'--TMPFILE--' | ||
] | ||
var tmpfiles = [options.csr] | ||
var delTempPWFiles = [] | ||
if (options.serviceCertificate) { | ||
params.push('-CA') | ||
params.push('--TMPFILE--') | ||
params.push('-CAkey') | ||
params.push('--TMPFILE--') | ||
if (options.serial) { | ||
params.push('-set_serial') | ||
if (helper.isNumber(options.serial)) { | ||
// set the serial to the max lenth of 20 octets () | ||
@@ -370,65 +379,89 @@ // A certificate serial number is not decimal conforming. That is the | ||
// the ACSII table). | ||
params.push('0x' + ('0000000000000000000000000000000000000000' + options.serial.toString(16)).slice(-40)) | ||
} else { | ||
if (helper.isHex(options.serial)) { | ||
if (options.serial.startsWith('0x')) { | ||
options.serial = options.serial.substring(2, options.serial.length) | ||
params.push('0x' + ('0000000000000000000000000000000000000000' + options.serial.toString(16)).slice(-40)) | ||
} else { | ||
if (helper.isHex(options.serial)) { | ||
if (options.serial.startsWith('0x')) { | ||
options.serial = options.serial.substring(2, options.serial.length) | ||
} | ||
params.push('0x' + ('0000000000000000000000000000000000000000' + options.serial).slice(-40)) | ||
} else { | ||
params.push('0x' + ('0000000000000000000000000000000000000000' + helper.toHex(options.serial)).slice(-40)) | ||
} | ||
params.push('0x' + ('0000000000000000000000000000000000000000' + options.serial).slice(-40)) | ||
} else { | ||
params.push('0x' + ('0000000000000000000000000000000000000000' + helper.toHex(options.serial)).slice(-40)) | ||
} | ||
} else { | ||
params.push('-CAcreateserial') | ||
if (options.serialFile) { | ||
params.push('-CAserial') | ||
params.push(options.serialFile + '.srl') | ||
} | ||
} | ||
if (options.serviceKeyPassword) { | ||
helper.createPasswordFile({ 'cipher': '', 'password': options.serviceKeyPassword, 'passType': 'in' }, params, delTempPWFiles[delTempPWFiles.length]) | ||
} | ||
tmpfiles.push(options.serviceCertificate) | ||
tmpfiles.push(options.serviceKey) | ||
} else { | ||
params.push('-CAcreateserial') | ||
if (options.serialFile) { | ||
params.push('-CAserial') | ||
params.push(options.serialFile + '.srl') | ||
params.push('-signkey') | ||
params.push('--TMPFILE--') | ||
if (options.serviceKeyPassword) { | ||
helper.createPasswordFile({ 'cipher': '', 'password': options.serviceKeyPassword, 'passType': 'in' }, params, delTempPWFiles[delTempPWFiles.length]) | ||
} | ||
tmpfiles.push(options.serviceKey) | ||
} | ||
if (options.serviceKeyPassword) { | ||
helper.createPasswordFile({ 'cipher': '', 'password': options.serviceKeyPassword, 'passType': 'in' }, params, delTempPWFiles) | ||
if (options.config) { | ||
params.push('-extensions') | ||
params.push('v3_req') | ||
params.push('-extfile') | ||
params.push('--TMPFILE--') | ||
tmpfiles.push(options.config) | ||
} else if (options.extFile) { | ||
params.push('-extfile') | ||
params.push(options.extFile) | ||
} else { | ||
var altNamesRep = [] | ||
if (data2 && data2.san) { | ||
for (var i = 0; i < data2.san.dns.length; i++) { | ||
altNamesRep.push('DNS' + '.' + (i + 1) + ' = ' + data2.san.dns[i]) | ||
} | ||
for (var i2 = 0; i2 < data2.san.ip.length; i2++) { | ||
altNamesRep.push('IP' + '.' + (i2 + 1) + ' = ' + data2.san.ip[i2]) | ||
} | ||
for (var i3 = 0; i3 < data2.san.email.length; i3++) { | ||
altNamesRep.push('email' + '.' + (i3 + 1) + ' = ' + data2.san.email[i3]) | ||
} | ||
params.push('-extensions') | ||
params.push('v3_req') | ||
params.push('-extfile') | ||
params.push('--TMPFILE--') | ||
tmpfiles.push([ | ||
'[v3_req]', | ||
'subjectAltName = @alt_names', | ||
'[alt_names]', | ||
altNamesRep.join('\n') | ||
].join('\n')) | ||
} | ||
} | ||
tmpfiles.push(options.serviceCertificate) | ||
tmpfiles.push(options.serviceKey) | ||
} else { | ||
params.push('-signkey') | ||
params.push('--TMPFILE--') | ||
if (options.serviceKeyPassword) { | ||
helper.createPasswordFile({ 'cipher': '', 'password': options.serviceKeyPassword, 'passType': 'in' }, params, delTempPWFiles) | ||
if (options.clientKeyPassword) { | ||
helper.createPasswordFile({ 'cipher': '', 'password': options.clientKeyPassword, 'passType': 'in' }, params, delTempPWFiles) | ||
} | ||
tmpfiles.push(options.serviceKey) | ||
} | ||
if (options.config) { | ||
params.push('-extensions') | ||
params.push('v3_req') | ||
params.push('-extfile') | ||
params.push('--TMPFILE--') | ||
tmpfiles.push(options.config) | ||
} else if (options.extFile) { | ||
params.push('-extfile') | ||
params.push(options.extFile) | ||
} | ||
if (options.clientKeyPassword) { | ||
helper.createPasswordFile({ 'cipher': '', 'password': options.clientKeyPassword, 'passType': 'in' }, params, delTempPWFiles) | ||
} | ||
openssl.exec(params, 'CERTIFICATE', tmpfiles, function (sslErr, data) { | ||
function done (err) { | ||
if (err) { | ||
return callback(err) | ||
openssl.exec(params, 'CERTIFICATE', tmpfiles, function (sslErr, data) { | ||
function done (err) { | ||
if (err) { | ||
return callback(err) | ||
} | ||
var response = { | ||
csr: options.csr, | ||
clientKey: options.clientKey, | ||
certificate: data, | ||
serviceKey: options.serviceKey | ||
} | ||
return callback(null, response) | ||
} | ||
var response = { | ||
csr: options.csr, | ||
clientKey: options.clientKey, | ||
certificate: data, | ||
serviceKey: options.serviceKey | ||
} | ||
return callback(null, response) | ||
} | ||
helper.deleteTempFiles(delTempPWFiles, function (fsErr) { | ||
done(sslErr || fsErr) | ||
helper.deleteTempFiles(delTempPWFiles, function (fsErr) { | ||
done(sslErr || fsErr) | ||
}) | ||
}) | ||
@@ -1133,3 +1166,3 @@ }) | ||
// hostnames | ||
tmp = pregMatchAll('DNS:([^,\\r\\n].*?)[,\\r\\n]', san) | ||
tmp = pregMatchAll('DNS:([^,\\r\\n].*?)[,\\r\\n\\s]', san) | ||
certValues.san.dns = tmp || '' | ||
@@ -1136,0 +1169,0 @@ |
@@ -13,3 +13,3 @@ { | ||
"description": "Create private keys and certificates with node.js and io.js", | ||
"version": "1.13.2", | ||
"version": "1.14.0", | ||
"repository": { | ||
@@ -52,3 +52,3 @@ "type": "git", | ||
"@semantic-release/npm": "^5.0.4", | ||
"ajv": "^6.0.0", | ||
"ajv": "^6.6.1", | ||
"auto-changelog": "^1.8.0", | ||
@@ -61,14 +61,14 @@ "chai": "^4.1.2", | ||
"eslint-config-standard": "^12.0.0", | ||
"eslint-plugin-import": "2.14.0", | ||
"eslint-plugin-import": "2.15.0", | ||
"eslint-plugin-json": "^1.2.1", | ||
"eslint-plugin-markdown": "^1.0.0-beta.8", | ||
"eslint-plugin-node": "^7.0.1", | ||
"eslint-plugin-node": "^8.0.0", | ||
"eslint-plugin-promise": "^4.0.1", | ||
"eslint-plugin-standard": "^4.0.0", | ||
"jsdoc": "^3.5.5", | ||
"marked": "^0.5.0", | ||
"marked": "^0.6.0", | ||
"mocha": "^5.2.0", | ||
"nyc": "^13.1.0", | ||
"semantic-release": "^15.9.15", | ||
"travis-deploy-once": "^5.0.7" | ||
"semantic-release": "^15.12.5", | ||
"travis-deploy-once": "^5.0.10" | ||
}, | ||
@@ -75,0 +75,0 @@ "engines": { |
@@ -443,2 +443,86 @@ 'use strict' | ||
describe('SAN certificate', function () { | ||
var cert | ||
it('Create default certificate', function (done) { | ||
var d = fs.readFileSync('./test/fixtures/ru_openssl.csr').toString() | ||
pem.createCertificate({ csr: d }, function (error, data) { | ||
hlp.checkError(error) | ||
hlp.checkCertificate(data) | ||
hlp.checkTmpEmpty() | ||
cert = data | ||
done() | ||
}) | ||
}) | ||
it('get its fingerprint', function (done) { | ||
pem.getFingerprint(cert.certificate, function (error, data) { | ||
hlp.checkError(error) | ||
hlp.checkFingerprint(data) | ||
hlp.checkTmpEmpty() | ||
done() | ||
}) | ||
}) | ||
it('get its modulus [not hashed]', function (done) { | ||
pem.getModulus(cert.certificate, function (error, | ||
data) { | ||
hlp.checkError(error) | ||
hlp.checkModulus(data) | ||
hlp.checkTmpEmpty() | ||
done() | ||
}) | ||
}) | ||
it('get its modulus [md5 hashed]', function (done) { | ||
pem.getModulus(cert.certificate, null, 'md5', | ||
function (error, data) { | ||
hlp.checkError(error) | ||
hlp.checkModulus(data, 'md5') | ||
hlp.checkTmpEmpty() | ||
done() | ||
}) | ||
}) | ||
it('read its data', function (done) { | ||
pem.readCertificateInfo(cert.certificate, function ( | ||
error, data) { | ||
hlp.checkError(error); | ||
['validity', 'serial', 'signatureAlgorithm', | ||
'publicKeySize', 'publicKeyAlgorithm' | ||
].forEach(function (k) { | ||
if (data[k]) { delete data[k] } | ||
}) | ||
hlp.checkCertificateData(data, { | ||
'commonName': 'Описание сайта', | ||
'country': 'RU', | ||
'dc': '', | ||
'emailAddress': 'envek@envek.name', | ||
'issuer': { | ||
'commonName': 'Описание сайта', | ||
'country': 'RU', | ||
'dc': '', | ||
'locality': 'Москва', | ||
'organization': 'Моя компания', | ||
'organizationUnit': 'Моё подразделение', | ||
'state': '' | ||
}, | ||
'locality': 'Москва', | ||
'organization': 'Моя компания', | ||
'organizationUnit': 'Моё подразделение', | ||
'san': { | ||
'dns': [ | ||
'example.com', | ||
'*.example.com' | ||
], | ||
'email': [], | ||
'ip': [] | ||
}, | ||
'state': '' | ||
}) | ||
hlp.checkTmpEmpty() | ||
done() | ||
}) | ||
}) | ||
}) | ||
describe('CA certificate', function () { | ||
@@ -445,0 +529,0 @@ var ca |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
187415
3300