@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
JavaScript
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