@credo-ts/core
Version:
<p align="center"> <br /> <img alt="Credo Logo" src="https://github.com/openwallet-foundation/credo-ts/blob/c7886cb8377ceb8ee4efe8d264211e561a75072d/images/credo-logo.png" height="250px" /> </p> <h1 align="center"><b>Credo - Core</b></h1
177 lines (176 loc) • 6.25 kB
JavaScript
import { TypedArrayEncoder } from "../../../utils/TypedArrayEncoder.mjs";
import "../../../utils/index.mjs";
import { PublicJwk } from "../../../modules/kms/jwk/PublicJwk.mjs";
import "../../../modules/kms/index.mjs";
import { CredoWebCryptoError } from "../CredoWebCryptoError.mjs";
import { ecPublicKeyWithK256AlgorithmIdentifier, ecPublicKeyWithP256AlgorithmIdentifier, ecPublicKeyWithP384AlgorithmIdentifier, ecPublicKeyWithP521AlgorithmIdentifier, ed25519AlgorithmIdentifier, rsaKeyAlgorithmIdentifier, x25519AlgorithmIdentifier } from "../algorithmIdentifiers.mjs";
import { AsnParser, AsnSerializer } from "@peculiar/asn1-schema";
import { SubjectPublicKeyInfo } from "@peculiar/asn1-x509";
import { RSAPublicKey } from "@peculiar/asn1-rsa";
//#region src/crypto/webcrypto/utils/keyAlgorithmConversion.ts
const publicJwkToCryptoKeyAlgorithm = (key, options) => {
const publicJwk = key.toJson();
if (publicJwk.kty === "EC") {
if (publicJwk.crv === "P-256" || publicJwk.crv === "P-384" || publicJwk.crv === "P-521") return {
name: "ECDSA",
namedCurve: publicJwk.crv
};
if (publicJwk.crv === "secp256k1") return {
name: "ECDSA",
namedCurve: "K-256"
};
} else if (publicJwk.kty === "OKP") {
if (publicJwk.crv === "Ed25519") return { name: "Ed25519" };
} else if (publicJwk.kty === "RSA") {
const modulusLength = TypedArrayEncoder.fromBase64Url(publicJwk.n).length * 8;
const publicExponent = TypedArrayEncoder.fromBase64Url(publicJwk.e);
switch (publicJwk.alg ?? options?.alg) {
case "PS256": return {
name: "RSA-PSS",
modulusLength,
publicExponent,
hash: { name: "SHA-256" }
};
case "PS384": return {
name: "RSA-PSS",
modulusLength,
publicExponent,
hash: { name: "SHA-384" }
};
case "PS512": return {
name: "RSA-PSS",
modulusLength,
publicExponent,
hash: { name: "SHA-512" }
};
case "RS256": return {
name: "RSASSA-PKCS1-v1_5",
modulusLength,
publicExponent,
hash: { name: "SHA-256" }
};
case "RS384": return {
name: "RSASSA-PKCS1-v1_5",
modulusLength,
publicExponent,
hash: { name: "SHA-384" }
};
case "RS512": return {
name: "RSASSA-PKCS1-v1_5",
modulusLength,
publicExponent,
hash: { name: "SHA-512" }
};
}
}
throw new CredoWebCryptoError(`Unsupported ${key.jwkTypeHumanDescription}`);
};
const cryptoKeyAlgorithmToCreateKeyOptions = (algorithm) => {
const algorithmName = algorithm.name.toUpperCase();
switch (algorithmName) {
case "ED25519": return {
kty: "OKP",
crv: "Ed25519"
};
case "X25519": return {
kty: "OKP",
crv: "X25519"
};
case "ECDSA": {
const crv = algorithm.namedCurve.toUpperCase();
switch (crv) {
case "P-256":
case "P-384":
case "P-521": return {
kty: "EC",
crv
};
case "K-256": return {
kty: "EC",
crv: "secp256k1"
};
default: throw new CredoWebCryptoError(`Unsupported curve for ECDSA: ${algorithm.namedCurve}`);
}
}
case "RSASSA-PKCS1-V1_5":
case "RSA-PSS": {
const rsaParams = algorithm;
if (rsaParams.publicExponent) throw new CredoWebCryptoError("Custom exponent not suported for RSA");
if (rsaParams.modulusLength !== 2048 && rsaParams.modulusLength !== 3072 && rsaParams.modulusLength !== 4096) throw new CredoWebCryptoError(`Unsupported modulusLength '${rsaParams.modulusLength}' for RSA key. Expected one of 2048, 3072, 4096.`);
return {
kty: "RSA",
modulusLength: rsaParams.modulusLength
};
}
}
throw new CredoWebCryptoError(`Unsupported algorithm: ${algorithmName}`);
};
const spkiToPublicJwk = (spki) => {
if (spki.algorithm.isEqual(ecPublicKeyWithP256AlgorithmIdentifier)) return PublicJwk.fromPublicKey({
kty: "EC",
crv: "P-256",
publicKey: new Uint8Array(spki.subjectPublicKey)
});
if (spki.algorithm.isEqual(ecPublicKeyWithP384AlgorithmIdentifier)) return PublicJwk.fromPublicKey({
kty: "EC",
crv: "P-384",
publicKey: new Uint8Array(spki.subjectPublicKey)
});
if (spki.algorithm.isEqual(ecPublicKeyWithP521AlgorithmIdentifier)) return PublicJwk.fromPublicKey({
kty: "EC",
crv: "P-521",
publicKey: new Uint8Array(spki.subjectPublicKey)
});
if (spki.algorithm.isEqual(ecPublicKeyWithK256AlgorithmIdentifier)) return PublicJwk.fromPublicKey({
kty: "EC",
crv: "secp256k1",
publicKey: new Uint8Array(spki.subjectPublicKey)
});
if (spki.algorithm.isEqual(ed25519AlgorithmIdentifier)) return PublicJwk.fromPublicKey({
kty: "OKP",
crv: "Ed25519",
publicKey: new Uint8Array(spki.subjectPublicKey)
});
if (spki.algorithm.isEqual(x25519AlgorithmIdentifier)) return PublicJwk.fromPublicKey({
kty: "OKP",
crv: "X25519",
publicKey: new Uint8Array(spki.subjectPublicKey)
});
if (spki.algorithm.isEqual(rsaKeyAlgorithmIdentifier)) {
const rsaPublicKey = AsnParser.parse(spki.subjectPublicKey, RSAPublicKey);
return PublicJwk.fromPublicKey({
kty: "RSA",
modulus: new Uint8Array(rsaPublicKey.modulus),
exponent: new Uint8Array(rsaPublicKey.publicExponent)
});
}
throw new CredoWebCryptoError(`Unsupported algorithm: ${spki.algorithm.algorithm}, with params: ${spki.algorithm.parameters ? "yes" : "no"}`);
};
const publicJwkToSpki = (publicJwk) => {
const publicKey = publicJwk.publicKey;
if (publicKey.kty === "RSA") {
const rsaPublicKey = new RSAPublicKey({
modulus: new Uint8Array(publicKey.modulus).buffer,
publicExponent: new Uint8Array(publicKey.exponent).buffer
});
const rsaPublicKeyDer = AsnSerializer.serialize(rsaPublicKey);
return new SubjectPublicKeyInfo({
algorithm: rsaKeyAlgorithmIdentifier,
subjectPublicKey: rsaPublicKeyDer
});
}
return new SubjectPublicKeyInfo({
algorithm: {
"P-256": ecPublicKeyWithP256AlgorithmIdentifier,
"P-384": ecPublicKeyWithP384AlgorithmIdentifier,
"P-521": ecPublicKeyWithP521AlgorithmIdentifier,
secp256k1: ecPublicKeyWithK256AlgorithmIdentifier,
Ed25519: ed25519AlgorithmIdentifier,
X25519: x25519AlgorithmIdentifier
}[publicKey.crv],
subjectPublicKey: new Uint8Array(publicKey.publicKey).buffer
});
};
//#endregion
export { cryptoKeyAlgorithmToCreateKeyOptions, publicJwkToCryptoKeyAlgorithm, publicJwkToSpki, spkiToPublicJwk };
//# sourceMappingURL=keyAlgorithmConversion.mjs.map