working rsa pem
This commit is contained in:
		
							parent
							
								
									f0166afeeb
								
							
						
					
					
						commit
						70103de28d
					
				
							
								
								
									
										14
									
								
								app.js
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								app.js
									
									
									
									
									
								
							| @ -45,17 +45,23 @@ | |||||||
|       }; |       }; | ||||||
|       console.log('opts', opts); |       console.log('opts', opts); | ||||||
|       Keypairs.generate(opts).then(function (results) { |       Keypairs.generate(opts).then(function (results) { | ||||||
|  |         var der; | ||||||
|         if (opts.kty == 'EC') { |         if (opts.kty == 'EC') { | ||||||
|           var der = x509.packPkcs8(results.private); |           der = x509.packPkcs8(results.private); | ||||||
|           var pem = Eckles.export({ jwk: results.private }) |           var pem = Eckles.export({ jwk: results.private }) | ||||||
|           $('.js-der').innerText = JSON.stringify(der, null, 2); |  | ||||||
|           $('.js-input-pem').innerText = pem; |           $('.js-input-pem').innerText = pem; | ||||||
|           $('.js-toc-der').hidden = false; |  | ||||||
|           $('.js-toc-pem').hidden = false; |           $('.js-toc-pem').hidden = false; | ||||||
|  |         } else { | ||||||
|  |           der = x509.packPkcs8(results.private); | ||||||
|  |           var pem = Rasha.pack({ jwk: results.private }).then(function (pem) { | ||||||
|  |             $('.js-input-pem').innerText = pem; | ||||||
|  |             $('.js-toc-pem').hidden = false; | ||||||
|  |           }) | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  |         $('.js-der').innerText = JSON.stringify(der, null, 2); | ||||||
|  |         $('.js-toc-der').hidden = false; | ||||||
|         $('.js-jwk').innerText = JSON.stringify(results, null, 2); |         $('.js-jwk').innerText = JSON.stringify(results, null, 2); | ||||||
|         //
 |  | ||||||
|         $('.js-loading').hidden = true; |         $('.js-loading').hidden = true; | ||||||
|         $('.js-jwk').hidden = false; |         $('.js-jwk').hidden = false; | ||||||
|         $$('input').map(function ($el) { $el.disabled = false; }); |         $$('input').map(function ($el) { $el.disabled = false; }); | ||||||
|  | |||||||
							
								
								
									
										61
									
								
								lib/rsa.js
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								lib/rsa.js
									
									
									
									
									
								
							| @ -3,6 +3,7 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| 
 | 
 | ||||||
| var RSA = exports.Rasha = {}; | var RSA = exports.Rasha = {}; | ||||||
|  | var x509 = exports.x509; | ||||||
| if ('undefined' !== typeof module) { module.exports = RSA; } | if ('undefined' !== typeof module) { module.exports = RSA; } | ||||||
| var Enc = {}; | var Enc = {}; | ||||||
| var textEncoder = new TextEncoder(); | var textEncoder = new TextEncoder(); | ||||||
| @ -106,6 +107,66 @@ RSA.thumbprint = function (opts) { | |||||||
|   }); |   }); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | RSA.export = function (opts) { | ||||||
|  |   if (!opts || !opts.jwk || 'object' !== typeof opts.jwk) { | ||||||
|  |     throw new Error("must pass { jwk: jwk }"); | ||||||
|  |   } | ||||||
|  |   var jwk = JSON.parse(JSON.stringify(opts.jwk)); | ||||||
|  |   var format = opts.format; | ||||||
|  |   var pub = opts.public; | ||||||
|  |   if (pub || -1 !== [ 'spki', 'pkix', 'ssh', 'rfc4716' ].indexOf(format)) { | ||||||
|  |     jwk = RSA.nueter(jwk); | ||||||
|  |   } | ||||||
|  |   if ('RSA' !== jwk.kty) { | ||||||
|  |     throw new Error("options.jwk.kty must be 'RSA' for RSA keys"); | ||||||
|  |   } | ||||||
|  |   if (!jwk.p) { | ||||||
|  |     // TODO test for n and e
 | ||||||
|  |     pub = true; | ||||||
|  |     if (!format || 'pkcs1' === format) { | ||||||
|  |       format = 'pkcs1'; | ||||||
|  |     } else if (-1 !== [ 'spki', 'pkix' ].indexOf(format)) { | ||||||
|  |       format = 'spki'; | ||||||
|  |     } else if (-1 !== [ 'ssh', 'rfc4716' ].indexOf(format)) { | ||||||
|  |       format = 'ssh'; | ||||||
|  |     } else { | ||||||
|  |       throw new Error("options.format must be 'spki', 'pkcs1', or 'ssh' for public RSA keys, not (" | ||||||
|  |         + typeof format + ") " + format); | ||||||
|  |     } | ||||||
|  |   } else { | ||||||
|  |     // TODO test for all necessary keys (d, p, q ...)
 | ||||||
|  |     if (!format || 'pkcs1' === format) { | ||||||
|  |       format = 'pkcs1'; | ||||||
|  |     } else if ('pkcs8' !== format) { | ||||||
|  |       throw new Error("options.format must be 'pkcs1' or 'pkcs8' for private RSA keys"); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   if ('pkcs1' === format) { | ||||||
|  |     if (jwk.d) { | ||||||
|  |       return PEM.packBlock({ type: "RSA PRIVATE KEY", bytes: x509.packPkcs1(jwk) }); | ||||||
|  |     } else { | ||||||
|  |       return PEM.packBlock({ type: "RSA PUBLIC KEY", bytes: x509.packPkcs1(jwk) }); | ||||||
|  |     } | ||||||
|  |   } else if ('pkcs8' === format) { | ||||||
|  |     return PEM.packBlock({ type: "PRIVATE KEY", bytes: x509.packPkcs8(jwk) }); | ||||||
|  |   } else if (-1 !== [ 'spki', 'pkix' ].indexOf(format)) { | ||||||
|  |     return PEM.packBlock({ type: "PUBLIC KEY", bytes: x509.packSpki(jwk) }); | ||||||
|  |   } else if (-1 !== [ 'ssh', 'rfc4716' ].indexOf(format)) { | ||||||
|  |     return SSH.pack({ jwk: jwk, comment: opts.comment }); | ||||||
|  |   } else { | ||||||
|  |     throw new Error("Sanity Error: reached unreachable code block with format: " + format); | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | 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 RSA.export(opts); | ||||||
|  |   }); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
| Enc.bufToUrlBase64 = function (u8) { | Enc.bufToUrlBase64 = function (u8) { | ||||||
|   return Enc.bufToBase64(u8) |   return Enc.bufToBase64(u8) | ||||||
|     .replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''); |     .replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, ''); | ||||||
|  | |||||||
							
								
								
									
										61
									
								
								lib/x509.js
									
									
									
									
									
								
							
							
						
						
									
										61
									
								
								lib/x509.js
									
									
									
									
									
								
							| @ -1,7 +1,7 @@ | |||||||
| 'use strict'; | 'use strict'; | ||||||
| (function (exports) { | (function (exports) { | ||||||
|   'use strict'; |   'use strict'; | ||||||
|   var x509 = exports.x509 = {};  |   var x509 = exports.x509 = {}; | ||||||
|   var ASN1 = exports.ASN1; |   var ASN1 = exports.ASN1; | ||||||
|   var Enc = exports.Enc; |   var Enc = exports.Enc; | ||||||
| 
 | 
 | ||||||
| @ -55,6 +55,27 @@ | |||||||
|     }; |     }; | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|  |   x509.packPkcs1 = function (jwk) { | ||||||
|  |     var n = ASN1.UInt(Enc.base64ToHex(jwk.n)); | ||||||
|  |     var e = ASN1.UInt(Enc.base64ToHex(jwk.e)); | ||||||
|  |    | ||||||
|  |     if (!jwk.d) { | ||||||
|  |       return Enc.hexToBuf(ASN1('30', n, e)); | ||||||
|  |     } | ||||||
|  |    | ||||||
|  |     return Enc.hexToBuf(ASN1('30' | ||||||
|  |     , ASN1.UInt('00') | ||||||
|  |     , n | ||||||
|  |     , e | ||||||
|  |     , ASN1.UInt(Enc.base64ToHex(jwk.d)) | ||||||
|  |     , ASN1.UInt(Enc.base64ToHex(jwk.p)) | ||||||
|  |     , ASN1.UInt(Enc.base64ToHex(jwk.q)) | ||||||
|  |     , ASN1.UInt(Enc.base64ToHex(jwk.dp)) | ||||||
|  |     , ASN1.UInt(Enc.base64ToHex(jwk.dq)) | ||||||
|  |     , ASN1.UInt(Enc.base64ToHex(jwk.qi)) | ||||||
|  |     )); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|   x509.parsePkcs8 = function parseEcPkcs8(u8, jwk) { |   x509.parsePkcs8 = function parseEcPkcs8(u8, jwk) { | ||||||
|     var index = 24 + (OBJ_ID_EC.length / 2); |     var index = 24 + (OBJ_ID_EC.length / 2); | ||||||
|     var len = 32; |     var len = 32; | ||||||
| @ -141,6 +162,44 @@ | |||||||
|    * @param {*} jwk  |    * @param {*} jwk  | ||||||
|    */ |    */ | ||||||
|   x509.packPkcs8 = function (jwk) { |   x509.packPkcs8 = function (jwk) { | ||||||
|  |     if (jwk.kty == 'RSA') { | ||||||
|  |       if (!jwk.d) { | ||||||
|  |         // Public RSA
 | ||||||
|  |         return Enc.hexToBuf(ASN1('30' | ||||||
|  |           , ASN1('30' | ||||||
|  |             , ASN1('06', '2a864886f70d010101') | ||||||
|  |             , ASN1('05') | ||||||
|  |           ) | ||||||
|  |           , ASN1.BitStr(ASN1('30' | ||||||
|  |             , ASN1.UInt(Enc.base64ToHex(jwk.n)) | ||||||
|  |             , ASN1.UInt(Enc.base64ToHex(jwk.e)) | ||||||
|  |           )) | ||||||
|  |         )); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       // Private RSA
 | ||||||
|  |       return Enc.hexToBuf(ASN1('30' | ||||||
|  |         , ASN1.UInt('00') | ||||||
|  |         , ASN1('30' | ||||||
|  |           , ASN1('06', '2a864886f70d010101') | ||||||
|  |           , ASN1('05') | ||||||
|  |         ) | ||||||
|  |         , ASN1('04' | ||||||
|  |           , ASN1('30' | ||||||
|  |             , ASN1.UInt('00') | ||||||
|  |             , ASN1.UInt(Enc.base64ToHex(jwk.n)) | ||||||
|  |             , ASN1.UInt(Enc.base64ToHex(jwk.e)) | ||||||
|  |             , ASN1.UInt(Enc.base64ToHex(jwk.d)) | ||||||
|  |             , ASN1.UInt(Enc.base64ToHex(jwk.p)) | ||||||
|  |             , ASN1.UInt(Enc.base64ToHex(jwk.q)) | ||||||
|  |             , ASN1.UInt(Enc.base64ToHex(jwk.dp)) | ||||||
|  |             , ASN1.UInt(Enc.base64ToHex(jwk.dq)) | ||||||
|  |             , ASN1.UInt(Enc.base64ToHex(jwk.qi)) | ||||||
|  |           ) | ||||||
|  |         ) | ||||||
|  |       )); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     var d = Enc.base64ToHex(jwk.d); |     var d = Enc.base64ToHex(jwk.d); | ||||||
|     var x = Enc.base64ToHex(jwk.x); |     var x = Enc.base64ToHex(jwk.x); | ||||||
|     var y = Enc.base64ToHex(jwk.y); |     var y = Enc.base64ToHex(jwk.y); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user