@microsoft/useragent-sdk
Version:
SDK for building decentralized identity wallets and enterprise agents.
141 lines • 5.93 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const W3cCryptoApiConstants_1 = require("./W3cCryptoApiConstants");
const JoseConstants_1 = require("../protocols/jose/JoseConstants");
/**
* Crypto helpers support for plugable crypto layer
*/
class CryptoHelpers {
/**
* The API which implements the requested algorithm
* @param cryptoFactory Crypto suite
* @param algorithmName Requested algorithm
* @param hash Optional hash for the algorithm
*/
static getSubtleCryptoForAlgorithm(cryptoFactory, algorithm) {
const jwa = CryptoHelpers.webCryptoToJwa(algorithm);
switch (algorithm.name.toUpperCase()) {
case 'RSASSA-PKCS1-V1_5':
case 'ECDSA':
case 'EDDSA':
case 'ED25519':
return cryptoFactory.getMessageSigner(jwa);
case 'RSA-OAEP':
case 'RSA-OAEP-256':
return cryptoFactory.getKeyEncrypter(jwa);
case 'AES-GCM':
return cryptoFactory.getSymmetricEncrypter(jwa);
case 'HMAC':
return cryptoFactory.getMessageAuthenticationCodeSigners(jwa);
case 'SHA-256':
case 'SHA-384':
case 'SHA-512':
return cryptoFactory.getMessageDigest(jwa);
}
throw new Error(`Algorithm '${JSON.stringify(algorithm)}' is not supported`);
}
/**
* Map the JWA algorithm to the W3C crypto API algorithm.
* The method restricts the supported algorithms. This can easily be extended.
* Based on https://www.w3.org/TR/WebCryptoAPI/ A. Mapping between JSON Web Key / JSON Web Algorithm
* @param jwaAlgorithmName Requested algorithm
*/
static jwaToWebCrypto(jwa, ...args) {
const regex = new RegExp('\\d+');
let matches;
switch (jwa.toUpperCase()) {
case JoseConstants_1.default.Rs256:
case JoseConstants_1.default.Rs384:
case JoseConstants_1.default.Rs512:
matches = regex.exec(jwa);
return { name: W3cCryptoApiConstants_1.default.RsaSsaPkcs1V15, hash: { name: `SHA-${CryptoHelpers.getRegexMatch(matches, 0)}` } };
case JoseConstants_1.default.RsaOaep:
case JoseConstants_1.default.RsaOaep256:
return { name: 'RSA-OAEP', hash: 'SHA-256' };
case JoseConstants_1.default.AesGcm128:
case JoseConstants_1.default.AesGcm192:
case JoseConstants_1.default.AesGcm256:
const iv = args[0];
const aad = args[1];
matches = regex.exec(jwa);
const length = parseInt(CryptoHelpers.getRegexMatch(matches, 0));
return { name: W3cCryptoApiConstants_1.default.AesGcm, iv: iv, additionalData: aad, tagLength: 128, length: length };
case JoseConstants_1.default.Es256K:
return { name: 'ECDSA', namedCurve: 'P-256K', hash: { name: 'SHA-256' }, format: 'DER' };
case JoseConstants_1.default.EdDSA:
case 'ED25519':
return { name: 'EDDSA', namedCurve: 'ed25519', hash: { name: 'SHA-256' } };
}
throw new Error(`Algorithm ${JSON.stringify(jwa)} is not supported`);
}
/**
* Maps the subtle crypto algorithm name to the JWA name
* @param algorithmName Requested algorithm
* @param hash Optional hash for the algorithm
*/
static webCryptoToJwa(algorithm) {
const hash = algorithm.hash || 'SHA-256';
switch (algorithm.name.toUpperCase()) {
case 'RSASSA-PKCS1-V1_5':
return `RS${CryptoHelpers.getHash(hash)}`;
case 'ECDSA':
return `ES256K`;
case 'EDDSA':
case 'ED25519':
return `EdDSA`;
case 'RSA-OAEP-256':
return 'RSA-OAEP-256';
case 'RSA-OAEP':
return `RSA-OAEP-${CryptoHelpers.getHash(hash)}`;
case 'AES-GCM':
const length = algorithm.length || 128;
return `A${length}GCMKW`;
case 'HMAC':
return `HS${CryptoHelpers.getHash(hash)}`;
case 'SHA-256':
case 'SHA-384':
case 'SHA-512':
return `SHA${CryptoHelpers.getHash(hash)}`;
}
throw new Error(`Algorithm '${JSON.stringify(algorithm)}' is not supported`);
}
/**
* Derive the key import algorithm
* @param algorithm used for signature
*/
static getKeyImportAlgorithm(algorithm, jwk) {
const hash = algorithm.hash || 'SHA-256';
const name = algorithm.name;
switch (algorithm.name.toUpperCase()) {
case 'RSASSA-PKCS1-V1_5':
return { name, hash: { name: "SHA-256" } };
case 'HMAC':
case 'SHA-256':
case 'SHA-384':
case 'SHA-512':
return { name, hash };
case 'ECDSA':
case 'EDDSA':
case 'ECDH':
case 'ED25519':
return { name, namedCurve: jwk.crv };
case 'RSA-OAEP':
case 'RSA-OAEP-256':
return { name, hash: 'SHA-256' };
case 'AES-GCM':
return { name };
}
throw new Error(`Algorithm '${JSON.stringify(algorithm)}' is not supported`);
}
static getHash(hash) {
if (hash.name) {
return (hash.name).toUpperCase().replace('SHA-', '');
}
return (hash || 'SHA-256').toUpperCase().replace('SHA-', '');
}
static getRegexMatch(matches, index) {
return matches[index];
}
}
exports.default = CryptoHelpers;
//# sourceMappingURL=CryptoHelpers.js.map