mirror of
https://github.com/denoland/deno.git
synced 2024-12-24 08:09:08 -05:00
feat(ext/crypto): AES key generation (#11869)
Support AES-CTR, AES-CBC, AES-GCM, and AES-KW in SubtleCrypto#generateKey.
This commit is contained in:
parent
fcd0992dba
commit
cee5be4539
4 changed files with 107 additions and 1414 deletions
|
@ -77,6 +77,10 @@
|
|||
"RSA-PSS": "RsaHashedKeyGenParams",
|
||||
"RSA-OAEP": "RsaHashedKeyGenParams",
|
||||
"ECDSA": "EcKeyGenParams",
|
||||
"AES-CTR": "AesKeyGenParams",
|
||||
"AES-CBC": "AesKeyGenParams",
|
||||
"AES-GCM": "AesKeyGenParams",
|
||||
"AES-KW": "AesKeyGenParams",
|
||||
"HMAC": "HmacKeyGenParams",
|
||||
},
|
||||
"sign": {
|
||||
|
@ -1415,10 +1419,40 @@
|
|||
return { publicKey, privateKey };
|
||||
}
|
||||
// TODO(lucacasonato): ECDH
|
||||
// TODO(lucacasonato): AES-CTR
|
||||
// TODO(lucacasonato): AES-CBC
|
||||
// TODO(lucacasonato): AES-GCM
|
||||
// TODO(lucacasonato): AES-KW
|
||||
case "AES-CTR":
|
||||
case "AES-CBC":
|
||||
case "AES-GCM": {
|
||||
// 1.
|
||||
if (
|
||||
ArrayPrototypeFind(
|
||||
usages,
|
||||
(u) =>
|
||||
!ArrayPrototypeIncludes([
|
||||
"encrypt",
|
||||
"decrypt",
|
||||
"wrapKey",
|
||||
"unwrapKey",
|
||||
], u),
|
||||
) !== undefined
|
||||
) {
|
||||
throw new DOMException("Invalid key usages", "SyntaxError");
|
||||
}
|
||||
|
||||
return generateKeyAES(normalizedAlgorithm, extractable, usages);
|
||||
}
|
||||
case "AES-KW": {
|
||||
// 1.
|
||||
if (
|
||||
ArrayPrototypeFind(
|
||||
usages,
|
||||
(u) => !ArrayPrototypeIncludes(["wrapKey", "unwrapKey"], u),
|
||||
) !== undefined
|
||||
) {
|
||||
throw new DOMException("Invalid key usages", "SyntaxError");
|
||||
}
|
||||
|
||||
return generateKeyAES(normalizedAlgorithm, extractable, usages);
|
||||
}
|
||||
case "HMAC": {
|
||||
// 1.
|
||||
if (
|
||||
|
@ -1473,6 +1507,42 @@
|
|||
}
|
||||
}
|
||||
|
||||
async function generateKeyAES(normalizedAlgorithm, extractable, usages) {
|
||||
// 2.
|
||||
if (!ArrayPrototypeIncludes([128, 192, 256], normalizedAlgorithm.length)) {
|
||||
throw new DOMException("Invalid key length", "OperationError");
|
||||
}
|
||||
|
||||
// 3.
|
||||
const keyData = await core.opAsync("op_crypto_generate_key", {
|
||||
name: normalizedAlgorithm.name,
|
||||
length: normalizedAlgorithm.length,
|
||||
});
|
||||
const handle = {};
|
||||
WeakMapPrototypeSet(KEY_STORE, handle, {
|
||||
type: "raw",
|
||||
data: keyData,
|
||||
});
|
||||
|
||||
// 6-8.
|
||||
const algorithm = {
|
||||
name: normalizedAlgorithm.name,
|
||||
length: normalizedAlgorithm.length,
|
||||
};
|
||||
|
||||
// 9-11.
|
||||
const key = constructKey(
|
||||
"secret",
|
||||
extractable,
|
||||
usages,
|
||||
algorithm,
|
||||
handle,
|
||||
);
|
||||
|
||||
// 12.
|
||||
return key;
|
||||
}
|
||||
|
||||
async function deriveBits(normalizedAlgorithm, baseKey, length) {
|
||||
switch (normalizedAlgorithm.name) {
|
||||
case "PBKDF2": {
|
||||
|
|
|
@ -117,6 +117,19 @@
|
|||
webidl.converters.EcKeyGenParams = webidl
|
||||
.createDictionaryConverter("EcKeyGenParams", dictEcKeyGenParams);
|
||||
|
||||
const dictAesKeyGenParams = [
|
||||
...dictAlgorithm,
|
||||
{
|
||||
key: "length",
|
||||
converter: (V, opts) =>
|
||||
webidl.converters["unsigned short"](V, { ...opts, enforceRange: true }),
|
||||
required: true,
|
||||
},
|
||||
];
|
||||
|
||||
webidl.converters.AesKeyGenParams = webidl
|
||||
.createDictionaryConverter("AesKeyGenParams", dictAesKeyGenParams);
|
||||
|
||||
const dictHmacKeyGenParams = [
|
||||
...dictAlgorithm,
|
||||
{
|
||||
|
|
|
@ -180,6 +180,18 @@ pub async fn op_crypto_generate_key(
|
|||
|
||||
private_key
|
||||
}
|
||||
Algorithm::AesCtr
|
||||
| Algorithm::AesCbc
|
||||
| Algorithm::AesGcm
|
||||
| Algorithm::AesKw => {
|
||||
let length = args.length.ok_or_else(not_supported)?;
|
||||
let mut key_data = vec![0u8; length];
|
||||
let rng = RingRand::SystemRandom::new();
|
||||
rng.fill(&mut key_data).map_err(|_| {
|
||||
custom_error("DOMExceptionOperationError", "Key generation failed")
|
||||
})?;
|
||||
key_data
|
||||
}
|
||||
Algorithm::Hmac => {
|
||||
let hash: HmacAlgorithm = args.hash.ok_or_else(not_supported)?.into();
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue