node-forge
Advanced tools
Comparing version 0.7.6 to 0.8.0
Forge ChangeLog | ||
=============== | ||
## 0.8.0 - 2019-01-31 | ||
### Fixed | ||
- Handle creation of certificates with `notBefore` and `notAfter` dates less | ||
than Jan 1, 1950 or greater than or equal to Jan 1, 2050. | ||
### Added | ||
- Add OID 2.5.4.13 "description". | ||
- Add OID 2.16.840.1.113730.1.13 "nsComment". | ||
- Also handle extension when creating a certificate. | ||
- `pki.verifyCertificateChain`: | ||
- Add `validityCheckDate` option to allow checking the certificate validity | ||
period against an arbitrary `Date` or `null` for no check at all. The | ||
current date is used by default. | ||
- `tls.createConnection`: | ||
- Add `verifyOptions` option that passes through to | ||
`pki.verifyCertificateChain`. Can be used for the above `validityCheckDate` | ||
option. | ||
### Changed | ||
- Support WebCrypto API in web workers. | ||
- `rsa.generateKeyPair`: | ||
- Use `crypto.generateKeyPair`/`crypto.generateKeyPairSync` on Node.js if | ||
available (10.12.0+) and not in pure JS mode. | ||
- Use JS fallback in `rsa.generateKeyPair` if `prng` option specified since | ||
this isn't supported by current native APIs. | ||
- Only run key generation comparison tests if keys will be deterministic. | ||
- PhantomJS is deprecated, now using Headless Chrome with Karma. | ||
- **Note**: Using Headless Chrome vs PhantomJS may cause newer JS features to | ||
slip into releases without proper support for older runtimes and browsers. | ||
Please report such issues and they will be addressed. | ||
- `pki.verifyCertificateChain`: | ||
- Signature changed to `(caStore, chain, options)`. Older `(caStore, chain, | ||
verify)` signature is still supported. New style is to to pass in a | ||
`verify` option. | ||
## 0.7.6 - 2018-08-14 | ||
@@ -5,0 +41,0 @@ |
@@ -111,5 +111,7 @@ /** | ||
_IN('2.5.4.11', 'organizationalUnitName'); | ||
_IN('2.5.4.13', 'description'); | ||
// X.509 extension OIDs | ||
_IN('2.16.840.1.113730.1.1', 'nsCertType'); | ||
_IN('2.16.840.1.113730.1.13', 'nsComment'); // deprecated in theory; still widely used | ||
_I_('2.5.29.1', 'authorityKeyIdentifier'); // deprecated, use .35 | ||
@@ -116,0 +118,0 @@ _I_('2.5.29.2', 'keyAttributes'); // obsolete use .37 or .15 |
@@ -270,9 +270,8 @@ /** | ||
var getRandomValues = null; | ||
if(typeof window !== 'undefined') { | ||
var _crypto = window.crypto || window.msCrypto; | ||
if(_crypto && _crypto.getRandomValues) { | ||
getRandomValues = function(arr) { | ||
return _crypto.getRandomValues(arr); | ||
}; | ||
} | ||
var globalScope = forge.util.globalScope; | ||
var _crypto = globalScope.crypto || globalScope.msCrypto; | ||
if(_crypto && _crypto.getRandomValues) { | ||
getRandomValues = function(arr) { | ||
return _crypto.getRandomValues(arr); | ||
}; | ||
} | ||
@@ -279,0 +278,0 @@ |
@@ -118,10 +118,10 @@ /** | ||
var getRandomValues = null; | ||
if(typeof window !== 'undefined') { | ||
var _crypto = window.crypto || window.msCrypto; | ||
if(_crypto && _crypto.getRandomValues) { | ||
getRandomValues = function(arr) { | ||
return _crypto.getRandomValues(arr); | ||
}; | ||
} | ||
var globalScope = forge.util.globalScope; | ||
var _crypto = globalScope.crypto || globalScope.msCrypto; | ||
if(_crypto && _crypto.getRandomValues) { | ||
getRandomValues = function(arr) { | ||
return _crypto.getRandomValues(arr); | ||
}; | ||
} | ||
if(forge.options.usePureJavaScript || | ||
@@ -128,0 +128,0 @@ (!forge.util.isNodejs && !getRandomValues)) { |
184
lib/rsa.js
@@ -77,5 +77,10 @@ /** | ||
var _crypto = forge.util.isNodejs ? require('crypto') : null; | ||
// shortcut for asn.1 API | ||
var asn1 = forge.asn1; | ||
// shortcut for util API | ||
var util = forge.util; | ||
/* | ||
@@ -88,2 +93,3 @@ * RSA encryption and decryption, see RFC 2313. | ||
// for finding primes, which are 30k+i for i = 1, 7, 11, 13, 17, 19, 23, 29 | ||
@@ -825,3 +831,3 @@ var GCD_30_DELTA = [6, 4, 2, 4, 2, 4, 6, 2]; | ||
* @param [options] options for key-pair generation, if given then 'bits' | ||
* and 'e' must *not* be given: | ||
* and 'e' must *not* be given: | ||
* bits the size for the private key in bits, (default: 2048). | ||
@@ -836,3 +842,3 @@ * e the public exponent to use, (default: 65537 (0x10001)). | ||
* prng a custom crypto-secure pseudo-random number generator to use, | ||
* that must define "getBytesSync". | ||
* that must define "getBytesSync". Disables use of native APIs. | ||
* algorithm the algorithm to use (default: 'PRIMEINC'). | ||
@@ -890,59 +896,104 @@ * @param [callback(err, keypair)] called once the operation completes. | ||
// if native code is permitted and a callback is given, use native | ||
// key generation code if available and if parameters are acceptable | ||
if(!forge.options.usePureJavaScript && callback && | ||
// use native code if permitted, available, and parameters are acceptable | ||
if(!forge.options.usePureJavaScript && !options.prng && | ||
bits >= 256 && bits <= 16384 && (e === 0x10001 || e === 3)) { | ||
if(_detectSubtleCrypto('generateKey') && _detectSubtleCrypto('exportKey')) { | ||
// use standard native generateKey | ||
return window.crypto.subtle.generateKey({ | ||
name: 'RSASSA-PKCS1-v1_5', | ||
modulusLength: bits, | ||
publicExponent: _intToUint8Array(e), | ||
hash: {name: 'SHA-256'} | ||
}, true /* key can be exported*/, ['sign', 'verify']) | ||
.then(function(pair) { | ||
return window.crypto.subtle.exportKey('pkcs8', pair.privateKey); | ||
// avoiding catch(function(err) {...}) to support IE <= 8 | ||
}).then(undefined, function(err) { | ||
callback(err); | ||
}).then(function(pkcs8) { | ||
if(pkcs8) { | ||
var privateKey = pki.privateKeyFromAsn1( | ||
asn1.fromDer(forge.util.createBuffer(pkcs8))); | ||
if(callback) { | ||
// try native async | ||
if(_detectNodeCrypto('generateKeyPair')) { | ||
return _crypto.generateKeyPair('rsa', { | ||
modulusLength: bits, | ||
publicExponent: e, | ||
publicKeyEncoding: { | ||
type: 'spki', | ||
format: 'pem' | ||
}, | ||
privateKeyEncoding: { | ||
type: 'pkcs8', | ||
format: 'pem' | ||
} | ||
}, function(err, pub, priv) { | ||
if (err) { | ||
return callback(err); | ||
} | ||
callback(null, { | ||
privateKey: privateKey, | ||
publicKey: pki.setRsaPublicKey(privateKey.n, privateKey.e) | ||
privateKey: pki.privateKeyFromPem(priv), | ||
publicKey: pki.publicKeyFromPem(pub) | ||
}); | ||
} | ||
}); | ||
} | ||
if(_detectSubtleMsCrypto('generateKey') && | ||
_detectSubtleMsCrypto('exportKey')) { | ||
var genOp = window.msCrypto.subtle.generateKey({ | ||
name: 'RSASSA-PKCS1-v1_5', | ||
modulusLength: bits, | ||
publicExponent: _intToUint8Array(e), | ||
hash: {name: 'SHA-256'} | ||
}, true /* key can be exported*/, ['sign', 'verify']); | ||
genOp.oncomplete = function(e) { | ||
var pair = e.target.result; | ||
var exportOp = window.msCrypto.subtle.exportKey( | ||
'pkcs8', pair.privateKey); | ||
exportOp.oncomplete = function(e) { | ||
var pkcs8 = e.target.result; | ||
var privateKey = pki.privateKeyFromAsn1( | ||
asn1.fromDer(forge.util.createBuffer(pkcs8))); | ||
callback(null, { | ||
privateKey: privateKey, | ||
publicKey: pki.setRsaPublicKey(privateKey.n, privateKey.e) | ||
}); | ||
}); | ||
} | ||
if(_detectSubtleCrypto('generateKey') && _detectSubtleCrypto('exportKey')) { | ||
// use standard native generateKey | ||
return util.globalScope.crypto.subtle.generateKey({ | ||
name: 'RSASSA-PKCS1-v1_5', | ||
modulusLength: bits, | ||
publicExponent: _intToUint8Array(e), | ||
hash: {name: 'SHA-256'} | ||
}, true /* key can be exported*/, ['sign', 'verify']) | ||
.then(function(pair) { | ||
return util.globalScope.crypto.subtle.exportKey( | ||
'pkcs8', pair.privateKey); | ||
// avoiding catch(function(err) {...}) to support IE <= 8 | ||
}).then(undefined, function(err) { | ||
callback(err); | ||
}).then(function(pkcs8) { | ||
if(pkcs8) { | ||
var privateKey = pki.privateKeyFromAsn1( | ||
asn1.fromDer(forge.util.createBuffer(pkcs8))); | ||
callback(null, { | ||
privateKey: privateKey, | ||
publicKey: pki.setRsaPublicKey(privateKey.n, privateKey.e) | ||
}); | ||
} | ||
}); | ||
} | ||
if(_detectSubtleMsCrypto('generateKey') && | ||
_detectSubtleMsCrypto('exportKey')) { | ||
var genOp = util.globalScope.msCrypto.subtle.generateKey({ | ||
name: 'RSASSA-PKCS1-v1_5', | ||
modulusLength: bits, | ||
publicExponent: _intToUint8Array(e), | ||
hash: {name: 'SHA-256'} | ||
}, true /* key can be exported*/, ['sign', 'verify']); | ||
genOp.oncomplete = function(e) { | ||
var pair = e.target.result; | ||
var exportOp = util.globalScope.msCrypto.subtle.exportKey( | ||
'pkcs8', pair.privateKey); | ||
exportOp.oncomplete = function(e) { | ||
var pkcs8 = e.target.result; | ||
var privateKey = pki.privateKeyFromAsn1( | ||
asn1.fromDer(forge.util.createBuffer(pkcs8))); | ||
callback(null, { | ||
privateKey: privateKey, | ||
publicKey: pki.setRsaPublicKey(privateKey.n, privateKey.e) | ||
}); | ||
}; | ||
exportOp.onerror = function(err) { | ||
callback(err); | ||
}; | ||
}; | ||
exportOp.onerror = function(err) { | ||
genOp.onerror = function(err) { | ||
callback(err); | ||
}; | ||
}; | ||
genOp.onerror = function(err) { | ||
callback(err); | ||
}; | ||
return; | ||
return; | ||
} | ||
} else { | ||
// try native sync | ||
if(_detectNodeCrypto('generateKeyPairSync')) { | ||
var keypair = _crypto.generateKeyPairSync('rsa', { | ||
modulusLength: bits, | ||
publicExponent: e, | ||
publicKeyEncoding: { | ||
type: 'spki', | ||
format: 'pem' | ||
}, | ||
privateKeyEncoding: { | ||
type: 'pkcs8', | ||
format: 'pem' | ||
} | ||
}); | ||
return { | ||
privateKey: pki.privateKeyFromPem(keypair.privateKey), | ||
publicKey: pki.publicKeyFromPem(keypair.publicKey) | ||
}; | ||
} | ||
} | ||
@@ -1736,2 +1787,13 @@ } | ||
/** | ||
* Performs feature detection on the Node crypto interface. | ||
* | ||
* @param fn the feature (function) to detect. | ||
* | ||
* @return true if detected, false if not. | ||
*/ | ||
function _detectNodeCrypto(fn) { | ||
return forge.util.isNodejs && typeof _crypto[fn] === 'function'; | ||
} | ||
/** | ||
* Performs feature detection on the SubtleCrypto interface. | ||
@@ -1744,6 +1806,6 @@ * | ||
function _detectSubtleCrypto(fn) { | ||
return (typeof window !== 'undefined' && | ||
typeof window.crypto === 'object' && | ||
typeof window.crypto.subtle === 'object' && | ||
typeof window.crypto.subtle[fn] === 'function'); | ||
return (typeof util.globalScope !== 'undefined' && | ||
typeof util.globalScope.crypto === 'object' && | ||
typeof util.globalScope.crypto.subtle === 'object' && | ||
typeof util.globalScope.crypto.subtle[fn] === 'function'); | ||
} | ||
@@ -1761,6 +1823,6 @@ | ||
function _detectSubtleMsCrypto(fn) { | ||
return (typeof window !== 'undefined' && | ||
typeof window.msCrypto === 'object' && | ||
typeof window.msCrypto.subtle === 'object' && | ||
typeof window.msCrypto.subtle[fn] === 'function'); | ||
return (typeof util.globalScope !== 'undefined' && | ||
typeof util.globalScope.msCrypto === 'object' && | ||
typeof util.globalScope.msCrypto.subtle === 'object' && | ||
typeof util.globalScope.msCrypto.subtle[fn] === 'function'); | ||
} | ||
@@ -1767,0 +1829,0 @@ |
{ | ||
"name": "node-forge", | ||
"version": "0.7.6", | ||
"version": "0.8.0", | ||
"description": "JavaScript implementations of network transports, cryptography, ciphers, PKI, message digests, and various utilities.", | ||
@@ -24,4 +24,4 @@ "homepage": "https://github.com/digitalbazaar/forge", | ||
"jshint": "^2.9.5", | ||
"karma": "^2.0.0", | ||
"karma-browserify": "^5.2.0", | ||
"karma": "^3.1.4", | ||
"karma-browserify": "^6.0.0", | ||
"karma-chrome-launcher": "^2.2.0", | ||
@@ -33,3 +33,2 @@ "karma-edge-launcher": "^0.4.2", | ||
"karma-mocha-reporter": "^2.2.5", | ||
"karma-phantomjs-launcher": "^1.0.2", | ||
"karma-safari-launcher": "^1.0.0", | ||
@@ -39,9 +38,10 @@ "karma-sauce-launcher": "^1.2.0", | ||
"karma-tap-reporter": "0.0.6", | ||
"karma-webpack": "^2.0.13", | ||
"karma-webpack": "^3.0.5", | ||
"mocha": "^5.0.1", | ||
"mocha-lcov-reporter": "^1.2.0", | ||
"nodejs-websocket": "^1.7.1", | ||
"nyc": "^11.5.0", | ||
"nyc": "^13.1.0", | ||
"opts": "^1.2.2", | ||
"webpack": "^3.11.0" | ||
"webpack": "^3.11.0", | ||
"worker-loader": "^2.0.0" | ||
}, | ||
@@ -48,0 +48,0 @@ "repository": { |
@@ -212,4 +212,2 @@ # Forge | ||
See the [testing README](./tests/README.md) for full details. | ||
### Prepare to run tests | ||
@@ -225,6 +223,6 @@ | ||
### Running automated tests with PhantomJS | ||
### Running automated tests with Headless Chrome | ||
Automated testing is done via [Karma][]. By default it will run the tests in a | ||
headless manner with PhantomJS. | ||
Automated testing is done via [Karma][]. By default it will run the tests with | ||
Headless Chrome. | ||
@@ -246,3 +244,3 @@ npm run test-karma | ||
npm run test-karma -- --browsers Chrome,Firefox,Safari,PhantomJS | ||
npm run test-karma -- --browsers Chrome,Firefox,Safari,ChromeHeadless | ||
@@ -967,4 +965,4 @@ The reporter option and `BUNDLER` environment variable can also be used. | ||
// generate an RSA key pair synchronously | ||
// *NOT RECOMMENDED* -- can be significantly slower than async and will not | ||
// use native APIs if available. | ||
// *NOT RECOMMENDED*: Can be significantly slower than async and may block | ||
// JavaScript execution. Will use native Node.js 10.12.0+ API if possible. | ||
var keypair = rsa.generateKeyPair({bits: 2048, e: 0x10001}); | ||
@@ -974,4 +972,4 @@ | ||
// use workers: -1 to run a fast core estimator to optimize # of workers | ||
// *RECOMMENDED* - can be significantly faster than sync -- and will use | ||
// native APIs if available. | ||
// *RECOMMENDED*: Can be significantly faster than sync. Will use native | ||
// Node.js 10.12.0+ or WebCrypto API if possible. | ||
rsa.generateKeyPair({bits: 2048, workers: 2}, function(err, keypair) { | ||
@@ -2047,4 +2045,4 @@ // keypair.privateKey, keypair.publicKey | ||
* http://digitalbazaar.com/2010/07/20/javascript-tls-1/ | ||
* http://digitalbazaar.com/2010/07/20/javascript-tls-2/ | ||
* https://digitalbazaar.com/2010/07/20/javascript-tls-1/ | ||
* https://digitalbazaar.com/2010/07/20/javascript-tls-2/ | ||
@@ -2069,38 +2067,38 @@ Contact | ||
[0.6.x]: https://github.com/digitalbazaar/forge/tree/0.6.x | ||
[3DES]: http://en.wikipedia.org/wiki/Triple_DES | ||
[AES]: http://en.wikipedia.org/wiki/Advanced_Encryption_Standard | ||
[ASN.1]: http://en.wikipedia.org/wiki/ASN.1 | ||
[3DES]: https://en.wikipedia.org/wiki/Triple_DES | ||
[AES]: https://en.wikipedia.org/wiki/Advanced_Encryption_Standard | ||
[ASN.1]: https://en.wikipedia.org/wiki/ASN.1 | ||
[Bower]: https://bower.io/ | ||
[Browserify]: http://browserify.org/ | ||
[CBC]: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation | ||
[CFB]: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation | ||
[CTR]: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation | ||
[CBC]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation | ||
[CFB]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation | ||
[CTR]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation | ||
[CommonJS]: https://en.wikipedia.org/wiki/CommonJS | ||
[DES]: http://en.wikipedia.org/wiki/Data_Encryption_Standard | ||
[ECB]: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation | ||
[Fortuna]: http://en.wikipedia.org/wiki/Fortuna_(PRNG) | ||
[GCM]: http://en.wikipedia.org/wiki/GCM_mode | ||
[HMAC]: http://en.wikipedia.org/wiki/HMAC | ||
[JavaScript]: http://en.wikipedia.org/wiki/JavaScript | ||
[DES]: https://en.wikipedia.org/wiki/Data_Encryption_Standard | ||
[ECB]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation | ||
[Fortuna]: https://en.wikipedia.org/wiki/Fortuna_(PRNG) | ||
[GCM]: https://en.wikipedia.org/wiki/GCM_mode | ||
[HMAC]: https://en.wikipedia.org/wiki/HMAC | ||
[JavaScript]: https://en.wikipedia.org/wiki/JavaScript | ||
[Karma]: https://karma-runner.github.io/ | ||
[MD5]: http://en.wikipedia.org/wiki/MD5 | ||
[Node.js]: http://nodejs.org/ | ||
[OFB]: http://en.wikipedia.org/wiki/Block_cipher_mode_of_operation | ||
[PKCS#10]: http://en.wikipedia.org/wiki/Certificate_signing_request | ||
[PKCS#12]: http://en.wikipedia.org/wiki/PKCS_%E2%99%AF12 | ||
[PKCS#5]: http://en.wikipedia.org/wiki/PKCS | ||
[PKCS#7]: http://en.wikipedia.org/wiki/Cryptographic_Message_Syntax | ||
[MD5]: https://en.wikipedia.org/wiki/MD5 | ||
[Node.js]: https://nodejs.org/ | ||
[OFB]: https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation | ||
[PKCS#10]: https://en.wikipedia.org/wiki/Certificate_signing_request | ||
[PKCS#12]: https://en.wikipedia.org/wiki/PKCS_%E2%99%AF12 | ||
[PKCS#5]: https://en.wikipedia.org/wiki/PKCS | ||
[PKCS#7]: https://en.wikipedia.org/wiki/Cryptographic_Message_Syntax | ||
[PayPal]: https://www.paypal.com/ | ||
[RC2]: http://en.wikipedia.org/wiki/RC2 | ||
[SHA-1]: http://en.wikipedia.org/wiki/SHA-1 | ||
[SHA-256]: http://en.wikipedia.org/wiki/SHA-256 | ||
[SHA-384]: http://en.wikipedia.org/wiki/SHA-384 | ||
[SHA-512]: http://en.wikipedia.org/wiki/SHA-512 | ||
[RC2]: https://en.wikipedia.org/wiki/RC2 | ||
[SHA-1]: https://en.wikipedia.org/wiki/SHA-1 | ||
[SHA-256]: https://en.wikipedia.org/wiki/SHA-256 | ||
[SHA-384]: https://en.wikipedia.org/wiki/SHA-384 | ||
[SHA-512]: https://en.wikipedia.org/wiki/SHA-512 | ||
[Subresource Integrity]: https://www.w3.org/TR/SRI/ | ||
[TLS]: http://en.wikipedia.org/wiki/Transport_Layer_Security | ||
[TLS]: https://en.wikipedia.org/wiki/Transport_Layer_Security | ||
[UMD]: https://github.com/umdjs/umd | ||
[X.509]: http://en.wikipedia.org/wiki/X.509 | ||
[X.509]: https://en.wikipedia.org/wiki/X.509 | ||
[freenode]: https://freenode.net/ | ||
[unpkg]: https://unpkg.com/ | ||
[webpack]: https://webpack.github.io/ | ||
[TweetNaCl]: https://github.com/dchest/tweetnacl-js | ||
[TweetNaCl.js]: https://github.com/dchest/tweetnacl-js |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
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
1682003
31563
2098