mirror of
				https://github.com/therootcompany/keypairs.js.git
				synced 2024-11-16 17:29:03 +00:00 
			
		
		
		
	Compare commits
	
		
			No commits in common. "main" and "v0.9.0" have entirely different histories.
		
	
	
		
	
		
| @ -1,6 +0,0 @@ | ||||
| { | ||||
| 	"esversion": 11, | ||||
| 	"node": true, | ||||
| 	"unused": true, | ||||
| 	"curly": true | ||||
| } | ||||
| @ -1,8 +0,0 @@ | ||||
| { | ||||
|   "bracketSpacing": true, | ||||
|   "printWidth": 80, | ||||
|   "singleQuote": true, | ||||
|   "tabWidth": 4, | ||||
|   "trailingComma": "none", | ||||
|   "useTabs": true | ||||
| } | ||||
							
								
								
									
										82
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										82
									
								
								README.md
									
									
									
									
									
								
							| @ -1,4 +1,4 @@ | ||||
| # [@root/keypairs](https://git.rootprojects.org/root/keypairs.js) | ||||
| # @root/keypairs | ||||
| 
 | ||||
| Lightweight JavaScript RSA and ECDSA utils that work on Windows, Mac, and Linux | ||||
| using modern node.js APIs (no need for C compiler). | ||||
| @ -20,8 +20,6 @@ and [Rasha.js (RSA)](https://git.coolaj86.com/coolaj86/rasha.js/). | ||||
|     -   [ ] Auth0 | ||||
| -   [ ] CLI | ||||
|     -   See [keypairs-cli](https://npmjs.com/packages/keypairs-cli/) | ||||
| -   [x] Node | ||||
| -   [x] Browsers (Webpack >=5) | ||||
| 
 | ||||
| <!-- | ||||
| 
 | ||||
| @ -42,7 +40,7 @@ A brief introduction to the APIs: | ||||
| ```js | ||||
| // generate a new keypair as jwk | ||||
| // (defaults to EC P-256 when no options are specified) | ||||
| Keypairs.generate().then(function (pair) { | ||||
| Keypairs.generate().then(function(pair) { | ||||
| 	console.log(pair.private); | ||||
| 	console.log(pair.public); | ||||
| }); | ||||
| @ -51,7 +49,7 @@ Keypairs.generate().then(function (pair) { | ||||
| ```js | ||||
| // JWK to PEM | ||||
| // (supports various 'format' and 'encoding' options) | ||||
| return Keypairs.export({ jwk: pair.private, format: 'pkcs8' }).then(function ( | ||||
| return Keypairs.export({ jwk: pair.private, format: 'pkcs8' }).then(function( | ||||
| 	pem | ||||
| ) { | ||||
| 	console.log(pem); | ||||
| @ -60,14 +58,14 @@ return Keypairs.export({ jwk: pair.private, format: 'pkcs8' }).then(function ( | ||||
| 
 | ||||
| ```js | ||||
| // PEM to JWK | ||||
| return Keypairs.import({ pem: pem }).then(function (jwk) { | ||||
| return Keypairs.import({ pem: pem }).then(function(jwk) { | ||||
| 	console.log(jwk); | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| ```js | ||||
| // Thumbprint a JWK (SHA256) | ||||
| return Keypairs.thumbprint({ jwk: jwk }).then(function (thumb) { | ||||
| return Keypairs.thumbprint({ jwk: jwk }).then(function(thumb) { | ||||
| 	console.log(thumb); | ||||
| }); | ||||
| ``` | ||||
| @ -88,72 +86,6 @@ return Keypairs.signJwt({ | ||||
| By default ECDSA keys will be used since they've had native support in node | ||||
| _much_ longer than RSA has, and they're smaller, and faster to generate. | ||||
| 
 | ||||
| ## Webpack 5+ (for Browsers) | ||||
| 
 | ||||
| This package includes native browser versions of all special functions. | ||||
| 
 | ||||
| Since Webpack 5 now fully supports vanilla JavaScript and exclusive browser builds out-of-the-box, | ||||
| it's pretty easy to create a minimal config to use Keypairs in your browser projects: | ||||
| 
 | ||||
| `webpack.config.js`: | ||||
| 
 | ||||
| ```js | ||||
| 'use strict'; | ||||
| 
 | ||||
| var path = require('path'); | ||||
| 
 | ||||
| module.exports = { | ||||
| 	entry: './main.js', | ||||
| 	mode: 'development', | ||||
| 	devServer: { | ||||
| 		contentBase: path.join(__dirname, 'dist'), | ||||
| 		port: 3001 | ||||
| 	}, | ||||
| 	output: { | ||||
| 		publicPath: 'http://localhost:3001/' | ||||
| 	}, | ||||
| 	module: { | ||||
| 		rules: [{}] | ||||
| 	}, | ||||
| 	plugins: [] | ||||
| }; | ||||
| ``` | ||||
| 
 | ||||
| `main.js`: | ||||
| 
 | ||||
| ```js | ||||
| 'use strict'; | ||||
| 
 | ||||
| var Keypairs = require('./keypairs.js'); | ||||
| 
 | ||||
| Keypairs.generate().then(function (pair) { | ||||
| 	console.log(pair.private); | ||||
| 	console.log(pair.public); | ||||
| }); | ||||
| ``` | ||||
| 
 | ||||
| `index.html`: | ||||
| 
 | ||||
| ```html | ||||
| <!DOCTYPE html> | ||||
| <html> | ||||
| 	<body> | ||||
| 		<script src="./dist/main.js"></script> | ||||
| 	</body> | ||||
| </html> | ||||
| ``` | ||||
| 
 | ||||
| ```bash | ||||
| npm install --save-dev webpack@5 | ||||
| # Or, if webpack 5 is still in beta: npm install --save-dev webpack@next | ||||
| 
 | ||||
| npm install --save-dev webpack-cli | ||||
| 
 | ||||
| npx webpack --mode=production | ||||
| 
 | ||||
| ls dist/main.js | ||||
| ``` | ||||
| 
 | ||||
| ## API Overview | ||||
| 
 | ||||
| -   generate (JWK) | ||||
| @ -192,7 +124,7 @@ Option Examples: | ||||
| Example: | ||||
| 
 | ||||
| ```js | ||||
| Keypairs.parse({ key: '...' }).catch(function (e) { | ||||
| Keypairs.parse({ key: '...' }).catch(function(e) { | ||||
| 	// could not be parsed or was a public key | ||||
| 	console.warn(e); | ||||
| 	return Keypairs.generate(); | ||||
| @ -213,7 +145,7 @@ Option Examples: | ||||
| Example: | ||||
| 
 | ||||
| ```js | ||||
| Keypairs.parseOrGenerate({ key: process.env['PRIVATE_KEY'] }).then(function ( | ||||
| Keypairs.parseOrGenerate({ key: process.env['PRIVATE_KEY'] }).then(function( | ||||
| 	pair | ||||
| ) { | ||||
| 	console.log(pair.public); | ||||
|  | ||||
| @ -23,7 +23,7 @@ if ( | ||||
| 		namedCurve: format === 'P-384' ? 'P-384' : 'P-256', | ||||
| 		encoding: format === 'der' ? 'der' : 'pem' | ||||
| 	}) | ||||
| 		.then(function (key) { | ||||
| 		.then(function(key) { | ||||
| 			if ('der' === infile || 'der' === format) { | ||||
| 				key.private = key.private.toString('binary'); | ||||
| 				key.public = key.public.toString('binary'); | ||||
| @ -31,7 +31,7 @@ if ( | ||||
| 			console.log(key.private); | ||||
| 			console.log(key.public); | ||||
| 		}) | ||||
| 		.catch(function (err) { | ||||
| 		.catch(function(err) { | ||||
| 			console.error(err); | ||||
| 			process.exit(1); | ||||
| 		}); | ||||
| @ -58,10 +58,10 @@ if ('string' === typeof key) { | ||||
| 	} | ||||
| 	var pub = -1 !== ['public', 'spki', 'pkix'].indexOf(format); | ||||
| 	Eckles.import({ pem: key, public: pub || format }) | ||||
| 		.then(function (jwk) { | ||||
| 		.then(function(jwk) { | ||||
| 			console.log(JSON.stringify(jwk, null, 2)); | ||||
| 		}) | ||||
| 		.catch(function (err) { | ||||
| 		.catch(function(err) { | ||||
| 			console.error(err); | ||||
| 			process.exit(1); | ||||
| 		}); | ||||
| @ -71,10 +71,10 @@ if ('string' === typeof key) { | ||||
| 		return; | ||||
| 	} | ||||
| 	Eckles.export({ jwk: key, format: format }) | ||||
| 		.then(function (pem) { | ||||
| 		.then(function(pem) { | ||||
| 			console.log(pem); | ||||
| 		}) | ||||
| 		.catch(function (err) { | ||||
| 		.catch(function(err) { | ||||
| 			console.error(err); | ||||
| 			process.exit(2); | ||||
| 		}); | ||||
|  | ||||
							
								
								
									
										12
									
								
								bin/rasha.js
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								bin/rasha.js
									
									
									
									
									
								
							| @ -29,7 +29,7 @@ if ( | ||||
| 		modulusLength: parseInt(format, 10) || 2048, | ||||
| 		encoding: parseInt(format, 10) ? null : format | ||||
| 	}) | ||||
| 		.then(function (key) { | ||||
| 		.then(function(key) { | ||||
| 			if ('der' === infile || 'der' === format) { | ||||
| 				key.private = key.private.toString('binary'); | ||||
| 				key.public = key.public.toString('binary'); | ||||
| @ -37,7 +37,7 @@ if ( | ||||
| 			console.info(key.private); | ||||
| 			console.info(key.public); | ||||
| 		}) | ||||
| 		.catch(function (err) { | ||||
| 		.catch(function(err) { | ||||
| 			console.error(err); | ||||
| 			process.exit(1); | ||||
| 		}); | ||||
| @ -74,10 +74,10 @@ if ('string' === typeof key) { | ||||
| 
 | ||||
| 	var pub = -1 !== ['public', 'spki', 'pkix'].indexOf(format); | ||||
| 	Rasha.import({ pem: key, public: pub || format }) | ||||
| 		.then(function (jwk) { | ||||
| 		.then(function(jwk) { | ||||
| 			console.info(JSON.stringify(jwk, null, 2)); | ||||
| 		}) | ||||
| 		.catch(function (err) { | ||||
| 		.catch(function(err) { | ||||
| 			console.error(err); | ||||
| 			process.exit(1); | ||||
| 		}); | ||||
| @ -87,14 +87,14 @@ if ('string' === typeof key) { | ||||
| 		return; | ||||
| 	} | ||||
| 	Rasha.export({ jwk: key, format: format }) | ||||
| 		.then(function (pem) { | ||||
| 		.then(function(pem) { | ||||
| 			if (sign) { | ||||
| 				signMessage(pem, msg); | ||||
| 				return; | ||||
| 			} | ||||
| 			console.info(pem); | ||||
| 		}) | ||||
| 		.catch(function (err) { | ||||
| 		.catch(function(err) { | ||||
| 			console.error(err); | ||||
| 			process.exit(2); | ||||
| 		}); | ||||
|  | ||||
							
								
								
									
										26
									
								
								ecdsa.js
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								ecdsa.js
									
									
									
									
									
								
							| @ -29,8 +29,8 @@ EC._universal = | ||||
| 	'Bluecrypt only supports crypto with standard cross-browser and cross-platform support.'; | ||||
| EC.generate = native.generate; | ||||
| 
 | ||||
| EC.export = function (opts) { | ||||
| 	return Promise.resolve().then(function () { | ||||
| EC.export = function(opts) { | ||||
| 	return Promise.resolve().then(function() { | ||||
| 		if (!opts || !opts.jwk || 'object' !== typeof opts.jwk) { | ||||
| 			throw new Error('must pass { jwk: jwk } as a JSON object'); | ||||
| 		} | ||||
| @ -109,8 +109,8 @@ EC.export = function (opts) { | ||||
| }; | ||||
| native.export = EC.export; | ||||
| 
 | ||||
| EC.import = function (opts) { | ||||
| 	return Promise.resolve().then(function () { | ||||
| EC.import = function(opts) { | ||||
| 	return Promise.resolve().then(function() { | ||||
| 		if (!opts || !opts.pem || 'string' !== typeof opts.pem) { | ||||
| 			throw new Error('must pass { pem: pem } as a string'); | ||||
| 		} | ||||
| @ -178,18 +178,18 @@ EC.import = function (opts) { | ||||
| }; | ||||
| native.import = EC.import; | ||||
| 
 | ||||
| EC.pack = function (opts) { | ||||
| 	return Promise.resolve().then(function () { | ||||
| EC.pack = function(opts) { | ||||
| 	return Promise.resolve().then(function() { | ||||
| 		return EC.export(opts); | ||||
| 	}); | ||||
| }; | ||||
| 
 | ||||
| // Chopping off the private parts is now part of the public API.
 | ||||
| // I thought it sounded a little too crude at first, but it really is the best name in every possible way.
 | ||||
| EC.neuter = function (opts) { | ||||
| EC.neuter = function(opts) { | ||||
| 	// trying to find the best balance of an immutable copy with custom attributes
 | ||||
| 	var jwk = {}; | ||||
| 	Object.keys(opts.jwk).forEach(function (k) { | ||||
| 	Object.keys(opts.jwk).forEach(function(k) { | ||||
| 		if ('undefined' === typeof opts.jwk[k]) { | ||||
| 			return; | ||||
| 		} | ||||
| @ -204,7 +204,7 @@ EC.neuter = function (opts) { | ||||
| native.neuter = EC.neuter; | ||||
| 
 | ||||
| // https://stackoverflow.com/questions/42588786/how-to-fingerprint-a-jwk
 | ||||
| EC.__thumbprint = function (jwk) { | ||||
| EC.__thumbprint = function(jwk) { | ||||
| 	// Use the same entropy for SHA as for key
 | ||||
| 	var alg = 'SHA-256'; | ||||
| 	if (/384/.test(jwk.crv)) { | ||||
| @ -218,20 +218,20 @@ EC.__thumbprint = function (jwk) { | ||||
| 		'","y":"' + | ||||
| 		jwk.y + | ||||
| 		'"}'; | ||||
| 	return sha2.sum(alg, payload).then(function (hash) { | ||||
| 	return sha2.sum(alg, payload).then(function(hash) { | ||||
| 		return Enc.bufToUrlBase64(Uint8Array.from(hash)); | ||||
| 	}); | ||||
| }; | ||||
| 
 | ||||
| EC.thumbprint = function (opts) { | ||||
| 	return Promise.resolve().then(function () { | ||||
| EC.thumbprint = function(opts) { | ||||
| 	return Promise.resolve().then(function() { | ||||
| 		var jwk; | ||||
| 		if ('EC' === opts.kty) { | ||||
| 			jwk = opts; | ||||
| 		} else if (opts.jwk) { | ||||
| 			jwk = opts.jwk; | ||||
| 		} else { | ||||
| 			return native.import(opts).then(function (jwk) { | ||||
| 			return native.import(opts).then(function(jwk) { | ||||
| 				return EC.__thumbprint(jwk); | ||||
| 			}); | ||||
| 		} | ||||
|  | ||||
							
								
								
									
										86
									
								
								keypairs.js
									
									
									
									
									
								
							
							
						
						
									
										86
									
								
								keypairs.js
									
									
									
									
									
								
							| @ -9,7 +9,7 @@ var Rasha = require('./rsa.js'); | ||||
| var Eckles = require('./ecdsa.js'); | ||||
| var native = require('./lib/node/keypairs.js'); | ||||
| 
 | ||||
| Keypairs.parse = function (opts) { | ||||
| Keypairs.parse = function(opts) { | ||||
| 	opts = opts || {}; | ||||
| 
 | ||||
| 	var err; | ||||
| @ -21,7 +21,7 @@ Keypairs.parse = function (opts) { | ||||
| 		try { | ||||
| 			jwk = JSON.parse(opts.key); | ||||
| 			p = Keypairs.export({ jwk: jwk }) | ||||
| 				.catch(function (e) { | ||||
| 				.catch(function(e) { | ||||
| 					pem = opts.key; | ||||
| 					err = new Error( | ||||
| 						"Not a valid jwk '" + | ||||
| @ -32,11 +32,11 @@ Keypairs.parse = function (opts) { | ||||
| 					err.code = 'EINVALID'; | ||||
| 					return Promise.reject(err); | ||||
| 				}) | ||||
| 				.then(function () { | ||||
| 				.then(function() { | ||||
| 					return jwk; | ||||
| 				}); | ||||
| 		} catch (e) { | ||||
| 			p = Keypairs.import({ pem: opts.key }).catch(function (e) { | ||||
| 			p = Keypairs.import({ pem: opts.key }).catch(function(e) { | ||||
| 				err = new Error( | ||||
| 					'Could not parse key (type ' + | ||||
| 						typeof opts.key + | ||||
| @ -53,10 +53,10 @@ Keypairs.parse = function (opts) { | ||||
| 		p = Promise.resolve(opts.key); | ||||
| 	} | ||||
| 
 | ||||
| 	return p.then(function (jwk) { | ||||
| 	return p.then(function(jwk) { | ||||
| 		var pubopts = JSON.parse(JSON.stringify(opts)); | ||||
| 		pubopts.jwk = jwk; | ||||
| 		return Keypairs.publish(pubopts).then(function (pub) { | ||||
| 		return Keypairs.publish(pubopts).then(function(pub) { | ||||
| 			// 'd' happens to be the name of a private part of both RSA and ECDSA keys
 | ||||
| 			if (opts.public || opts.publish || !jwk.d) { | ||||
| 				if (opts.private) { | ||||
| @ -75,13 +75,13 @@ Keypairs.parse = function (opts) { | ||||
| 	}); | ||||
| }; | ||||
| 
 | ||||
| Keypairs.parseOrGenerate = function (opts) { | ||||
| Keypairs.parseOrGenerate = function(opts) { | ||||
| 	if (!opts.key) { | ||||
| 		return Keypairs.generate(opts); | ||||
| 	} | ||||
| 	opts.private = true; | ||||
| 	return Keypairs.parse(opts).catch(function (e) { | ||||
| 		return Keypairs.generate(opts).then(function (pair) { | ||||
| 	return Keypairs.parse(opts).catch(function(e) { | ||||
| 		return Keypairs.generate(opts).then(function(pair) { | ||||
| 			pair.parseError = e; | ||||
| 			return pair; | ||||
| 		}); | ||||
| @ -93,7 +93,7 @@ Keypairs._stance = | ||||
| 	" properly and securely use non-standard crypto then you shouldn't need Bluecrypt anyway."; | ||||
| Keypairs._universal = | ||||
| 	'Bluecrypt only supports crypto with standard cross-browser and cross-platform support.'; | ||||
| Keypairs.generate = function (opts) { | ||||
| Keypairs.generate = function(opts) { | ||||
| 	opts = opts || {}; | ||||
| 	var p; | ||||
| 	if (!opts.kty) { | ||||
| @ -107,7 +107,7 @@ Keypairs.generate = function (opts) { | ||||
| 	} else if (/^RSA$/i.test(opts.kty)) { | ||||
| 		p = Rasha.generate(opts); | ||||
| 	} else { | ||||
| 		return Promise.reject( | ||||
| 		return Promise.Reject( | ||||
| 			new Error( | ||||
| 				"'" + | ||||
| 					opts.kty + | ||||
| @ -117,8 +117,8 @@ Keypairs.generate = function (opts) { | ||||
| 			) | ||||
| 		); | ||||
| 	} | ||||
| 	return p.then(function (pair) { | ||||
| 		return Keypairs.thumbprint({ jwk: pair.public }).then(function (thumb) { | ||||
| 	return p.then(function(pair) { | ||||
| 		return Keypairs.thumbprint({ jwk: pair.public }).then(function(thumb) { | ||||
| 			pair.private.kid = thumb; // maybe not the same id on the private key?
 | ||||
| 			pair.public.kid = thumb; | ||||
| 			return pair; | ||||
| @ -126,22 +126,22 @@ Keypairs.generate = function (opts) { | ||||
| 	}); | ||||
| }; | ||||
| 
 | ||||
| Keypairs.import = function (opts) { | ||||
| Keypairs.import = function(opts) { | ||||
| 	return Eckles.import(opts) | ||||
| 		.catch(function () { | ||||
| 		.catch(function() { | ||||
| 			return Rasha.import(opts); | ||||
| 		}) | ||||
| 		.then(function (jwk) { | ||||
| 			return Keypairs.thumbprint({ jwk: jwk }).then(function (thumb) { | ||||
| 		.then(function(jwk) { | ||||
| 			return Keypairs.thumbprint({ jwk: jwk }).then(function(thumb) { | ||||
| 				jwk.kid = thumb; | ||||
| 				return jwk; | ||||
| 			}); | ||||
| 		}); | ||||
| }; | ||||
| 
 | ||||
| Keypairs.export = function (opts) { | ||||
| 	return Eckles.export(opts).catch(function (err) { | ||||
| 		return Rasha.export(opts).catch(function () { | ||||
| Keypairs.export = function(opts) { | ||||
| 	return Eckles.export(opts).catch(function(err) { | ||||
| 		return Rasha.export(opts).catch(function() { | ||||
| 			return Promise.reject(err); | ||||
| 		}); | ||||
| 	}); | ||||
| @ -153,10 +153,10 @@ native.export = Keypairs.export; | ||||
|  * Chopping off the private parts is now part of the public API. | ||||
|  * I thought it sounded a little too crude at first, but it really is the best name in every possible way. | ||||
|  */ | ||||
| Keypairs.neuter = function (opts) { | ||||
| Keypairs.neuter = function(opts) { | ||||
| 	/** trying to find the best balance of an immutable copy with custom attributes */ | ||||
| 	var jwk = {}; | ||||
| 	Object.keys(opts.jwk).forEach(function (k) { | ||||
| 	Object.keys(opts.jwk).forEach(function(k) { | ||||
| 		if ('undefined' === typeof opts.jwk[k]) { | ||||
| 			return; | ||||
| 		} | ||||
| @ -169,8 +169,8 @@ Keypairs.neuter = function (opts) { | ||||
| 	return jwk; | ||||
| }; | ||||
| 
 | ||||
| Keypairs.thumbprint = function (opts) { | ||||
| 	return Promise.resolve().then(function () { | ||||
| Keypairs.thumbprint = function(opts) { | ||||
| 	return Promise.resolve().then(function() { | ||||
| 		if (/EC/i.test(opts.jwk.kty)) { | ||||
| 			return Eckles.thumbprint(opts); | ||||
| 		} else { | ||||
| @ -179,7 +179,7 @@ Keypairs.thumbprint = function (opts) { | ||||
| 	}); | ||||
| }; | ||||
| 
 | ||||
| Keypairs.publish = function (opts) { | ||||
| Keypairs.publish = function(opts) { | ||||
| 	if ('object' !== typeof opts.jwk || !opts.jwk.kty) { | ||||
| 		throw new Error('invalid jwk: ' + JSON.stringify(opts.jwk)); | ||||
| 	} | ||||
| @ -205,20 +205,20 @@ Keypairs.publish = function (opts) { | ||||
| 	if (jwk.kid) { | ||||
| 		return Promise.resolve(jwk); | ||||
| 	} | ||||
| 	return Keypairs.thumbprint({ jwk: jwk }).then(function (thumb) { | ||||
| 	return Keypairs.thumbprint({ jwk: jwk }).then(function(thumb) { | ||||
| 		jwk.kid = thumb; | ||||
| 		return jwk; | ||||
| 	}); | ||||
| }; | ||||
| 
 | ||||
| // JWT a.k.a. JWS with Claims using Compact Serialization
 | ||||
| Keypairs.signJwt = function (opts) { | ||||
| 	return Keypairs.thumbprint({ jwk: opts.jwk }).then(function (thumb) { | ||||
| Keypairs.signJwt = function(opts) { | ||||
| 	return Keypairs.thumbprint({ jwk: opts.jwk }).then(function(thumb) { | ||||
| 		var header = opts.header || {}; | ||||
| 		var claims = JSON.parse(JSON.stringify(opts.claims || {})); | ||||
| 		header.typ = 'JWT'; | ||||
| 
 | ||||
| 		if (!header.kid && !header.jwk && false !== header.kid) { | ||||
| 		if (!header.kid && false !== header.kid) { | ||||
| 			header.kid = thumb; | ||||
| 		} | ||||
| 		if (!header.alg && opts.alg) { | ||||
| @ -260,14 +260,14 @@ Keypairs.signJwt = function (opts) { | ||||
| 			protected: header, | ||||
| 			header: undefined, | ||||
| 			payload: claims | ||||
| 		}).then(function (jws) { | ||||
| 		}).then(function(jws) { | ||||
| 			return [jws.protected, jws.payload, jws.signature].join('.'); | ||||
| 		}); | ||||
| 	}); | ||||
| }; | ||||
| 
 | ||||
| Keypairs.signJws = function (opts) { | ||||
| 	return Keypairs.thumbprint(opts).then(function (thumb) { | ||||
| Keypairs.signJws = function(opts) { | ||||
| 	return Keypairs.thumbprint(opts).then(function(thumb) { | ||||
| 		function alg() { | ||||
| 			if (!opts.jwk) { | ||||
| 				throw new Error("opts.jwk must exist and must declare 'typ'"); | ||||
| @ -294,19 +294,19 @@ Keypairs.signJws = function (opts) { | ||||
| 				if (!protect.alg) { | ||||
| 					protect.alg = alg(); | ||||
| 				} | ||||
| 
 | ||||
| 				// There's a particular request where ACME / Let's Encrypt explicitly doesn't use a kid
 | ||||
| 				// There should be a kid unless it's `false` or there's a `jwk` (a self-signed JWS)
 | ||||
| 				if (!protect.kid) { | ||||
| 					if (false === protect.kid) { | ||||
| 						protect.kid = undefined; | ||||
| 					} else if (!protect.jwk) { | ||||
| 						protect.kid = thumb; | ||||
| 					} | ||||
| 				if (false === protect.kid) { | ||||
| 					protect.kid = undefined; | ||||
| 				} else if (!protect.kid) { | ||||
| 					protect.kid = thumb; | ||||
| 				} | ||||
| 				protectedHeader = JSON.stringify(protect); | ||||
| 			} | ||||
| 
 | ||||
| 			// Not sure how to handle the empty case since ACME POST-as-GET must be empty
 | ||||
| 			//if (!payload) {
 | ||||
| 			//  throw new Error("opts.payload should be JSON, string, or ArrayBuffer (it may be empty, but that must be explicit)");
 | ||||
| 			//}
 | ||||
| 			// Trying to detect if it's a plain object (not Buffer, ArrayBuffer, Array, Uint8Array, etc)
 | ||||
| 			if ( | ||||
| 				payload && | ||||
| @ -325,7 +325,7 @@ Keypairs.signJws = function (opts) { | ||||
| 			var payload64 = Enc.bufToUrlBase64(payload); | ||||
| 			var msg = protected64 + '.' + payload64; | ||||
| 
 | ||||
| 			return native._sign(opts, msg).then(function (buf) { | ||||
| 			return native._sign(opts, msg).then(function(buf) { | ||||
| 				var signedMsg = { | ||||
| 					protected: protected64, | ||||
| 					payload: payload64, | ||||
| @ -339,7 +339,7 @@ Keypairs.signJws = function (opts) { | ||||
| 		if (opts.jwk) { | ||||
| 			return sign(); | ||||
| 		} else { | ||||
| 			return Keypairs.import({ pem: opts.pem }).then(function (pair) { | ||||
| 			return Keypairs.import({ pem: opts.pem }).then(function(pair) { | ||||
| 				opts.jwk = pair.private; | ||||
| 				return sign(); | ||||
| 			}); | ||||
| @ -350,7 +350,7 @@ Keypairs.signJws = function (opts) { | ||||
| // TODO expose consistently
 | ||||
| Keypairs.sign = native._sign; | ||||
| 
 | ||||
| Keypairs._getBits = function (opts) { | ||||
| Keypairs._getBits = function(opts) { | ||||
| 	if (opts.alg) { | ||||
| 		return opts.alg.replace(/[a-z\-]/gi, ''); | ||||
| 	} | ||||
|  | ||||
| @ -4,7 +4,7 @@ var native = module.exports; | ||||
| // XXX received from caller
 | ||||
| var EC = native; | ||||
| 
 | ||||
| native.generate = function (opts) { | ||||
| native.generate = function(opts) { | ||||
| 	var wcOpts = {}; | ||||
| 	if (!opts) { | ||||
| 		opts = {}; | ||||
| @ -41,10 +41,10 @@ native.generate = function (opts) { | ||||
| 	var extractable = true; | ||||
| 	return window.crypto.subtle | ||||
| 		.generateKey(wcOpts, extractable, ['sign', 'verify']) | ||||
| 		.then(function (result) { | ||||
| 		.then(function(result) { | ||||
| 			return window.crypto.subtle | ||||
| 				.exportKey('jwk', result.privateKey) | ||||
| 				.then(function (privJwk) { | ||||
| 				.then(function(privJwk) { | ||||
| 					privJwk.key_ops = undefined; | ||||
| 					privJwk.ext = undefined; | ||||
| 					return { | ||||
|  | ||||
| @ -2,8 +2,8 @@ | ||||
| 
 | ||||
| var Keypairs = module.exports; | ||||
| 
 | ||||
| Keypairs._sign = function (opts, payload) { | ||||
| 	return Keypairs._import(opts).then(function (privkey) { | ||||
| Keypairs._sign = function(opts, payload) { | ||||
| 	return Keypairs._import(opts).then(function(privkey) { | ||||
| 		if ('string' === typeof payload) { | ||||
| 			payload = new TextEncoder().encode(payload); | ||||
| 		} | ||||
| @ -17,7 +17,7 @@ Keypairs._sign = function (opts, payload) { | ||||
| 				privkey, | ||||
| 				payload | ||||
| 			) | ||||
| 			.then(function (signature) { | ||||
| 			.then(function(signature) { | ||||
| 				signature = new Uint8Array(signature); // ArrayBuffer -> u8
 | ||||
| 				// This will come back into play for CSRs, but not for JOSE
 | ||||
| 				if ('EC' === opts.jwk.kty && /x509|asn1/i.test(opts.format)) { | ||||
| @ -30,8 +30,8 @@ Keypairs._sign = function (opts, payload) { | ||||
| 	}); | ||||
| }; | ||||
| 
 | ||||
| Keypairs._import = function (opts) { | ||||
| 	return Promise.resolve().then(function () { | ||||
| Keypairs._import = function(opts) { | ||||
| 	return Promise.resolve().then(function() { | ||||
| 		var ops; | ||||
| 		// all private keys just happen to have a 'd'
 | ||||
| 		if (opts.jwk.d) { | ||||
| @ -55,7 +55,7 @@ Keypairs._import = function (opts) { | ||||
| 				true, | ||||
| 				ops | ||||
| 			) | ||||
| 			.then(function (privkey) { | ||||
| 			.then(function(privkey) { | ||||
| 				delete opts.jwk.ext; | ||||
| 				return privkey; | ||||
| 			}); | ||||
| @ -64,7 +64,7 @@ Keypairs._import = function (opts) { | ||||
| 
 | ||||
| // ECDSA JOSE / JWS / JWT signatures differ from "normal" ASN1/X509 ECDSA signatures
 | ||||
| // https://tools.ietf.org/html/rfc7518#section-3.4
 | ||||
| Keypairs._ecdsaJoseSigToAsn1Sig = function (bufsig) { | ||||
| Keypairs._ecdsaJoseSigToAsn1Sig = function(bufsig) { | ||||
| 	// it's easier to do the manipulation in the browser with an array
 | ||||
| 	bufsig = Array.from(bufsig); | ||||
| 	var hlen = bufsig.length / 2; // should be even
 | ||||
| @ -99,7 +99,7 @@ Keypairs._ecdsaJoseSigToAsn1Sig = function (bufsig) { | ||||
| 	); | ||||
| }; | ||||
| 
 | ||||
| Keypairs._getName = function (opts) { | ||||
| Keypairs._getName = function(opts) { | ||||
| 	if (/EC/i.test(opts.jwk.kty)) { | ||||
| 		return 'ECDSA'; | ||||
| 	} else { | ||||
|  | ||||
| @ -4,7 +4,7 @@ var native = module.exports; | ||||
| // XXX added by caller: _stance, neuter
 | ||||
| var RSA = native; | ||||
| 
 | ||||
| native.generate = function (opts) { | ||||
| native.generate = function(opts) { | ||||
| 	var wcOpts = {}; | ||||
| 	if (!opts) { | ||||
| 		opts = {}; | ||||
| @ -46,10 +46,10 @@ native.generate = function (opts) { | ||||
| 	var extractable = true; | ||||
| 	return window.crypto.subtle | ||||
| 		.generateKey(wcOpts, extractable, ['sign', 'verify']) | ||||
| 		.then(function (result) { | ||||
| 		.then(function(result) { | ||||
| 			return window.crypto.subtle | ||||
| 				.exportKey('jwk', result.privateKey) | ||||
| 				.then(function (privJwk) { | ||||
| 				.then(function(privJwk) { | ||||
| 					return { | ||||
| 						private: privJwk, | ||||
| 						public: RSA.neuter({ jwk: privJwk }) | ||||
|  | ||||
| @ -3,13 +3,11 @@ | ||||
| var sha2 = module.exports; | ||||
| 
 | ||||
| var encoder = new TextEncoder(); | ||||
| sha2.sum = function (alg, str) { | ||||
| sha2.sum = function(alg, str) { | ||||
| 	var data = str; | ||||
| 	if ('string' === typeof data) { | ||||
| 		data = encoder.encode(str); | ||||
| 	} | ||||
| 	var sha = 'SHA-' + String(alg).replace(/^sha-?/i, ''); | ||||
| 	return window.crypto.subtle.digest(sha, data).then(function (buf) { | ||||
| 		return new Uint8Array(buf); | ||||
| 	}); | ||||
| 	return window.crypto.subtle.digest(sha, data); | ||||
| }; | ||||
|  | ||||
| @ -5,8 +5,8 @@ var native = module.exports; | ||||
| var EC = native; | ||||
| // TODO SSH
 | ||||
| 
 | ||||
| native.generate = function (opts) { | ||||
| 	return Promise.resolve().then(function () { | ||||
| native.generate = function(opts) { | ||||
| 	return Promise.resolve().then(function() { | ||||
| 		var typ = 'ec'; | ||||
| 		var format = opts.format; | ||||
| 		var encoding = opts.encoding; | ||||
| @ -48,7 +48,7 @@ native.generate = function (opts) { | ||||
| 			pub = { type: 'spki', format: 'pem' }; | ||||
| 		} | ||||
| 
 | ||||
| 		return new Promise(function (resolve, reject) { | ||||
| 		return new Promise(function(resolve, reject) { | ||||
| 			return require('crypto').generateKeyPair( | ||||
| 				typ, | ||||
| 				{ | ||||
| @ -56,7 +56,7 @@ native.generate = function (opts) { | ||||
| 					privateKeyEncoding: priv, | ||||
| 					publicKeyEncoding: pub | ||||
| 				}, | ||||
| 				function (err, pubkey, privkey) { | ||||
| 				function(err, pubkey, privkey) { | ||||
| 					if (err) { | ||||
| 						reject(err); | ||||
| 					} | ||||
| @ -66,7 +66,7 @@ native.generate = function (opts) { | ||||
| 					}); | ||||
| 				} | ||||
| 			); | ||||
| 		}).then(function (keypair) { | ||||
| 		}).then(function(keypair) { | ||||
| 			if ('jwk' === format) { | ||||
| 				return Promise.all([ | ||||
| 					native.import({ | ||||
| @ -78,7 +78,7 @@ native.generate = function (opts) { | ||||
| 						format: pub.type, | ||||
| 						public: true | ||||
| 					}) | ||||
| 				]).then(function (pair) { | ||||
| 				]).then(function(pair) { | ||||
| 					return { | ||||
| 						private: pair[0], | ||||
| 						public: pair[1] | ||||
| @ -96,12 +96,12 @@ native.generate = function (opts) { | ||||
| 					format: format, | ||||
| 					public: true | ||||
| 				}) | ||||
| 				.then(function (jwk) { | ||||
| 				.then(function(jwk) { | ||||
| 					return EC.export({ | ||||
| 						jwk: jwk, | ||||
| 						format: opts.format, | ||||
| 						public: true | ||||
| 					}).then(function (pub) { | ||||
| 					}).then(function(pub) { | ||||
| 						return { | ||||
| 							private: keypair.private, | ||||
| 							public: pub | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | ||||
| 'use strict'; | ||||
| 
 | ||||
| module.exports = function (bitlen, exp) { | ||||
| module.exports = function(bitlen, exp) { | ||||
| 	var k = require('node-forge').pki.rsa.generateKeyPair({ | ||||
| 		bits: bitlen || 2048, | ||||
| 		e: exp || 0x10001 | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | ||||
| 'use strict'; | ||||
| 
 | ||||
| module.exports = function (bitlen, exp) { | ||||
| module.exports = function(bitlen, exp) { | ||||
| 	var keypair = require('crypto').generateKeyPairSync('rsa', { | ||||
| 		modulusLength: bitlen, | ||||
| 		publicExponent: exp, | ||||
|  | ||||
| @ -4,7 +4,7 @@ | ||||
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | ||||
| 'use strict'; | ||||
| 
 | ||||
| module.exports = function (bitlen, exp) { | ||||
| module.exports = function(bitlen, exp) { | ||||
| 	var ursa; | ||||
| 	try { | ||||
| 		ursa = require('ursa'); | ||||
| @ -13,7 +13,10 @@ module.exports = function (bitlen, exp) { | ||||
| 	} | ||||
| 	var keypair = ursa.generatePrivateKey(bitlen, exp); | ||||
| 	var result = { | ||||
| 		privateKeyPem: keypair.toPrivatePem().toString('ascii').trim() | ||||
| 		privateKeyPem: keypair | ||||
| 			.toPrivatePem() | ||||
| 			.toString('ascii') | ||||
| 			.trim() | ||||
| 	}; | ||||
| 	return result; | ||||
| }; | ||||
|  | ||||
| @ -6,7 +6,7 @@ | ||||
| 
 | ||||
| var oldver = false; | ||||
| 
 | ||||
| module.exports = function (bitlen, exp) { | ||||
| module.exports = function(bitlen, exp) { | ||||
| 	bitlen = parseInt(bitlen, 10) || 2048; | ||||
| 	exp = parseInt(exp, 10) || 65537; | ||||
| 
 | ||||
|  | ||||
| @ -3,14 +3,17 @@ | ||||
| var Keypairs = module.exports; | ||||
| var crypto = require('crypto'); | ||||
| 
 | ||||
| Keypairs._sign = function (opts, payload) { | ||||
| 	return Keypairs._import(opts).then(function (pem) { | ||||
| Keypairs._sign = function(opts, payload) { | ||||
| 	return Keypairs._import(opts).then(function(pem) { | ||||
| 		payload = Buffer.from(payload); | ||||
| 
 | ||||
| 		// node specifies RSA-SHAxxx even when it's actually ecdsa (it's all encoded x509 shasums anyway)
 | ||||
| 		// TODO opts.alg = (protect||header).alg
 | ||||
| 		var nodeAlg = 'SHA' + Keypairs._getBits(opts); | ||||
| 		var binsig = crypto.createSign(nodeAlg).update(payload).sign(pem); | ||||
| 		var binsig = crypto | ||||
| 			.createSign(nodeAlg) | ||||
| 			.update(payload) | ||||
| 			.sign(pem); | ||||
| 
 | ||||
| 		if ('EC' === opts.jwk.kty && !/x509|asn1/i.test(opts.format)) { | ||||
| 			// ECDSA JWT signatures differ from "normal" ECDSA signatures
 | ||||
| @ -22,7 +25,7 @@ Keypairs._sign = function (opts, payload) { | ||||
| 	}); | ||||
| }; | ||||
| 
 | ||||
| Keypairs._import = function (opts) { | ||||
| Keypairs._import = function(opts) { | ||||
| 	if (opts.pem && opts.jwk) { | ||||
| 		return Promise.resolve(opts.pem); | ||||
| 	} else { | ||||
| @ -31,7 +34,7 @@ Keypairs._import = function (opts) { | ||||
| 	} | ||||
| }; | ||||
| 
 | ||||
| Keypairs._ecdsaAsn1SigToJoseSig = function (binsig) { | ||||
| Keypairs._ecdsaAsn1SigToJoseSig = function(binsig) { | ||||
| 	// should have asn1 sequence header of 0x30
 | ||||
| 	if (0x30 !== binsig[0]) { | ||||
| 		throw new Error('Impossible EC SHA head marker'); | ||||
|  | ||||
| @ -7,9 +7,9 @@ var RSA = native; | ||||
| var PEM = require('@root/pem'); | ||||
| var X509 = require('@root/x509'); | ||||
| 
 | ||||
| native.generate = function (opts) { | ||||
| native.generate = function(opts) { | ||||
| 	opts.kty = 'RSA'; | ||||
| 	return native._generate(opts).then(function (pair) { | ||||
| 	return native._generate(opts).then(function(pair) { | ||||
| 		var format = opts.format; | ||||
| 		var encoding = opts.encoding; | ||||
| 
 | ||||
| @ -74,23 +74,23 @@ native.generate = function (opts) { | ||||
| 		} | ||||
| 
 | ||||
| 		var exOpts = { jwk: pair.private, format: format, encoding: encoding }; | ||||
| 		return RSA.export(exOpts).then(function (priv) { | ||||
| 		return RSA.export(exOpts).then(function(priv) { | ||||
| 			exOpts.public = true; | ||||
| 			if ('pkcs8' === exOpts.format) { | ||||
| 				exOpts.format = 'spki'; | ||||
| 			} | ||||
| 			return RSA.export(exOpts).then(function (pub) { | ||||
| 			return RSA.export(exOpts).then(function(pub) { | ||||
| 				return { private: priv, public: pub }; | ||||
| 			}); | ||||
| 		}); | ||||
| 	}); | ||||
| }; | ||||
| 
 | ||||
| native._generate = function (opts) { | ||||
| native._generate = function(opts) { | ||||
| 	if (!opts) { | ||||
| 		opts = {}; | ||||
| 	} | ||||
| 	return new Promise(function (resolve, reject) { | ||||
| 	return new Promise(function(resolve, reject) { | ||||
| 		try { | ||||
| 			var modlen = opts.modulusLength || 2048; | ||||
| 			var exp = opts.publicExponent || 0x10001; | ||||
|  | ||||
| @ -4,11 +4,14 @@ | ||||
| var sha2 = module.exports; | ||||
| var crypto = require('crypto'); | ||||
| 
 | ||||
| sha2.sum = function (alg, str) { | ||||
| 	return Promise.resolve().then(function () { | ||||
| sha2.sum = function(alg, str) { | ||||
| 	return Promise.resolve().then(function() { | ||||
| 		var sha = 'sha' + String(alg).replace(/^sha-?/i, ''); | ||||
| 		// utf8 is the default for strings
 | ||||
| 		var buf = Buffer.from(str); | ||||
| 		return crypto.createHash(sha).update(buf).digest(); | ||||
| 		return crypto | ||||
| 			.createHash(sha) | ||||
| 			.update(buf) | ||||
| 			.digest(); | ||||
| 	}); | ||||
| }; | ||||
|  | ||||
							
								
								
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -1,6 +1,6 @@ | ||||
| { | ||||
| 	"name": "@root/keypairs", | ||||
| 	"version": "0.10.2", | ||||
| 	"version": "0.9.0", | ||||
| 	"lockfileVersion": 1, | ||||
| 	"requires": true, | ||||
| 	"dependencies": { | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| { | ||||
| 	"name": "@root/keypairs", | ||||
| 	"version": "0.10.2", | ||||
| 	"version": "0.9.0", | ||||
| 	"description": "Lightweight, Zero-Dependency RSA and EC/ECDSA crypto for Node.js and Browsers", | ||||
| 	"main": "keypairs.js", | ||||
| 	"browser": { | ||||
| @ -20,7 +20,7 @@ | ||||
| 	], | ||||
| 	"repository": { | ||||
| 		"type": "git", | ||||
| 		"url": "https://github.com/therootcompany/keypairs.js.git" | ||||
| 		"url": "https://git.rootprojects.org/root/csr.js.git" | ||||
| 	}, | ||||
| 	"keywords": [ | ||||
| 		"ASN.1", | ||||
|  | ||||
							
								
								
									
										26
									
								
								rsa.js
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								rsa.js
									
									
									
									
									
								
							| @ -20,10 +20,10 @@ RSA.generate = native.generate; | ||||
| 
 | ||||
| // Chopping off the private parts is now part of the public API.
 | ||||
| // I thought it sounded a little too crude at first, but it really is the best name in every possible way.
 | ||||
| RSA.neuter = function (opts) { | ||||
| RSA.neuter = function(opts) { | ||||
| 	// trying to find the best balance of an immutable copy with custom attributes
 | ||||
| 	var jwk = {}; | ||||
| 	Object.keys(opts.jwk).forEach(function (k) { | ||||
| 	Object.keys(opts.jwk).forEach(function(k) { | ||||
| 		if ('undefined' === typeof opts.jwk[k]) { | ||||
| 			return; | ||||
| 		} | ||||
| @ -38,7 +38,7 @@ RSA.neuter = function (opts) { | ||||
| native.neuter = RSA.neuter; | ||||
| 
 | ||||
| // https://stackoverflow.com/questions/42588786/how-to-fingerprint-a-jwk
 | ||||
| RSA.__thumbprint = function (jwk) { | ||||
| RSA.__thumbprint = function(jwk) { | ||||
| 	// Use the same entropy for SHA as for key
 | ||||
| 	var len = Math.floor(jwk.n.length * 0.75); | ||||
| 	var alg = 'SHA-256'; | ||||
| @ -51,20 +51,20 @@ RSA.__thumbprint = function (jwk) { | ||||
| 	} | ||||
| 	return sha2 | ||||
| 		.sum(alg, '{"e":"' + jwk.e + '","kty":"RSA","n":"' + jwk.n + '"}') | ||||
| 		.then(function (hash) { | ||||
| 		.then(function(hash) { | ||||
| 			return Enc.bufToUrlBase64(Uint8Array.from(hash)); | ||||
| 		}); | ||||
| }; | ||||
| 
 | ||||
| RSA.thumbprint = function (opts) { | ||||
| 	return Promise.resolve().then(function () { | ||||
| RSA.thumbprint = function(opts) { | ||||
| 	return Promise.resolve().then(function() { | ||||
| 		var jwk; | ||||
| 		if ('EC' === opts.kty) { | ||||
| 			jwk = opts; | ||||
| 		} else if (opts.jwk) { | ||||
| 			jwk = opts.jwk; | ||||
| 		} else { | ||||
| 			return RSA.import(opts).then(function (jwk) { | ||||
| 			return RSA.import(opts).then(function(jwk) { | ||||
| 				return RSA.__thumbprint(jwk); | ||||
| 			}); | ||||
| 		} | ||||
| @ -72,8 +72,8 @@ RSA.thumbprint = function (opts) { | ||||
| 	}); | ||||
| }; | ||||
| 
 | ||||
| RSA.export = function (opts) { | ||||
| 	return Promise.resolve().then(function () { | ||||
| RSA.export = function(opts) { | ||||
| 	return Promise.resolve().then(function() { | ||||
| 		if (!opts || !opts.jwk || 'object' !== typeof opts.jwk) { | ||||
| 			throw new Error('must pass { jwk: jwk }'); | ||||
| 		} | ||||
| @ -152,16 +152,16 @@ RSA.export = function (opts) { | ||||
| }; | ||||
| native.export = RSA.export; | ||||
| 
 | ||||
| RSA.pack = function (opts) { | ||||
| RSA.pack = function(opts) { | ||||
| 	// wrapped in a promise for API compatibility
 | ||||
| 	// with the forthcoming browser version
 | ||||
| 	// (and potential future native node capability)
 | ||||
| 	return Promise.resolve().then(function () { | ||||
| 	return Promise.resolve().then(function() { | ||||
| 		return RSA.export(opts); | ||||
| 	}); | ||||
| }; | ||||
| 
 | ||||
| RSA._importSync = function (opts) { | ||||
| RSA._importSync = function(opts) { | ||||
| 	if (!opts || !opts.pem || 'string' !== typeof opts.pem) { | ||||
| 		throw new Error('must pass { pem: pem } as a string'); | ||||
| 	} | ||||
| @ -185,7 +185,7 @@ RSA.parse = function parseRsa(opts) { | ||||
| 	// wrapped in a promise for API compatibility
 | ||||
| 	// with the forthcoming browser version
 | ||||
| 	// (and potential future native node capability)
 | ||||
| 	return Promise.resolve().then(function () { | ||||
| 	return Promise.resolve().then(function() { | ||||
| 		return RSA._importSync(opts); | ||||
| 	}); | ||||
| }; | ||||
|  | ||||
| @ -4,7 +4,7 @@ var Keypairs = require('../'); | ||||
| 
 | ||||
| /* global Promise*/ | ||||
| Keypairs.parseOrGenerate({ key: null }) | ||||
| 	.then(function (pair) { | ||||
| 	.then(function(pair) { | ||||
| 		// should NOT have any warning output
 | ||||
| 		if (!pair.private || !pair.public) { | ||||
| 			throw new Error('missing key pairs'); | ||||
| @ -12,42 +12,42 @@ Keypairs.parseOrGenerate({ key: null }) | ||||
| 
 | ||||
| 		return Promise.all([ | ||||
| 			// Testing Public Part of key
 | ||||
| 			Keypairs.export({ jwk: pair.public }).then(function (pem) { | ||||
| 			Keypairs.export({ jwk: pair.public }).then(function(pem) { | ||||
| 				if (!/--BEGIN PUBLIC/.test(pem)) { | ||||
| 					throw new Error('did not export public pem'); | ||||
| 				} | ||||
| 				return Promise.all([ | ||||
| 					Keypairs.parse({ key: pem }).then(function (pair) { | ||||
| 					Keypairs.parse({ key: pem }).then(function(pair) { | ||||
| 						if (pair.private) { | ||||
| 							throw new Error("shouldn't have private part"); | ||||
| 						} | ||||
| 						return true; | ||||
| 					}), | ||||
| 					Keypairs.parse({ key: pem, private: true }) | ||||
| 						.then(function () { | ||||
| 						.then(function() { | ||||
| 							var err = new Error( | ||||
| 								'should have thrown an error when private key was required and public pem was given' | ||||
| 							); | ||||
| 							err.code = 'NOERR'; | ||||
| 							throw err; | ||||
| 						}) | ||||
| 						.catch(function (e) { | ||||
| 						.catch(function(e) { | ||||
| 							if ('NOERR' === e.code) { | ||||
| 								throw e; | ||||
| 							} | ||||
| 							return true; | ||||
| 						}) | ||||
| 				]).then(function () { | ||||
| 				]).then(function() { | ||||
| 					return true; | ||||
| 				}); | ||||
| 			}), | ||||
| 			// Testing Private Part of Key
 | ||||
| 			Keypairs.export({ jwk: pair.private }).then(function (pem) { | ||||
| 			Keypairs.export({ jwk: pair.private }).then(function(pem) { | ||||
| 				if (!/--BEGIN .*PRIVATE KEY--/.test(pem)) { | ||||
| 					throw new Error('did not export private pem: ' + pem); | ||||
| 				} | ||||
| 				return Promise.all([ | ||||
| 					Keypairs.parse({ key: pem }).then(function (pair) { | ||||
| 					Keypairs.parse({ key: pem }).then(function(pair) { | ||||
| 						if (!pair.private) { | ||||
| 							throw new Error('should have private part'); | ||||
| 						} | ||||
| @ -56,7 +56,7 @@ Keypairs.parseOrGenerate({ key: null }) | ||||
| 						} | ||||
| 						return true; | ||||
| 					}), | ||||
| 					Keypairs.parse({ key: pem, public: true }).then(function ( | ||||
| 					Keypairs.parse({ key: pem, public: true }).then(function( | ||||
| 						pair | ||||
| 					) { | ||||
| 						if (pair.private) { | ||||
| @ -69,12 +69,12 @@ Keypairs.parseOrGenerate({ key: null }) | ||||
| 						} | ||||
| 						return true; | ||||
| 					}) | ||||
| 				]).then(function () { | ||||
| 				]).then(function() { | ||||
| 					return true; | ||||
| 				}); | ||||
| 			}), | ||||
| 			Keypairs.parseOrGenerate({ key: 'not a key', public: true }).then( | ||||
| 				function (pair) { | ||||
| 				function(pair) { | ||||
| 					// SHOULD have warning output
 | ||||
| 					if (!pair.private || !pair.public) { | ||||
| 						throw new Error( | ||||
| @ -89,18 +89,18 @@ Keypairs.parseOrGenerate({ key: null }) | ||||
| 					return true; | ||||
| 				} | ||||
| 			), | ||||
| 			Keypairs.parse({ key: JSON.stringify(pair.private) }).then( | ||||
| 				function (pair) { | ||||
| 					if (!pair.private || !pair.public) { | ||||
| 						throw new Error('missing key pairs (stringified jwt)'); | ||||
| 					} | ||||
| 					return true; | ||||
| 			Keypairs.parse({ key: JSON.stringify(pair.private) }).then(function( | ||||
| 				pair | ||||
| 			) { | ||||
| 				if (!pair.private || !pair.public) { | ||||
| 					throw new Error('missing key pairs (stringified jwt)'); | ||||
| 				} | ||||
| 			), | ||||
| 				return true; | ||||
| 			}), | ||||
| 			Keypairs.parse({ | ||||
| 				key: JSON.stringify(pair.private), | ||||
| 				public: true | ||||
| 			}).then(function (pair) { | ||||
| 			}).then(function(pair) { | ||||
| 				if (pair.private) { | ||||
| 					throw new Error("has private key when it shouldn't"); | ||||
| 				} | ||||
| @ -110,14 +110,14 @@ Keypairs.parseOrGenerate({ key: null }) | ||||
| 				return true; | ||||
| 			}), | ||||
| 			Keypairs.parse({ key: JSON.stringify(pair.public), private: true }) | ||||
| 				.then(function () { | ||||
| 				.then(function() { | ||||
| 					var err = new Error( | ||||
| 						'should have thrown an error when private key was required and public jwk was given' | ||||
| 					); | ||||
| 					err.code = 'NOERR'; | ||||
| 					throw err; | ||||
| 				}) | ||||
| 				.catch(function (e) { | ||||
| 				.catch(function(e) { | ||||
| 					if ('NOERR' === e.code) { | ||||
| 						throw e; | ||||
| 					} | ||||
| @ -130,7 +130,7 @@ Keypairs.parseOrGenerate({ key: null }) | ||||
| 				alg: 'ES256', | ||||
| 				iss: 'https://example.com/', | ||||
| 				exp: '1h' | ||||
| 			}).then(function (jwt) { | ||||
| 			}).then(function(jwt) { | ||||
| 				var parts = jwt.split('.'); | ||||
| 				var now = Math.round(Date.now() / 1000); | ||||
| 				var token = { | ||||
| @ -144,10 +144,10 @@ Keypairs.parseOrGenerate({ key: null }) | ||||
| 				} | ||||
| 				throw new Error('token was not properly generated'); | ||||
| 			}) | ||||
| 		]).then(function (results) { | ||||
| 		]).then(function(results) { | ||||
| 			if ( | ||||
| 				results.length && | ||||
| 				results.every(function (v) { | ||||
| 				results.every(function(v) { | ||||
| 					return true === v; | ||||
| 				}) | ||||
| 			) { | ||||
| @ -158,7 +158,7 @@ Keypairs.parseOrGenerate({ key: null }) | ||||
| 			} | ||||
| 		}); | ||||
| 	}) | ||||
| 	.catch(function (e) { | ||||
| 	.catch(function(e) { | ||||
| 		console.error('Caught an unexpected (failing) error:'); | ||||
| 		console.error(e); | ||||
| 		process.exit(1); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user