diff options
-rw-r--r-- | packages/server/src/helpers/convertPublicKeyToPEM.ts | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/packages/server/src/helpers/convertPublicKeyToPEM.ts b/packages/server/src/helpers/convertPublicKeyToPEM.ts new file mode 100644 index 0000000..a7e04bd --- /dev/null +++ b/packages/server/src/helpers/convertPublicKeyToPEM.ts @@ -0,0 +1,64 @@ +import cbor from 'cbor'; +import jwkToPem from 'jwk-to-pem'; +import base64url from 'base64url'; + +import { COSEKEYS, COSEKTY, COSECRV } from './convertCOSEtoPKCS'; + +export default function convertPublicKeyToPEM(publicKey: string): string { + const struct = cbor.decodeFirstSync(base64url.toBuffer(publicKey)); + + const kty = struct.get(COSEKEYS.kty); + + if (!kty) { + throw new Error('Public key was missing kty'); + } + + if (kty === COSEKTY.EC2) { + const crv = struct.get(COSEKEYS.crv); + const x = struct.get(COSEKEYS.x); + const y = struct.get(COSEKEYS.y); + + if (!crv) { + throw new Error('Public key was missing crv (EC2)'); + } + + if (!x) { + throw new Error('Public key was missing x (EC2)'); + } + + if (!y) { + throw new Error('Public key was missing y (EC2)'); + } + + const ecPEM = jwkToPem({ + kty: 'EC', + // Specify curve as "P-256" from "p256" + crv: COSECRV[crv as number].replace('p', 'P-'), + x: (x as Buffer).toString('base64'), + y: (y as Buffer).toString('base64'), + }); + + return ecPEM; + } else if (kty === COSEKTY.RSA) { + const n = struct.get(COSEKEYS.n); + const e = struct.get(COSEKEYS.e); + + if (!n) { + throw new Error('Public key was missing n (RSA)'); + } + + if (!e) { + throw new Error('Public key was missing e (RSA)'); + } + + const rsaPEM = jwkToPem({ + kty: 'RSA', + n: (n as Buffer).toString('base64'), + e: (e as Buffer).toString('base64'), + }); + + return rsaPEM; + } + + throw new Error(`Could not convert public key type ${kty} to PEM`); +} |