forked from root/acme.js
working pem generation
This commit is contained in:
parent
1b01c2c413
commit
735ec948da
8
app.js
8
app.js
|
@ -44,15 +44,19 @@ function run() {
|
||||||
console.log('opts', opts);
|
console.log('opts', opts);
|
||||||
Keypairs.generate(opts).then(function (results) {
|
Keypairs.generate(opts).then(function (results) {
|
||||||
var der = x509.packPkcs8(results.private);
|
var der = x509.packPkcs8(results.private);
|
||||||
console.log(der)
|
var pem = Eckles.export({jwk:results.private})
|
||||||
// Pem.encode(x509.packPkcs8(privateJwk))
|
|
||||||
$('.js-jwk').innerText = JSON.stringify(results, null, 2);
|
$('.js-jwk').innerText = JSON.stringify(results, null, 2);
|
||||||
|
$('.js-der').innerText = JSON.stringify(der, null, 2);
|
||||||
|
$('.js-input-pem').innerText = pem;
|
||||||
//
|
//
|
||||||
$('.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; });
|
||||||
$$('button').map(function ($el) { $el.disabled = false; });
|
$$('button').map(function ($el) { $el.disabled = false; });
|
||||||
$('.js-toc-jwk').hidden = false;
|
$('.js-toc-jwk').hidden = false;
|
||||||
|
$('.js-toc-der').hidden = false;
|
||||||
|
$('.js-toc-pem').hidden = false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
14
index.html
14
index.html
|
@ -1,6 +1,12 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>BlueCrypt</title>
|
<title>BlueCrypt</title>
|
||||||
|
<style>
|
||||||
|
textarea {
|
||||||
|
width: 42em;
|
||||||
|
height: 10em;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>BlueCrypt for the Browser</h1>
|
<h1>BlueCrypt for the Browser</h1>
|
||||||
|
@ -58,6 +64,14 @@
|
||||||
<summary>JWK Keypair</summary>
|
<summary>JWK Keypair</summary>
|
||||||
<pre><code class="js-jwk"> </code></pre>
|
<pre><code class="js-jwk"> </code></pre>
|
||||||
</details>
|
</details>
|
||||||
|
<details class="js-toc-der" hidden>
|
||||||
|
<summary>DER Binary</summary>
|
||||||
|
<pre><code class="js-der"> </code></pre>
|
||||||
|
</details>
|
||||||
|
<details class="js-toc-pem" hidden>
|
||||||
|
<summary>PEM (base64-encoded DER)</summary>
|
||||||
|
<textarea class="js-input-pem" readonly></textarea>
|
||||||
|
</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>
|
||||||
<pre><code class="js-acme-account-request"> </code></pre>
|
<pre><code class="js-acme-account-request"> </code></pre>
|
||||||
|
|
53
lib/ecdsa.js
53
lib/ecdsa.js
|
@ -51,6 +51,59 @@ EC.generate = function (opts) {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
EC.export = function (opts) {
|
||||||
|
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;
|
||||||
|
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 (!jwk.d) {
|
||||||
|
if (!format || -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' or 'ssh' for public EC keys, not ("
|
||||||
|
+ typeof format + ") " + format);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!format || 'sec1' === format) {
|
||||||
|
format = 'sec1';
|
||||||
|
} else if ('pkcs8' !== format) {
|
||||||
|
throw new Error("options.format must be 'sec1' or 'pkcs8' for private EC keys, not '" + format + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
return PEM.packBlock({ type: "EC PRIVATE KEY", bytes: x509.packSec1(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.packSsh(jwk);
|
||||||
|
} else {
|
||||||
|
throw new Error("Sanity Error: reached unreachable code block with format: " + format);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
EC.pack = function (opts) {
|
||||||
|
return Promise.resolve().then(function () {
|
||||||
|
return EC.exportSync(opts);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Chopping off the private parts is now part of the public API.
|
// 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.
|
// 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) {
|
||||||
|
|
Loading…
Reference in New Issue