forked from root/acme.js
		
	display all ASN.1/x509 formats
This commit is contained in:
		
							parent
							
								
									b2174e3923
								
							
						
					
					
						commit
						76621560cb
					
				
							
								
								
									
										69
									
								
								app.js
									
									
									
									
									
								
							
							
						
						
									
										69
									
								
								app.js
									
									
									
									
									
								
							@ -2,6 +2,9 @@
 | 
				
			|||||||
  'use strict';
 | 
					  'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  var Keypairs = window.Keypairs;
 | 
					  var Keypairs = window.Keypairs;
 | 
				
			||||||
 | 
					  var Rasha = window.Rasha;
 | 
				
			||||||
 | 
					  var Eckles = window.Eckles;
 | 
				
			||||||
 | 
					  var x509 = window.x509;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function $(sel) {
 | 
					  function $(sel) {
 | 
				
			||||||
    return document.querySelector(sel);
 | 
					    return document.querySelector(sel);
 | 
				
			||||||
@ -35,9 +38,10 @@
 | 
				
			|||||||
      $('.js-loading').hidden = false;
 | 
					      $('.js-loading').hidden = false;
 | 
				
			||||||
      $('.js-jwk').hidden = true;
 | 
					      $('.js-jwk').hidden = true;
 | 
				
			||||||
      $('.js-toc-der-public').hidden = true;
 | 
					      $('.js-toc-der-public').hidden = true;
 | 
				
			||||||
      $('.js-toc-pem-public').hidden = true;
 | 
					 | 
				
			||||||
      $('.js-toc-der-private').hidden = true;
 | 
					      $('.js-toc-der-private').hidden = true;
 | 
				
			||||||
      $('.js-toc-pem-private').hidden = true;
 | 
					      $$('.js-toc-pem').forEach(function ($el) {
 | 
				
			||||||
 | 
					        $el.hidden = true;
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
      $$('input').map(function ($el) { $el.disabled = true; });
 | 
					      $$('input').map(function ($el) { $el.disabled = true; });
 | 
				
			||||||
      $$('button').map(function ($el) { $el.disabled = true; });
 | 
					      $$('button').map(function ($el) { $el.disabled = true; });
 | 
				
			||||||
      var opts = {
 | 
					      var opts = {
 | 
				
			||||||
@ -47,32 +51,47 @@
 | 
				
			|||||||
      };
 | 
					      };
 | 
				
			||||||
      console.log('opts', opts);
 | 
					      console.log('opts', opts);
 | 
				
			||||||
      Keypairs.generate(opts).then(function (results) {
 | 
					      Keypairs.generate(opts).then(function (results) {
 | 
				
			||||||
        var der_public, der_private;
 | 
					        var pubDer;
 | 
				
			||||||
        if (opts.kty == 'EC') {
 | 
					        var privDer;
 | 
				
			||||||
          der_public = x509.packSpki(results.public);
 | 
					        if (/EC/i.test(opts.kty)) {
 | 
				
			||||||
          der_private = x509.packPkcs8(results.private);
 | 
					          privDer = x509.packPkcs8(results.private);
 | 
				
			||||||
          var pem_private = Eckles.export({ jwk: results.private })
 | 
					          pubDer = x509.packSpki(results.public);
 | 
				
			||||||
          var pem_public = Eckles.export({ jwk: results.public, public: true })
 | 
					          Eckles.export({ jwk: results.private, format: 'sec1' }).then(function (pem) {
 | 
				
			||||||
          $('.js-input-pem-public').innerText = pem_public;
 | 
					            $('.js-input-pem-sec1-private').innerText = pem;
 | 
				
			||||||
          $('.js-toc-pem-public').hidden = false;
 | 
					            $('.js-toc-pem-sec1-private').hidden = false;
 | 
				
			||||||
          $('.js-input-pem-private').innerText = pem_private;
 | 
					          });
 | 
				
			||||||
          $('.js-toc-pem-private').hidden = false;
 | 
					          Eckles.export({ jwk: results.private, format: 'pkcs8' }).then(function (pem) {
 | 
				
			||||||
 | 
					            $('.js-input-pem-pkcs8-private').innerText = pem;
 | 
				
			||||||
 | 
					            $('.js-toc-pem-pkcs8-private').hidden = false;
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					          Eckles.export({ jwk: results.public, public: true }).then(function (pem) {
 | 
				
			||||||
 | 
					            $('.js-input-pem-spki-public').innerText = pem;
 | 
				
			||||||
 | 
					            $('.js-toc-pem-spki-public').hidden = false;
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          der_private = x509.packPkcs8(results.private);
 | 
					          privDer = x509.packPkcs8(results.private);
 | 
				
			||||||
          der_public = x509.packPkcs8(results.public);
 | 
					          pubDer = x509.packSpki(results.public);
 | 
				
			||||||
          Rasha.pack({ jwk: results.private }).then(function (pem) {
 | 
					          Rasha.export({ jwk: results.private, format: 'pkcs1' }).then(function (pem) {
 | 
				
			||||||
            $('.js-input-pem-private').innerText = pem;
 | 
					            $('.js-input-pem-pkcs1-private').innerText = pem;
 | 
				
			||||||
            $('.js-toc-pem-private').hidden = false;
 | 
					            $('.js-toc-pem-pkcs1-private').hidden = false;
 | 
				
			||||||
          })
 | 
					          });
 | 
				
			||||||
          Rasha.pack({ jwk: results.public }).then(function (pem) {
 | 
					          Rasha.export({ jwk: results.private, format: 'pkcs8' }).then(function (pem) {
 | 
				
			||||||
            $('.js-input-pem-public').innerText = pem;
 | 
					            $('.js-input-pem-pkcs8-private').innerText = pem;
 | 
				
			||||||
            $('.js-toc-pem-public').hidden = false;
 | 
					            $('.js-toc-pem-pkcs8-private').hidden = false;
 | 
				
			||||||
          })
 | 
					          });
 | 
				
			||||||
 | 
					          Rasha.export({ jwk: results.public, format: 'pkcs1' }).then(function (pem) {
 | 
				
			||||||
 | 
					            $('.js-input-pem-pkcs1-public').innerText = pem;
 | 
				
			||||||
 | 
					            $('.js-toc-pem-pkcs1-public').hidden = false;
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					          Rasha.export({ jwk: results.public, format: 'spki' }).then(function (pem) {
 | 
				
			||||||
 | 
					            $('.js-input-pem-spki-public').innerText = pem;
 | 
				
			||||||
 | 
					            $('.js-toc-pem-spki-public').hidden = false;
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $('.js-der-public').innerText = der_public;
 | 
					        $('.js-der-public').innerText = pubDer;
 | 
				
			||||||
        $('.js-toc-der-public').hidden = false;
 | 
					        $('.js-toc-der-public').hidden = false;
 | 
				
			||||||
        $('.js-der-private').innerText = der_private;
 | 
					        $('.js-der-private').innerText = privDer;
 | 
				
			||||||
        $('.js-toc-der-private').hidden = false;
 | 
					        $('.js-toc-der-private').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;
 | 
				
			||||||
@ -87,7 +106,7 @@
 | 
				
			|||||||
      ev.preventDefault();
 | 
					      ev.preventDefault();
 | 
				
			||||||
      ev.stopPropagation();
 | 
					      ev.stopPropagation();
 | 
				
			||||||
      $('.js-loading').hidden = false;
 | 
					      $('.js-loading').hidden = false;
 | 
				
			||||||
      ACME.accounts.create
 | 
					      //ACME.accounts.create
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    $('.js-generate').hidden = false;
 | 
					    $('.js-generate').hidden = false;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										34
									
								
								index.html
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								index.html
									
									
									
									
									
								
							@ -8,10 +8,10 @@
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      /* need to word wrap the binary no space der */
 | 
					      /* need to word wrap the binary no space der */
 | 
				
			||||||
      .js-der-public, .js-der-private{
 | 
					      .js-der-public, .js-der-private{
 | 
				
			||||||
        white-space: pre-wrap;      /* CSS3 */   
 | 
					        white-space: pre-wrap;      /* CSS3 */
 | 
				
			||||||
        white-space: -moz-pre-wrap; /* Firefox */    
 | 
					        white-space: -moz-pre-wrap; /* Firefox */
 | 
				
			||||||
        white-space: -pre-wrap;     /* Opera <7 */   
 | 
					        white-space: -pre-wrap;     /* Opera <7 */
 | 
				
			||||||
        white-space: -o-pre-wrap;   /* Opera 7 */    
 | 
					        white-space: -o-pre-wrap;   /* Opera 7 */
 | 
				
			||||||
        word-wrap: break-word;      /* IE */
 | 
					        word-wrap: break-word;      /* IE */
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    </style>
 | 
					    </style>
 | 
				
			||||||
@ -80,13 +80,25 @@
 | 
				
			|||||||
      <summary>DER Public Binary</summary>
 | 
					      <summary>DER Public Binary</summary>
 | 
				
			||||||
      <pre><code class="js-der-public"> </code></pre>
 | 
					      <pre><code class="js-der-public"> </code></pre>
 | 
				
			||||||
    </details>
 | 
					    </details>
 | 
				
			||||||
    <details class="js-toc-pem-private" hidden>
 | 
					    <details class="js-toc-pem js-toc-pem-pkcs1-private" hidden>
 | 
				
			||||||
      <summary>PEM Private (base64-encoded DER)</summary>
 | 
					      <summary>PEM Private (base64-encoded PKCS1 DER)</summary>
 | 
				
			||||||
      <pre><code  class="js-input-pem-private" ></code></pre>
 | 
					      <pre><code  class="js-input-pem-pkcs1-private" ></code></pre>
 | 
				
			||||||
    </details>
 | 
					    </details>
 | 
				
			||||||
    <details class="js-toc-pem-public" hidden>
 | 
					    <details class="js-toc-pem js-toc-pem-sec1-private" hidden>
 | 
				
			||||||
      <summary>PEM Public (base64-encoded DER)</summary>
 | 
					      <summary>PEM Private (base64-encoded SEC1 DER)</summary>
 | 
				
			||||||
      <pre><code  class="js-input-pem-public" ></code></pre>
 | 
					      <pre><code  class="js-input-pem-sec1-private" ></code></pre>
 | 
				
			||||||
 | 
					    </details>
 | 
				
			||||||
 | 
					    <details class="js-toc-pem js-toc-pem-pkcs8-private" hidden>
 | 
				
			||||||
 | 
					      <summary>PEM Private (base64-encoded PKCS8 DER)</summary>
 | 
				
			||||||
 | 
					      <pre><code  class="js-input-pem-pkcs8-private" ></code></pre>
 | 
				
			||||||
 | 
					    </details>
 | 
				
			||||||
 | 
					    <details class="js-toc-pem js-toc-pem-pkcs1-public" hidden>
 | 
				
			||||||
 | 
					      <summary>PEM Public (base64-encoded PKCS1 DER)</summary>
 | 
				
			||||||
 | 
					      <pre><code  class="js-input-pem-pkcs1-public" ></code></pre>
 | 
				
			||||||
 | 
					    </details>
 | 
				
			||||||
 | 
					    <details class="js-toc-pem js-toc-pem-spki-public" hidden>
 | 
				
			||||||
 | 
					      <summary>PEM Public (base64-encoded SPKI/PKIX DER)</summary>
 | 
				
			||||||
 | 
					      <pre><code  class="js-input-pem-spki-public" ></code></pre>
 | 
				
			||||||
    </details>
 | 
					    </details>
 | 
				
			||||||
    <details class="js-toc-acme-account-request" hidden>
 | 
					    <details class="js-toc-acme-account-request" hidden>
 | 
				
			||||||
      <summary>ACME Account Request</summary>
 | 
					      <summary>ACME Account Request</summary>
 | 
				
			||||||
@ -97,9 +109,9 @@
 | 
				
			|||||||
      <pre><code class="js-acme-account-response"> </code></pre>
 | 
					      <pre><code class="js-acme-account-response"> </code></pre>
 | 
				
			||||||
    </details>
 | 
					    </details>
 | 
				
			||||||
    <script src="./lib/bluecrypt-encoding.js"></script>
 | 
					    <script src="./lib/bluecrypt-encoding.js"></script>
 | 
				
			||||||
    <script src="./lib/ecdsa.js"></script>
 | 
					 | 
				
			||||||
    <script src="./lib/asn1-packer.js"></script>
 | 
					    <script src="./lib/asn1-packer.js"></script>
 | 
				
			||||||
    <script src="./lib/x509.js"></script>
 | 
					    <script src="./lib/x509.js"></script>
 | 
				
			||||||
 | 
					    <script src="./lib/ecdsa.js"></script>
 | 
				
			||||||
    <script src="./lib/rsa.js"></script>
 | 
					    <script src="./lib/rsa.js"></script>
 | 
				
			||||||
    <script src="./lib/keypairs.js"></script>
 | 
					    <script src="./lib/keypairs.js"></script>
 | 
				
			||||||
    <script src="./lib/acme.js"></script>
 | 
					    <script src="./lib/acme.js"></script>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										89
									
								
								lib/ecdsa.js
									
									
									
									
									
								
							
							
						
						
									
										89
									
								
								lib/ecdsa.js
									
									
									
									
									
								
							@ -3,7 +3,10 @@
 | 
				
			|||||||
'use strict';
 | 
					'use strict';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var EC = exports.Eckles = {};
 | 
					var EC = exports.Eckles = {};
 | 
				
			||||||
 | 
					var x509 = exports.x509;
 | 
				
			||||||
if ('undefined' !== typeof module) { module.exports = EC; }
 | 
					if ('undefined' !== typeof module) { module.exports = EC; }
 | 
				
			||||||
 | 
					var PEM = exports.PEM;
 | 
				
			||||||
 | 
					var SSH = exports.SSH;
 | 
				
			||||||
var Enc = {};
 | 
					var Enc = {};
 | 
				
			||||||
var textEncoder = new TextEncoder();
 | 
					var textEncoder = new TextEncoder();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -32,7 +35,7 @@ EC.generate = function (opts) {
 | 
				
			|||||||
      + " Please choose either 'P-256' or 'P-384'. "
 | 
					      + " Please choose either 'P-256' or 'P-384'. "
 | 
				
			||||||
      + EC._stance));
 | 
					      + EC._stance));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  
 | 
					
 | 
				
			||||||
  var extractable = true;
 | 
					  var extractable = true;
 | 
				
			||||||
  return window.crypto.subtle.generateKey(
 | 
					  return window.crypto.subtle.generateKey(
 | 
				
			||||||
    wcOpts
 | 
					    wcOpts
 | 
				
			||||||
@ -52,51 +55,53 @@ EC.generate = function (opts) {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EC.export = function (opts) {
 | 
					EC.export = function (opts) {
 | 
				
			||||||
  if (!opts || !opts.jwk || 'object' !== typeof opts.jwk) {
 | 
					  return Promise.resolve().then(function () {
 | 
				
			||||||
    throw new Error("must pass { jwk: jwk } as a JSON object");
 | 
					    if (!opts || !opts.jwk || 'object' !== typeof opts.jwk) {
 | 
				
			||||||
  }
 | 
					      throw new Error("must pass { jwk: jwk } as a JSON object");
 | 
				
			||||||
  var jwk = JSON.parse(JSON.stringify(opts.jwk));
 | 
					    }
 | 
				
			||||||
  var format = opts.format;
 | 
					    var jwk = JSON.parse(JSON.stringify(opts.jwk));
 | 
				
			||||||
  if (opts.public || -1 !== [ 'spki', 'pkix', 'ssh', 'rfc4716' ].indexOf(format)) {
 | 
					    var format = opts.format;
 | 
				
			||||||
    jwk.d = null;
 | 
					    if (opts.public || -1 !== [ 'spki', 'pkix', 'ssh', 'rfc4716' ].indexOf(format)) {
 | 
				
			||||||
  }
 | 
					      jwk.d = null;
 | 
				
			||||||
  if ('EC' !== jwk.kty) {
 | 
					    }
 | 
				
			||||||
    throw new Error("options.jwk.kty must be 'EC' for EC keys");
 | 
					    if ('EC' !== jwk.kty) {
 | 
				
			||||||
  }
 | 
					      throw new Error("options.jwk.kty must be 'EC' for EC keys");
 | 
				
			||||||
  if (!jwk.d) {
 | 
					    }
 | 
				
			||||||
    if (!format || -1 !== [ 'spki', 'pkix' ].indexOf(format)) {
 | 
					    if (!jwk.d) {
 | 
				
			||||||
      format = 'spki';
 | 
					      if (!format || -1 !== [ 'spki', 'pkix' ].indexOf(format)) {
 | 
				
			||||||
    } else if (-1 !== [ 'ssh', 'rfc4716' ].indexOf(format)) {
 | 
					        format = 'spki';
 | 
				
			||||||
      format = 'ssh';
 | 
					      } else if (-1 !== [ 'ssh', 'rfc4716' ].indexOf(format)) {
 | 
				
			||||||
 | 
					        format = 'ssh';
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        throw new Error("options.format must be 'spki' or 'ssh' for public EC keys, not ("
 | 
				
			||||||
 | 
					          + typeof format + ") " + format);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      throw new Error("options.format must be 'spki' or 'ssh' for public EC keys, not ("
 | 
					      if (!format || 'sec1' === format) {
 | 
				
			||||||
        + typeof format + ") " + format);
 | 
					        format = 'sec1';
 | 
				
			||||||
 | 
					      } else if ('pkcs8' !== format) {
 | 
				
			||||||
 | 
					        throw new Error("options.format must be 'sec1' or 'pkcs8' for private EC keys, not '" + format + "'");
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } else {
 | 
					    if (-1 === [ 'P-256', 'P-384' ].indexOf(jwk.crv)) {
 | 
				
			||||||
    if (!format || 'sec1' === format) {
 | 
					      throw new Error("options.jwk.crv must be either P-256 or P-384 for EC keys, not '" + jwk.crv + "'");
 | 
				
			||||||
      format = 'sec1';
 | 
					    }
 | 
				
			||||||
    } else if ('pkcs8' !== format) {
 | 
					    if (!jwk.y) {
 | 
				
			||||||
      throw new Error("options.format must be 'sec1' or 'pkcs8' for private EC keys, not '" + format + "'");
 | 
					      throw new Error("options.jwk.y must be a urlsafe base64-encoded either P-256 or P-384");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  if (-1 === [ 'P-256', 'P-384' ].indexOf(jwk.crv)) {
 | 
					 | 
				
			||||||
    throw new Error("options.jwk.crv must be either P-256 or P-384 for EC keys, not '" + jwk.crv + "'");
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  if (!jwk.y) {
 | 
					 | 
				
			||||||
    throw new Error("options.jwk.y must be a urlsafe base64-encoded either P-256 or P-384");
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if ('sec1' === format) {
 | 
					    if ('sec1' === format) {
 | 
				
			||||||
    return PEM.packBlock({ type: "EC PRIVATE KEY", bytes: x509.packSec1(jwk) });
 | 
					      return PEM.packBlock({ type: "EC PRIVATE KEY", bytes: x509.packSec1(jwk) });
 | 
				
			||||||
  } else if ('pkcs8' === format) {
 | 
					    } else if ('pkcs8' === format) {
 | 
				
			||||||
    return PEM.packBlock({ type: "PRIVATE KEY", bytes: x509.packPkcs8(jwk) });
 | 
					      return PEM.packBlock({ type: "PRIVATE KEY", bytes: x509.packPkcs8(jwk) });
 | 
				
			||||||
  } else if (-1 !== [ 'spki', 'pkix' ].indexOf(format)) {
 | 
					    } else if (-1 !== [ 'spki', 'pkix' ].indexOf(format)) {
 | 
				
			||||||
    return PEM.packBlock({ type: "PUBLIC KEY", bytes: x509.packSpki(jwk) });
 | 
					      return PEM.packBlock({ type: "PUBLIC KEY", bytes: x509.packSpki(jwk) });
 | 
				
			||||||
  } else if (-1 !== [ 'ssh', 'rfc4716' ].indexOf(format)) {
 | 
					    } else if (-1 !== [ 'ssh', 'rfc4716' ].indexOf(format)) {
 | 
				
			||||||
    return SSH.packSsh(jwk);
 | 
					      return SSH.packSsh(jwk);
 | 
				
			||||||
  } else {
 | 
					    } else {
 | 
				
			||||||
    throw new Error("Sanity Error: reached unreachable code block with format: " + format);
 | 
					      throw new Error("Sanity Error: reached unreachable code block with format: " + format);
 | 
				
			||||||
  }
 | 
					    }
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
EC.pack = function (opts) {
 | 
					EC.pack = function (opts) {
 | 
				
			||||||
  return Promise.resolve().then(function () {
 | 
					  return Promise.resolve().then(function () {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										92
									
								
								lib/rsa.js
									
									
									
									
									
								
							
							
						
						
									
										92
									
								
								lib/rsa.js
									
									
									
									
									
								
							@ -5,6 +5,8 @@
 | 
				
			|||||||
var RSA = exports.Rasha = {};
 | 
					var RSA = exports.Rasha = {};
 | 
				
			||||||
var x509 = exports.x509;
 | 
					var x509 = exports.x509;
 | 
				
			||||||
if ('undefined' !== typeof module) { module.exports = RSA; }
 | 
					if ('undefined' !== typeof module) { module.exports = RSA; }
 | 
				
			||||||
 | 
					var PEM = exports.PEM;
 | 
				
			||||||
 | 
					var SSH = exports.SSH;
 | 
				
			||||||
var Enc = {};
 | 
					var Enc = {};
 | 
				
			||||||
var textEncoder = new TextEncoder();
 | 
					var textEncoder = new TextEncoder();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -108,55 +110,57 @@ RSA.thumbprint = function (opts) {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RSA.export = function (opts) {
 | 
					RSA.export = function (opts) {
 | 
				
			||||||
  if (!opts || !opts.jwk || 'object' !== typeof opts.jwk) {
 | 
					  return Promise.resolve().then(function () {
 | 
				
			||||||
    throw new Error("must pass { jwk: jwk }");
 | 
					    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 jwk = JSON.parse(JSON.stringify(opts.jwk));
 | 
				
			||||||
  var pub = opts.public;
 | 
					    var format = opts.format;
 | 
				
			||||||
  if (pub || -1 !== [ 'spki', 'pkix', 'ssh', 'rfc4716' ].indexOf(format)) {
 | 
					    var pub = opts.public;
 | 
				
			||||||
    jwk = RSA.nueter(jwk);
 | 
					    if (pub || -1 !== [ 'spki', 'pkix', 'ssh', 'rfc4716' ].indexOf(format)) {
 | 
				
			||||||
  }
 | 
					      jwk = RSA.neuter({ jwk: jwk });
 | 
				
			||||||
  if ('RSA' !== jwk.kty) {
 | 
					    }
 | 
				
			||||||
    throw new Error("options.jwk.kty must be 'RSA' for RSA keys");
 | 
					    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
 | 
					    if (!jwk.p) {
 | 
				
			||||||
    pub = true;
 | 
					      // TODO test for n and e
 | 
				
			||||||
    if (!format || 'pkcs1' === format) {
 | 
					      pub = true;
 | 
				
			||||||
      format = 'pkcs1';
 | 
					      if (!format || 'pkcs1' === format) {
 | 
				
			||||||
    } else if (-1 !== [ 'spki', 'pkix' ].indexOf(format)) {
 | 
					        format = 'pkcs1';
 | 
				
			||||||
      format = 'spki';
 | 
					      } else if (-1 !== [ 'spki', 'pkix' ].indexOf(format)) {
 | 
				
			||||||
    } else if (-1 !== [ 'ssh', 'rfc4716' ].indexOf(format)) {
 | 
					        format = 'spki';
 | 
				
			||||||
      format = 'ssh';
 | 
					      } 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 {
 | 
					    } else {
 | 
				
			||||||
      throw new Error("options.format must be 'spki', 'pkcs1', or 'ssh' for public RSA keys, not ("
 | 
					      // TODO test for all necessary keys (d, p, q ...)
 | 
				
			||||||
        + typeof format + ") " + format);
 | 
					      if (!format || 'pkcs1' === format) {
 | 
				
			||||||
 | 
					        format = 'pkcs1';
 | 
				
			||||||
 | 
					      } else if ('pkcs8' !== format) {
 | 
				
			||||||
 | 
					        throw new Error("options.format must be 'pkcs1' or 'pkcs8' for private RSA keys");
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } 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 ('pkcs1' === format) {
 | 
				
			||||||
    if (jwk.d) {
 | 
					      if (jwk.d) {
 | 
				
			||||||
      return PEM.packBlock({ type: "RSA PRIVATE KEY", bytes: x509.packPkcs1(jwk) });
 | 
					        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 {
 | 
					    } else {
 | 
				
			||||||
      return PEM.packBlock({ type: "RSA PUBLIC KEY", bytes: x509.packPkcs1(jwk) });
 | 
					      throw new Error("Sanity Error: reached unreachable code block with format: " + format);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  } 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) {
 | 
					RSA.pack = function (opts) {
 | 
				
			||||||
  // wrapped in a promise for API compatibility
 | 
					  // wrapped in a promise for API compatibility
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										51
									
								
								lib/x509.js
									
									
									
									
									
								
							
							
						
						
									
										51
									
								
								lib/x509.js
									
									
									
									
									
								
							@ -58,11 +58,11 @@
 | 
				
			|||||||
  x509.packPkcs1 = function (jwk) {
 | 
					  x509.packPkcs1 = function (jwk) {
 | 
				
			||||||
    var n = ASN1.UInt(Enc.base64ToHex(jwk.n));
 | 
					    var n = ASN1.UInt(Enc.base64ToHex(jwk.n));
 | 
				
			||||||
    var e = ASN1.UInt(Enc.base64ToHex(jwk.e));
 | 
					    var e = ASN1.UInt(Enc.base64ToHex(jwk.e));
 | 
				
			||||||
  
 | 
					
 | 
				
			||||||
    if (!jwk.d) {
 | 
					    if (!jwk.d) {
 | 
				
			||||||
      return Enc.hexToBuf(ASN1('30', n, e));
 | 
					      return Enc.hexToBuf(ASN1('30', n, e));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  
 | 
					
 | 
				
			||||||
    return Enc.hexToBuf(ASN1('30'
 | 
					    return Enc.hexToBuf(ASN1('30'
 | 
				
			||||||
    , ASN1.UInt('00')
 | 
					    , ASN1.UInt('00')
 | 
				
			||||||
    , n
 | 
					    , n
 | 
				
			||||||
@ -159,10 +159,10 @@
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * take a private jwk and creates a der from it
 | 
					   * take a private jwk and creates a der from it
 | 
				
			||||||
   * @param {*} jwk 
 | 
					   * @param {*} jwk
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  x509.packPkcs8 = function (jwk) {
 | 
					  x509.packPkcs8 = function (jwk) {
 | 
				
			||||||
    if (jwk.kty == 'RSA') {
 | 
					    if ('RSA' === jwk.kty) {
 | 
				
			||||||
      if (!jwk.d) {
 | 
					      if (!jwk.d) {
 | 
				
			||||||
        // Public RSA
 | 
					        // Public RSA
 | 
				
			||||||
        return Enc.hexToBuf(ASN1('30'
 | 
					        return Enc.hexToBuf(ASN1('30'
 | 
				
			||||||
@ -219,6 +219,49 @@
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  x509.packSpki = function (jwk) {
 | 
					  x509.packSpki = function (jwk) {
 | 
				
			||||||
 | 
					    if (/EC/i.test(jwk.kty)) {
 | 
				
			||||||
 | 
					      return x509.packSpkiEc(jwk);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return x509.packSpkiRsa(jwk);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  x509.packSpkiRsa = function (jwk) {
 | 
				
			||||||
 | 
					  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))
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					  ));
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					  x509.packSpkiEc = function (jwk) {
 | 
				
			||||||
    var x = Enc.base64ToHex(jwk.x);
 | 
					    var x = Enc.base64ToHex(jwk.x);
 | 
				
			||||||
    var y = Enc.base64ToHex(jwk.y);
 | 
					    var y = Enc.base64ToHex(jwk.y);
 | 
				
			||||||
    var objId = ('P-256' === jwk.crv) ? OBJ_ID_EC : OBJ_ID_EC_384;
 | 
					    var objId = ('P-256' === jwk.crv) ? OBJ_ID_EC : OBJ_ID_EC_384;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user