| 
									
										
										
										
											2016-07-30 16:35:25 -04:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var forge = require('node-forge'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | function notToJson() { | 
					
						
							|  |  |  |   return undefined; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-30 19:09:37 -04:00
										 |  |  | var forgec = module.exports = { | 
					
						
							| 
									
										
										
										
											2016-07-30 16:35:25 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   //
 | 
					
						
							|  |  |  |   // to components
 | 
					
						
							|  |  |  |   //
 | 
					
						
							| 
									
										
										
										
											2016-08-01 04:03:50 -04:00
										 |  |  |   _toStandardBase64: function (str) { | 
					
						
							|  |  |  |     var b64 = str.replace(/-/g, "+").replace(/_/g, "/").replace(/=/g, ""); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     switch (b64.length % 4) { | 
					
						
							|  |  |  |       case 2: b64 += "=="; break; | 
					
						
							|  |  |  |       case 3: b64 += "="; break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return b64; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-08-02 16:42:44 -04:00
										 |  |  | , _base64UrlToBin: function (base64) { | 
					
						
							| 
									
										
										
										
											2016-08-01 04:03:50 -04:00
										 |  |  |     var std64 = forgec._toStandardBase64(base64); | 
					
						
							|  |  |  |     var hex = new Buffer(std64, 'base64').toString("hex"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return new forge.jsbn.BigInteger(hex, 16); | 
					
						
							| 
									
										
										
										
											2016-07-30 16:35:25 -04:00
										 |  |  |   } | 
					
						
							|  |  |  | , _privateJwkToComponents: function (jwk) { | 
					
						
							|  |  |  |     var components = []; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-30 23:47:52 -04:00
										 |  |  |     // [ 'n', 'e', 'd', 'p', 'q', 'dP', 'dQ', 'qInv' ]
 | 
					
						
							| 
									
										
										
										
											2016-07-30 16:35:25 -04:00
										 |  |  |     [ 'n', 'e', 'd', 'p', 'q', 'dp', 'dq', 'qi' ].forEach(function (key) { | 
					
						
							| 
									
										
										
										
											2016-08-02 16:42:44 -04:00
										 |  |  |       components.push(forgec._base64UrlToBin(jwk[key])); | 
					
						
							| 
									
										
										
										
											2016-07-30 16:35:25 -04:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return components; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | , _publicJwkToComponents: function (jwk) { | 
					
						
							|  |  |  |     var components = []; | 
					
						
							|  |  |  |     [ 'n', 'e' ].forEach(function (key) { | 
					
						
							| 
									
										
										
										
											2016-08-02 16:42:44 -04:00
										 |  |  |       components.push(forgec._base64UrlToBin(jwk[key])); | 
					
						
							| 
									
										
										
										
											2016-07-30 16:35:25 -04:00
										 |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return components; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   //
 | 
					
						
							|  |  |  |   // Generate New Keypair
 | 
					
						
							|  |  |  |   //
 | 
					
						
							|  |  |  | , generateKeypair: function (bitlen, exp, options, cb) { | 
					
						
							| 
									
										
										
										
											2016-08-01 04:03:50 -04:00
										 |  |  |     var fkeypair = forge.pki.rsa.generateKeyPair({ bits: bitlen || 1024, e: exp || 0x10001 }); | 
					
						
							| 
									
										
										
										
											2016-08-02 16:42:44 -04:00
										 |  |  |     var result = { | 
					
						
							| 
									
										
										
										
											2016-08-01 04:03:50 -04:00
										 |  |  |       _forge: fkeypair.privateKey | 
					
						
							|  |  |  |     , _forgePublic: fkeypair.publicKey | 
					
						
							| 
									
										
										
										
											2016-08-02 16:42:44 -04:00
										 |  |  |     }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     result._forge.toJSON = notToJson; | 
					
						
							|  |  |  |     result._forgePublic.toJSON = notToJson; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     cb(null, result); | 
					
						
							| 
									
										
										
										
											2016-07-30 16:35:25 -04:00
										 |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-01 04:03:50 -04:00
										 |  |  |   //
 | 
					
						
							|  |  |  |   // Import (no-op)
 | 
					
						
							|  |  |  |   //
 | 
					
						
							|  |  |  | , _forgeImportJwk: function (keypair) { | 
					
						
							| 
									
										
										
										
											2016-08-01 05:36:39 -04:00
										 |  |  |     if (!keypair._forge && keypair.privateKeyJwk) { | 
					
						
							|  |  |  |       keypair._forge = forge.pki.rsa.setPrivateKey.apply( | 
					
						
							|  |  |  |         forge.pki.rsa | 
					
						
							|  |  |  |       , forgec._privateJwkToComponents(keypair.privateKeyJwk) | 
					
						
							|  |  |  |       ); | 
					
						
							| 
									
										
										
										
											2016-08-02 16:42:44 -04:00
										 |  |  |       keypair._forge.toJSON = notToJson; | 
					
						
							| 
									
										
										
										
											2016-08-01 05:36:39 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     forgec._forgeImportPublicJwk(keypair); | 
					
						
							| 
									
										
										
										
											2016-08-01 04:03:50 -04:00
										 |  |  |   } | 
					
						
							|  |  |  | , _forgeImportPublicJwk: function (keypair) { | 
					
						
							| 
									
										
										
										
											2016-08-01 05:36:39 -04:00
										 |  |  |     if (keypair._forgePublic) { | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (keypair._forge) { | 
					
						
							|  |  |  |       keypair._forgePublic = forge.pki.rsa.setPublicKey(keypair._forge.n, keypair._forge.e); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (keypair.publicKeyJwk) { | 
					
						
							|  |  |  |       keypair._forgePublic = forge.pki.rsa.setPublicKey.apply( | 
					
						
							|  |  |  |         forge.pki.rsa | 
					
						
							|  |  |  |       , forgec._publicJwkToComponents(keypair.publicKeyJwk || keypair.privateKeyJwk) | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-08-02 16:42:44 -04:00
										 |  |  |     if (keypair._forgePublic) { | 
					
						
							|  |  |  |       keypair._forgePublic.toJSON = notToJson; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-08-01 04:03:50 -04:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-08-01 10:01:52 -04:00
										 |  |  | , _forgeImportPem: function (keypair) { | 
					
						
							|  |  |  |     if (!keypair._forge && keypair.privateKeyPem) { | 
					
						
							|  |  |  |       keypair._forge = forge.pki.privateKeyFromPem(keypair.privateKeyPem); | 
					
						
							| 
									
										
										
										
											2016-08-02 16:42:44 -04:00
										 |  |  |       keypair._forge.toJSON = notToJson; | 
					
						
							| 
									
										
										
										
											2016-08-01 10:01:52 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     forgec._forgeImportPublicPem(keypair); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | , _forgeImportPublicPem: function (keypair) { | 
					
						
							|  |  |  |     if (keypair._forgePublic) { | 
					
						
							|  |  |  |       return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (keypair._forge) { | 
					
						
							|  |  |  |       keypair._forgePublic = forge.pki.rsa.setPublicKey(keypair._forge.n, keypair._forge.e); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if (keypair.publicKeyPem) { | 
					
						
							|  |  |  |       keypair._forgePublic = keypair._forgePublic || forge.pki.publicKeyFromPem(keypair.publicKeyPem); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-08-02 16:42:44 -04:00
										 |  |  |     if (keypair._forgePublic) { | 
					
						
							|  |  |  |       keypair._forgePublic.toJSON = notToJson; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2016-08-01 10:01:52 -04:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-08-01 04:03:50 -04:00
										 |  |  | , import: function (keypair) { | 
					
						
							|  |  |  |     // no-op since this must be done anyway in extra
 | 
					
						
							|  |  |  |     return keypair; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-30 16:35:25 -04:00
										 |  |  |   //
 | 
					
						
							|  |  |  |   // Export Public / Private PEMs
 | 
					
						
							|  |  |  |   //
 | 
					
						
							| 
									
										
										
										
											2016-07-30 23:47:52 -04:00
										 |  |  | , exportPrivatePem: function (keypair) { | 
					
						
							| 
									
										
										
										
											2016-07-30 16:35:25 -04:00
										 |  |  |     if (keypair.privateKeyPem) { | 
					
						
							|  |  |  |       return keypair.privateKeyPem; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-01 09:50:46 -04:00
										 |  |  |     if (keypair.privateKeyJwk && !keypair._forge) { | 
					
						
							| 
									
										
										
										
											2016-08-01 04:03:50 -04:00
										 |  |  |       forgec._forgeImportJwk(keypair); | 
					
						
							| 
									
										
										
										
											2016-07-30 16:35:25 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-01 09:50:46 -04:00
										 |  |  |     if (keypair._forge) { | 
					
						
							| 
									
										
										
										
											2016-08-01 04:03:50 -04:00
										 |  |  |       return forge.pki.privateKeyToPem(keypair._forge); | 
					
						
							| 
									
										
										
										
											2016-07-30 16:35:25 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     throw new Error("None of privateKeyPem, _forge, or privateKeyJwk found. No way to export private key PEM"); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2016-07-30 23:47:52 -04:00
										 |  |  | , exportPublicPem: function (keypair) { | 
					
						
							| 
									
										
										
										
											2016-07-30 16:35:25 -04:00
										 |  |  |     if (keypair.publicKeyPem) { | 
					
						
							|  |  |  |       return keypair.publicKeyPem; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if ((keypair.privateKeyJwk || keypair.publicKeyJwk) | 
					
						
							| 
									
										
										
										
											2016-08-01 09:50:46 -04:00
										 |  |  |       && !(keypair._forge || keypair._forgePublic) | 
					
						
							| 
									
										
										
										
											2016-07-30 16:35:25 -04:00
										 |  |  |     ) { | 
					
						
							| 
									
										
										
										
											2016-08-01 04:03:50 -04:00
										 |  |  |       forgec._forgeImportPublicJwk(keypair); | 
					
						
							| 
									
										
										
										
											2016-07-30 16:35:25 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-01 10:01:52 -04:00
										 |  |  |     if (!keypair._forge) { | 
					
						
							|  |  |  |       if (keypair.privateKeyPem) { | 
					
						
							|  |  |  |         forgec._forgeImportPem(keypair); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (keypair.publicKeyPem) { | 
					
						
							|  |  |  |       return keypair.publicKeyPem; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (keypair._forge || keypair._forgePublic) { | 
					
						
							| 
									
										
										
										
											2016-08-01 04:03:50 -04:00
										 |  |  |       return forge.pki.publicKeyToPem(keypair._forgePublic || keypair._forge); | 
					
						
							| 
									
										
										
										
											2016-07-30 16:35:25 -04:00
										 |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-01 10:01:52 -04:00
										 |  |  |     throw new Error("None of publicKeyPem, _forge, _forgePublic, publicKeyJwk, privateKeyPem, or privateKeyJwk found. No way to export public key PEM"); | 
					
						
							| 
									
										
										
										
											2016-07-30 16:35:25 -04:00
										 |  |  |   } | 
					
						
							|  |  |  | //, exportPrivateKeyJwk: NOT IMPLEMENTED HERE
 | 
					
						
							|  |  |  | //, exportPublicKeyJwk: NOT IMPLEMENTED HERE
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | }; |