codekingpro/portable-devtools
114k
1"use strict";
2var __importDefault = (this && this.__importDefault) || function (mod) {
3 return (mod && mod.__esModule) ? mod : { "default": mod };
4};
5Object.defineProperty(exports, "__esModule", { value: true });
6exports.getPublicKey = getPublicKey;
7const crypto_1 = __importDefault(require("crypto"));
8const error_1 = require("../error");
9const oid_1 = require("./oid");
10const ASN1_TAG_SEQUENCE = 0x30;
11const ANS1_TAG_BIT_STRING = 0x03;
12const NULL_BYTE = 0x00;
13const OID_EDDSA = '1.3.101.112';
14const OID_EC_PUBLIC_KEY = '1.2.840.10045.2.1';
15const OID_EC_CURVE_P256V1 = '1.2.840.10045.3.1.7';
16const PEM_HEADER = '-----BEGIN PUBLIC KEY-----';
17function getPublicKey(keyInfo) {
18 switch (keyInfo.keyType) {
19 case 'rsa':
20 return getRSAPublicKey(keyInfo);
21 case 'ed25519':
22 return getED25519PublicKey(keyInfo);
23 case 'ecdsa':
24 case 'ecdsa-sha2-nistp256':
25 case 'ecdsa-sha2-nistp384':
26 return getECDCSAPublicKey(keyInfo);
27 default:
28 throw new error_1.UnsupportedAlgorithmError(`Unsupported key type: ${keyInfo.keyType}`);
29 }
30}
31function getRSAPublicKey(keyInfo) {
32 // Only support PEM-encoded RSA keys
33 if (!keyInfo.keyVal.startsWith(PEM_HEADER)) {
34 throw new error_1.CryptoError('Invalid key format');
35 }
36 const key = crypto_1.default.createPublicKey(keyInfo.keyVal);
37 switch (keyInfo.scheme) {
38 case 'rsassa-pss-sha256':
39 return {
40 key: key,
41 padding: crypto_1.default.constants.RSA_PKCS1_PSS_PADDING,
42 };
43 default:
44 throw new error_1.UnsupportedAlgorithmError(`Unsupported RSA scheme: ${keyInfo.scheme}`);
45 }
46}
47function getED25519PublicKey(keyInfo) {
48 let key;
49 // If key is already PEM-encoded we can just parse it
50 if (keyInfo.keyVal.startsWith(PEM_HEADER)) {
51 key = crypto_1.default.createPublicKey(keyInfo.keyVal);
52 }
53 else {
54 // If key is not PEM-encoded it had better be hex
55 if (!isHex(keyInfo.keyVal)) {
56 throw new error_1.CryptoError('Invalid key format');
57 }
58 key = crypto_1.default.createPublicKey({
59 key: ed25519.hexToDER(keyInfo.keyVal),
60 format: 'der',
61 type: 'spki',
62 });
63 }
64 return { key };
65}
66function getECDCSAPublicKey(keyInfo) {
67 let key;
68 // If key is already PEM-encoded we can just parse it
69 if (keyInfo.keyVal.startsWith(PEM_HEADER)) {
70 key = crypto_1.default.createPublicKey(keyInfo.keyVal);
71 }
72 else {
73 // If key is not PEM-encoded it had better be hex
74 if (!isHex(keyInfo.keyVal)) {
75 throw new error_1.CryptoError('Invalid key format');
76 }
77 key = crypto_1.default.createPublicKey({
78 key: ecdsa.hexToDER(keyInfo.keyVal),
79 format: 'der',
80 type: 'spki',
81 });
82 }
83 return { key };
84}
85const ed25519 = {
86 // Translates a hex key into a crypto KeyObject
87 // https://keygen.sh/blog/how-to-use-hexadecimal-ed25519-keys-in-node/
88 hexToDER: (hex) => {
89 const key = Buffer.from(hex, 'hex');
90 const oid = (0, oid_1.encodeOIDString)(OID_EDDSA);
91 // Create a byte sequence containing the OID and key
92 const elements = Buffer.concat([
93 Buffer.concat([
94 Buffer.from([ASN1_TAG_SEQUENCE]),
95 Buffer.from([oid.length]),
96 oid,
97 ]),
98 Buffer.concat([
99 Buffer.from([ANS1_TAG_BIT_STRING]),
100 Buffer.from([key.length + 1]),
101 Buffer.from([NULL_BYTE]),
102 key,
103 ]),
104 ]);
105 // Wrap up by creating a sequence of elements
106 const der = Buffer.concat([
107 Buffer.from([ASN1_TAG_SEQUENCE]),
108 Buffer.from([elements.length]),
109 elements,
110 ]);
111 return der;
112 },
113};
114const ecdsa = {
115 hexToDER: (hex) => {
116 const key = Buffer.from(hex, 'hex');
117 const bitString = Buffer.concat([
118 Buffer.from([ANS1_TAG_BIT_STRING]),
119 Buffer.from([key.length + 1]),
120 Buffer.from([NULL_BYTE]),
121 key,
122 ]);
123 const oids = Buffer.concat([
124 (0, oid_1.encodeOIDString)(OID_EC_PUBLIC_KEY),
125 (0, oid_1.encodeOIDString)(OID_EC_CURVE_P256V1),
126 ]);
127 const oidSequence = Buffer.concat([
128 Buffer.from([ASN1_TAG_SEQUENCE]),
129 Buffer.from([oids.length]),
130 oids,
131 ]);
132 // Wrap up by creating a sequence of elements
133 const der = Buffer.concat([
134 Buffer.from([ASN1_TAG_SEQUENCE]),
135 Buffer.from([oidSequence.length + bitString.length]),
136 oidSequence,
137 bitString,
138 ]);
139 return der;
140 },
141};
142const isHex = (key) => /^[0-9a-fA-F]+$/.test(key);
143 