summaryrefslogtreecommitdiffhomepage
path: root/packages/server/src/helpers/convertPublicKeyToPEM.ts
blob: 834f96c1fe6bbcad1120de48183d8163d5187b10 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
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 publicKeyBuffer = base64url.toBuffer(publicKey);

  let struct;
  try {
    struct = cbor.decodeAllSync(publicKeyBuffer)[0];
  } catch (err) {
    throw new Error(`Error decoding public key while converting to PEM: ${err.message}`);
  }

  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`);
}