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

1 lines • 17.3 kB
{"version":3,"file":"KeyManagementApi.mjs","names":[],"sources":["../../../src/modules/kms/KeyManagementApi.ts"],"sourcesContent":["import { AgentContext } from '../../agent'\nimport { injectable } from '../../plugins'\nimport { zParseWithErrorHandling } from '../../utils/zod'\nimport { KeyManagementError } from './error/KeyManagementError'\nimport { KeyManagementKeyNotFoundError } from './error/KeyManagementKeyNotFoundError'\nimport { getJwkHumanDescription, type KmsJwkPrivate } from './jwk'\nimport { createKeyTypeForSigningAlgorithm } from './jwk/alg/signing'\nimport { KeyManagementModuleConfig } from './KeyManagementModuleConfig'\nimport {\n getKmsOperationHumanDescription,\n type KmsDecryptOptions,\n type KmsDeleteKeyOptions,\n type KmsGetPublicKeyOptions,\n type KmsImportKeyOptions,\n type KmsOperation,\n type KmsRandomBytesOptions,\n} from './options'\nimport { type WithBackend, zWithBackend } from './options/backend'\nimport {\n type KmsCreateKeyForSignatureAlgorithmOptions,\n type KmsCreateKeyOptions,\n type KmsCreateKeyReturn,\n type KmsCreateKeyType,\n type KmsCreateKeyTypeAsymmetric,\n zKmsCreateKeyForSignatureAlgorithmOptions,\n zKmsCreateKeyOptions,\n} from './options/KmsCreateKeyOptions'\nimport { zKmsDecryptOptions } from './options/KmsDecryptOptions'\nimport { zKmsDeleteKeyOptions } from './options/KmsDeleteKeyOptions'\nimport { type KmsEncryptOptions, zKmsEncryptOptions } from './options/KmsEncryptOptions'\nimport { zKmsGetPublicKeyOptions } from './options/KmsGetPublicKeyOptions'\nimport { type KmsImportKeyReturn, zKmsImportKeyOptions } from './options/KmsImportKeyOptions'\nimport { zKmsRandomBytesOptions } from './options/KmsRandomBytesOptions'\nimport { type KmsSignOptions, zKmsSignOptions } from './options/KmsSignOptions'\nimport { type KmsVerifyOptions, zKmsVerifyOptions } from './options/KmsVerifyOptions'\n\n@injectable()\nexport class KeyManagementApi {\n public constructor(\n private keyManagementConfig: KeyManagementModuleConfig,\n private agentContext: AgentContext\n ) {}\n\n /**\n * Whether an operation is supported.\n *\n * @returns a list of backends that support the operation. In case\n * no backends are supported it returns an empty array\n */\n public supportedBackendsForOperation(operation: KmsOperation): string[] {\n const supportedBackends: string[] = []\n\n for (const kms of this.keyManagementConfig.backends) {\n const isOperationSupported = kms.isOperationSupported(this.agentContext, operation)\n if (isOperationSupported) {\n supportedBackends.push(kms.backend)\n }\n }\n\n return supportedBackends\n }\n\n /**\n * Create a key.\n */\n public async createKey<Type extends KmsCreateKeyType>(\n options: WithBackend<KmsCreateKeyOptions<Type>>\n ): Promise<KmsCreateKeyReturn<Type>> {\n const { backend, ...kmsOptions } = zParseWithErrorHandling(\n zWithBackend(zKmsCreateKeyOptions),\n options,\n 'Invalid options provided to createKey method'\n )\n\n const kms = this.getKms(this.agentContext, backend, {\n operation: 'createKey',\n type: options.type,\n })\n\n const key = await kms.createKey(this.agentContext, kmsOptions)\n key.publicJwk.kid = key.keyId\n\n this.agentContext.config.logger.debug(\n `Created key ${getJwkHumanDescription(key.publicJwk)} with key id '${key.keyId}'`\n )\n\n return key\n }\n\n /**\n * Create a key.\n */\n public async createKeyForSignatureAlgorithm(\n options: WithBackend<KmsCreateKeyForSignatureAlgorithmOptions>\n ): Promise<KmsCreateKeyReturn<KmsCreateKeyTypeAsymmetric>> {\n const { backend, algorithm, ...kmsOptions } = zParseWithErrorHandling(\n zWithBackend(zKmsCreateKeyForSignatureAlgorithmOptions),\n options,\n 'Invalid options provided to createKeyForSignatureAlgorithm method'\n )\n\n const type = createKeyTypeForSigningAlgorithm(algorithm)\n const kms = this.getKms(this.agentContext, backend, {\n operation: 'createKey',\n type,\n })\n\n // Ensure the kid is set to the keyId\n const key = await kms.createKey(this.agentContext, {\n ...kmsOptions,\n type,\n })\n key.publicJwk.kid = key.keyId\n\n return key\n }\n\n /**\n * Sign using a key.\n */\n public async sign(options: WithBackend<KmsSignOptions>) {\n const { backend, ...kmsOptions } = zParseWithErrorHandling(\n zWithBackend(zKmsSignOptions),\n options,\n 'Invalid options provided to sign method'\n )\n\n const operation = {\n operation: 'sign',\n algorithm: options.algorithm,\n } as const\n\n const kms = backend\n ? this.getKms(this.agentContext, backend, operation)\n : (await this.getKmsForOperationAndKeyId(this.agentContext, options.keyId, operation)).kms\n return await kms.sign(this.agentContext, kmsOptions)\n }\n\n /**\n * Verify using a key.\n */\n public async verify(options: WithBackend<KmsVerifyOptions>) {\n const { backend, ...kmsOptions } = zParseWithErrorHandling(\n zWithBackend(zKmsVerifyOptions),\n options,\n 'Invalid options provided to verify method'\n )\n\n const operation = { operation: 'verify', algorithm: options.algorithm } as const\n const keyId = options.key.keyId\n const kms =\n backend || !keyId\n ? this.getKms(this.agentContext, backend, operation)\n : (await this.getKmsForOperationAndKeyId(this.agentContext, keyId, operation)).kms\n\n return await kms.verify(this.agentContext, kmsOptions)\n }\n\n /**\n * Encrypt.\n */\n public async encrypt(options: WithBackend<KmsEncryptOptions>) {\n const { backend, ...kmsOptions } = zParseWithErrorHandling(\n zWithBackend(zKmsEncryptOptions),\n options,\n 'Invalid options provided to encrypt method'\n )\n\n const operation = {\n operation: 'encrypt',\n encryption: options.encryption,\n keyAgreement: options.key.keyAgreement,\n } as const\n const keyId = routingKeyId(options.key)\n const kms =\n backend || !keyId\n ? this.getKms(this.agentContext, backend, operation)\n : (await this.getKmsForOperationAndKeyId(this.agentContext, keyId, operation)).kms\n\n return await kms.encrypt(this.agentContext, kmsOptions)\n }\n\n /**\n * Decrypt.\n */\n public async decrypt(options: WithBackend<KmsDecryptOptions>) {\n const { backend, ...kmsOptions } = zParseWithErrorHandling(\n zWithBackend(zKmsDecryptOptions),\n options,\n 'Invalid options provided to decrypt method'\n )\n\n const operation = {\n operation: 'decrypt',\n decryption: options.decryption,\n keyAgreement: options.key.keyAgreement,\n } as const\n const keyId = routingKeyId(options.key)\n const kms =\n backend || !keyId\n ? this.getKms(this.agentContext, backend, operation)\n : (await this.getKmsForOperationAndKeyId(this.agentContext, keyId, operation)).kms\n\n return await kms.decrypt(this.agentContext, kmsOptions)\n }\n\n /**\n * Import a key.\n */\n public async importKey<Jwk extends KmsJwkPrivate>(\n options: WithBackend<KmsImportKeyOptions<Jwk>>\n ): Promise<KmsImportKeyReturn<Jwk>> {\n const { backend, ...kmsOptions } = zParseWithErrorHandling(\n zWithBackend(zKmsImportKeyOptions),\n options,\n 'Invalid options provided to importKey method'\n )\n\n const operation = {\n operation: 'importKey',\n privateJwk: options.privateJwk,\n } as const\n const kms = this.getKms(this.agentContext, backend, operation)\n\n const key = await kms.importKey(this.agentContext, kmsOptions)\n\n this.agentContext.config.logger.trace(\n `Imported key ${getJwkHumanDescription(key.publicJwk)} with key id '${key.keyId}'`\n )\n\n return key\n }\n\n /**\n * Get a public key.\n */\n public async getPublicKey(options: WithBackend<KmsGetPublicKeyOptions>) {\n const { backend, keyId } = zParseWithErrorHandling(\n zWithBackend(zKmsGetPublicKeyOptions),\n options,\n 'Invalid options provided to getPublicKey method'\n )\n\n if (backend) {\n const kms = this.getKms(this.agentContext, backend)\n const publicKey = await kms.getPublicKey(this.agentContext, keyId)\n\n if (!publicKey) {\n throw new KeyManagementKeyNotFoundError(keyId, [backend])\n }\n }\n\n const { publicKey } = await this.getKmsForOperationAndKeyId(this.agentContext, options.keyId)\n return publicKey\n }\n\n /**\n * Delete a key.\n */\n public async deleteKey(options: WithBackend<KmsDeleteKeyOptions>) {\n const { backend, ...kmsOptions } = zParseWithErrorHandling(\n zWithBackend(zKmsDeleteKeyOptions),\n options,\n 'Invalid options provided to deleteKey method'\n )\n\n const operation = {\n operation: 'deleteKey',\n } as const\n const kms = this.getKms(this.agentContext, backend, operation)\n return await kms.deleteKey(this.agentContext, kmsOptions)\n }\n\n /**\n * Generate random bytes\n */\n public randomBytes(options: WithBackend<KmsRandomBytesOptions>) {\n const { backend, ...kmsOptions } = zParseWithErrorHandling(\n zWithBackend(zKmsRandomBytesOptions),\n options,\n 'Invalid options provided to randomBytes method'\n )\n\n const operation = {\n operation: 'randomBytes',\n } as const\n const kms = this.getKms(this.agentContext, backend, operation)\n return kms.randomBytes(this.agentContext, kmsOptions)\n }\n\n /**\n * Get the kms associated with a specific `keyId`.\n *\n * This uses a naive approach of fetching the key for each configured kms\n * until it finds the registered key.\n *\n * In the future this approach might be optimized based on:\n * - caching\n * - keeping a registry\n * - backend specific key prefixes\n */\n private async getKmsForOperationAndKeyId(agentContext: AgentContext, keyId: string, operation?: KmsOperation) {\n for (const kms of this.keyManagementConfig.backends) {\n if (operation && !kms.isOperationSupported(agentContext, operation)) continue\n\n const publicKey = await kms.getPublicKey(this.agentContext, keyId)\n if (publicKey)\n return {\n publicKey,\n kms,\n }\n }\n\n throw new KeyManagementKeyNotFoundError(\n keyId,\n this.keyManagementConfig.backends.map((b) => b.backend),\n operation\n ? `The key may exist in one of the key management services in which case the key management service does not support the ${getKmsOperationHumanDescription(operation)}`\n : undefined\n )\n }\n\n /**\n * Get the kms backend for a specific operation.\n *\n * If a backend is provided, it will be checked if the backend supports\n * the operation. Otherwise the default backend (the `defaultBackend` from\n * the `KeyManagementModuleConfig`, or the first registered backend if no\n * `defaultBackend` was configured) will be used if it supports the operation.\n * If the default backend does not support the operation, the first other\n * backend that supports the operation will be used and a warning will be logged.\n */\n private getKms(agentContext: AgentContext, backend?: string, operation?: KmsOperation) {\n const backends = this.keyManagementConfig.backends\n\n if (backend) {\n const kms = backends.find((kms) => kms.backend === backend)\n if (!kms) {\n const availableBackends = backends.map((kms) => `'${kms.backend}'`)\n throw new KeyManagementError(\n `No key management service is configured for backend '${backend}'. Available backends are ${availableBackends.join(\n ', '\n )}`\n )\n }\n\n if (operation && !kms.isOperationSupported(agentContext, operation)) {\n throw new KeyManagementError(\n `Key management service backend '${backend}' does not support ${getKmsOperationHumanDescription(operation)}`\n )\n }\n\n return kms\n }\n\n if (backends.length > 0) {\n const defaultKms = this.keyManagementConfig.defaultBackend\n if (!operation || defaultKms.isOperationSupported(agentContext, operation)) return defaultKms\n\n const fallbackKms = backends.find(\n (kms) => kms !== defaultKms && kms.isOperationSupported(agentContext, operation)\n )\n\n if (fallbackKms) {\n return fallbackKms\n }\n }\n\n throw new KeyManagementError(\n operation\n ? `No key management service backend found that supports ${getKmsOperationHumanDescription(operation)}`\n : 'No key management service backend found.'\n )\n }\n}\n\nfunction routingKeyId(key: KmsEncryptOptions['key'] | KmsDecryptOptions['key']): string | undefined {\n if (key.keyId) return key.keyId\n if (key.keyAgreement && 'keyId' in key.keyAgreement) return key.keyAgreement.keyId\n return undefined\n}\n"],"mappings":"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"}