mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -05:00
feat(ext/crypto): export elliptic keys as "raw" (#14764)
This commit adds support for the "raw" format when exporting public ECDH/ECDSA keys via the SubtleCrypto.exportKey method.
This commit is contained in:
parent
753f32024f
commit
ff5def9ed5
3 changed files with 104 additions and 5 deletions
|
@ -1318,11 +1318,19 @@ Deno.test(async function testImportEcDhJwk() {
|
|||
}
|
||||
});
|
||||
|
||||
const ecTestKeys = {
|
||||
"256": {
|
||||
const ecTestKeys = [
|
||||
{
|
||||
size: 256,
|
||||
namedCurve: "P-256",
|
||||
// deno-fmt-ignore
|
||||
raw: new Uint8Array([
|
||||
4, 210, 16, 176, 166, 249, 217, 240, 18, 134, 128, 88, 180, 63, 164, 244,
|
||||
113, 1, 133, 67, 187, 160, 12, 146, 80, 223, 146, 87, 194, 172, 174, 93,
|
||||
209, 206, 3, 117, 82, 212, 129, 69, 12, 227, 155, 77, 16, 149, 112, 27,
|
||||
23, 91, 250, 179, 75, 142, 108, 9, 158, 24, 241, 193, 152, 53, 131, 97,
|
||||
232,
|
||||
]),
|
||||
// deno-fmt-ignore
|
||||
spki: new Uint8Array([
|
||||
48, 89, 48, 19, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 8, 42, 134, 72, 206,
|
||||
61, 3, 1, 7, 3, 66, 0, 4, 210, 16, 176, 166, 249, 217, 240, 18, 134, 128,
|
||||
|
@ -1344,16 +1352,69 @@ const ecTestKeys = {
|
|||
131, 97, 232,
|
||||
]),
|
||||
},
|
||||
};
|
||||
{
|
||||
size: 384,
|
||||
namedCurve: "P-384",
|
||||
// deno-fmt-ignore
|
||||
raw: new Uint8Array([
|
||||
4, 118, 64, 176, 165, 100, 177, 112, 49, 254, 58, 53, 158, 63, 73, 200,
|
||||
148, 248, 242, 216, 186, 80, 92, 160, 53, 64, 232, 157, 19, 1, 12, 226,
|
||||
115, 51, 42, 143, 98, 206, 55, 220, 108, 78, 24, 71, 157, 21, 120, 126,
|
||||
104, 157, 86, 48, 226, 110, 96, 52, 48, 77, 170, 9, 231, 159, 26, 165,
|
||||
200, 26, 164, 99, 46, 227, 169, 105, 172, 225, 60, 102, 141, 145, 139,
|
||||
165, 47, 72, 53, 17, 17, 246, 161, 220, 26, 21, 23, 219, 1, 107, 185,
|
||||
163, 215,
|
||||
]),
|
||||
// deno-fmt-ignore
|
||||
spki: new Uint8Array([
|
||||
48, 118, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43, 129, 4, 0,
|
||||
34, 3, 98, 0, 4, 118, 64, 176, 165, 100, 177, 112, 49, 254, 58, 53, 158,
|
||||
63, 73, 200, 148, 248, 242, 216, 186, 80, 92, 160, 53, 64, 232, 157, 19,
|
||||
1, 12, 226, 115, 51, 42, 143, 98, 206, 55, 220, 108, 78, 24, 71, 157, 21,
|
||||
120, 126, 104, 157, 86, 48, 226, 110, 96, 52, 48, 77, 170, 9, 231, 159,
|
||||
26, 165, 200, 26, 164, 99, 46, 227, 169, 105, 172, 225, 60, 102, 141,
|
||||
145, 139, 165, 47, 72, 53, 17, 17, 246, 161, 220, 26, 21, 23, 219, 1,
|
||||
107, 185, 163, 215,
|
||||
]),
|
||||
// deno-fmt-ignore
|
||||
pkcs8: new Uint8Array([
|
||||
48, 129, 182, 2, 1, 0, 48, 16, 6, 7, 42, 134, 72, 206, 61, 2, 1, 6, 5, 43,
|
||||
129, 4, 0, 34, 4, 129, 158, 48, 129, 155, 2, 1, 1, 4, 48, 202, 7, 195,
|
||||
169, 124, 170, 81, 169, 253, 127, 56, 28, 98, 90, 255, 165, 72, 142, 133,
|
||||
138, 237, 200, 176, 92, 179, 192, 83, 28, 47, 118, 157, 152, 47, 65, 133,
|
||||
140, 50, 83, 182, 191, 224, 96, 216, 179, 59, 150, 15, 233, 161, 100, 3,
|
||||
98, 0, 4, 118, 64, 176, 165, 100, 177, 112, 49, 254, 58, 53, 158, 63, 73,
|
||||
200, 148, 248, 242, 216, 186, 80, 92, 160, 53, 64, 232, 157, 19, 1, 12,
|
||||
226, 115, 51, 42, 143, 98, 206, 55, 220, 108, 78, 24, 71, 157, 21, 120,
|
||||
126, 104, 157, 86, 48, 226, 110, 96, 52, 48, 77, 170, 9, 231, 159, 26,
|
||||
165, 200, 26, 164, 99, 46, 227, 169, 105, 172, 225, 60, 102, 141, 145,
|
||||
139, 165, 47, 72, 53, 17, 17, 246, 161, 220, 26, 21, 23, 219, 1, 107,
|
||||
185, 163, 215,
|
||||
]),
|
||||
},
|
||||
];
|
||||
|
||||
Deno.test(async function testImportEcSpkiPkcs8() {
|
||||
const subtle = window.crypto.subtle;
|
||||
assert(subtle);
|
||||
|
||||
for (
|
||||
const [_key, keyData] of Object.entries(ecTestKeys)
|
||||
const { namedCurve, raw, spki, pkcs8 } of ecTestKeys
|
||||
) {
|
||||
const { namedCurve, spki, pkcs8 } = keyData;
|
||||
const rawPublicKeyECDSA = await subtle.importKey(
|
||||
"raw",
|
||||
raw,
|
||||
{ name: "ECDSA", namedCurve },
|
||||
true,
|
||||
["verify"],
|
||||
);
|
||||
|
||||
const expPublicKeyRaw = await subtle.exportKey(
|
||||
"raw",
|
||||
rawPublicKeyECDSA,
|
||||
);
|
||||
|
||||
assertEquals(new Uint8Array(expPublicKeyRaw), raw);
|
||||
|
||||
const privateKeyECDSA = await subtle.importKey(
|
||||
"pkcs8",
|
||||
|
|
|
@ -3433,6 +3433,24 @@
|
|||
|
||||
function exportKeyEC(format, key, innerKey) {
|
||||
switch (format) {
|
||||
case "raw": {
|
||||
// 1.
|
||||
if (key[_type] !== "public") {
|
||||
throw new DOMException(
|
||||
"Key is not a public key",
|
||||
"InvalidAccessError",
|
||||
);
|
||||
}
|
||||
|
||||
// 2.
|
||||
const data = core.opSync("op_crypto_export_key", {
|
||||
algorithm: key[_algorithm].name,
|
||||
namedCurve: key[_algorithm].namedCurve,
|
||||
format: "raw",
|
||||
}, innerKey);
|
||||
|
||||
return data.buffer;
|
||||
}
|
||||
case "pkcs8": {
|
||||
// 1.
|
||||
if (key[_type] !== "private") {
|
||||
|
|
|
@ -25,6 +25,7 @@ pub struct ExportKeyOptions {
|
|||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum ExportKeyFormat {
|
||||
Raw,
|
||||
Pkcs8,
|
||||
Spki,
|
||||
JwkPublic,
|
||||
|
@ -54,6 +55,7 @@ pub enum ExportKeyAlgorithm {
|
|||
#[derive(Serialize)]
|
||||
#[serde(untagged)]
|
||||
pub enum ExportKeyResult {
|
||||
Raw(ZeroCopyBuf),
|
||||
Pkcs8(ZeroCopyBuf),
|
||||
Spki(ZeroCopyBuf),
|
||||
JwkSecret {
|
||||
|
@ -228,6 +230,24 @@ fn export_key_ec(
|
|||
named_curve: EcNamedCurve,
|
||||
) -> Result<ExportKeyResult, deno_core::anyhow::Error> {
|
||||
match format {
|
||||
ExportKeyFormat::Raw => {
|
||||
let subject_public_key = match named_curve {
|
||||
EcNamedCurve::P256 => {
|
||||
let point = key_data.as_ec_public_key_p256()?;
|
||||
|
||||
point.as_ref().to_vec()
|
||||
}
|
||||
EcNamedCurve::P384 => {
|
||||
let point = key_data.as_ec_public_key_p384()?;
|
||||
|
||||
point.as_ref().to_vec()
|
||||
}
|
||||
EcNamedCurve::P521 => {
|
||||
return Err(data_error("Unsupported named curve"))
|
||||
}
|
||||
};
|
||||
Ok(ExportKeyResult::Raw(subject_public_key.into()))
|
||||
}
|
||||
ExportKeyFormat::Spki => {
|
||||
let subject_public_key = match named_curve {
|
||||
EcNamedCurve::P256 => {
|
||||
|
|
Loading…
Add table
Reference in a new issue