forked from root/acme.js
make Prettier
This commit is contained in:
parent
8e2763ecd6
commit
0d26a42bc7
576
examples/app.js
576
examples/app.js
|
@ -1,274 +1,340 @@
|
||||||
/*global Promise*/
|
/*global Promise*/
|
||||||
(function () {
|
(function() {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var Keypairs = window.Keypairs;
|
var Keypairs = window.Keypairs;
|
||||||
var Rasha = window.Rasha;
|
var Rasha = window.Rasha;
|
||||||
var Eckles = window.Eckles;
|
var Eckles = window.Eckles;
|
||||||
var x509 = window.x509;
|
var x509 = window.x509;
|
||||||
var CSR = window.CSR;
|
var CSR = window.CSR;
|
||||||
var ACME = window.ACME;
|
var ACME = window.ACME;
|
||||||
var accountStuff = {};
|
var accountStuff = {};
|
||||||
|
|
||||||
function $(sel) {
|
function $(sel) {
|
||||||
return document.querySelector(sel);
|
return document.querySelector(sel);
|
||||||
}
|
}
|
||||||
function $$(sel) {
|
function $$(sel) {
|
||||||
return Array.prototype.slice.call(document.querySelectorAll(sel));
|
return Array.prototype.slice.call(document.querySelectorAll(sel));
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkTos(tos) {
|
function checkTos(tos) {
|
||||||
if ($('input[name="tos"]:checked')) {
|
if ($('input[name="tos"]:checked')) {
|
||||||
return tos;
|
return tos;
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function run() {
|
function run() {
|
||||||
console.log('hello');
|
console.log('hello');
|
||||||
|
|
||||||
// Show different options for ECDSA vs RSA
|
// Show different options for ECDSA vs RSA
|
||||||
$$('input[name="kty"]').forEach(function ($el) {
|
$$('input[name="kty"]').forEach(function($el) {
|
||||||
$el.addEventListener('change', function (ev) {
|
$el.addEventListener('change', function(ev) {
|
||||||
console.log(this);
|
console.log(this);
|
||||||
console.log(ev);
|
console.log(ev);
|
||||||
if ("RSA" === ev.target.value) {
|
if ('RSA' === ev.target.value) {
|
||||||
$('.js-rsa-opts').hidden = false;
|
$('.js-rsa-opts').hidden = false;
|
||||||
$('.js-ec-opts').hidden = true;
|
$('.js-ec-opts').hidden = true;
|
||||||
} else {
|
} else {
|
||||||
$('.js-rsa-opts').hidden = true;
|
$('.js-rsa-opts').hidden = true;
|
||||||
$('.js-ec-opts').hidden = false;
|
$('.js-ec-opts').hidden = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// Generate a key on submit
|
// Generate a key on submit
|
||||||
$('form.js-keygen').addEventListener('submit', function (ev) {
|
$('form.js-keygen').addEventListener('submit', function(ev) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
$('.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-der-private').hidden = true;
|
$('.js-toc-der-private').hidden = true;
|
||||||
$$('.js-toc-pem').forEach(function ($el) {
|
$$('.js-toc-pem').forEach(function($el) {
|
||||||
$el.hidden = true;
|
$el.hidden = true;
|
||||||
});
|
});
|
||||||
$$('input').map(function ($el) { $el.disabled = true; });
|
$$('input').map(function($el) {
|
||||||
$$('button').map(function ($el) { $el.disabled = true; });
|
$el.disabled = true;
|
||||||
var opts = {
|
});
|
||||||
kty: $('input[name="kty"]:checked').value
|
$$('button').map(function($el) {
|
||||||
, namedCurve: $('input[name="ec-crv"]:checked').value
|
$el.disabled = true;
|
||||||
, modulusLength: $('input[name="rsa-len"]:checked').value
|
});
|
||||||
};
|
var opts = {
|
||||||
var then = Date.now();
|
kty: $('input[name="kty"]:checked').value,
|
||||||
console.log('opts', opts);
|
namedCurve: $('input[name="ec-crv"]:checked').value,
|
||||||
Keypairs.generate(opts).then(function (results) {
|
modulusLength: $('input[name="rsa-len"]:checked').value
|
||||||
console.log("Key generation time:", (Date.now() - then) + "ms");
|
};
|
||||||
var pubDer;
|
var then = Date.now();
|
||||||
var privDer;
|
console.log('opts', opts);
|
||||||
if (/EC/i.test(opts.kty)) {
|
Keypairs.generate(opts).then(function(results) {
|
||||||
privDer = x509.packPkcs8(results.private);
|
console.log('Key generation time:', Date.now() - then + 'ms');
|
||||||
pubDer = x509.packSpki(results.public);
|
var pubDer;
|
||||||
Eckles.export({ jwk: results.private, format: 'sec1' }).then(function (pem) {
|
var privDer;
|
||||||
$('.js-input-pem-sec1-private').innerText = pem;
|
if (/EC/i.test(opts.kty)) {
|
||||||
$('.js-toc-pem-sec1-private').hidden = false;
|
privDer = x509.packPkcs8(results.private);
|
||||||
});
|
pubDer = x509.packSpki(results.public);
|
||||||
Eckles.export({ jwk: results.private, format: 'pkcs8' }).then(function (pem) {
|
Eckles.export({
|
||||||
$('.js-input-pem-pkcs8-private').innerText = pem;
|
jwk: results.private,
|
||||||
$('.js-toc-pem-pkcs8-private').hidden = false;
|
format: 'sec1'
|
||||||
});
|
}).then(function(pem) {
|
||||||
Eckles.export({ jwk: results.public, public: true }).then(function (pem) {
|
$('.js-input-pem-sec1-private').innerText = pem;
|
||||||
$('.js-input-pem-spki-public').innerText = pem;
|
$('.js-toc-pem-sec1-private').hidden = false;
|
||||||
$('.js-toc-pem-spki-public').hidden = false;
|
});
|
||||||
});
|
Eckles.export({
|
||||||
} else {
|
jwk: results.private,
|
||||||
privDer = x509.packPkcs8(results.private);
|
format: 'pkcs8'
|
||||||
pubDer = x509.packSpki(results.public);
|
}).then(function(pem) {
|
||||||
Rasha.export({ jwk: results.private, format: 'pkcs1' }).then(function (pem) {
|
$('.js-input-pem-pkcs8-private').innerText = pem;
|
||||||
$('.js-input-pem-pkcs1-private').innerText = pem;
|
$('.js-toc-pem-pkcs8-private').hidden = false;
|
||||||
$('.js-toc-pem-pkcs1-private').hidden = false;
|
});
|
||||||
});
|
Eckles.export({ jwk: results.public, public: true }).then(
|
||||||
Rasha.export({ jwk: results.private, format: 'pkcs8' }).then(function (pem) {
|
function(pem) {
|
||||||
$('.js-input-pem-pkcs8-private').innerText = pem;
|
$('.js-input-pem-spki-public').innerText = pem;
|
||||||
$('.js-toc-pem-pkcs8-private').hidden = false;
|
$('.js-toc-pem-spki-public').hidden = false;
|
||||||
});
|
}
|
||||||
Rasha.export({ jwk: results.public, format: 'pkcs1' }).then(function (pem) {
|
);
|
||||||
$('.js-input-pem-pkcs1-public').innerText = pem;
|
} else {
|
||||||
$('.js-toc-pem-pkcs1-public').hidden = false;
|
privDer = x509.packPkcs8(results.private);
|
||||||
});
|
pubDer = x509.packSpki(results.public);
|
||||||
Rasha.export({ jwk: results.public, format: 'spki' }).then(function (pem) {
|
Rasha.export({
|
||||||
$('.js-input-pem-spki-public').innerText = pem;
|
jwk: results.private,
|
||||||
$('.js-toc-pem-spki-public').hidden = false;
|
format: 'pkcs1'
|
||||||
});
|
}).then(function(pem) {
|
||||||
}
|
$('.js-input-pem-pkcs1-private').innerText = pem;
|
||||||
|
$('.js-toc-pem-pkcs1-private').hidden = false;
|
||||||
|
});
|
||||||
|
Rasha.export({
|
||||||
|
jwk: results.private,
|
||||||
|
format: 'pkcs8'
|
||||||
|
}).then(function(pem) {
|
||||||
|
$('.js-input-pem-pkcs8-private').innerText = pem;
|
||||||
|
$('.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 = pubDer;
|
$('.js-der-public').innerText = pubDer;
|
||||||
$('.js-toc-der-public').hidden = false;
|
$('.js-toc-der-public').hidden = false;
|
||||||
$('.js-der-private').innerText = privDer;
|
$('.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;
|
||||||
$('.js-jwk').hidden = false;
|
$('.js-jwk').hidden = false;
|
||||||
$$('input').map(function ($el) { $el.disabled = false; });
|
$$('input').map(function($el) {
|
||||||
$$('button').map(function ($el) { $el.disabled = false; });
|
$el.disabled = false;
|
||||||
$('.js-toc-jwk').hidden = false;
|
});
|
||||||
|
$$('button').map(function($el) {
|
||||||
|
$el.disabled = false;
|
||||||
|
});
|
||||||
|
$('.js-toc-jwk').hidden = false;
|
||||||
|
|
||||||
$('.js-create-account').hidden = false;
|
$('.js-create-account').hidden = false;
|
||||||
$('.js-create-csr').hidden = false;
|
$('.js-create-csr').hidden = false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$('form.js-acme-account').addEventListener('submit', function (ev) {
|
$('form.js-acme-account').addEventListener('submit', function(ev) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
$('.js-loading').hidden = false;
|
$('.js-loading').hidden = false;
|
||||||
var acme = ACME.create({
|
var acme = ACME.create({
|
||||||
Keypairs: Keypairs
|
Keypairs: Keypairs,
|
||||||
, CSR: CSR
|
CSR: CSR
|
||||||
});
|
});
|
||||||
acme.init('https://acme-staging-v02.api.letsencrypt.org/directory').then(function (result) {
|
acme.init(
|
||||||
console.log('acme result', result);
|
'https://acme-staging-v02.api.letsencrypt.org/directory'
|
||||||
var privJwk = JSON.parse($('.js-jwk').innerText).private;
|
).then(function(result) {
|
||||||
var email = $('.js-email').value;
|
console.log('acme result', result);
|
||||||
return acme.accounts.create({
|
var privJwk = JSON.parse($('.js-jwk').innerText).private;
|
||||||
email: email
|
var email = $('.js-email').value;
|
||||||
, agreeToTerms: checkTos
|
return acme.accounts
|
||||||
, accountKeypair: { privateKeyJwk: privJwk }
|
.create({
|
||||||
}).then(function (account) {
|
email: email,
|
||||||
console.log("account created result:", account);
|
agreeToTerms: checkTos,
|
||||||
accountStuff.account = account;
|
accountKeypair: { privateKeyJwk: privJwk }
|
||||||
accountStuff.privateJwk = privJwk;
|
})
|
||||||
accountStuff.email = email;
|
.then(function(account) {
|
||||||
accountStuff.acme = acme;
|
console.log('account created result:', account);
|
||||||
$('.js-create-order').hidden = false;
|
accountStuff.account = account;
|
||||||
$('.js-toc-acme-account-response').hidden = false;
|
accountStuff.privateJwk = privJwk;
|
||||||
$('.js-acme-account-response').innerText = JSON.stringify(account, null, 2);
|
accountStuff.email = email;
|
||||||
}).catch(function (err) {
|
accountStuff.acme = acme;
|
||||||
console.error("A bad thing happened:");
|
$('.js-create-order').hidden = false;
|
||||||
console.error(err);
|
$('.js-toc-acme-account-response').hidden = false;
|
||||||
window.alert(err.message || JSON.stringify(err, null, 2));
|
$(
|
||||||
});
|
'.js-acme-account-response'
|
||||||
});
|
).innerText = JSON.stringify(account, null, 2);
|
||||||
});
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
console.error('A bad thing happened:');
|
||||||
|
console.error(err);
|
||||||
|
window.alert(
|
||||||
|
err.message || JSON.stringify(err, null, 2)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
$('form.js-csr').addEventListener('submit', function (ev) {
|
$('form.js-csr').addEventListener('submit', function(ev) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
generateCsr();
|
generateCsr();
|
||||||
});
|
});
|
||||||
|
|
||||||
$('form.js-acme-order').addEventListener('submit', function (ev) {
|
$('form.js-acme-order').addEventListener('submit', function(ev) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
var account = accountStuff.account;
|
var account = accountStuff.account;
|
||||||
var privJwk = accountStuff.privateJwk;
|
var privJwk = accountStuff.privateJwk;
|
||||||
var email = accountStuff.email;
|
var email = accountStuff.email;
|
||||||
var acme = accountStuff.acme;
|
var acme = accountStuff.acme;
|
||||||
|
|
||||||
|
var domains = ($('.js-domains').value || 'example.com').split(
|
||||||
|
/[, ]+/g
|
||||||
|
);
|
||||||
|
return getDomainPrivkey().then(function(domainPrivJwk) {
|
||||||
|
console.log('Has CSR already?');
|
||||||
|
console.log(accountStuff.csr);
|
||||||
|
return acme.certificates
|
||||||
|
.create({
|
||||||
|
accountKeypair: { privateKeyJwk: privJwk },
|
||||||
|
account: account,
|
||||||
|
serverKeypair: { privateKeyJwk: domainPrivJwk },
|
||||||
|
csr: accountStuff.csr,
|
||||||
|
domains: domains,
|
||||||
|
skipDryRun:
|
||||||
|
$('input[name="skip-dryrun"]:checked') && true,
|
||||||
|
agreeToTerms: checkTos,
|
||||||
|
challenges: {
|
||||||
|
'dns-01': {
|
||||||
|
set: function(opts) {
|
||||||
|
console.info('dns-01 set challenge:');
|
||||||
|
console.info('TXT', opts.dnsHost);
|
||||||
|
console.info(opts.dnsAuthorization);
|
||||||
|
return new Promise(function(resolve) {
|
||||||
|
while (
|
||||||
|
!window.confirm(
|
||||||
|
'Did you set the challenge?'
|
||||||
|
)
|
||||||
|
) {}
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
remove: function(opts) {
|
||||||
|
console.log('dns-01 remove challenge:');
|
||||||
|
console.info('TXT', opts.dnsHost);
|
||||||
|
console.info(opts.dnsAuthorization);
|
||||||
|
return new Promise(function(resolve) {
|
||||||
|
while (
|
||||||
|
!window.confirm(
|
||||||
|
'Did you delete the challenge?'
|
||||||
|
)
|
||||||
|
) {}
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'http-01': {
|
||||||
|
set: function(opts) {
|
||||||
|
console.info('http-01 set challenge:');
|
||||||
|
console.info(opts.challengeUrl);
|
||||||
|
console.info(opts.keyAuthorization);
|
||||||
|
return new Promise(function(resolve) {
|
||||||
|
while (
|
||||||
|
!window.confirm(
|
||||||
|
'Did you set the challenge?'
|
||||||
|
)
|
||||||
|
) {}
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
remove: function(opts) {
|
||||||
|
console.log('http-01 remove challenge:');
|
||||||
|
console.info(opts.challengeUrl);
|
||||||
|
console.info(opts.keyAuthorization);
|
||||||
|
return new Promise(function(resolve) {
|
||||||
|
while (
|
||||||
|
!window.confirm(
|
||||||
|
'Did you delete the challenge?'
|
||||||
|
)
|
||||||
|
) {}
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
challengeTypes: [
|
||||||
|
$('input[name="acme-challenge-type"]:checked').value
|
||||||
|
]
|
||||||
|
})
|
||||||
|
.then(function(results) {
|
||||||
|
console.log('Got Certificates:');
|
||||||
|
console.log(results);
|
||||||
|
$('.js-toc-acme-order-response').hidden = false;
|
||||||
|
$('.js-acme-order-response').innerText = JSON.stringify(
|
||||||
|
results,
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.catch(function(err) {
|
||||||
|
console.error('challenge failed:');
|
||||||
|
console.error(err);
|
||||||
|
window.alert(
|
||||||
|
'failed! ' + err.message || JSON.stringify(err)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
var domains = ($('.js-domains').value||'example.com').split(/[, ]+/g);
|
$('.js-generate').hidden = false;
|
||||||
return getDomainPrivkey().then(function (domainPrivJwk) {
|
}
|
||||||
console.log('Has CSR already?');
|
|
||||||
console.log(accountStuff.csr);
|
|
||||||
return acme.certificates.create({
|
|
||||||
accountKeypair: { privateKeyJwk: privJwk }
|
|
||||||
, account: account
|
|
||||||
, serverKeypair: { privateKeyJwk: domainPrivJwk }
|
|
||||||
, csr: accountStuff.csr
|
|
||||||
, domains: domains
|
|
||||||
, skipDryRun: $('input[name="skip-dryrun"]:checked') && true
|
|
||||||
, agreeToTerms: checkTos
|
|
||||||
, challenges: {
|
|
||||||
'dns-01': {
|
|
||||||
set: function (opts) {
|
|
||||||
console.info('dns-01 set challenge:');
|
|
||||||
console.info('TXT', opts.dnsHost);
|
|
||||||
console.info(opts.dnsAuthorization);
|
|
||||||
return new Promise(function (resolve) {
|
|
||||||
while (!window.confirm("Did you set the challenge?")) {}
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
, remove: function (opts) {
|
|
||||||
console.log('dns-01 remove challenge:');
|
|
||||||
console.info('TXT', opts.dnsHost);
|
|
||||||
console.info(opts.dnsAuthorization);
|
|
||||||
return new Promise(function (resolve) {
|
|
||||||
while (!window.confirm("Did you delete the challenge?")) {}
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
, 'http-01': {
|
|
||||||
set: function (opts) {
|
|
||||||
console.info('http-01 set challenge:');
|
|
||||||
console.info(opts.challengeUrl);
|
|
||||||
console.info(opts.keyAuthorization);
|
|
||||||
return new Promise(function (resolve) {
|
|
||||||
while (!window.confirm("Did you set the challenge?")) {}
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
, remove: function (opts) {
|
|
||||||
console.log('http-01 remove challenge:');
|
|
||||||
console.info(opts.challengeUrl);
|
|
||||||
console.info(opts.keyAuthorization);
|
|
||||||
return new Promise(function (resolve) {
|
|
||||||
while (!window.confirm("Did you delete the challenge?")) {}
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
, challengeTypes: [$('input[name="acme-challenge-type"]:checked').value]
|
|
||||||
}).then(function (results) {
|
|
||||||
console.log('Got Certificates:');
|
|
||||||
console.log(results);
|
|
||||||
$('.js-toc-acme-order-response').hidden = false;
|
|
||||||
$('.js-acme-order-response').innerText = JSON.stringify(results, null, 2);
|
|
||||||
}).catch(function (err) {
|
|
||||||
console.error("challenge failed:");
|
|
||||||
console.error(err);
|
|
||||||
window.alert("failed! " + err.message || JSON.stringify(err));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.js-generate').hidden = false;
|
function getDomainPrivkey() {
|
||||||
}
|
if (accountStuff.domainPrivateJwk) {
|
||||||
|
return Promise.resolve(accountStuff.domainPrivateJwk);
|
||||||
|
}
|
||||||
|
return Keypairs.generate({
|
||||||
|
kty: $('input[name="kty"]:checked').value,
|
||||||
|
namedCurve: $('input[name="ec-crv"]:checked').value,
|
||||||
|
modulusLength: $('input[name="rsa-len"]:checked').value
|
||||||
|
}).then(function(pair) {
|
||||||
|
console.log('domain keypair:', pair);
|
||||||
|
accountStuff.domainPrivateJwk = pair.private;
|
||||||
|
return pair.private;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function getDomainPrivkey() {
|
function generateCsr() {
|
||||||
if (accountStuff.domainPrivateJwk) { return Promise.resolve(accountStuff.domainPrivateJwk); }
|
var domains = ($('.js-domains').value || 'example.com').split(/[, ]+/g);
|
||||||
return Keypairs.generate({
|
//var privJwk = JSON.parse($('.js-jwk').innerText).private;
|
||||||
kty: $('input[name="kty"]:checked').value
|
return getDomainPrivkey().then(function(privJwk) {
|
||||||
, namedCurve: $('input[name="ec-crv"]:checked').value
|
accountStuff.domainPrivateJwk = privJwk;
|
||||||
, modulusLength: $('input[name="rsa-len"]:checked').value
|
return CSR({ jwk: privJwk, domains: domains }).then(function(pem) {
|
||||||
}).then(function (pair) {
|
// Verify with https://www.sslshopper.com/csr-decoder.html
|
||||||
console.log('domain keypair:', pair);
|
accountStuff.csr = pem;
|
||||||
accountStuff.domainPrivateJwk = pair.private;
|
console.log('Created CSR:');
|
||||||
return pair.private;
|
console.log(pem);
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateCsr() {
|
console.log('CSR info:');
|
||||||
var domains = ($('.js-domains').value||'example.com').split(/[, ]+/g);
|
console.log(CSR._info(pem));
|
||||||
//var privJwk = JSON.parse($('.js-jwk').innerText).private;
|
|
||||||
return getDomainPrivkey().then(function (privJwk) {
|
|
||||||
accountStuff.domainPrivateJwk = privJwk;
|
|
||||||
return CSR({ jwk: privJwk, domains: domains }).then(function (pem) {
|
|
||||||
// Verify with https://www.sslshopper.com/csr-decoder.html
|
|
||||||
accountStuff.csr = pem;
|
|
||||||
console.log('Created CSR:');
|
|
||||||
console.log(pem);
|
|
||||||
|
|
||||||
console.log('CSR info:');
|
return pem;
|
||||||
console.log(CSR._info(pem));
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return pem;
|
window.addEventListener('load', run);
|
||||||
});
|
})();
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('load', run);
|
|
||||||
}());
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
ENV=DEV
|
||||||
|
SUBSCRIBER_EMAIL=letsencrypt+staging@example.com
|
||||||
|
BASE_DOMAIN=test.example.com
|
||||||
|
CHALLENGE_TYPE=dns-01
|
||||||
|
CHALLENGE_PLUGIN=digitalocean
|
||||||
|
CHALLENGE_OPTIONS='{"token":"xxxxxxxxxxxx"}'
|
|
@ -1,153 +1,238 @@
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Bluecrypt ACME - A Root Project</title>
|
<title>Bluecrypt ACME - A Root Project</title>
|
||||||
<style>
|
<meta charset="UTF-8" />
|
||||||
textarea {
|
<style>
|
||||||
width: 42em;
|
textarea {
|
||||||
height: 10em;
|
width: 42em;
|
||||||
}
|
height: 10em;
|
||||||
/* need to word wrap the binary no space der */
|
}
|
||||||
.js-der-public, .js-der-private{
|
/* need to word wrap the binary no space der */
|
||||||
white-space: pre-wrap; /* CSS3 */
|
.js-der-public,
|
||||||
white-space: -moz-pre-wrap; /* Firefox */
|
.js-der-private {
|
||||||
white-space: -pre-wrap; /* Opera <7 */
|
white-space: pre-wrap; /* CSS3 */
|
||||||
white-space: -o-pre-wrap; /* Opera 7 */
|
white-space: -moz-pre-wrap; /* Firefox */
|
||||||
word-wrap: break-word; /* IE */
|
white-space: -pre-wrap; /* Opera <7 */
|
||||||
}
|
white-space: -o-pre-wrap; /* Opera 7 */
|
||||||
</style>
|
word-wrap: break-word; /* IE */
|
||||||
</head>
|
}
|
||||||
<body>
|
</style>
|
||||||
<h1>@bluecrypt/acme: Let's Encrypt for the Browser</h1>
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>
|
||||||
|
@bluecrypt/acme: Let's Encrypt for the Browser
|
||||||
|
</h1>
|
||||||
|
|
||||||
<p>This is intended to be explored with your JavaScript console open.</p>
|
<p>
|
||||||
<pre><code><script src="<a href="https://rootprojects.org/acme/bluecrypt-acme.js">https://rootprojects.org/acme/bluecrypt-acme.js</a>"></script></code></pre>
|
This is intended to be explored with your JavaScript console open.
|
||||||
<pre><code><script src="<a href="https://rootprojects.org/acme/bluecrypt-acme.min.js">https://rootprojects.org/acme/bluecrypt-acme.min.js</a>"></script></code></pre>
|
</p>
|
||||||
<a href="https://git.rootprojects.org/root/bluecrypt-acme.js">Documentation</a>
|
<pre><code><script src="<a href="https://rootprojects.org/acme/bluecrypt-acme.js">https://rootprojects.org/acme/bluecrypt-acme.js</a>"></script></code></pre>
|
||||||
|
<pre><code><script src="<a href="https://rootprojects.org/acme/bluecrypt-acme.min.js">https://rootprojects.org/acme/bluecrypt-acme.min.js</a>"></script></code></pre>
|
||||||
|
<a href="https://git.rootprojects.org/root/bluecrypt-acme.js"
|
||||||
|
>Documentation</a
|
||||||
|
>
|
||||||
|
|
||||||
<h2>1. Keypair Generation</h2>
|
<h2>1. Keypair Generation</h2>
|
||||||
<form class="js-keygen">
|
<form class="js-keygen">
|
||||||
<p>Key Type:</p>
|
<p>Key Type:</p>
|
||||||
<div>
|
<div>
|
||||||
<input type="radio" id="-ktyEC"
|
<input type="radio" id="-ktyEC" name="kty" value="EC" checked />
|
||||||
name="kty" value="EC" checked>
|
<label for="-ktyEC">ECDSA</label>
|
||||||
<label for="-ktyEC">ECDSA</label>
|
<input type="radio" id="-ktyRSA" name="kty" value="RSA" />
|
||||||
<input type="radio" id="-ktyRSA"
|
<label for="-ktyRSA">RSA</label>
|
||||||
name="kty" value="RSA">
|
</div>
|
||||||
<label for="-ktyRSA">RSA</label>
|
<div class="js-ec-opts">
|
||||||
</div>
|
<p>EC Options:</p>
|
||||||
<div class="js-ec-opts">
|
<label for="-crv2"
|
||||||
<p>EC Options:</p>
|
><input
|
||||||
<label for="-crv2"><input type="radio" id="-crv2"
|
type="radio"
|
||||||
name="ec-crv" value="P-256" checked>P-256</label>
|
id="-crv2"
|
||||||
<label for="-crv3"><input type="radio" id="-crv3"
|
name="ec-crv"
|
||||||
name="ec-crv" value="P-384">P-384</label>
|
value="P-256"
|
||||||
<!-- label for="-crv5"><input type="radio" id="-crv5"
|
checked
|
||||||
|
/>P-256</label
|
||||||
|
>
|
||||||
|
<label for="-crv3"
|
||||||
|
><input
|
||||||
|
type="radio"
|
||||||
|
id="-crv3"
|
||||||
|
name="ec-crv"
|
||||||
|
value="P-384"
|
||||||
|
/>P-384</label
|
||||||
|
>
|
||||||
|
<!-- label for="-crv5"><input type="radio" id="-crv5"
|
||||||
name="ec-crv" value="P-521">P-521</label -->
|
name="ec-crv" value="P-521">P-521</label -->
|
||||||
</div>
|
</div>
|
||||||
<div class="js-rsa-opts" hidden>
|
<div class="js-rsa-opts" hidden>
|
||||||
<p>RSA Options:</p>
|
<p>RSA Options:</p>
|
||||||
<label for="-modlen2"><input type="radio" id="-modlen2"
|
<label for="-modlen2"
|
||||||
name="rsa-len" value="2048" checked>2048</label>
|
><input
|
||||||
<label for="-modlen3"><input type="radio" id="-modlen3"
|
type="radio"
|
||||||
name="rsa-len" value="3072">3072</label>
|
id="-modlen2"
|
||||||
<label for="-modlen5"><input type="radio" id="-modlen5"
|
name="rsa-len"
|
||||||
name="rsa-len" value="4096">4096</label>
|
value="2048"
|
||||||
</div>
|
checked
|
||||||
<button class="js-generate" hidden>Generate</button>
|
/>2048</label
|
||||||
</form>
|
>
|
||||||
|
<label for="-modlen3"
|
||||||
|
><input
|
||||||
|
type="radio"
|
||||||
|
id="-modlen3"
|
||||||
|
name="rsa-len"
|
||||||
|
value="3072"
|
||||||
|
/>3072</label
|
||||||
|
>
|
||||||
|
<label for="-modlen5"
|
||||||
|
><input
|
||||||
|
type="radio"
|
||||||
|
id="-modlen5"
|
||||||
|
name="rsa-len"
|
||||||
|
value="4096"
|
||||||
|
/>4096</label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<button class="js-generate" hidden>Generate</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
<h2>2. ACME Account</h2>
|
<h2>2. ACME Account</h2>
|
||||||
<form class="js-acme-account">
|
<form class="js-acme-account">
|
||||||
<label for="-acmeEmail">Email:</label>
|
<label for="-acmeEmail">Email:</label>
|
||||||
<input class="js-email" type="email" id="-acmeEmail" value="john.doe@gmail.com">
|
<input
|
||||||
<br>
|
class="js-email"
|
||||||
<label for="-acmeTos"><input class="js-tos" name="tos" type="checkbox" id="-acmeTos" checked>
|
type="email"
|
||||||
Agree to Let's Encrypt Terms of Service</label>
|
id="-acmeEmail"
|
||||||
<br>
|
value="john.doe@gmail.com"
|
||||||
<button class="js-create-account" hidden>Create Account</button>
|
/>
|
||||||
</form>
|
<br />
|
||||||
|
<label for="-acmeTos"
|
||||||
|
><input
|
||||||
|
class="js-tos"
|
||||||
|
name="tos"
|
||||||
|
type="checkbox"
|
||||||
|
id="-acmeTos"
|
||||||
|
checked
|
||||||
|
/>
|
||||||
|
Agree to Let's Encrypt Terms of Service</label
|
||||||
|
>
|
||||||
|
<br />
|
||||||
|
<button class="js-create-account" hidden>Create Account</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
<h2>3. (optional) Certificate Signing Request</h2>
|
<h2>3. (optional) Certificate Signing Request</h2>
|
||||||
<form class="js-csr">
|
<form class="js-csr">
|
||||||
<label for="-acmeDomains">Domains:</label>
|
<label for="-acmeDomains">Domains:</label>
|
||||||
<input class="js-domains" type="text" id="-acmeDomains" value="example.com www.example.com">
|
<input
|
||||||
<br>
|
class="js-domains"
|
||||||
<button class="js-create-csr" hidden>Create CSR</button>
|
type="text"
|
||||||
</form>
|
id="-acmeDomains"
|
||||||
|
value="example.com www.example.com"
|
||||||
|
/>
|
||||||
|
<br />
|
||||||
|
<button class="js-create-csr" hidden>Create CSR</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
<h2>4. ACME Certificate Order</h2>
|
<h2>4. ACME Certificate Order</h2>
|
||||||
<form class="js-acme-order">
|
<form class="js-acme-order">
|
||||||
Challenge type:
|
Challenge type:
|
||||||
<label for="-http01"><input type="radio" id="-http01"
|
<label for="-http01"
|
||||||
name="acme-challenge-type" value="http-01" checked>http-01</label>
|
><input
|
||||||
<label for="-dns01"><input type="radio" id="-dns01"
|
type="radio"
|
||||||
name="acme-challenge-type" value="dns-01">dns-01</label>
|
id="-http01"
|
||||||
<br>
|
name="acme-challenge-type"
|
||||||
<label for="-skipDryrun"><input class="js-skip-dryrun" name="skip-dryrun"
|
value="http-01"
|
||||||
type="checkbox" id="-skipDryrun" checked> Skip dry-run challenge</label>
|
checked
|
||||||
<br>
|
/>http-01</label
|
||||||
<button class="js-create-order" hidden>Create Order</button>
|
>
|
||||||
</form>
|
<label for="-dns01"
|
||||||
|
><input
|
||||||
|
type="radio"
|
||||||
|
id="-dns01"
|
||||||
|
name="acme-challenge-type"
|
||||||
|
value="dns-01"
|
||||||
|
/>dns-01</label
|
||||||
|
>
|
||||||
|
<br />
|
||||||
|
<label for="-skipDryrun"
|
||||||
|
><input
|
||||||
|
class="js-skip-dryrun"
|
||||||
|
name="skip-dryrun"
|
||||||
|
type="checkbox"
|
||||||
|
id="-skipDryrun"
|
||||||
|
checked
|
||||||
|
/>
|
||||||
|
Skip dry-run challenge</label
|
||||||
|
>
|
||||||
|
<br />
|
||||||
|
<button class="js-create-order" hidden>Create Order</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
<div class="js-loading" hidden>Loading</div>
|
<div class="js-loading" hidden>Loading</div>
|
||||||
|
|
||||||
<details class="js-toc-jwk" hidden>
|
<details class="js-toc-jwk" hidden>
|
||||||
<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-private" hidden>
|
<details class="js-toc-der-private" hidden>
|
||||||
<summary>DER Private Binary</summary>
|
<summary>DER Private Binary</summary>
|
||||||
<pre><code class="js-der-private"> </code></pre>
|
<pre><code class="js-der-private"> </code></pre>
|
||||||
</details>
|
</details>
|
||||||
<details class="js-toc-der-public" hidden>
|
<details class="js-toc-der-public" hidden>
|
||||||
<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 js-toc-pem-pkcs1-private" hidden>
|
<details class="js-toc-pem js-toc-pem-pkcs1-private" hidden>
|
||||||
<summary>PEM Private (base64-encoded PKCS1 DER)</summary>
|
<summary>PEM Private (base64-encoded PKCS1 DER)</summary>
|
||||||
<pre><code class="js-input-pem-pkcs1-private" ></code></pre>
|
<pre><code class="js-input-pem-pkcs1-private" ></code></pre>
|
||||||
</details>
|
</details>
|
||||||
<details class="js-toc-pem js-toc-pem-sec1-private" hidden>
|
<details class="js-toc-pem js-toc-pem-sec1-private" hidden>
|
||||||
<summary>PEM Private (base64-encoded SEC1 DER)</summary>
|
<summary>PEM Private (base64-encoded SEC1 DER)</summary>
|
||||||
<pre><code class="js-input-pem-sec1-private" ></code></pre>
|
<pre><code class="js-input-pem-sec1-private" ></code></pre>
|
||||||
</details>
|
</details>
|
||||||
<details class="js-toc-pem js-toc-pem-pkcs8-private" hidden>
|
<details class="js-toc-pem js-toc-pem-pkcs8-private" hidden>
|
||||||
<summary>PEM Private (base64-encoded PKCS8 DER)</summary>
|
<summary>PEM Private (base64-encoded PKCS8 DER)</summary>
|
||||||
<pre><code class="js-input-pem-pkcs8-private" ></code></pre>
|
<pre><code class="js-input-pem-pkcs8-private" ></code></pre>
|
||||||
</details>
|
</details>
|
||||||
<details class="js-toc-pem js-toc-pem-pkcs1-public" hidden>
|
<details class="js-toc-pem js-toc-pem-pkcs1-public" hidden>
|
||||||
<summary>PEM Public (base64-encoded PKCS1 DER)</summary>
|
<summary>PEM Public (base64-encoded PKCS1 DER)</summary>
|
||||||
<pre><code class="js-input-pem-pkcs1-public" ></code></pre>
|
<pre><code class="js-input-pem-pkcs1-public" ></code></pre>
|
||||||
</details>
|
</details>
|
||||||
<details class="js-toc-pem js-toc-pem-spki-public" hidden>
|
<details class="js-toc-pem js-toc-pem-spki-public" hidden>
|
||||||
<summary>PEM Public (base64-encoded SPKI/PKIX DER)</summary>
|
<summary>PEM Public (base64-encoded SPKI/PKIX DER)</summary>
|
||||||
<pre><code class="js-input-pem-spki-public" ></code></pre>
|
<pre><code class="js-input-pem-spki-public" ></code></pre>
|
||||||
</details>
|
</details>
|
||||||
<details class="js-toc-acme-account-response" hidden>
|
<details class="js-toc-acme-account-response" hidden>
|
||||||
<summary>ACME Account Request</summary>
|
<summary>ACME Account Request</summary>
|
||||||
<pre><code class="js-acme-account-response"> </code></pre>
|
<pre><code class="js-acme-account-response"> </code></pre>
|
||||||
</details>
|
</details>
|
||||||
<details class="js-toc-acme-order-response" hidden>
|
<details class="js-toc-acme-order-response" hidden>
|
||||||
<summary>ACME Order Response</summary>
|
<summary>ACME Order Response</summary>
|
||||||
<pre><code class="js-acme-order-response"> </code></pre>
|
<pre><code class="js-acme-order-response"> </code></pre>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<br>
|
<br />
|
||||||
<p>Bluecrypt™ is a collection of lightweight, zero-dependency, libraries written in VanillaJS.
|
<p>
|
||||||
They are fast, tiny, and secure, using the native features of modern browsers where possible.
|
Bluecrypt™ is a collection of lightweight, zero-dependency,
|
||||||
This means it's easy-to-use crypto in kilobytes, not megabytes.</p>
|
libraries written in VanillaJS. They are fast, tiny, and secure,
|
||||||
<br>
|
using the native features of modern browsers where possible. This
|
||||||
<footer>View (git) source <a href="https://git.rootprojects.org/root/bluecrypt-acme.js">@bluecrypt/acme</a></footer>
|
means it's easy-to-use crypto in kilobytes, not megabytes.
|
||||||
|
</p>
|
||||||
|
<br />
|
||||||
|
<footer>
|
||||||
|
View (git) source
|
||||||
|
<a href="https://git.rootprojects.org/root/bluecrypt-acme.js"
|
||||||
|
>@bluecrypt/acme</a
|
||||||
|
>
|
||||||
|
</footer>
|
||||||
|
|
||||||
<script src="./lib/encoding.js"></script>
|
<script src="./lib/encoding.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/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/asn1-parser.js"></script>
|
<script src="./lib/asn1-parser.js"></script>
|
||||||
<script src="./lib/csr.js"></script>
|
<script src="./lib/csr.js"></script>
|
||||||
<script src="./lib/acme.js"></script>
|
<script src="./lib/acme.js"></script>
|
||||||
<script src="./app.js"></script>
|
<script src="./app.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Loading…
Reference in New Issue