UNPKG

@sphereon/ssi-sdk-ext.kms-musap-rn

Version:

Sphereon SSI-SDK react-native plugin for management of keys with musap.

239 lines (238 loc) 8.31 kB
var __defProp = Object.defineProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); // src/MusapKeyManagerSystem.ts import { PEMToBinary } from "@sphereon/ssi-sdk-ext.x509-utils"; import { isSignatureAlgorithmType, MusapClient, signatureAlgorithmFromKeyAlgorithm } from "@sphereon/musap-react-native"; import { AbstractKeyManagementSystem } from "@veramo/key-manager"; import { Loggers } from "@sphereon/ssi-types"; import { asn1DerToRawPublicKey, calculateJwkThumbprintForKey, hexStringFromUint8Array, isAsn1Der, isRawCompressedPublicKey, toRawCompressedHexPublicKey } from "@sphereon/ssi-sdk-ext.key-utils"; import * as u8a from "uint8arrays"; var { fromString, toString } = u8a; var logger = Loggers.DEFAULT.get("sphereon:musap-rn-kms"); var MusapKeyManagementSystem = class extends AbstractKeyManagementSystem { static { __name(this, "MusapKeyManagementSystem"); } musapClient; sscdType; sscdId; defaultKeyAttributes; defaultSignAttributes; constructor(sscdType, sscdId, opts) { super(); try { this.musapClient = MusapClient; this.sscdType = sscdType ? sscdType : "TEE"; this.sscdId = sscdId ?? this.sscdType; this.defaultKeyAttributes = opts?.defaultKeyAttributes; this.defaultSignAttributes = opts?.defaultSignAttributes; const enabledSscds = this.musapClient.listEnabledSscds(); if (!enabledSscds.some((value) => value.sscdId == sscdId)) { this.musapClient.enableSscd(this.sscdType, this.sscdId, opts?.externalSscdSettings); } } catch (e) { console.error("enableSscd", e); throw Error("enableSscd failed"); } } async listKeys() { const keysJson = this.musapClient.listKeys(); return keysJson.map((key) => this.asMusapKeyInfo(key)); } async createKey(args) { const { type, meta } = args; if (meta === void 0 || !("keyAlias" in meta)) { return Promise.reject(Error("a unique keyAlias field is required for MUSAP")); } if (this.sscdType == "EXTERNAL") { const existingKeys = this.musapClient.listKeys(); const extKey = existingKeys.find((musapKey) => musapKey.sscdType === "External Signature"); if (extKey) { extKey.algorithm = "eccp256r1"; return this.asMusapKeyInfo(extKey); } return Promise.reject(Error(`No external key was bound yet for sscd ${this.sscdId}`)); } const keyGenReq = { keyAlgorithm: this.mapKeyTypeToAlgorithmType(type), keyUsage: "keyUsage" in meta ? meta.keyUsage : "sign", keyAlias: meta.keyAlias, attributes: this.recordToKeyAttributes({ ...this.defaultKeyAttributes, ..."attributes" in meta ? meta.attributes : {} }), role: "role" in meta ? meta.role : "administrator" }; try { const generatedKeyUri = await this.musapClient.generateKey(this.sscdType, keyGenReq); if (generatedKeyUri) { logger.debug("Generated key:", generatedKeyUri); const key = this.musapClient.getKeyByUri(generatedKeyUri); return this.asMusapKeyInfo(key); } else { return Promise.reject(new Error("Failed to generate key. No key URI")); } } catch (error) { logger.error("An error occurred:", error); throw error; } } mapKeyTypeToAlgorithmType = /* @__PURE__ */ __name((type) => { switch (type) { case "Secp256k1": return "ECCP256K1"; case "Secp256r1": return "ECCP256R1"; case "RSA": return "RSA2K"; default: throw new Error(`Key type ${type} is not supported by MUSAP`); } }, "mapKeyTypeToAlgorithmType"); mapAlgorithmTypeToKeyType = /* @__PURE__ */ __name((type) => { switch (type) { case "eccp256k1": return "Secp256k1"; case "eccp256r1": return "Secp256r1"; case "ecc_ed25519": return "Ed25519"; case "rsa2k": case "rsa4k": return "RSA"; default: throw new Error(`Key type ${type} is not supported.`); } }, "mapAlgorithmTypeToKeyType"); async deleteKey({ kid }) { try { const key = this.musapClient.getKeyById(kid); if (key.sscdType === "External Signature") { return true; } void this.musapClient.removeKey(kid); return true; } catch (error) { console.warn("Failed to delete key:", error); return false; } } determineAlgorithm(providedAlgorithm, keyAlgorithm) { if (providedAlgorithm === void 0) { return signatureAlgorithmFromKeyAlgorithm(keyAlgorithm); } if (isSignatureAlgorithmType(providedAlgorithm)) { return providedAlgorithm; } return signatureAlgorithmFromKeyAlgorithm(providedAlgorithm); } async sign(args) { if (!args.keyRef) { throw new Error("key_not_found: No key ref provided"); } const data = Array.from(args.data); const dataBase64 = toString(args.data, "base64pad"); const key = this.musapClient.getKeyById(args.keyRef.kid); if (key.sscdType === "External Signature") { key.algorithm = "eccp256r1"; } const signatureReq = { keyUri: key.keyUri, data, dataBase64, algorithm: this.determineAlgorithm(args.algorithm, key.algorithm), displayText: args.displayText, transId: args.transId, format: args.format ?? "RAW", attributes: this.recordToSignatureAttributes({ ...this.defaultSignAttributes, ...args.attributes }) }; return this.musapClient.sign(signatureReq); } async importKey(args) { throw new Error("importKey is not implemented for MusapKeyManagementSystem."); } decodeMusapPublicKey = /* @__PURE__ */ __name((args) => { const { publicKey, keyType } = args; const pemBinary = PEMToBinary(publicKey.pem); const pemString = toString(pemBinary, "utf8"); const isDoubleEncoded = pemBinary.length > 0 && typeof pemString === "string" && pemString.startsWith("MF"); if (isDoubleEncoded) { const actualDerBytes = fromString(pemString, "base64"); const keyDataStart = 24; const keyData = actualDerBytes.slice(keyDataStart); let publicKeyHex = toString(keyData, "hex"); if (publicKeyHex.length <= 128 && !publicKeyHex.startsWith("04")) { publicKeyHex = "04" + publicKeyHex; } while (publicKeyHex.startsWith("04") && publicKeyHex.length < 130) { publicKeyHex = publicKeyHex + "0"; } if (publicKeyHex.startsWith("04") && publicKeyHex.length === 130) { const xCoord = fromString(publicKeyHex.slice(2, 66), "hex"); const yCoord = fromString(publicKeyHex.slice(66, 130), "hex"); const prefix = new Uint8Array([ yCoord[31] % 2 === 0 ? 2 : 3 ]); const compressedKey = new Uint8Array(33); compressedKey.set(prefix, 0); compressedKey.set(xCoord, 1); return toString(compressedKey, "hex"); } return publicKeyHex; } const publicKeyBinary = isAsn1Der(pemBinary) ? asn1DerToRawPublicKey(pemBinary, keyType) : pemBinary; return isRawCompressedPublicKey(publicKeyBinary) ? hexStringFromUint8Array(publicKeyBinary) : toRawCompressedHexPublicKey(publicKeyBinary, keyType); }, "decodeMusapPublicKey"); asMusapKeyInfo(args) { const { keyId, publicKey, ...metadata } = { ...args }; const keyType = this.mapAlgorithmTypeToKeyType(args.algorithm); const publicKeyHex = this.decodeMusapPublicKey({ publicKey, keyType }); const keyInfo = { kid: keyId, type: keyType, publicKeyHex, meta: metadata }; const jwkThumbprint = calculateJwkThumbprintForKey({ key: keyInfo }); keyInfo.meta = { ...keyInfo.meta, jwkThumbprint }; return keyInfo; } sharedSecret(args) { throw new Error("Not supported."); } recordToKeyAttributes(record) { if (!record) { return []; } return Object.entries(record).map(([key, value]) => ({ name: key, value })); } recordToSignatureAttributes(record) { if (!record) { return []; } return Object.entries(record).map(([key, value]) => ({ name: key, value })); } }; export { MusapKeyManagementSystem }; //# sourceMappingURL=index.js.map