|
|
@ -4,6 +4,8 @@ |
|
|
|
var BACME = exports.BACME = {}; |
|
|
|
var webFetch = exports.fetch; |
|
|
|
var webCrypto = exports.crypto; |
|
|
|
var Promise = window.Promise; |
|
|
|
var CSR = window.CSR; |
|
|
|
|
|
|
|
var directoryUrl = 'https://acme-staging-v02.api.letsencrypt.org/directory'; |
|
|
|
var directory; |
|
|
@ -15,7 +17,6 @@ var accountKeypair; |
|
|
|
var accountJwk; |
|
|
|
|
|
|
|
var accountUrl; |
|
|
|
var signedAccount; |
|
|
|
|
|
|
|
BACME.challengePrefixes = { |
|
|
|
'http-01': '/.well-known/acme-challenge' |
|
|
@ -62,35 +63,7 @@ BACME.accounts = {}; |
|
|
|
// type = ECDSA
|
|
|
|
// bitlength = 256
|
|
|
|
BACME.accounts.generateKeypair = function (opts) { |
|
|
|
var wcOpts = {}; |
|
|
|
|
|
|
|
// ECDSA has only the P curves and an associated bitlength
|
|
|
|
if (/^EC/i.test(opts.type)) { |
|
|
|
wcOpts.name = 'ECDSA'; |
|
|
|
if (/256/.test(opts.bitlength)) { |
|
|
|
wcOpts.namedCurve = 'P-256'; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// RSA-PSS is another option, but I don't think it's used for Let's Encrypt
|
|
|
|
// I think the hash is only necessary for signing, not generation or import
|
|
|
|
if (/^RS/i.test(opts.type)) { |
|
|
|
wcOpts.name = 'RSASSA-PKCS1-v1_5'; |
|
|
|
wcOpts.modulusLength = opts.bitlength; |
|
|
|
if (opts.bitlength < 2048) { |
|
|
|
wcOpts.modulusLength = opts.bitlength * 8; |
|
|
|
} |
|
|
|
wcOpts.publicExponent = new Uint8Array([0x01, 0x00, 0x01]); |
|
|
|
wcOpts.hash = { name: "SHA-256" }; |
|
|
|
} |
|
|
|
|
|
|
|
// https://github.com/diafygi/webcrypto-examples#ecdsa---generatekey
|
|
|
|
var extractable = true; |
|
|
|
return webCrypto.subtle.generateKey( |
|
|
|
wcOpts |
|
|
|
, extractable |
|
|
|
, [ 'sign', 'verify' ] |
|
|
|
).then(function (result) { |
|
|
|
return BACME.generateKeypair(opts).then(function (result) { |
|
|
|
accountKeypair = result; |
|
|
|
|
|
|
|
return webCrypto.subtle.exportKey( |
|
|
@ -115,7 +88,7 @@ BACME.accounts.generateKeypair = function (opts) { |
|
|
|
//return accountKeypair;
|
|
|
|
}); |
|
|
|
*/ |
|
|
|
}) |
|
|
|
}); |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
@ -158,7 +131,7 @@ BACME._importKey = function (jwk) { |
|
|
|
e: priv.e |
|
|
|
, kty: priv.kty |
|
|
|
, n: priv.n |
|
|
|
} |
|
|
|
}; |
|
|
|
if (!priv.p) { |
|
|
|
priv = null; |
|
|
|
} |
|
|
@ -280,7 +253,6 @@ BACME.accounts.sign = function (opts) { |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
var account; |
|
|
|
var accountId; |
|
|
|
|
|
|
|
BACME.accounts.set = function (opts) { |
|
|
@ -316,7 +288,6 @@ BACME.accounts.set = function (opts) { |
|
|
|
}; |
|
|
|
|
|
|
|
var orderUrl; |
|
|
|
var signedOrder; |
|
|
|
|
|
|
|
BACME.orders = {}; |
|
|
|
|
|
|
@ -345,7 +316,6 @@ BACME.orders.sign = function (opts) { |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|
var order; |
|
|
|
var currentOrderUrl; |
|
|
|
var authorizationUrls; |
|
|
|
var finalizeUrl; |
|
|
@ -571,28 +541,52 @@ BACME.challenges.check = function (opts) { |
|
|
|
var domainKeypair; |
|
|
|
var domainJwk; |
|
|
|
|
|
|
|
BACME.domains = {}; |
|
|
|
// TODO factor out from BACME.accounts.generateKeypair
|
|
|
|
BACME.domains.generateKeypair = function () { |
|
|
|
BACME.generateKeypair = function (opts) { |
|
|
|
var wcOpts = {}; |
|
|
|
|
|
|
|
// ECDSA has only the P curves and an associated bitlength
|
|
|
|
if (/^EC/i.test(opts.type)) { |
|
|
|
wcOpts.name = 'ECDSA'; |
|
|
|
if (/256/.test(opts.bitlength)) { |
|
|
|
wcOpts.namedCurve = 'P-256'; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// RSA-PSS is another option, but I don't think it's used for Let's Encrypt
|
|
|
|
// I think the hash is only necessary for signing, not generation or import
|
|
|
|
if (/^RS/i.test(opts.type)) { |
|
|
|
wcOpts.name = 'RSASSA-PKCS1-v1_5'; |
|
|
|
wcOpts.modulusLength = opts.bitlength; |
|
|
|
if (opts.bitlength < 2048) { |
|
|
|
wcOpts.modulusLength = opts.bitlength * 8; |
|
|
|
} |
|
|
|
wcOpts.publicExponent = new Uint8Array([0x01, 0x00, 0x01]); |
|
|
|
wcOpts.hash = { name: "SHA-256" }; |
|
|
|
} |
|
|
|
var extractable = true; |
|
|
|
return window.crypto.subtle.generateKey( |
|
|
|
{ name: "ECDSA", namedCurve: "P-256" } |
|
|
|
, extractable |
|
|
|
, [ 'sign', 'verify' ] |
|
|
|
).then(function (result) { |
|
|
|
); |
|
|
|
}; |
|
|
|
BACME.domains = {}; |
|
|
|
// TODO factor out from BACME.accounts.generateKeypair even more
|
|
|
|
BACME.domains.generateKeypair = function (opts) { |
|
|
|
return BACME.generateKeypair(opts).then(function (result) { |
|
|
|
domainKeypair = result; |
|
|
|
|
|
|
|
return window.crypto.subtle.exportKey( |
|
|
|
"jwk" |
|
|
|
, result.privateKey |
|
|
|
).then(function (jwk) { |
|
|
|
).then(function (privJwk) { |
|
|
|
|
|
|
|
domainJwk = jwk; |
|
|
|
domainJwk = privJwk; |
|
|
|
console.log('private jwk:'); |
|
|
|
console.log(JSON.stringify(jwk, null, 2)); |
|
|
|
console.log(JSON.stringify(privJwk, null, 2)); |
|
|
|
|
|
|
|
return domainKeypair; |
|
|
|
}) |
|
|
|
return privJwk; |
|
|
|
}); |
|
|
|
}); |
|
|
|
}; |
|
|
|
|
|
|
|