feat: Validate named curve paramters on importing
This commit is contained in:
parent
b9a4fe2ad6
commit
7624baf42b
|
@ -140,11 +140,13 @@ export class EcCrypto {
|
||||||
case "spki": {
|
case "spki": {
|
||||||
const keyInfo = AsnParser.parse(new Uint8Array(keyData as ArrayBuffer), core.asn1.PublicKeyInfo);
|
const keyInfo = AsnParser.parse(new Uint8Array(keyData as ArrayBuffer), core.asn1.PublicKeyInfo);
|
||||||
const asnKey = new core.asn1.EcPublicKey(keyInfo.publicKey);
|
const asnKey = new core.asn1.EcPublicKey(keyInfo.publicKey);
|
||||||
|
this.assertKeyParameters(keyInfo.publicKeyAlgorithm.parameters, algorithm.namedCurve);
|
||||||
return this.importPublicKey(asnKey, algorithm, extractable, keyUsages);
|
return this.importPublicKey(asnKey, algorithm, extractable, keyUsages);
|
||||||
}
|
}
|
||||||
case "pkcs8": {
|
case "pkcs8": {
|
||||||
const keyInfo = AsnParser.parse(new Uint8Array(keyData as ArrayBuffer), core.asn1.PrivateKeyInfo);
|
const keyInfo = AsnParser.parse(new Uint8Array(keyData as ArrayBuffer), core.asn1.PrivateKeyInfo);
|
||||||
const asnKey = AsnParser.parse(keyInfo.privateKey, core.asn1.EcPrivateKey);
|
const asnKey = AsnParser.parse(keyInfo.privateKey, core.asn1.EcPrivateKey);
|
||||||
|
this.assertKeyParameters(keyInfo.privateKeyAlgorithm.parameters, algorithm.namedCurve);
|
||||||
return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages);
|
return this.importPrivateKey(asnKey, algorithm, extractable, keyUsages);
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -152,6 +154,23 @@ export class EcCrypto {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static assertKeyParameters(parameters: ArrayBuffer | null | undefined, namedCurve: string) {
|
||||||
|
if (!parameters) {
|
||||||
|
throw new core.CryptoError("Key info doesn't have required parameters");
|
||||||
|
}
|
||||||
|
|
||||||
|
let namedCurveIdentifier = "";
|
||||||
|
try {
|
||||||
|
namedCurveIdentifier = AsnParser.parse(parameters, core.asn1.ObjectIdentifier).value;
|
||||||
|
} catch (e) {
|
||||||
|
throw new core.CryptoError("Cannot read key info parameters");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getOidByNamedCurve(namedCurve) !== namedCurveIdentifier) {
|
||||||
|
throw new core.CryptoError("Key info parameter doesn't match to named curve");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected static async importPrivateKey(asnKey: core.asn1.EcPrivateKey, algorithm: EcKeyImportParams, extractable: boolean, keyUsages: KeyUsage[]) {
|
protected static async importPrivateKey(asnKey: core.asn1.EcPrivateKey, algorithm: EcKeyImportParams, extractable: boolean, keyUsages: KeyUsage[]) {
|
||||||
const keyInfo = new core.asn1.PrivateKeyInfo();
|
const keyInfo = new core.asn1.PrivateKeyInfo();
|
||||||
keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.10045.2.1";
|
keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.10045.2.1";
|
||||||
|
@ -171,7 +190,8 @@ export class EcCrypto {
|
||||||
protected static async importPublicKey(asnKey: core.asn1.EcPublicKey, algorithm: EcKeyImportParams, extractable: boolean, keyUsages: KeyUsage[]) {
|
protected static async importPublicKey(asnKey: core.asn1.EcPublicKey, algorithm: EcKeyImportParams, extractable: boolean, keyUsages: KeyUsage[]) {
|
||||||
const keyInfo = new core.asn1.PublicKeyInfo();
|
const keyInfo = new core.asn1.PublicKeyInfo();
|
||||||
keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.10045.2.1";
|
keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.10045.2.1";
|
||||||
keyInfo.publicKeyAlgorithm.parameters = AsnSerializer.serialize(new core.asn1.ObjectIdentifier(getOidByNamedCurve(algorithm.namedCurve)));
|
const namedCurve = getOidByNamedCurve(algorithm.namedCurve);
|
||||||
|
keyInfo.publicKeyAlgorithm.parameters = AsnSerializer.serialize(new core.asn1.ObjectIdentifier(namedCurve));
|
||||||
keyInfo.publicKey = asnKey.value;
|
keyInfo.publicKey = asnKey.value;
|
||||||
|
|
||||||
const key = new EcPublicKey();
|
const key = new EcPublicKey();
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import assert from "assert";
|
import assert from "assert";
|
||||||
import { WebcryptoTest } from "@peculiar/webcrypto-test";
|
import { WebcryptoTest } from "@peculiar/webcrypto-test";
|
||||||
|
import * as core from "webcrypto-core";
|
||||||
import { Crypto } from "../src";
|
import { Crypto } from "../src";
|
||||||
|
|
||||||
const crypto = new Crypto();
|
const crypto = new Crypto();
|
||||||
|
@ -14,18 +15,28 @@ context("Crypto", () => {
|
||||||
const array = new Uint8Array(5);
|
const array = new Uint8Array(5);
|
||||||
const array2 = crypto.getRandomValues(array);
|
const array2 = crypto.getRandomValues(array);
|
||||||
|
|
||||||
assert.notEqual(Buffer.from(array).toString("hex"), "0000000000");
|
assert.notStrictEqual(Buffer.from(array).toString("hex"), "0000000000");
|
||||||
assert.equal(Buffer.from(array2).equals(array), true);
|
assert.strictEqual(Buffer.from(array2).equals(array), true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("Uint16Array", () => {
|
it("Uint16Array", () => {
|
||||||
const array = new Uint16Array(5);
|
const array = new Uint16Array(5);
|
||||||
const array2 = crypto.getRandomValues(array);
|
const array2 = crypto.getRandomValues(array);
|
||||||
|
|
||||||
assert.notEqual(Buffer.from(array).toString("hex"), "00000000000000000000");
|
assert.notStrictEqual(Buffer.from(array).toString("hex"), "00000000000000000000");
|
||||||
assert.equal(Buffer.from(array2).equals(Buffer.from(array)), true);
|
assert.strictEqual(Buffer.from(array2).equals(Buffer.from(array)), true);
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Import wrong named curve", async () => {
|
||||||
|
const spki = Buffer.from("MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAETzlbSDQWz+1nwEHsrT516OAEX5YWzwVYj39BH+Rv5yoP9yLgM5wIXgOls5DoLDJVQ+45XDrD/xjSCcul5NACZw==", "base64");
|
||||||
|
await assert.rejects(crypto.subtle.importKey(
|
||||||
|
"spki",
|
||||||
|
spki,
|
||||||
|
{ name: "ECDSA", namedCurve: "K-256" } as Algorithm,
|
||||||
|
false,
|
||||||
|
["verify"]), core.CryptoError);
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
Reference in New Issue