(pem: string, name: string)
| 60 | * Shared between the dfx and icp identity loaders. |
| 61 | */ |
| 62 | export const parseEd25519Pem = (pem: string, name: string): Identity => { |
| 63 | let jwk; |
| 64 | try { |
| 65 | const key = createPrivateKey({ key: pem, format: 'pem' }); |
| 66 | jwk = key.export({ format: 'jwk' }); |
| 67 | } catch (err) { |
| 68 | throw new Error(`Failed to parse PEM for identity '${name}': ${(err as Error).message}`); |
| 69 | } |
| 70 | |
| 71 | if (jwk.kty !== 'OKP' || jwk.crv !== 'Ed25519') { |
| 72 | throw new Error( |
| 73 | `Identity '${name}' is not Ed25519 (kty=${jwk.kty}, crv=${jwk.crv}). The audit supports Ed25519 identities only.`, |
| 74 | ); |
| 75 | } |
| 76 | if (typeof jwk.d !== 'string' || typeof jwk.x !== 'string') { |
| 77 | throw new Error(`Identity '${name}' PEM is missing key material.`); |
| 78 | } |
| 79 | |
| 80 | // agent-js Ed25519KeyIdentity.fromSecretKey takes the 32-byte seed only; |
| 81 | // the public key is derived internally. |
| 82 | const secret = b64urlDecode(jwk.d); |
| 83 | return Ed25519KeyIdentity.fromSecretKey(secret.buffer); |
| 84 | }; |
| 85 | |
| 86 | export const b64urlDecode = (input: string): Uint8Array => { |
| 87 | const pad = '='.repeat((4 - (input.length % 4)) % 4); |
no test coverage detected