From eea46d8ff6fe7fac9bf900773681f01563b5e7c4 Mon Sep 17 00:00:00 2001 From: sanderPostma Date: Tue, 10 Dec 2024 12:24:26 +0100 Subject: [PATCH] chore: musap-react-native ios eSim fix --- packages/kms-musap-rn/package.json | 1 + .../kms-musap-rn/src/MusapKeyManagerSystem.ts | 89 +++++++++---------- pnpm-lock.yaml | 7 +- 3 files changed, 49 insertions(+), 48 deletions(-) diff --git a/packages/kms-musap-rn/package.json b/packages/kms-musap-rn/package.json index 13bea99b..4089a523 100644 --- a/packages/kms-musap-rn/package.json +++ b/packages/kms-musap-rn/package.json @@ -17,6 +17,7 @@ "@veramo/core": "4.2.0", "@veramo/key-manager": "4.2.0", "@veramo/kms-local": "4.2.0", + "uint8arrays": "^3.1.1", "text-encoding": "^0.7.0" }, "devDependencies": { diff --git a/packages/kms-musap-rn/src/MusapKeyManagerSystem.ts b/packages/kms-musap-rn/src/MusapKeyManagerSystem.ts index c4799c07..60960c2f 100644 --- a/packages/kms-musap-rn/src/MusapKeyManagerSystem.ts +++ b/packages/kms-musap-rn/src/MusapKeyManagerSystem.ts @@ -30,6 +30,7 @@ import { isRawCompressedPublicKey, toRawCompressedHexPublicKey, } from '@sphereon/ssi-sdk-ext.key-utils' +import * as u8a from 'uint8arrays' export const logger = Loggers.DEFAULT.get('sphereon:musap-rn-kms') @@ -195,65 +196,61 @@ export class MusapKeyManagementSystem extends AbstractKeyManagementSystem { throw new Error('importKey is not implemented for MusapKeyManagementSystem.') } - private decodeMusapPublicKey = (args: { publicKey: { pem: string }, keyType: TKeyType }): string => { - const { publicKey, keyType } = args; - - try { - // First try the normal PEM decoding path - const pemBinary = PEMToBinary(publicKey.pem) + const { publicKey, keyType } = args - // Check if we got a string that looks like base64 (might be double encoded) - const isDoubleEncoded = pemBinary.length > 0 && - typeof Buffer.from(pemBinary).toString() === 'string' && - Buffer.from(pemBinary).toString().startsWith('MF'); + // First try the normal PEM decoding path + const pemBinary = PEMToBinary(publicKey.pem) - if (isDoubleEncoded) { - // Handle double-encoded case - const innerBase64 = Buffer.from(pemBinary).toString() - const actualDerBytes = Buffer.from(innerBase64, 'base64') + // Check if we got a string that looks like base64 (might be double encoded) + // Convert Uint8Array to string safely + const pemString = u8a.toString(pemBinary, 'utf8') + const isDoubleEncoded = pemBinary.length > 0 && + typeof pemString === 'string' && + pemString.startsWith('MF') - // For double-encoded case, we know the key data starts after the header - const keyDataStart = 24 - const keyData = actualDerBytes.slice(keyDataStart) + if (isDoubleEncoded) { + // Handle double-encoded case + const actualDerBytes = u8a.fromString(pemString, 'base64') - // Convert to public key hex - let publicKeyHex = Buffer.from(keyData).toString('hex') + // For double-encoded case, we know the key data starts after the header + const keyDataStart = 24 + const keyData = actualDerBytes.slice(keyDataStart) - // If it's not compressed yet and doesn't start with 0x04 (uncompressed point marker), add it - if (publicKeyHex.length <= 128 && !publicKeyHex.startsWith('04')) { - publicKeyHex = '04' + publicKeyHex - } - - // Ensure we have full 65 bytes for uncompressed keys - while (publicKeyHex.startsWith('04') && publicKeyHex.length < 130) { - publicKeyHex = publicKeyHex + '0' - } + // Convert to public key hex + let publicKeyHex = u8a.toString(keyData, 'hex') - // Now convert to compressed format if needed - if (publicKeyHex.startsWith('04') && publicKeyHex.length === 130) { - const xCoord = Buffer.from(publicKeyHex.slice(2, 66), 'hex') - const yCoord = Buffer.from(publicKeyHex.slice(66, 130), 'hex') - const prefix = Buffer.from([yCoord[31] % 2 === 0 ? 0x02 : 0x03]) - const compressedKey = Buffer.concat([prefix, xCoord]) - return compressedKey.toString('hex') - } + // If it's not compressed yet and doesn't start with 0x04 (uncompressed point marker), add it + if (publicKeyHex.length <= 128 && !publicKeyHex.startsWith('04')) { + publicKeyHex = '04' + publicKeyHex + } - return publicKeyHex + // Ensure we have full 65 bytes for uncompressed keys + while (publicKeyHex.startsWith('04') && publicKeyHex.length < 130) { + publicKeyHex = publicKeyHex + '0' } - // Not double encoded, proceed with normal path - const publicKeyBinary = isAsn1Der(pemBinary) ? asn1DerToRawPublicKey(pemBinary, keyType) : pemBinary - return isRawCompressedPublicKey(publicKeyBinary) - ? hexStringFromUint8Array(publicKeyBinary) - : toRawCompressedHexPublicKey(publicKeyBinary, keyType) + // Now convert to compressed format if needed + if (publicKeyHex.startsWith('04') && publicKeyHex.length === 130) { + const xCoord = u8a.fromString(publicKeyHex.slice(2, 66), 'hex') + const yCoord = u8a.fromString(publicKeyHex.slice(66, 130), 'hex') + const prefix = new Uint8Array([yCoord[31] % 2 === 0 ? 0x02 : 0x03]) + const compressedKey = new Uint8Array(33) // 1 byte prefix + 32 bytes x coordinate + compressedKey.set(prefix, 0) + compressedKey.set(xCoord, 1) + return u8a.toString(compressedKey, 'hex') + } - } catch (error) { - console.warn('Error decoding public key:', error) - // If all else fails, try direct conversion - return publicKey.pem + return publicKeyHex } + + // Not double encoded, proceed with normal path + const publicKeyBinary = isAsn1Der(pemBinary) ? asn1DerToRawPublicKey(pemBinary, keyType) : pemBinary + return isRawCompressedPublicKey(publicKeyBinary) + ? hexStringFromUint8Array(publicKeyBinary) + : toRawCompressedHexPublicKey(publicKeyBinary, keyType) } + private asMusapKeyInfo(args: MusapKey): ManagedKeyInfo { const { keyId, publicKey, ...metadata }: KeyMetadata = { ...args } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b0d3ddac..6eb7bea5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -224,7 +224,7 @@ importers: version: link:../key-utils '@transmute/did-key-bls12381': specifier: 0.3.0-unstable.10 - version: 0.3.0-unstable.10(encoding@0.1.13)(expo@51.0.38(@babel/core@7.26.0)(@babel/preset-env@7.26.0(@babel/core@7.26.0))(encoding@0.1.13))(react-native@0.76.0(@babel/core@7.26.0)(@babel/preset-env@7.26.0(@babel/core@7.26.0))(encoding@0.1.13)(react@18.3.1))(web-streams-polyfill@3.3.3) + version: 0.3.0-unstable.10(encoding@0.1.13)(web-streams-polyfill@3.3.3) '@veramo/core': specifier: 4.2.0 version: 4.2.0(patch_hash=c5oempznsz4br5w3tcuk2i2mau) @@ -838,6 +838,9 @@ importers: text-encoding: specifier: ^0.7.0 version: 0.7.0 + uint8arrays: + specifier: ^3.1.1 + version: 3.1.1 devDependencies: '@types/text-encoding': specifier: 0.0.39 @@ -12922,7 +12925,7 @@ snapshots: '@transmute/did-context@0.6.1-unstable.37': {} - '@transmute/did-key-bls12381@0.3.0-unstable.10(encoding@0.1.13)(expo@51.0.38(@babel/core@7.26.0)(@babel/preset-env@7.26.0(@babel/core@7.26.0))(encoding@0.1.13))(react-native@0.76.0(@babel/core@7.26.0)(@babel/preset-env@7.26.0(@babel/core@7.26.0))(encoding@0.1.13)(react@18.3.1))(web-streams-polyfill@3.3.3)': + '@transmute/did-key-bls12381@0.3.0-unstable.10(encoding@0.1.13)(web-streams-polyfill@3.3.3)': dependencies: '@transmute/bls12381-key-pair': 0.7.0-unstable.81(encoding@0.1.13) '@transmute/did-key-common': 0.3.0-unstable.10(encoding@0.1.13)(expo@51.0.38(@babel/core@7.26.0)(@babel/preset-env@7.26.0(@babel/core@7.26.0))(encoding@0.1.13))(react-native@0.76.0(@babel/core@7.26.0)(@babel/preset-env@7.26.0(@babel/core@7.26.0))(encoding@0.1.13)(react@18.3.1))(web-streams-polyfill@3.3.3)