UNPKG

@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

205 lines (201 loc) • 10.1 kB
import { AgentContext } from "../../agent/context/AgentContext.mjs"; import { injectable } from "../../plugins/index.mjs"; import { __decorateMetadata } from "../../_virtual/_@oxc-project_runtime@0.112.0/helpers/decorateMetadata.mjs"; import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.112.0/helpers/decorate.mjs"; import "../../agent/index.mjs"; import { KeyManagementError } from "./error/KeyManagementError.mjs"; import { KeyManagementKeyNotFoundError } from "./error/KeyManagementKeyNotFoundError.mjs"; import { getJwkHumanDescription } from "./jwk/humanDescription.mjs"; import { createKeyTypeForSigningAlgorithm } from "./jwk/alg/signing.mjs"; import { zParseWithErrorHandling } from "../../utils/zod.mjs"; import "./jwk/index.mjs"; import { KeyManagementModuleConfig } from "./KeyManagementModuleConfig.mjs"; import { getKmsOperationHumanDescription } from "./options/KmsOperation.mjs"; import "./options/index.mjs"; import { zWithBackend } from "./options/backend.mjs"; import { zKmsCreateKeyForSignatureAlgorithmOptions, zKmsCreateKeyOptions } from "./options/KmsCreateKeyOptions.mjs"; import { zKmsEncryptOptions } from "./options/KmsEncryptOptions.mjs"; import { zKmsDecryptOptions } from "./options/KmsDecryptOptions.mjs"; import { zKmsDeleteKeyOptions } from "./options/KmsDeleteKeyOptions.mjs"; import { zKmsGetPublicKeyOptions } from "./options/KmsGetPublicKeyOptions.mjs"; import { zKmsImportKeyOptions } from "./options/KmsImportKeyOptions.mjs"; import { zKmsRandomBytesOptions } from "./options/KmsRandomBytesOptions.mjs"; import { zKmsSignOptions } from "./options/KmsSignOptions.mjs"; import { zKmsVerifyOptions } from "./options/KmsVerifyOptions.mjs"; //#region src/modules/kms/KeyManagementApi.ts var _ref, _ref2; let KeyManagementApi = class KeyManagementApi { constructor(keyManagementConfig, agentContext) { this.keyManagementConfig = keyManagementConfig; this.agentContext = agentContext; } /** * Whether an operation is supported. * * @returns a list of backends that support the operation. In case * no backends are supported it returns an empty array */ supportedBackendsForOperation(operation) { const supportedBackends = []; for (const kms of this.keyManagementConfig.backends) if (kms.isOperationSupported(this.agentContext, operation)) supportedBackends.push(kms.backend); return supportedBackends; } /** * Create a key. */ async createKey(options) { const { backend, ...kmsOptions } = zParseWithErrorHandling(zWithBackend(zKmsCreateKeyOptions), options, "Invalid options provided to createKey method"); const key = await this.getKms(this.agentContext, backend, { operation: "createKey", type: options.type }).createKey(this.agentContext, kmsOptions); key.publicJwk.kid = key.keyId; this.agentContext.config.logger.debug(`Created key ${getJwkHumanDescription(key.publicJwk)} with key id '${key.keyId}'`); return key; } /** * Create a key. */ async createKeyForSignatureAlgorithm(options) { const { backend, algorithm, ...kmsOptions } = zParseWithErrorHandling(zWithBackend(zKmsCreateKeyForSignatureAlgorithmOptions), options, "Invalid options provided to createKeyForSignatureAlgorithm method"); const type = createKeyTypeForSigningAlgorithm(algorithm); const key = await this.getKms(this.agentContext, backend, { operation: "createKey", type }).createKey(this.agentContext, { ...kmsOptions, type }); key.publicJwk.kid = key.keyId; return key; } /** * Sign using a key. */ async sign(options) { const { backend, ...kmsOptions } = zParseWithErrorHandling(zWithBackend(zKmsSignOptions), options, "Invalid options provided to sign method"); const operation = { operation: "sign", algorithm: options.algorithm }; return await (backend ? this.getKms(this.agentContext, backend, operation) : (await this.getKmsForOperationAndKeyId(this.agentContext, options.keyId, operation)).kms).sign(this.agentContext, kmsOptions); } /** * Verify using a key. */ async verify(options) { const { backend, ...kmsOptions } = zParseWithErrorHandling(zWithBackend(zKmsVerifyOptions), options, "Invalid options provided to verify method"); const operation = { operation: "verify", algorithm: options.algorithm }; return await (backend || typeof options.key !== "string" ? this.getKms(this.agentContext, backend, operation) : (await this.getKmsForOperationAndKeyId(this.agentContext, options.key, operation)).kms).verify(this.agentContext, kmsOptions); } /** * Encrypt. */ async encrypt(options) { const { backend, ...kmsOptions } = zParseWithErrorHandling(zWithBackend(zKmsEncryptOptions), options, "Invalid options provided to encrypt method"); const operation = { operation: "encrypt", encryption: options.encryption, keyAgreement: options.key.keyAgreement }; return await (backend || typeof options.key !== "string" ? this.getKms(this.agentContext, backend, operation) : (await this.getKmsForOperationAndKeyId(this.agentContext, options.key, operation)).kms).encrypt(this.agentContext, kmsOptions); } /** * Decrypt. */ async decrypt(options) { const { backend, ...kmsOptions } = zParseWithErrorHandling(zWithBackend(zKmsDecryptOptions), options, "Invalid options provided to decrypt method"); const operation = { operation: "decrypt", decryption: options.decryption, keyAgreement: options.key.keyAgreement }; return await (backend || typeof options.key !== "string" ? this.getKms(this.agentContext, backend, operation) : (await this.getKmsForOperationAndKeyId(this.agentContext, options.key, operation)).kms).decrypt(this.agentContext, kmsOptions); } /** * Import a key. */ async importKey(options) { const { backend, ...kmsOptions } = zParseWithErrorHandling(zWithBackend(zKmsImportKeyOptions), options, "Invalid options provided to importKey method"); const operation = { operation: "importKey", privateJwk: options.privateJwk }; const key = await this.getKms(this.agentContext, backend, operation).importKey(this.agentContext, kmsOptions); this.agentContext.config.logger.trace(`Imported key ${getJwkHumanDescription(key.publicJwk)} with key id '${key.keyId}'`); return key; } /** * Get a public key. */ async getPublicKey(options) { const { backend, keyId } = zParseWithErrorHandling(zWithBackend(zKmsGetPublicKeyOptions), options, "Invalid options provided to getPublicKey method"); if (backend) { if (!await this.getKms(this.agentContext, backend).getPublicKey(this.agentContext, keyId)) throw new KeyManagementKeyNotFoundError(keyId, [backend]); } const { publicKey } = await this.getKmsForOperationAndKeyId(this.agentContext, options.keyId); return publicKey; } /** * Delete a key. */ async deleteKey(options) { const { backend, ...kmsOptions } = zParseWithErrorHandling(zWithBackend(zKmsDeleteKeyOptions), options, "Invalid options provided to deleteKey method"); return await this.getKms(this.agentContext, backend, { operation: "deleteKey" }).deleteKey(this.agentContext, kmsOptions); } /** * Generate random bytes */ randomBytes(options) { const { backend, ...kmsOptions } = zParseWithErrorHandling(zWithBackend(zKmsRandomBytesOptions), options, "Invalid options provided to randomBytes method"); return this.getKms(this.agentContext, backend, { operation: "randomBytes" }).randomBytes(this.agentContext, kmsOptions); } /** * Get the kms associated with a specific `keyId`. * * This uses a naive approach of fetching the key for each configured kms * until it finds the registered key. * * In the future this approach might be optimized based on: * - caching * - keeping a registry * - backend specific key prefixes */ async getKmsForOperationAndKeyId(agentContext, keyId, operation) { for (const kms of this.keyManagementConfig.backends) { if (!(operation ? kms.isOperationSupported(agentContext, operation) : true)) continue; const publicKey = await kms.getPublicKey(this.agentContext, keyId); if (publicKey) return { publicKey, kms }; } if (operation) throw new KeyManagementKeyNotFoundError(keyId, this.keyManagementConfig.backends.map((b) => b.backend), `The key may exist in one of the key management services in which case the key management service does not support the ${getKmsOperationHumanDescription(operation)}`); throw new KeyManagementKeyNotFoundError(keyId, this.keyManagementConfig.backends.map((b) => b.backend)); } /** * Get the kms backend for a specific operation. * * If a backend is provided, it will be checked if the backend supports * the operation. Otherwise the first backend that supports the operation * will be used. */ getKms(agentContext, backend, operation) { if (backend) { const kms = this.keyManagementConfig.backends.find((kms) => kms.backend === backend); if (!kms) throw new KeyManagementError(`No key management service is configured for backend '${backend}'. Available backends are ${this.keyManagementConfig.backends.map((kms) => `'${kms.backend}'`).join(", ")}`); if (!(operation ? kms.isOperationSupported(agentContext, operation) : true) && operation) throw new KeyManagementError(`Key management service backend '${backend}' does not support ${getKmsOperationHumanDescription(operation)}`); return kms; } for (const kms of this.keyManagementConfig.backends) if (operation ? kms.isOperationSupported(agentContext, operation) : true) return kms; if (operation) throw new KeyManagementError(`No key management service backend found that supports ${getKmsOperationHumanDescription(operation)}`); throw new KeyManagementError("No key management service backend found."); } }; KeyManagementApi = __decorate([injectable(), __decorateMetadata("design:paramtypes", [typeof (_ref = typeof KeyManagementModuleConfig !== "undefined" && KeyManagementModuleConfig) === "function" ? _ref : Object, typeof (_ref2 = typeof AgentContext !== "undefined" && AgentContext) === "function" ? _ref2 : Object])], KeyManagementApi); //#endregion export { KeyManagementApi }; //# sourceMappingURL=KeyManagementApi.mjs.map