@sphereon/ssi-sdk-ext.kms-musap-rn 0.27.1-next.6 → 0.28.1-feature.esm.cjs.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,259 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/index.ts
22
+ var index_exports = {};
23
+ __export(index_exports, {
24
+ MusapKeyManagementSystem: () => MusapKeyManagementSystem
25
+ });
26
+ module.exports = __toCommonJS(index_exports);
27
+
28
+ // src/MusapKeyManagerSystem.ts
29
+ var import_ssi_sdk_ext = require("@sphereon/ssi-sdk-ext.x509-utils");
30
+ var import_musap_react_native = require("@sphereon/musap-react-native");
31
+ var import_key_manager = require("@veramo/key-manager");
32
+ var import_text_encoding = require("text-encoding");
33
+ var import_ssi_types = require("@sphereon/ssi-types");
34
+ var import_ssi_sdk_ext2 = require("@sphereon/ssi-sdk-ext.key-utils");
35
+ var import_from_string = require("uint8arrays/from-string");
36
+ var import_to_string = require("uint8arrays/to-string");
37
+ var logger = import_ssi_types.Loggers.DEFAULT.get("sphereon:musap-rn-kms");
38
+ var MusapKeyManagementSystem = class extends import_key_manager.AbstractKeyManagementSystem {
39
+ static {
40
+ __name(this, "MusapKeyManagementSystem");
41
+ }
42
+ musapClient;
43
+ sscdType;
44
+ sscdId;
45
+ defaultKeyAttributes;
46
+ defaultSignAttributes;
47
+ constructor(sscdType, sscdId, opts) {
48
+ super();
49
+ try {
50
+ this.musapClient = import_musap_react_native.MusapClient;
51
+ this.sscdType = sscdType ? sscdType : "TEE";
52
+ this.sscdId = sscdId ?? this.sscdType;
53
+ this.defaultKeyAttributes = opts?.defaultKeyAttributes;
54
+ this.defaultSignAttributes = opts?.defaultSignAttributes;
55
+ const enabledSscds = this.musapClient.listEnabledSscds();
56
+ if (!enabledSscds.some((value) => value.sscdId == sscdId)) {
57
+ this.musapClient.enableSscd(this.sscdType, this.sscdId, opts?.externalSscdSettings);
58
+ }
59
+ } catch (e) {
60
+ console.error("enableSscd", e);
61
+ throw Error("enableSscd failed");
62
+ }
63
+ }
64
+ async listKeys() {
65
+ const keysJson = this.musapClient.listKeys();
66
+ return keysJson.map((key) => this.asMusapKeyInfo(key));
67
+ }
68
+ async createKey(args) {
69
+ const { type, meta } = args;
70
+ if (meta === void 0 || !("keyAlias" in meta)) {
71
+ return Promise.reject(Error("a unique keyAlias field is required for MUSAP"));
72
+ }
73
+ if (this.sscdType == "EXTERNAL") {
74
+ const existingKeys = this.musapClient.listKeys();
75
+ const extKey = existingKeys.find((musapKey) => musapKey.sscdType === "External Signature");
76
+ if (extKey) {
77
+ extKey.algorithm = "eccp256r1";
78
+ return this.asMusapKeyInfo(extKey);
79
+ }
80
+ return Promise.reject(Error(`No external key was bound yet for sscd ${this.sscdId}`));
81
+ }
82
+ const keyGenReq = {
83
+ keyAlgorithm: this.mapKeyTypeToAlgorithmType(type),
84
+ keyUsage: "keyUsage" in meta ? meta.keyUsage : "sign",
85
+ keyAlias: meta.keyAlias,
86
+ attributes: this.recordToKeyAttributes({
87
+ ...this.defaultKeyAttributes,
88
+ ..."attributes" in meta ? meta.attributes : {}
89
+ }),
90
+ role: "role" in meta ? meta.role : "administrator"
91
+ };
92
+ try {
93
+ const generatedKeyUri = await this.musapClient.generateKey(this.sscdType, keyGenReq);
94
+ if (generatedKeyUri) {
95
+ logger.debug("Generated key:", generatedKeyUri);
96
+ const key = this.musapClient.getKeyByUri(generatedKeyUri);
97
+ return this.asMusapKeyInfo(key);
98
+ } else {
99
+ return Promise.reject(new Error("Failed to generate key. No key URI"));
100
+ }
101
+ } catch (error) {
102
+ logger.error("An error occurred:", error);
103
+ throw error;
104
+ }
105
+ }
106
+ mapKeyTypeToAlgorithmType = /* @__PURE__ */ __name((type) => {
107
+ switch (type) {
108
+ case "Secp256k1":
109
+ return "ECCP256K1";
110
+ case "Secp256r1":
111
+ return "ECCP256R1";
112
+ case "RSA":
113
+ return "RSA2K";
114
+ default:
115
+ throw new Error(`Key type ${type} is not supported by MUSAP`);
116
+ }
117
+ }, "mapKeyTypeToAlgorithmType");
118
+ mapAlgorithmTypeToKeyType = /* @__PURE__ */ __name((type) => {
119
+ switch (type) {
120
+ case "eccp256k1":
121
+ return "Secp256k1";
122
+ case "eccp256r1":
123
+ return "Secp256r1";
124
+ case "ecc_ed25519":
125
+ return "Ed25519";
126
+ case "rsa2k":
127
+ case "rsa4k":
128
+ return "RSA";
129
+ default:
130
+ throw new Error(`Key type ${type} is not supported.`);
131
+ }
132
+ }, "mapAlgorithmTypeToKeyType");
133
+ async deleteKey({ kid }) {
134
+ try {
135
+ const key = this.musapClient.getKeyById(kid);
136
+ if (key.sscdType === "External Signature") {
137
+ return true;
138
+ }
139
+ void this.musapClient.removeKey(kid);
140
+ return true;
141
+ } catch (error) {
142
+ console.warn("Failed to delete key:", error);
143
+ return false;
144
+ }
145
+ }
146
+ determineAlgorithm(providedAlgorithm, keyAlgorithm) {
147
+ if (providedAlgorithm === void 0) {
148
+ return (0, import_musap_react_native.signatureAlgorithmFromKeyAlgorithm)(keyAlgorithm);
149
+ }
150
+ if ((0, import_musap_react_native.isSignatureAlgorithmType)(providedAlgorithm)) {
151
+ return providedAlgorithm;
152
+ }
153
+ return (0, import_musap_react_native.signatureAlgorithmFromKeyAlgorithm)(providedAlgorithm);
154
+ }
155
+ async sign(args) {
156
+ if (!args.keyRef) {
157
+ throw new Error("key_not_found: No key ref provided");
158
+ }
159
+ const data = new import_text_encoding.TextDecoder().decode(args.data);
160
+ const key = this.musapClient.getKeyById(args.keyRef.kid);
161
+ if (key.sscdType === "External Signature") {
162
+ key.algorithm = "eccp256r1";
163
+ }
164
+ const signatureReq = {
165
+ keyUri: key.keyUri,
166
+ data,
167
+ algorithm: this.determineAlgorithm(args.algorithm, key.algorithm),
168
+ displayText: args.displayText,
169
+ transId: args.transId,
170
+ format: args.format ?? "RAW",
171
+ attributes: this.recordToSignatureAttributes({
172
+ ...this.defaultSignAttributes,
173
+ ...args.attributes
174
+ })
175
+ };
176
+ return this.musapClient.sign(signatureReq);
177
+ }
178
+ async importKey(args) {
179
+ throw new Error("importKey is not implemented for MusapKeyManagementSystem.");
180
+ }
181
+ decodeMusapPublicKey = /* @__PURE__ */ __name((args) => {
182
+ const { publicKey, keyType } = args;
183
+ const pemBinary = (0, import_ssi_sdk_ext.PEMToBinary)(publicKey.pem);
184
+ const pemString = (0, import_to_string.toString)(pemBinary, "utf8");
185
+ const isDoubleEncoded = pemBinary.length > 0 && typeof pemString === "string" && pemString.startsWith("MF");
186
+ if (isDoubleEncoded) {
187
+ const actualDerBytes = (0, import_from_string.fromString)(pemString, "base64");
188
+ const keyDataStart = 24;
189
+ const keyData = actualDerBytes.slice(keyDataStart);
190
+ let publicKeyHex = (0, import_to_string.toString)(keyData, "hex");
191
+ if (publicKeyHex.length <= 128 && !publicKeyHex.startsWith("04")) {
192
+ publicKeyHex = "04" + publicKeyHex;
193
+ }
194
+ while (publicKeyHex.startsWith("04") && publicKeyHex.length < 130) {
195
+ publicKeyHex = publicKeyHex + "0";
196
+ }
197
+ if (publicKeyHex.startsWith("04") && publicKeyHex.length === 130) {
198
+ const xCoord = (0, import_from_string.fromString)(publicKeyHex.slice(2, 66), "hex");
199
+ const yCoord = (0, import_from_string.fromString)(publicKeyHex.slice(66, 130), "hex");
200
+ const prefix = new Uint8Array([
201
+ yCoord[31] % 2 === 0 ? 2 : 3
202
+ ]);
203
+ const compressedKey = new Uint8Array(33);
204
+ compressedKey.set(prefix, 0);
205
+ compressedKey.set(xCoord, 1);
206
+ return (0, import_to_string.toString)(compressedKey, "hex");
207
+ }
208
+ return publicKeyHex;
209
+ }
210
+ const publicKeyBinary = (0, import_ssi_sdk_ext2.isAsn1Der)(pemBinary) ? (0, import_ssi_sdk_ext2.asn1DerToRawPublicKey)(pemBinary, keyType) : pemBinary;
211
+ return (0, import_ssi_sdk_ext2.isRawCompressedPublicKey)(publicKeyBinary) ? (0, import_ssi_sdk_ext2.hexStringFromUint8Array)(publicKeyBinary) : (0, import_ssi_sdk_ext2.toRawCompressedHexPublicKey)(publicKeyBinary, keyType);
212
+ }, "decodeMusapPublicKey");
213
+ asMusapKeyInfo(args) {
214
+ const { keyId, publicKey, ...metadata } = {
215
+ ...args
216
+ };
217
+ const keyType = this.mapAlgorithmTypeToKeyType(args.algorithm);
218
+ const publicKeyHex = this.decodeMusapPublicKey({
219
+ publicKey,
220
+ keyType
221
+ });
222
+ const keyInfo = {
223
+ kid: keyId,
224
+ type: keyType,
225
+ publicKeyHex,
226
+ meta: metadata
227
+ };
228
+ const jwkThumbprint = (0, import_ssi_sdk_ext2.calculateJwkThumbprintForKey)({
229
+ key: keyInfo
230
+ });
231
+ keyInfo.meta = {
232
+ ...keyInfo.meta,
233
+ jwkThumbprint
234
+ };
235
+ return keyInfo;
236
+ }
237
+ sharedSecret(args) {
238
+ throw new Error("Not supported.");
239
+ }
240
+ recordToKeyAttributes(record) {
241
+ if (!record) {
242
+ return [];
243
+ }
244
+ return Object.entries(record).map(([key, value]) => ({
245
+ name: key,
246
+ value
247
+ }));
248
+ }
249
+ recordToSignatureAttributes(record) {
250
+ if (!record) {
251
+ return [];
252
+ }
253
+ return Object.entries(record).map(([key, value]) => ({
254
+ name: key,
255
+ value
256
+ }));
257
+ }
258
+ };
259
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/MusapKeyManagerSystem.ts"],"sourcesContent":["export { MusapKeyManagementSystem } from './MusapKeyManagerSystem'\n\nexport interface KeyMetadata {\n algorithms?: string[]\n\n [x: string]: any\n}\n","import { PEMToBinary } from '@sphereon/ssi-sdk-ext.x509-utils'\nimport { IKey, ManagedKeyInfo, MinimalImportableKey, TKeyType } from '@veramo/core'\nimport {\n ExternalSscdSettings,\n IMusapClient,\n isSignatureAlgorithmType,\n JWSAlgorithm,\n KeyAlgorithm,\n KeyAlgorithmType,\n KeyAttribute,\n KeyGenReq,\n MusapClient,\n MusapKey,\n signatureAlgorithmFromKeyAlgorithm,\n SignatureAlgorithmType,\n SignatureAttribute,\n SignatureFormat,\n SignatureReq,\n SscdType,\n} from '@sphereon/musap-react-native'\nimport { AbstractKeyManagementSystem } from '@veramo/key-manager'\nimport { TextDecoder } from 'text-encoding'\nimport { Loggers } from '@sphereon/ssi-types'\nimport { KeyMetadata } from './index'\nimport {\n asn1DerToRawPublicKey,\n calculateJwkThumbprintForKey,\n hexStringFromUint8Array,\n isAsn1Der,\n isRawCompressedPublicKey,\n toRawCompressedHexPublicKey,\n} from '@sphereon/ssi-sdk-ext.key-utils'\n// @ts-ignore\nimport { fromString } from 'uint8arrays/from-string'\n// @ts-ignore\nimport { toString } from 'uint8arrays/to-string'\n\nexport const logger = Loggers.DEFAULT.get('sphereon:musap-rn-kms')\n\nexport class MusapKeyManagementSystem extends AbstractKeyManagementSystem {\n private musapClient: IMusapClient\n private readonly sscdType: SscdType\n private readonly sscdId: string\n private readonly defaultKeyAttributes: Record<string, string> | undefined\n private readonly defaultSignAttributes: Record<string, string> | undefined\n\n constructor(\n sscdType?: SscdType,\n sscdId?: string,\n opts?: {\n externalSscdSettings?: ExternalSscdSettings\n defaultKeyAttributes?: Record<string, string>\n defaultSignAttributes?: Record<string, string>\n }\n ) {\n super()\n try {\n this.musapClient = MusapClient\n this.sscdType = sscdType ? sscdType : 'TEE'\n this.sscdId = sscdId ?? this.sscdType\n this.defaultKeyAttributes = opts?.defaultKeyAttributes\n this.defaultSignAttributes = opts?.defaultSignAttributes\n\n const enabledSscds = this.musapClient.listEnabledSscds()\n if (!enabledSscds.some((value) => value.sscdId == sscdId)) {\n this.musapClient.enableSscd(this.sscdType, this.sscdId, opts?.externalSscdSettings)\n }\n } catch (e) {\n console.error('enableSscd', e)\n throw Error('enableSscd failed')\n }\n }\n\n async listKeys(): Promise<ManagedKeyInfo[]> {\n const keysJson: MusapKey[] = this.musapClient.listKeys() as MusapKey[]\n return keysJson.map((key) => this.asMusapKeyInfo(key))\n }\n\n async createKey(args: { type: TKeyType; meta?: KeyMetadata }): Promise<ManagedKeyInfo> {\n const { type, meta } = args\n if (meta === undefined || !('keyAlias' in meta)) {\n return Promise.reject(Error('a unique keyAlias field is required for MUSAP'))\n }\n\n if (this.sscdType == 'EXTERNAL') {\n const existingKeys: MusapKey[] = this.musapClient.listKeys() as MusapKey[]\n const extKey = existingKeys.find((musapKey) => (musapKey.sscdType as string) === 'External Signature') // FIXME returning does not match SscdType enum\n if (extKey) {\n extKey.algorithm = 'eccp256r1' // FIXME MUSAP announces key as rsa2k, but it's actually EC\n return this.asMusapKeyInfo(extKey)\n }\n return Promise.reject(Error(`No external key was bound yet for sscd ${this.sscdId}`))\n }\n\n const keyGenReq = {\n keyAlgorithm: this.mapKeyTypeToAlgorithmType(type),\n keyUsage: 'keyUsage' in meta ? (meta.keyUsage as string) : 'sign',\n keyAlias: meta.keyAlias as string,\n attributes: this.recordToKeyAttributes({ ...this.defaultKeyAttributes, ...('attributes' in meta ? meta.attributes : {}) }),\n role: 'role' in meta ? (meta.role as string) : 'administrator',\n } satisfies KeyGenReq\n\n try {\n const generatedKeyUri = await this.musapClient.generateKey(this.sscdType, keyGenReq)\n if (generatedKeyUri) {\n logger.debug('Generated key:', generatedKeyUri)\n const key = this.musapClient.getKeyByUri(generatedKeyUri)\n return this.asMusapKeyInfo(key)\n } else {\n return Promise.reject(new Error('Failed to generate key. No key URI'))\n }\n } catch (error) {\n logger.error('An error occurred:', error)\n throw error\n }\n }\n\n private mapKeyTypeToAlgorithmType = (type: TKeyType): KeyAlgorithmType => {\n switch (type) {\n case 'Secp256k1':\n return 'ECCP256K1'\n case 'Secp256r1':\n return 'ECCP256R1'\n case 'RSA':\n return 'RSA2K'\n default:\n throw new Error(`Key type ${type} is not supported by MUSAP`)\n }\n }\n\n private mapAlgorithmTypeToKeyType = (type: KeyAlgorithm): TKeyType => {\n switch (type) {\n case 'eccp256k1':\n return 'Secp256k1'\n case 'eccp256r1':\n return 'Secp256r1'\n case 'ecc_ed25519':\n return 'Ed25519'\n case 'rsa2k':\n case 'rsa4k':\n return 'RSA'\n default:\n throw new Error(`Key type ${type} is not supported.`)\n }\n }\n\n async deleteKey({ kid }: { kid: string }): Promise<boolean> {\n try {\n const key: MusapKey = this.musapClient.getKeyById(kid) as MusapKey\n if ((key.sscdType as string) === 'External Signature') {\n return true // FIXME we can't remove a eSim key for now because this would mean onboarding again\n }\n void this.musapClient.removeKey(kid)\n return true\n } catch (error) {\n console.warn('Failed to delete key:', error)\n return false\n }\n }\n\n private determineAlgorithm(providedAlgorithm: string | undefined, keyAlgorithm: KeyAlgorithm): SignatureAlgorithmType {\n if (providedAlgorithm === undefined) {\n return signatureAlgorithmFromKeyAlgorithm(keyAlgorithm)\n }\n\n if (isSignatureAlgorithmType(providedAlgorithm)) {\n return providedAlgorithm\n }\n\n // Veramo translates TKeyType to JWSAlgorithm\n return signatureAlgorithmFromKeyAlgorithm(providedAlgorithm as JWSAlgorithm)\n }\n\n async sign(args: { keyRef: Pick<IKey, 'kid'>; algorithm?: string; data: Uint8Array; [x: string]: any }): Promise<string> {\n if (!args.keyRef) {\n throw new Error('key_not_found: No key ref provided')\n }\n\n const data = new TextDecoder().decode(args.data as Uint8Array)\n\n const key: MusapKey = this.musapClient.getKeyById(args.keyRef.kid) as MusapKey\n if ((key.sscdType as string) === 'External Signature') {\n key.algorithm = 'eccp256r1' // FIXME MUSAP announces key as rsa2k, but it's actually EC\n }\n const signatureReq: SignatureReq = {\n keyUri: key.keyUri,\n data,\n algorithm: this.determineAlgorithm(args.algorithm, key.algorithm),\n displayText: args.displayText,\n transId: args.transId,\n format: (args.format as SignatureFormat) ?? 'RAW',\n attributes: this.recordToSignatureAttributes({ ...this.defaultSignAttributes, ...args.attributes }),\n }\n return this.musapClient.sign(signatureReq)\n }\n\n async importKey(args: Omit<MinimalImportableKey, 'kms'> & { privateKeyPEM?: string }): Promise<ManagedKeyInfo> {\n throw new Error('importKey is not implemented for MusapKeyManagementSystem.')\n }\n\n private decodeMusapPublicKey = (args: { publicKey: { pem: string }; keyType: TKeyType }): string => {\n const { publicKey, keyType } = args\n\n // First try the normal PEM decoding path\n const pemBinary = PEMToBinary(publicKey.pem)\n\n // Check if we got a string that looks like base64 (might be double encoded)\n // Convert Uint8Array to string safely\n const pemString = toString(pemBinary, 'utf8')\n const isDoubleEncoded = pemBinary.length > 0 && typeof pemString === 'string' && pemString.startsWith('MF')\n\n if (isDoubleEncoded) {\n // Handle double-encoded case\n const actualDerBytes = fromString(pemString, 'base64')\n\n // For double-encoded case, we know the key data starts after the header\n const keyDataStart = 24\n const keyData = actualDerBytes.slice(keyDataStart)\n\n // Convert to public key hex\n let publicKeyHex = toString(keyData, 'hex')\n\n // If it's not compressed yet and doesn't start with 0x04 (uncompressed point marker), add it\n if (publicKeyHex.length <= 128 && !publicKeyHex.startsWith('04')) {\n publicKeyHex = '04' + publicKeyHex\n }\n\n // Ensure we have full 65 bytes for uncompressed keys\n while (publicKeyHex.startsWith('04') && publicKeyHex.length < 130) {\n publicKeyHex = publicKeyHex + '0'\n }\n\n // Now convert to compressed format if needed\n if (publicKeyHex.startsWith('04') && publicKeyHex.length === 130) {\n const xCoord = fromString(publicKeyHex.slice(2, 66), 'hex')\n const yCoord = fromString(publicKeyHex.slice(66, 130), 'hex')\n const prefix = new Uint8Array([yCoord[31] % 2 === 0 ? 0x02 : 0x03])\n const compressedKey = new Uint8Array(33) // 1 byte prefix + 32 bytes x coordinate\n compressedKey.set(prefix, 0)\n compressedKey.set(xCoord, 1)\n return toString(compressedKey, 'hex')\n }\n\n return publicKeyHex\n }\n\n // Not double encoded, proceed with normal path\n const publicKeyBinary = isAsn1Der(pemBinary) ? asn1DerToRawPublicKey(pemBinary, keyType) : pemBinary\n return isRawCompressedPublicKey(publicKeyBinary)\n ? hexStringFromUint8Array(publicKeyBinary)\n : toRawCompressedHexPublicKey(publicKeyBinary, keyType)\n }\n\n private asMusapKeyInfo(args: MusapKey): ManagedKeyInfo {\n const { keyId, publicKey, ...metadata }: KeyMetadata = { ...args }\n const keyType = this.mapAlgorithmTypeToKeyType(args.algorithm)\n\n const publicKeyHex = this.decodeMusapPublicKey({\n publicKey: publicKey,\n keyType: keyType,\n })\n\n const keyInfo: Partial<ManagedKeyInfo> = {\n kid: keyId,\n type: keyType,\n publicKeyHex,\n meta: metadata,\n }\n\n const jwkThumbprint = calculateJwkThumbprintForKey({ key: keyInfo as ManagedKeyInfo })\n keyInfo.meta = { ...keyInfo.meta, jwkThumbprint }\n return keyInfo as ManagedKeyInfo\n }\n\n sharedSecret(args: { myKeyRef: Pick<IKey, 'kid'>; theirKey: Pick<IKey, 'publicKeyHex' | 'type'> }): Promise<string> {\n throw new Error('Not supported.')\n }\n\n private recordToKeyAttributes(record?: Record<string, string>): KeyAttribute[] {\n if (!record) {\n return []\n }\n return Object.entries(record).map(([key, value]) => ({\n name: key,\n value,\n }))\n }\n\n private recordToSignatureAttributes(record?: Record<string, string>): SignatureAttribute[] {\n if (!record) {\n return []\n }\n return Object.entries(record).map(([key, value]) => ({\n name: key,\n value,\n }))\n }\n}\n"],"mappings":"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","names":["import_ssi_sdk_ext","logger","Loggers","DEFAULT","get","MusapKeyManagementSystem","AbstractKeyManagementSystem","musapClient","sscdType","sscdId","defaultKeyAttributes","defaultSignAttributes","constructor","opts","MusapClient","enabledSscds","listEnabledSscds","some","value","enableSscd","externalSscdSettings","e","console","error","Error","listKeys","keysJson","map","key","asMusapKeyInfo","createKey","args","type","meta","undefined","Promise","reject","existingKeys","extKey","find","musapKey","algorithm","keyGenReq","keyAlgorithm","mapKeyTypeToAlgorithmType","keyUsage","keyAlias","attributes","recordToKeyAttributes","role","generatedKeyUri","generateKey","debug","getKeyByUri","mapAlgorithmTypeToKeyType","deleteKey","kid","getKeyById","removeKey","warn","determineAlgorithm","providedAlgorithm","signatureAlgorithmFromKeyAlgorithm","isSignatureAlgorithmType","sign","keyRef","data","TextDecoder","decode","signatureReq","keyUri","displayText","transId","format","recordToSignatureAttributes","importKey","decodeMusapPublicKey","publicKey","keyType","pemBinary","PEMToBinary","pem","pemString","toString","isDoubleEncoded","length","startsWith","actualDerBytes","fromString","keyDataStart","keyData","slice","publicKeyHex","xCoord","yCoord","prefix","Uint8Array","compressedKey","set","publicKeyBinary","isAsn1Der","asn1DerToRawPublicKey","isRawCompressedPublicKey","hexStringFromUint8Array","toRawCompressedHexPublicKey","keyId","metadata","keyInfo","jwkThumbprint","calculateJwkThumbprintForKey","sharedSecret","record","Object","entries","name"]}
@@ -1,9 +1,8 @@
1
- import { IKey, ManagedKeyInfo, MinimalImportableKey, TKeyType } from '@veramo/core';
2
- import { ExternalSscdSettings, SscdType } from '@sphereon/musap-react-native';
1
+ import { ManagedKeyInfo, TKeyType, IKey, MinimalImportableKey } from '@veramo/core';
2
+ import { SscdType, ExternalSscdSettings } from '@sphereon/musap-react-native';
3
3
  import { AbstractKeyManagementSystem } from '@veramo/key-manager';
4
- import { KeyMetadata } from './index';
5
- export declare const logger: import("@sphereon/ssi-types").ISimpleLogger<unknown>;
6
- export declare class MusapKeyManagementSystem extends AbstractKeyManagementSystem {
4
+
5
+ declare class MusapKeyManagementSystem extends AbstractKeyManagementSystem {
7
6
  private musapClient;
8
7
  private readonly sscdType;
9
8
  private readonly sscdId;
@@ -34,6 +33,7 @@ export declare class MusapKeyManagementSystem extends AbstractKeyManagementSyste
34
33
  importKey(args: Omit<MinimalImportableKey, 'kms'> & {
35
34
  privateKeyPEM?: string;
36
35
  }): Promise<ManagedKeyInfo>;
36
+ private decodeMusapPublicKey;
37
37
  private asMusapKeyInfo;
38
38
  sharedSecret(args: {
39
39
  myKeyRef: Pick<IKey, 'kid'>;
@@ -42,4 +42,10 @@ export declare class MusapKeyManagementSystem extends AbstractKeyManagementSyste
42
42
  private recordToKeyAttributes;
43
43
  private recordToSignatureAttributes;
44
44
  }
45
- //# sourceMappingURL=MusapKeyManagerSystem.d.ts.map
45
+
46
+ interface KeyMetadata {
47
+ algorithms?: string[];
48
+ [x: string]: any;
49
+ }
50
+
51
+ export { type KeyMetadata, MusapKeyManagementSystem };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,51 @@
1
- export { MusapKeyManagementSystem } from './MusapKeyManagerSystem';
2
- export interface KeyMetadata {
1
+ import { ManagedKeyInfo, TKeyType, IKey, MinimalImportableKey } from '@veramo/core';
2
+ import { SscdType, ExternalSscdSettings } from '@sphereon/musap-react-native';
3
+ import { AbstractKeyManagementSystem } from '@veramo/key-manager';
4
+
5
+ declare class MusapKeyManagementSystem extends AbstractKeyManagementSystem {
6
+ private musapClient;
7
+ private readonly sscdType;
8
+ private readonly sscdId;
9
+ private readonly defaultKeyAttributes;
10
+ private readonly defaultSignAttributes;
11
+ constructor(sscdType?: SscdType, sscdId?: string, opts?: {
12
+ externalSscdSettings?: ExternalSscdSettings;
13
+ defaultKeyAttributes?: Record<string, string>;
14
+ defaultSignAttributes?: Record<string, string>;
15
+ });
16
+ listKeys(): Promise<ManagedKeyInfo[]>;
17
+ createKey(args: {
18
+ type: TKeyType;
19
+ meta?: KeyMetadata;
20
+ }): Promise<ManagedKeyInfo>;
21
+ private mapKeyTypeToAlgorithmType;
22
+ private mapAlgorithmTypeToKeyType;
23
+ deleteKey({ kid }: {
24
+ kid: string;
25
+ }): Promise<boolean>;
26
+ private determineAlgorithm;
27
+ sign(args: {
28
+ keyRef: Pick<IKey, 'kid'>;
29
+ algorithm?: string;
30
+ data: Uint8Array;
31
+ [x: string]: any;
32
+ }): Promise<string>;
33
+ importKey(args: Omit<MinimalImportableKey, 'kms'> & {
34
+ privateKeyPEM?: string;
35
+ }): Promise<ManagedKeyInfo>;
36
+ private decodeMusapPublicKey;
37
+ private asMusapKeyInfo;
38
+ sharedSecret(args: {
39
+ myKeyRef: Pick<IKey, 'kid'>;
40
+ theirKey: Pick<IKey, 'publicKeyHex' | 'type'>;
41
+ }): Promise<string>;
42
+ private recordToKeyAttributes;
43
+ private recordToSignatureAttributes;
44
+ }
45
+
46
+ interface KeyMetadata {
3
47
  algorithms?: string[];
4
48
  [x: string]: any;
5
49
  }
6
- //# sourceMappingURL=index.d.ts.map
50
+
51
+ export { type KeyMetadata, MusapKeyManagementSystem };
package/dist/index.js CHANGED
@@ -1,6 +1,238 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MusapKeyManagementSystem = void 0;
4
- var MusapKeyManagerSystem_1 = require("./MusapKeyManagerSystem");
5
- Object.defineProperty(exports, "MusapKeyManagementSystem", { enumerable: true, get: function () { return MusapKeyManagerSystem_1.MusapKeyManagementSystem; } });
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // src/MusapKeyManagerSystem.ts
5
+ import { PEMToBinary } from "@sphereon/ssi-sdk-ext.x509-utils";
6
+ import { isSignatureAlgorithmType, MusapClient, signatureAlgorithmFromKeyAlgorithm } from "@sphereon/musap-react-native";
7
+ import { AbstractKeyManagementSystem } from "@veramo/key-manager";
8
+ import { TextDecoder } from "text-encoding";
9
+ import { Loggers } from "@sphereon/ssi-types";
10
+ import { asn1DerToRawPublicKey, calculateJwkThumbprintForKey, hexStringFromUint8Array, isAsn1Der, isRawCompressedPublicKey, toRawCompressedHexPublicKey } from "@sphereon/ssi-sdk-ext.key-utils";
11
+ import { fromString } from "uint8arrays/from-string";
12
+ import { toString } from "uint8arrays/to-string";
13
+ var logger = Loggers.DEFAULT.get("sphereon:musap-rn-kms");
14
+ var MusapKeyManagementSystem = class extends AbstractKeyManagementSystem {
15
+ static {
16
+ __name(this, "MusapKeyManagementSystem");
17
+ }
18
+ musapClient;
19
+ sscdType;
20
+ sscdId;
21
+ defaultKeyAttributes;
22
+ defaultSignAttributes;
23
+ constructor(sscdType, sscdId, opts) {
24
+ super();
25
+ try {
26
+ this.musapClient = MusapClient;
27
+ this.sscdType = sscdType ? sscdType : "TEE";
28
+ this.sscdId = sscdId ?? this.sscdType;
29
+ this.defaultKeyAttributes = opts?.defaultKeyAttributes;
30
+ this.defaultSignAttributes = opts?.defaultSignAttributes;
31
+ const enabledSscds = this.musapClient.listEnabledSscds();
32
+ if (!enabledSscds.some((value) => value.sscdId == sscdId)) {
33
+ this.musapClient.enableSscd(this.sscdType, this.sscdId, opts?.externalSscdSettings);
34
+ }
35
+ } catch (e) {
36
+ console.error("enableSscd", e);
37
+ throw Error("enableSscd failed");
38
+ }
39
+ }
40
+ async listKeys() {
41
+ const keysJson = this.musapClient.listKeys();
42
+ return keysJson.map((key) => this.asMusapKeyInfo(key));
43
+ }
44
+ async createKey(args) {
45
+ const { type, meta } = args;
46
+ if (meta === void 0 || !("keyAlias" in meta)) {
47
+ return Promise.reject(Error("a unique keyAlias field is required for MUSAP"));
48
+ }
49
+ if (this.sscdType == "EXTERNAL") {
50
+ const existingKeys = this.musapClient.listKeys();
51
+ const extKey = existingKeys.find((musapKey) => musapKey.sscdType === "External Signature");
52
+ if (extKey) {
53
+ extKey.algorithm = "eccp256r1";
54
+ return this.asMusapKeyInfo(extKey);
55
+ }
56
+ return Promise.reject(Error(`No external key was bound yet for sscd ${this.sscdId}`));
57
+ }
58
+ const keyGenReq = {
59
+ keyAlgorithm: this.mapKeyTypeToAlgorithmType(type),
60
+ keyUsage: "keyUsage" in meta ? meta.keyUsage : "sign",
61
+ keyAlias: meta.keyAlias,
62
+ attributes: this.recordToKeyAttributes({
63
+ ...this.defaultKeyAttributes,
64
+ ..."attributes" in meta ? meta.attributes : {}
65
+ }),
66
+ role: "role" in meta ? meta.role : "administrator"
67
+ };
68
+ try {
69
+ const generatedKeyUri = await this.musapClient.generateKey(this.sscdType, keyGenReq);
70
+ if (generatedKeyUri) {
71
+ logger.debug("Generated key:", generatedKeyUri);
72
+ const key = this.musapClient.getKeyByUri(generatedKeyUri);
73
+ return this.asMusapKeyInfo(key);
74
+ } else {
75
+ return Promise.reject(new Error("Failed to generate key. No key URI"));
76
+ }
77
+ } catch (error) {
78
+ logger.error("An error occurred:", error);
79
+ throw error;
80
+ }
81
+ }
82
+ mapKeyTypeToAlgorithmType = /* @__PURE__ */ __name((type) => {
83
+ switch (type) {
84
+ case "Secp256k1":
85
+ return "ECCP256K1";
86
+ case "Secp256r1":
87
+ return "ECCP256R1";
88
+ case "RSA":
89
+ return "RSA2K";
90
+ default:
91
+ throw new Error(`Key type ${type} is not supported by MUSAP`);
92
+ }
93
+ }, "mapKeyTypeToAlgorithmType");
94
+ mapAlgorithmTypeToKeyType = /* @__PURE__ */ __name((type) => {
95
+ switch (type) {
96
+ case "eccp256k1":
97
+ return "Secp256k1";
98
+ case "eccp256r1":
99
+ return "Secp256r1";
100
+ case "ecc_ed25519":
101
+ return "Ed25519";
102
+ case "rsa2k":
103
+ case "rsa4k":
104
+ return "RSA";
105
+ default:
106
+ throw new Error(`Key type ${type} is not supported.`);
107
+ }
108
+ }, "mapAlgorithmTypeToKeyType");
109
+ async deleteKey({ kid }) {
110
+ try {
111
+ const key = this.musapClient.getKeyById(kid);
112
+ if (key.sscdType === "External Signature") {
113
+ return true;
114
+ }
115
+ void this.musapClient.removeKey(kid);
116
+ return true;
117
+ } catch (error) {
118
+ console.warn("Failed to delete key:", error);
119
+ return false;
120
+ }
121
+ }
122
+ determineAlgorithm(providedAlgorithm, keyAlgorithm) {
123
+ if (providedAlgorithm === void 0) {
124
+ return signatureAlgorithmFromKeyAlgorithm(keyAlgorithm);
125
+ }
126
+ if (isSignatureAlgorithmType(providedAlgorithm)) {
127
+ return providedAlgorithm;
128
+ }
129
+ return signatureAlgorithmFromKeyAlgorithm(providedAlgorithm);
130
+ }
131
+ async sign(args) {
132
+ if (!args.keyRef) {
133
+ throw new Error("key_not_found: No key ref provided");
134
+ }
135
+ const data = new TextDecoder().decode(args.data);
136
+ const key = this.musapClient.getKeyById(args.keyRef.kid);
137
+ if (key.sscdType === "External Signature") {
138
+ key.algorithm = "eccp256r1";
139
+ }
140
+ const signatureReq = {
141
+ keyUri: key.keyUri,
142
+ data,
143
+ algorithm: this.determineAlgorithm(args.algorithm, key.algorithm),
144
+ displayText: args.displayText,
145
+ transId: args.transId,
146
+ format: args.format ?? "RAW",
147
+ attributes: this.recordToSignatureAttributes({
148
+ ...this.defaultSignAttributes,
149
+ ...args.attributes
150
+ })
151
+ };
152
+ return this.musapClient.sign(signatureReq);
153
+ }
154
+ async importKey(args) {
155
+ throw new Error("importKey is not implemented for MusapKeyManagementSystem.");
156
+ }
157
+ decodeMusapPublicKey = /* @__PURE__ */ __name((args) => {
158
+ const { publicKey, keyType } = args;
159
+ const pemBinary = PEMToBinary(publicKey.pem);
160
+ const pemString = toString(pemBinary, "utf8");
161
+ const isDoubleEncoded = pemBinary.length > 0 && typeof pemString === "string" && pemString.startsWith("MF");
162
+ if (isDoubleEncoded) {
163
+ const actualDerBytes = fromString(pemString, "base64");
164
+ const keyDataStart = 24;
165
+ const keyData = actualDerBytes.slice(keyDataStart);
166
+ let publicKeyHex = toString(keyData, "hex");
167
+ if (publicKeyHex.length <= 128 && !publicKeyHex.startsWith("04")) {
168
+ publicKeyHex = "04" + publicKeyHex;
169
+ }
170
+ while (publicKeyHex.startsWith("04") && publicKeyHex.length < 130) {
171
+ publicKeyHex = publicKeyHex + "0";
172
+ }
173
+ if (publicKeyHex.startsWith("04") && publicKeyHex.length === 130) {
174
+ const xCoord = fromString(publicKeyHex.slice(2, 66), "hex");
175
+ const yCoord = fromString(publicKeyHex.slice(66, 130), "hex");
176
+ const prefix = new Uint8Array([
177
+ yCoord[31] % 2 === 0 ? 2 : 3
178
+ ]);
179
+ const compressedKey = new Uint8Array(33);
180
+ compressedKey.set(prefix, 0);
181
+ compressedKey.set(xCoord, 1);
182
+ return toString(compressedKey, "hex");
183
+ }
184
+ return publicKeyHex;
185
+ }
186
+ const publicKeyBinary = isAsn1Der(pemBinary) ? asn1DerToRawPublicKey(pemBinary, keyType) : pemBinary;
187
+ return isRawCompressedPublicKey(publicKeyBinary) ? hexStringFromUint8Array(publicKeyBinary) : toRawCompressedHexPublicKey(publicKeyBinary, keyType);
188
+ }, "decodeMusapPublicKey");
189
+ asMusapKeyInfo(args) {
190
+ const { keyId, publicKey, ...metadata } = {
191
+ ...args
192
+ };
193
+ const keyType = this.mapAlgorithmTypeToKeyType(args.algorithm);
194
+ const publicKeyHex = this.decodeMusapPublicKey({
195
+ publicKey,
196
+ keyType
197
+ });
198
+ const keyInfo = {
199
+ kid: keyId,
200
+ type: keyType,
201
+ publicKeyHex,
202
+ meta: metadata
203
+ };
204
+ const jwkThumbprint = calculateJwkThumbprintForKey({
205
+ key: keyInfo
206
+ });
207
+ keyInfo.meta = {
208
+ ...keyInfo.meta,
209
+ jwkThumbprint
210
+ };
211
+ return keyInfo;
212
+ }
213
+ sharedSecret(args) {
214
+ throw new Error("Not supported.");
215
+ }
216
+ recordToKeyAttributes(record) {
217
+ if (!record) {
218
+ return [];
219
+ }
220
+ return Object.entries(record).map(([key, value]) => ({
221
+ name: key,
222
+ value
223
+ }));
224
+ }
225
+ recordToSignatureAttributes(record) {
226
+ if (!record) {
227
+ return [];
228
+ }
229
+ return Object.entries(record).map(([key, value]) => ({
230
+ name: key,
231
+ value
232
+ }));
233
+ }
234
+ };
235
+ export {
236
+ MusapKeyManagementSystem
237
+ };
6
238
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,iEAAkE;AAAzD,iIAAA,wBAAwB,OAAA"}
1
+ {"version":3,"sources":["../src/MusapKeyManagerSystem.ts"],"sourcesContent":["import { PEMToBinary } from '@sphereon/ssi-sdk-ext.x509-utils'\nimport { IKey, ManagedKeyInfo, MinimalImportableKey, TKeyType } from '@veramo/core'\nimport {\n ExternalSscdSettings,\n IMusapClient,\n isSignatureAlgorithmType,\n JWSAlgorithm,\n KeyAlgorithm,\n KeyAlgorithmType,\n KeyAttribute,\n KeyGenReq,\n MusapClient,\n MusapKey,\n signatureAlgorithmFromKeyAlgorithm,\n SignatureAlgorithmType,\n SignatureAttribute,\n SignatureFormat,\n SignatureReq,\n SscdType,\n} from '@sphereon/musap-react-native'\nimport { AbstractKeyManagementSystem } from '@veramo/key-manager'\nimport { TextDecoder } from 'text-encoding'\nimport { Loggers } from '@sphereon/ssi-types'\nimport { KeyMetadata } from './index'\nimport {\n asn1DerToRawPublicKey,\n calculateJwkThumbprintForKey,\n hexStringFromUint8Array,\n isAsn1Der,\n isRawCompressedPublicKey,\n toRawCompressedHexPublicKey,\n} from '@sphereon/ssi-sdk-ext.key-utils'\n// @ts-ignore\nimport { fromString } from 'uint8arrays/from-string'\n// @ts-ignore\nimport { toString } from 'uint8arrays/to-string'\n\nexport const logger = Loggers.DEFAULT.get('sphereon:musap-rn-kms')\n\nexport class MusapKeyManagementSystem extends AbstractKeyManagementSystem {\n private musapClient: IMusapClient\n private readonly sscdType: SscdType\n private readonly sscdId: string\n private readonly defaultKeyAttributes: Record<string, string> | undefined\n private readonly defaultSignAttributes: Record<string, string> | undefined\n\n constructor(\n sscdType?: SscdType,\n sscdId?: string,\n opts?: {\n externalSscdSettings?: ExternalSscdSettings\n defaultKeyAttributes?: Record<string, string>\n defaultSignAttributes?: Record<string, string>\n }\n ) {\n super()\n try {\n this.musapClient = MusapClient\n this.sscdType = sscdType ? sscdType : 'TEE'\n this.sscdId = sscdId ?? this.sscdType\n this.defaultKeyAttributes = opts?.defaultKeyAttributes\n this.defaultSignAttributes = opts?.defaultSignAttributes\n\n const enabledSscds = this.musapClient.listEnabledSscds()\n if (!enabledSscds.some((value) => value.sscdId == sscdId)) {\n this.musapClient.enableSscd(this.sscdType, this.sscdId, opts?.externalSscdSettings)\n }\n } catch (e) {\n console.error('enableSscd', e)\n throw Error('enableSscd failed')\n }\n }\n\n async listKeys(): Promise<ManagedKeyInfo[]> {\n const keysJson: MusapKey[] = this.musapClient.listKeys() as MusapKey[]\n return keysJson.map((key) => this.asMusapKeyInfo(key))\n }\n\n async createKey(args: { type: TKeyType; meta?: KeyMetadata }): Promise<ManagedKeyInfo> {\n const { type, meta } = args\n if (meta === undefined || !('keyAlias' in meta)) {\n return Promise.reject(Error('a unique keyAlias field is required for MUSAP'))\n }\n\n if (this.sscdType == 'EXTERNAL') {\n const existingKeys: MusapKey[] = this.musapClient.listKeys() as MusapKey[]\n const extKey = existingKeys.find((musapKey) => (musapKey.sscdType as string) === 'External Signature') // FIXME returning does not match SscdType enum\n if (extKey) {\n extKey.algorithm = 'eccp256r1' // FIXME MUSAP announces key as rsa2k, but it's actually EC\n return this.asMusapKeyInfo(extKey)\n }\n return Promise.reject(Error(`No external key was bound yet for sscd ${this.sscdId}`))\n }\n\n const keyGenReq = {\n keyAlgorithm: this.mapKeyTypeToAlgorithmType(type),\n keyUsage: 'keyUsage' in meta ? (meta.keyUsage as string) : 'sign',\n keyAlias: meta.keyAlias as string,\n attributes: this.recordToKeyAttributes({ ...this.defaultKeyAttributes, ...('attributes' in meta ? meta.attributes : {}) }),\n role: 'role' in meta ? (meta.role as string) : 'administrator',\n } satisfies KeyGenReq\n\n try {\n const generatedKeyUri = await this.musapClient.generateKey(this.sscdType, keyGenReq)\n if (generatedKeyUri) {\n logger.debug('Generated key:', generatedKeyUri)\n const key = this.musapClient.getKeyByUri(generatedKeyUri)\n return this.asMusapKeyInfo(key)\n } else {\n return Promise.reject(new Error('Failed to generate key. No key URI'))\n }\n } catch (error) {\n logger.error('An error occurred:', error)\n throw error\n }\n }\n\n private mapKeyTypeToAlgorithmType = (type: TKeyType): KeyAlgorithmType => {\n switch (type) {\n case 'Secp256k1':\n return 'ECCP256K1'\n case 'Secp256r1':\n return 'ECCP256R1'\n case 'RSA':\n return 'RSA2K'\n default:\n throw new Error(`Key type ${type} is not supported by MUSAP`)\n }\n }\n\n private mapAlgorithmTypeToKeyType = (type: KeyAlgorithm): TKeyType => {\n switch (type) {\n case 'eccp256k1':\n return 'Secp256k1'\n case 'eccp256r1':\n return 'Secp256r1'\n case 'ecc_ed25519':\n return 'Ed25519'\n case 'rsa2k':\n case 'rsa4k':\n return 'RSA'\n default:\n throw new Error(`Key type ${type} is not supported.`)\n }\n }\n\n async deleteKey({ kid }: { kid: string }): Promise<boolean> {\n try {\n const key: MusapKey = this.musapClient.getKeyById(kid) as MusapKey\n if ((key.sscdType as string) === 'External Signature') {\n return true // FIXME we can't remove a eSim key for now because this would mean onboarding again\n }\n void this.musapClient.removeKey(kid)\n return true\n } catch (error) {\n console.warn('Failed to delete key:', error)\n return false\n }\n }\n\n private determineAlgorithm(providedAlgorithm: string | undefined, keyAlgorithm: KeyAlgorithm): SignatureAlgorithmType {\n if (providedAlgorithm === undefined) {\n return signatureAlgorithmFromKeyAlgorithm(keyAlgorithm)\n }\n\n if (isSignatureAlgorithmType(providedAlgorithm)) {\n return providedAlgorithm\n }\n\n // Veramo translates TKeyType to JWSAlgorithm\n return signatureAlgorithmFromKeyAlgorithm(providedAlgorithm as JWSAlgorithm)\n }\n\n async sign(args: { keyRef: Pick<IKey, 'kid'>; algorithm?: string; data: Uint8Array; [x: string]: any }): Promise<string> {\n if (!args.keyRef) {\n throw new Error('key_not_found: No key ref provided')\n }\n\n const data = new TextDecoder().decode(args.data as Uint8Array)\n\n const key: MusapKey = this.musapClient.getKeyById(args.keyRef.kid) as MusapKey\n if ((key.sscdType as string) === 'External Signature') {\n key.algorithm = 'eccp256r1' // FIXME MUSAP announces key as rsa2k, but it's actually EC\n }\n const signatureReq: SignatureReq = {\n keyUri: key.keyUri,\n data,\n algorithm: this.determineAlgorithm(args.algorithm, key.algorithm),\n displayText: args.displayText,\n transId: args.transId,\n format: (args.format as SignatureFormat) ?? 'RAW',\n attributes: this.recordToSignatureAttributes({ ...this.defaultSignAttributes, ...args.attributes }),\n }\n return this.musapClient.sign(signatureReq)\n }\n\n async importKey(args: Omit<MinimalImportableKey, 'kms'> & { privateKeyPEM?: string }): Promise<ManagedKeyInfo> {\n throw new Error('importKey is not implemented for MusapKeyManagementSystem.')\n }\n\n private decodeMusapPublicKey = (args: { publicKey: { pem: string }; keyType: TKeyType }): string => {\n const { publicKey, keyType } = args\n\n // First try the normal PEM decoding path\n const pemBinary = PEMToBinary(publicKey.pem)\n\n // Check if we got a string that looks like base64 (might be double encoded)\n // Convert Uint8Array to string safely\n const pemString = toString(pemBinary, 'utf8')\n const isDoubleEncoded = pemBinary.length > 0 && typeof pemString === 'string' && pemString.startsWith('MF')\n\n if (isDoubleEncoded) {\n // Handle double-encoded case\n const actualDerBytes = fromString(pemString, 'base64')\n\n // For double-encoded case, we know the key data starts after the header\n const keyDataStart = 24\n const keyData = actualDerBytes.slice(keyDataStart)\n\n // Convert to public key hex\n let publicKeyHex = toString(keyData, 'hex')\n\n // If it's not compressed yet and doesn't start with 0x04 (uncompressed point marker), add it\n if (publicKeyHex.length <= 128 && !publicKeyHex.startsWith('04')) {\n publicKeyHex = '04' + publicKeyHex\n }\n\n // Ensure we have full 65 bytes for uncompressed keys\n while (publicKeyHex.startsWith('04') && publicKeyHex.length < 130) {\n publicKeyHex = publicKeyHex + '0'\n }\n\n // Now convert to compressed format if needed\n if (publicKeyHex.startsWith('04') && publicKeyHex.length === 130) {\n const xCoord = fromString(publicKeyHex.slice(2, 66), 'hex')\n const yCoord = fromString(publicKeyHex.slice(66, 130), 'hex')\n const prefix = new Uint8Array([yCoord[31] % 2 === 0 ? 0x02 : 0x03])\n const compressedKey = new Uint8Array(33) // 1 byte prefix + 32 bytes x coordinate\n compressedKey.set(prefix, 0)\n compressedKey.set(xCoord, 1)\n return toString(compressedKey, 'hex')\n }\n\n return publicKeyHex\n }\n\n // Not double encoded, proceed with normal path\n const publicKeyBinary = isAsn1Der(pemBinary) ? asn1DerToRawPublicKey(pemBinary, keyType) : pemBinary\n return isRawCompressedPublicKey(publicKeyBinary)\n ? hexStringFromUint8Array(publicKeyBinary)\n : toRawCompressedHexPublicKey(publicKeyBinary, keyType)\n }\n\n private asMusapKeyInfo(args: MusapKey): ManagedKeyInfo {\n const { keyId, publicKey, ...metadata }: KeyMetadata = { ...args }\n const keyType = this.mapAlgorithmTypeToKeyType(args.algorithm)\n\n const publicKeyHex = this.decodeMusapPublicKey({\n publicKey: publicKey,\n keyType: keyType,\n })\n\n const keyInfo: Partial<ManagedKeyInfo> = {\n kid: keyId,\n type: keyType,\n publicKeyHex,\n meta: metadata,\n }\n\n const jwkThumbprint = calculateJwkThumbprintForKey({ key: keyInfo as ManagedKeyInfo })\n keyInfo.meta = { ...keyInfo.meta, jwkThumbprint }\n return keyInfo as ManagedKeyInfo\n }\n\n sharedSecret(args: { myKeyRef: Pick<IKey, 'kid'>; theirKey: Pick<IKey, 'publicKeyHex' | 'type'> }): Promise<string> {\n throw new Error('Not supported.')\n }\n\n private recordToKeyAttributes(record?: Record<string, string>): KeyAttribute[] {\n if (!record) {\n return []\n }\n return Object.entries(record).map(([key, value]) => ({\n name: key,\n value,\n }))\n }\n\n private recordToSignatureAttributes(record?: Record<string, string>): SignatureAttribute[] {\n if (!record) {\n return []\n }\n return Object.entries(record).map(([key, value]) => ({\n name: key,\n value,\n }))\n }\n}\n"],"mappings":"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","names":["PEMToBinary","isSignatureAlgorithmType","MusapClient","signatureAlgorithmFromKeyAlgorithm","AbstractKeyManagementSystem","TextDecoder","Loggers","asn1DerToRawPublicKey","calculateJwkThumbprintForKey","hexStringFromUint8Array","isAsn1Der","isRawCompressedPublicKey","toRawCompressedHexPublicKey","fromString","toString","logger","Loggers","DEFAULT","get","MusapKeyManagementSystem","AbstractKeyManagementSystem","musapClient","sscdType","sscdId","defaultKeyAttributes","defaultSignAttributes","constructor","opts","MusapClient","enabledSscds","listEnabledSscds","some","value","enableSscd","externalSscdSettings","e","console","error","Error","listKeys","keysJson","map","key","asMusapKeyInfo","createKey","args","type","meta","undefined","Promise","reject","existingKeys","extKey","find","musapKey","algorithm","keyGenReq","keyAlgorithm","mapKeyTypeToAlgorithmType","keyUsage","keyAlias","attributes","recordToKeyAttributes","role","generatedKeyUri","generateKey","debug","getKeyByUri","mapAlgorithmTypeToKeyType","deleteKey","kid","getKeyById","removeKey","warn","determineAlgorithm","providedAlgorithm","signatureAlgorithmFromKeyAlgorithm","isSignatureAlgorithmType","sign","keyRef","data","TextDecoder","decode","signatureReq","keyUri","displayText","transId","format","recordToSignatureAttributes","importKey","decodeMusapPublicKey","publicKey","keyType","pemBinary","PEMToBinary","pem","pemString","toString","isDoubleEncoded","length","startsWith","actualDerBytes","fromString","keyDataStart","keyData","slice","publicKeyHex","xCoord","yCoord","prefix","Uint8Array","compressedKey","set","publicKeyBinary","isAsn1Der","asn1DerToRawPublicKey","isRawCompressedPublicKey","hexStringFromUint8Array","toRawCompressedHexPublicKey","keyId","metadata","keyInfo","jwkThumbprint","calculateJwkThumbprintForKey","sharedSecret","record","Object","entries","name"]}
package/package.json CHANGED
@@ -1,30 +1,42 @@
1
1
  {
2
2
  "name": "@sphereon/ssi-sdk-ext.kms-musap-rn",
3
3
  "description": "Sphereon SSI-SDK react-native plugin for management of keys with musap.",
4
- "version": "0.27.1-next.6+7161cdc",
5
- "source": "src/index.ts",
6
- "main": "dist/index.js",
7
- "types": "dist/index.d.ts",
4
+ "version": "0.28.1-feature.esm.cjs.8+4c162d1",
5
+ "source": "./src/index.ts",
6
+ "type": "module",
7
+ "main": "./dist/index.cjs",
8
+ "module": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "require": "./dist/index.cjs"
18
+ }
19
+ },
8
20
  "scripts": {
9
- "build": "tsc --build",
10
- "build:clean": "tsc --build --clean && tsc --build"
21
+ "build": "tsup --config ../../tsup.config.ts --tsconfig ../../tsconfig.tsup.json"
11
22
  },
12
23
  "dependencies": {
13
24
  "@sphereon/musap-react-native": "0.2.1-next.170",
14
- "@sphereon/ssi-sdk-ext.key-utils": "0.27.1-next.6+7161cdc",
15
- "@sphereon/ssi-sdk-ext.x509-utils": "0.27.1-next.6+7161cdc",
16
- "@sphereon/ssi-types": "0.30.2-feature.SDK.41.oidf.support.286",
25
+ "@sphereon/ssi-sdk-ext.key-utils": "^0.28.1-feature.esm.cjs.8+4c162d1",
26
+ "@sphereon/ssi-sdk-ext.x509-utils": "^0.28.1-feature.esm.cjs.8+4c162d1",
27
+ "@sphereon/ssi-types": " ^0.33",
17
28
  "@veramo/core": "4.2.0",
18
29
  "@veramo/key-manager": "4.2.0",
19
30
  "@veramo/kms-local": "4.2.0",
20
- "text-encoding": "^0.7.0"
31
+ "text-encoding": "^0.7.0",
32
+ "uint8arrays": " 3.1.1"
21
33
  },
22
34
  "devDependencies": {
23
35
  "@types/text-encoding": "0.0.39"
24
36
  },
25
37
  "files": [
26
- "dist/**/*",
27
- "src/**/*",
38
+ "dist",
39
+ "src",
28
40
  "README.md",
29
41
  "LICENSE"
30
42
  ],
@@ -41,5 +53,5 @@
41
53
  "react-native",
42
54
  "Veramo"
43
55
  ],
44
- "gitHead": "7161cdca6d24315f01b785ed437edb27ef49f0f3"
56
+ "gitHead": "4c162d14577f462070adeea3e7ec5a443c324ee7"
45
57
  }
@@ -30,6 +30,10 @@ import {
30
30
  isRawCompressedPublicKey,
31
31
  toRawCompressedHexPublicKey,
32
32
  } from '@sphereon/ssi-sdk-ext.key-utils'
33
+ // @ts-ignore
34
+ import { fromString } from 'uint8arrays/from-string'
35
+ // @ts-ignore
36
+ import { toString } from 'uint8arrays/to-string'
33
37
 
34
38
  export const logger = Loggers.DEFAULT.get('sphereon:musap-rn-kms')
35
39
 
@@ -40,11 +44,15 @@ export class MusapKeyManagementSystem extends AbstractKeyManagementSystem {
40
44
  private readonly defaultKeyAttributes: Record<string, string> | undefined
41
45
  private readonly defaultSignAttributes: Record<string, string> | undefined
42
46
 
43
- constructor(sscdType?: SscdType, sscdId?: string, opts?: {
44
- externalSscdSettings?: ExternalSscdSettings,
45
- defaultKeyAttributes?: Record<string, string>,
46
- defaultSignAttributes?: Record<string, string>
47
- }) {
47
+ constructor(
48
+ sscdType?: SscdType,
49
+ sscdId?: string,
50
+ opts?: {
51
+ externalSscdSettings?: ExternalSscdSettings
52
+ defaultKeyAttributes?: Record<string, string>
53
+ defaultSignAttributes?: Record<string, string>
54
+ }
55
+ ) {
48
56
  super()
49
57
  try {
50
58
  this.musapClient = MusapClient
@@ -54,7 +62,7 @@ export class MusapKeyManagementSystem extends AbstractKeyManagementSystem {
54
62
  this.defaultSignAttributes = opts?.defaultSignAttributes
55
63
 
56
64
  const enabledSscds = this.musapClient.listEnabledSscds()
57
- if (!enabledSscds.some(value => value.sscdId == sscdId)) {
65
+ if (!enabledSscds.some((value) => value.sscdId == sscdId)) {
58
66
  this.musapClient.enableSscd(this.sscdType, this.sscdId, opts?.externalSscdSettings)
59
67
  }
60
68
  } catch (e) {
@@ -64,7 +72,7 @@ export class MusapKeyManagementSystem extends AbstractKeyManagementSystem {
64
72
  }
65
73
 
66
74
  async listKeys(): Promise<ManagedKeyInfo[]> {
67
- const keysJson: MusapKey[] = (this.musapClient.listKeys()) as MusapKey[]
75
+ const keysJson: MusapKey[] = this.musapClient.listKeys() as MusapKey[]
68
76
  return keysJson.map((key) => this.asMusapKeyInfo(key))
69
77
  }
70
78
 
@@ -75,8 +83,8 @@ export class MusapKeyManagementSystem extends AbstractKeyManagementSystem {
75
83
  }
76
84
 
77
85
  if (this.sscdType == 'EXTERNAL') {
78
- const existingKeys: MusapKey[] = (this.musapClient.listKeys()) as MusapKey[]
79
- const extKey = existingKeys.find(musapKey => musapKey.sscdType as string === 'External Signature') // FIXME returning does not match SscdType enum
86
+ const existingKeys: MusapKey[] = this.musapClient.listKeys() as MusapKey[]
87
+ const extKey = existingKeys.find((musapKey) => (musapKey.sscdType as string) === 'External Signature') // FIXME returning does not match SscdType enum
80
88
  if (extKey) {
81
89
  extKey.algorithm = 'eccp256r1' // FIXME MUSAP announces key as rsa2k, but it's actually EC
82
90
  return this.asMusapKeyInfo(extKey)
@@ -137,12 +145,12 @@ export class MusapKeyManagementSystem extends AbstractKeyManagementSystem {
137
145
  }
138
146
 
139
147
  async deleteKey({ kid }: { kid: string }): Promise<boolean> {
140
- try {
141
- const key: MusapKey = this.musapClient.getKeyById(kid) as MusapKey
142
- if (key.sscdType as string === 'External Signature') {
143
- return true // FIXME we can't remove a eSim key for now because this would mean onboarding again
144
- }
145
- void this.musapClient.removeKey(kid)
148
+ try {
149
+ const key: MusapKey = this.musapClient.getKeyById(kid) as MusapKey
150
+ if ((key.sscdType as string) === 'External Signature') {
151
+ return true // FIXME we can't remove a eSim key for now because this would mean onboarding again
152
+ }
153
+ void this.musapClient.removeKey(kid)
146
154
  return true
147
155
  } catch (error) {
148
156
  console.warn('Failed to delete key:', error)
@@ -163,12 +171,7 @@ export class MusapKeyManagementSystem extends AbstractKeyManagementSystem {
163
171
  return signatureAlgorithmFromKeyAlgorithm(providedAlgorithm as JWSAlgorithm)
164
172
  }
165
173
 
166
- async sign(args: {
167
- keyRef: Pick<IKey, 'kid'>;
168
- algorithm?: string;
169
- data: Uint8Array;
170
- [x: string]: any
171
- }): Promise<string> {
174
+ async sign(args: { keyRef: Pick<IKey, 'kid'>; algorithm?: string; data: Uint8Array; [x: string]: any }): Promise<string> {
172
175
  if (!args.keyRef) {
173
176
  throw new Error('key_not_found: No key ref provided')
174
177
  }
@@ -176,7 +179,7 @@ export class MusapKeyManagementSystem extends AbstractKeyManagementSystem {
176
179
  const data = new TextDecoder().decode(args.data as Uint8Array)
177
180
 
178
181
  const key: MusapKey = this.musapClient.getKeyById(args.keyRef.kid) as MusapKey
179
- if (key.sscdType as string === 'External Signature') {
182
+ if ((key.sscdType as string) === 'External Signature') {
180
183
  key.algorithm = 'eccp256r1' // FIXME MUSAP announces key as rsa2k, but it's actually EC
181
184
  }
182
185
  const signatureReq: SignatureReq = {
@@ -195,15 +198,68 @@ export class MusapKeyManagementSystem extends AbstractKeyManagementSystem {
195
198
  throw new Error('importKey is not implemented for MusapKeyManagementSystem.')
196
199
  }
197
200
 
198
- private asMusapKeyInfo(args: MusapKey): ManagedKeyInfo {
199
- const { keyId, publicKey, ...metadata }: KeyMetadata = { ...args }
200
- const keyType = this.mapAlgorithmTypeToKeyType(args.algorithm)
201
+ private decodeMusapPublicKey = (args: { publicKey: { pem: string }; keyType: TKeyType }): string => {
202
+ const { publicKey, keyType } = args
203
+
204
+ // First try the normal PEM decoding path
205
+ const pemBinary = PEMToBinary(publicKey.pem)
206
+
207
+ // Check if we got a string that looks like base64 (might be double encoded)
208
+ // Convert Uint8Array to string safely
209
+ const pemString = toString(pemBinary, 'utf8')
210
+ const isDoubleEncoded = pemBinary.length > 0 && typeof pemString === 'string' && pemString.startsWith('MF')
211
+
212
+ if (isDoubleEncoded) {
213
+ // Handle double-encoded case
214
+ const actualDerBytes = fromString(pemString, 'base64')
215
+
216
+ // For double-encoded case, we know the key data starts after the header
217
+ const keyDataStart = 24
218
+ const keyData = actualDerBytes.slice(keyDataStart)
219
+
220
+ // Convert to public key hex
221
+ let publicKeyHex = toString(keyData, 'hex')
222
+
223
+ // If it's not compressed yet and doesn't start with 0x04 (uncompressed point marker), add it
224
+ if (publicKeyHex.length <= 128 && !publicKeyHex.startsWith('04')) {
225
+ publicKeyHex = '04' + publicKeyHex
226
+ }
201
227
 
202
- const pemBinary = PEMToBinary(args.publicKey.pem) // The der is flawed, it's not binary but a string [123, 4567]
228
+ // Ensure we have full 65 bytes for uncompressed keys
229
+ while (publicKeyHex.startsWith('04') && publicKeyHex.length < 130) {
230
+ publicKeyHex = publicKeyHex + '0'
231
+ }
232
+
233
+ // Now convert to compressed format if needed
234
+ if (publicKeyHex.startsWith('04') && publicKeyHex.length === 130) {
235
+ const xCoord = fromString(publicKeyHex.slice(2, 66), 'hex')
236
+ const yCoord = fromString(publicKeyHex.slice(66, 130), 'hex')
237
+ const prefix = new Uint8Array([yCoord[31] % 2 === 0 ? 0x02 : 0x03])
238
+ const compressedKey = new Uint8Array(33) // 1 byte prefix + 32 bytes x coordinate
239
+ compressedKey.set(prefix, 0)
240
+ compressedKey.set(xCoord, 1)
241
+ return toString(compressedKey, 'hex')
242
+ }
243
+
244
+ return publicKeyHex
245
+ }
246
+
247
+ // Not double encoded, proceed with normal path
203
248
  const publicKeyBinary = isAsn1Der(pemBinary) ? asn1DerToRawPublicKey(pemBinary, keyType) : pemBinary
204
- const publicKeyHex = isRawCompressedPublicKey(publicKeyBinary) // TODO In the future I think it's better to have an option in KeyGenReq to specify which public key format we want back. Now it's different in iOS vs Android and we need to handle that inconsistency afterwards
249
+ return isRawCompressedPublicKey(publicKeyBinary)
205
250
  ? hexStringFromUint8Array(publicKeyBinary)
206
251
  : toRawCompressedHexPublicKey(publicKeyBinary, keyType)
252
+ }
253
+
254
+ private asMusapKeyInfo(args: MusapKey): ManagedKeyInfo {
255
+ const { keyId, publicKey, ...metadata }: KeyMetadata = { ...args }
256
+ const keyType = this.mapAlgorithmTypeToKeyType(args.algorithm)
257
+
258
+ const publicKeyHex = this.decodeMusapPublicKey({
259
+ publicKey: publicKey,
260
+ keyType: keyType,
261
+ })
262
+
207
263
  const keyInfo: Partial<ManagedKeyInfo> = {
208
264
  kid: keyId,
209
265
  type: keyType,
@@ -1 +0,0 @@
1
- {"version":3,"file":"MusapKeyManagerSystem.d.ts","sourceRoot":"","sources":["../src/MusapKeyManagerSystem.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AACnF,OAAO,EACL,oBAAoB,EAepB,QAAQ,EACT,MAAM,8BAA8B,CAAA;AACrC,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAA;AAGjE,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAUrC,eAAO,MAAM,MAAM,sDAA+C,CAAA;AAElE,qBAAa,wBAAyB,SAAQ,2BAA2B;IACvE,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAoC;IACzE,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAoC;gBAE9D,QAAQ,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QACvD,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;QAC5C,oBAAoB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC9C,qBAAqB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAC/C;IAmBK,QAAQ,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;IAKrC,SAAS,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,IAAI,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC;IAuCtF,OAAO,CAAC,yBAAyB,CAWhC;IAED,OAAO,CAAC,yBAAyB,CAchC;IAEK,SAAS,CAAC,EAAE,GAAG,EAAE,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAc3D,OAAO,CAAC,kBAAkB;IAapB,IAAI,CAAC,IAAI,EAAE;QACf,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,IAAI,EAAE,UAAU,CAAC;QACjB,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAA;KACjB,GAAG,OAAO,CAAC,MAAM,CAAC;IAuBb,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,oBAAoB,EAAE,KAAK,CAAC,GAAG;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC;IAI9G,OAAO,CAAC,cAAc;IAqBtB,YAAY,CAAC,IAAI,EAAE;QAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAInH,OAAO,CAAC,qBAAqB;IAU7B,OAAO,CAAC,2BAA2B;CASpC"}
@@ -1,217 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __rest = (this && this.__rest) || function (s, e) {
12
- var t = {};
13
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
14
- t[p] = s[p];
15
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
16
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
17
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
18
- t[p[i]] = s[p[i]];
19
- }
20
- return t;
21
- };
22
- Object.defineProperty(exports, "__esModule", { value: true });
23
- exports.MusapKeyManagementSystem = exports.logger = void 0;
24
- const ssi_sdk_ext_x509_utils_1 = require("@sphereon/ssi-sdk-ext.x509-utils");
25
- const musap_react_native_1 = require("@sphereon/musap-react-native");
26
- const key_manager_1 = require("@veramo/key-manager");
27
- const text_encoding_1 = require("text-encoding");
28
- const ssi_types_1 = require("@sphereon/ssi-types");
29
- const ssi_sdk_ext_key_utils_1 = require("@sphereon/ssi-sdk-ext.key-utils");
30
- exports.logger = ssi_types_1.Loggers.DEFAULT.get('sphereon:musap-rn-kms');
31
- class MusapKeyManagementSystem extends key_manager_1.AbstractKeyManagementSystem {
32
- constructor(sscdType, sscdId, opts) {
33
- super();
34
- this.mapKeyTypeToAlgorithmType = (type) => {
35
- switch (type) {
36
- case 'Secp256k1':
37
- return 'ECCP256K1';
38
- case 'Secp256r1':
39
- return 'ECCP256R1';
40
- case 'RSA':
41
- return 'RSA2K';
42
- default:
43
- throw new Error(`Key type ${type} is not supported by MUSAP`);
44
- }
45
- };
46
- this.mapAlgorithmTypeToKeyType = (type) => {
47
- switch (type) {
48
- case 'eccp256k1':
49
- return 'Secp256k1';
50
- case 'eccp256r1':
51
- return 'Secp256r1';
52
- case 'ecc_ed25519':
53
- return 'Ed25519';
54
- case 'rsa2k':
55
- case 'rsa4k':
56
- return 'RSA';
57
- default:
58
- throw new Error(`Key type ${type} is not supported.`);
59
- }
60
- };
61
- try {
62
- this.musapClient = musap_react_native_1.MusapClient;
63
- this.sscdType = sscdType ? sscdType : 'TEE';
64
- this.sscdId = sscdId !== null && sscdId !== void 0 ? sscdId : this.sscdType;
65
- this.defaultKeyAttributes = opts === null || opts === void 0 ? void 0 : opts.defaultKeyAttributes;
66
- this.defaultSignAttributes = opts === null || opts === void 0 ? void 0 : opts.defaultSignAttributes;
67
- const enabledSscds = this.musapClient.listEnabledSscds();
68
- if (!enabledSscds.some(value => value.sscdId == sscdId)) {
69
- this.musapClient.enableSscd(this.sscdType, this.sscdId, opts === null || opts === void 0 ? void 0 : opts.externalSscdSettings);
70
- }
71
- }
72
- catch (e) {
73
- console.error('enableSscd', e);
74
- throw Error('enableSscd failed');
75
- }
76
- }
77
- listKeys() {
78
- return __awaiter(this, void 0, void 0, function* () {
79
- const keysJson = (this.musapClient.listKeys());
80
- return keysJson.map((key) => this.asMusapKeyInfo(key));
81
- });
82
- }
83
- createKey(args) {
84
- return __awaiter(this, void 0, void 0, function* () {
85
- const { type, meta } = args;
86
- if (meta === undefined || !('keyAlias' in meta)) {
87
- return Promise.reject(Error('a unique keyAlias field is required for MUSAP'));
88
- }
89
- if (this.sscdType == 'EXTERNAL') {
90
- const existingKeys = (this.musapClient.listKeys());
91
- const extKey = existingKeys.find(musapKey => musapKey.sscdType === 'External Signature'); // FIXME returning does not match SscdType enum
92
- if (extKey) {
93
- extKey.algorithm = 'eccp256r1'; // FIXME MUSAP announces key as rsa2k, but it's actually EC
94
- return this.asMusapKeyInfo(extKey);
95
- }
96
- return Promise.reject(Error(`No external key was bound yet for sscd ${this.sscdId}`));
97
- }
98
- const keyGenReq = {
99
- keyAlgorithm: this.mapKeyTypeToAlgorithmType(type),
100
- keyUsage: 'keyUsage' in meta ? meta.keyUsage : 'sign',
101
- keyAlias: meta.keyAlias,
102
- attributes: this.recordToKeyAttributes(Object.assign(Object.assign({}, this.defaultKeyAttributes), ('attributes' in meta ? meta.attributes : {}))),
103
- role: 'role' in meta ? meta.role : 'administrator',
104
- };
105
- try {
106
- const generatedKeyUri = yield this.musapClient.generateKey(this.sscdType, keyGenReq);
107
- if (generatedKeyUri) {
108
- exports.logger.debug('Generated key:', generatedKeyUri);
109
- const key = this.musapClient.getKeyByUri(generatedKeyUri);
110
- return this.asMusapKeyInfo(key);
111
- }
112
- else {
113
- return Promise.reject(new Error('Failed to generate key. No key URI'));
114
- }
115
- }
116
- catch (error) {
117
- exports.logger.error('An error occurred:', error);
118
- throw error;
119
- }
120
- });
121
- }
122
- deleteKey(_a) {
123
- return __awaiter(this, arguments, void 0, function* ({ kid }) {
124
- try {
125
- const key = this.musapClient.getKeyById(kid);
126
- if (key.sscdType === 'External Signature') {
127
- return true; // FIXME we can't remove a eSim key for now because this would mean onboarding again
128
- }
129
- void this.musapClient.removeKey(kid);
130
- return true;
131
- }
132
- catch (error) {
133
- console.warn('Failed to delete key:', error);
134
- return false;
135
- }
136
- });
137
- }
138
- determineAlgorithm(providedAlgorithm, keyAlgorithm) {
139
- if (providedAlgorithm === undefined) {
140
- return (0, musap_react_native_1.signatureAlgorithmFromKeyAlgorithm)(keyAlgorithm);
141
- }
142
- if ((0, musap_react_native_1.isSignatureAlgorithmType)(providedAlgorithm)) {
143
- return providedAlgorithm;
144
- }
145
- // Veramo translates TKeyType to JWSAlgorithm
146
- return (0, musap_react_native_1.signatureAlgorithmFromKeyAlgorithm)(providedAlgorithm);
147
- }
148
- sign(args) {
149
- return __awaiter(this, void 0, void 0, function* () {
150
- var _a;
151
- if (!args.keyRef) {
152
- throw new Error('key_not_found: No key ref provided');
153
- }
154
- const data = new text_encoding_1.TextDecoder().decode(args.data);
155
- const key = this.musapClient.getKeyById(args.keyRef.kid);
156
- if (key.sscdType === 'External Signature') {
157
- key.algorithm = 'eccp256r1'; // FIXME MUSAP announces key as rsa2k, but it's actually EC
158
- }
159
- const signatureReq = {
160
- keyUri: key.keyUri,
161
- data,
162
- algorithm: this.determineAlgorithm(args.algorithm, key.algorithm),
163
- displayText: args.displayText,
164
- transId: args.transId,
165
- format: (_a = args.format) !== null && _a !== void 0 ? _a : 'RAW',
166
- attributes: this.recordToSignatureAttributes(Object.assign(Object.assign({}, this.defaultSignAttributes), args.attributes)),
167
- };
168
- return this.musapClient.sign(signatureReq);
169
- });
170
- }
171
- importKey(args) {
172
- return __awaiter(this, void 0, void 0, function* () {
173
- throw new Error('importKey is not implemented for MusapKeyManagementSystem.');
174
- });
175
- }
176
- asMusapKeyInfo(args) {
177
- const _a = Object.assign({}, args), { keyId, publicKey } = _a, metadata = __rest(_a, ["keyId", "publicKey"]);
178
- const keyType = this.mapAlgorithmTypeToKeyType(args.algorithm);
179
- const pemBinary = (0, ssi_sdk_ext_x509_utils_1.PEMToBinary)(args.publicKey.pem); // The der is flawed, it's not binary but a string [123, 4567]
180
- const publicKeyBinary = (0, ssi_sdk_ext_key_utils_1.isAsn1Der)(pemBinary) ? (0, ssi_sdk_ext_key_utils_1.asn1DerToRawPublicKey)(pemBinary, keyType) : pemBinary;
181
- const publicKeyHex = (0, ssi_sdk_ext_key_utils_1.isRawCompressedPublicKey)(publicKeyBinary) // TODO In the future I think it's better to have an option in KeyGenReq to specify which public key format we want back. Now it's different in iOS vs Android and we need to handle that inconsistency afterwards
182
- ? (0, ssi_sdk_ext_key_utils_1.hexStringFromUint8Array)(publicKeyBinary)
183
- : (0, ssi_sdk_ext_key_utils_1.toRawCompressedHexPublicKey)(publicKeyBinary, keyType);
184
- const keyInfo = {
185
- kid: keyId,
186
- type: keyType,
187
- publicKeyHex,
188
- meta: metadata,
189
- };
190
- const jwkThumbprint = (0, ssi_sdk_ext_key_utils_1.calculateJwkThumbprintForKey)({ key: keyInfo });
191
- keyInfo.meta = Object.assign(Object.assign({}, keyInfo.meta), { jwkThumbprint });
192
- return keyInfo;
193
- }
194
- sharedSecret(args) {
195
- throw new Error('Not supported.');
196
- }
197
- recordToKeyAttributes(record) {
198
- if (!record) {
199
- return [];
200
- }
201
- return Object.entries(record).map(([key, value]) => ({
202
- name: key,
203
- value,
204
- }));
205
- }
206
- recordToSignatureAttributes(record) {
207
- if (!record) {
208
- return [];
209
- }
210
- return Object.entries(record).map(([key, value]) => ({
211
- name: key,
212
- value,
213
- }));
214
- }
215
- }
216
- exports.MusapKeyManagementSystem = MusapKeyManagementSystem;
217
- //# sourceMappingURL=MusapKeyManagerSystem.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"MusapKeyManagerSystem.js","sourceRoot":"","sources":["../src/MusapKeyManagerSystem.ts"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAA;AAElE,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,EAAE,CAAA;IAErB,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAA;CACjB"}