| 
									
										
										
										
											2015-12-15 03:39:01 -08:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var crypto = require('crypto'); | 
					
						
							|  |  |  | var ursa = require('ursa'); | 
					
						
							|  |  |  | var forge = require('node-forge'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function binstr2b64(binstr) { | 
					
						
							|  |  |  |   return new Buffer(binstr, 'binary').toString('base64'); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function toAcmePrivateKey(privkeyPem) { | 
					
						
							|  |  |  |   var forgePrivkey = forge.pki.privateKeyFromPem(privkeyPem); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     kty: "RSA" | 
					
						
							|  |  |  |   , n: binstr2b64(forgePrivkey.n) | 
					
						
							|  |  |  |   , e: binstr2b64(forgePrivkey.e) | 
					
						
							|  |  |  |   , d: binstr2b64(forgePrivkey.d) | 
					
						
							|  |  |  |   , p: binstr2b64(forgePrivkey.p) | 
					
						
							|  |  |  |   , q: binstr2b64(forgePrivkey.q) | 
					
						
							|  |  |  |   , dp: binstr2b64(forgePrivkey.dP) | 
					
						
							|  |  |  |   , dq: binstr2b64(forgePrivkey.dQ) | 
					
						
							|  |  |  |   , qi: binstr2b64(forgePrivkey.qInv) | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function generateRsaKeypair(bitlen, exp, cb) { | 
					
						
							|  |  |  |   var keypair = ursa.generatePrivateKey(bitlen /*|| 2048*/, exp /*65537*/); | 
					
						
							|  |  |  |   var pems = { | 
					
						
							| 
									
										
										
										
											2015-12-15 13:11:19 +00:00
										 |  |  |     publicKeyPem: keypair.toPublicPem().toString('ascii')   // ascii PEM: ----BEGIN...
 | 
					
						
							|  |  |  |   , privateKeyPem: keypair.toPrivatePem().toString('ascii') // ascii PEM: ----BEGIN...
 | 
					
						
							| 
									
										
										
										
											2015-12-15 03:39:01 -08:00
										 |  |  |   }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-15 12:45:36 +00:00
										 |  |  |   // I would have chosen sha1 or sha2... but whatever
 | 
					
						
							| 
									
										
										
										
											2015-12-15 03:39:01 -08:00
										 |  |  |   pems.publicKeyMd5 = crypto.createHash('md5').update(pems.publicKeyPem).digest('hex'); | 
					
						
							| 
									
										
										
										
											2015-12-15 12:45:36 +00:00
										 |  |  |   // json { n: ..., e: ..., iq: ..., etc }
 | 
					
						
							|  |  |  |   pems.privateKeyJwk = toAcmePrivateKey(pems.privateKeyPem); | 
					
						
							|  |  |  |   pems.privateKeyJson = pems.privateKeyJwk; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-15 03:39:01 -08:00
										 |  |  |   // TODO thumbprint
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   cb(null, pems); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function parseAccountPrivateKey(pkj, cb) { | 
					
						
							|  |  |  |   Object.keys(pkj).forEach(function (key) { | 
					
						
							|  |  |  |     pkj[key] = new Buffer(pkj[key], 'base64'); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   var priv; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   try { | 
					
						
							|  |  |  |     priv = ursa.createPrivateKeyFromComponents( | 
					
						
							|  |  |  |       pkj.n // modulus
 | 
					
						
							|  |  |  |     , pkj.e // exponent
 | 
					
						
							|  |  |  |     , pkj.p | 
					
						
							|  |  |  |     , pkj.q | 
					
						
							|  |  |  |     , pkj.dp | 
					
						
							|  |  |  |     , pkj.dq | 
					
						
							|  |  |  |     , pkj.qi | 
					
						
							|  |  |  |     , pkj.d | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   } catch(e) { | 
					
						
							|  |  |  |     cb(e); | 
					
						
							|  |  |  |     return; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   cb(null, { | 
					
						
							|  |  |  |     privateKeyPem: priv.toPrivatePem.toString('ascii') | 
					
						
							| 
									
										
										
										
											2015-12-15 13:11:19 +00:00
										 |  |  |   , publicKeyPem: priv.toPublicPem.toString('ascii') | 
					
						
							| 
									
										
										
										
											2015-12-15 03:39:01 -08:00
										 |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports.parseAccountPrivateKey = parseAccountPrivateKey; | 
					
						
							|  |  |  | module.exports.generateRsaKeypair = generateRsaKeypair; | 
					
						
							|  |  |  | module.exports.toAcmePrivateKey = toAcmePrivateKey; |