summaryrefslogtreecommitdiff
path: root/deps/npm/node_modules/@tufjs/models/dist/utils/key.js
blob: 1f795ba1a2733f24c364e867c4d560824804fdb4 (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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getPublicKey = void 0;
const crypto_1 = __importDefault(require("crypto"));
const error_1 = require("../error");
const oid_1 = require("./oid");
const ASN1_TAG_SEQUENCE = 0x30;
const ANS1_TAG_BIT_STRING = 0x03;
const NULL_BYTE = 0x00;
const OID_EDDSA = '1.3.101.112';
const OID_EC_PUBLIC_KEY = '1.2.840.10045.2.1';
const OID_EC_CURVE_P256V1 = '1.2.840.10045.3.1.7';
const PEM_HEADER = '-----BEGIN PUBLIC KEY-----';
function getPublicKey(keyInfo) {
    switch (keyInfo.keyType) {
        case 'rsa':
            return getRSAPublicKey(keyInfo);
        case 'ed25519':
            return getED25519PublicKey(keyInfo);
        case 'ecdsa':
        case 'ecdsa-sha2-nistp256':
        case 'ecdsa-sha2-nistp384':
            return getECDCSAPublicKey(keyInfo);
        default:
            throw new error_1.UnsupportedAlgorithmError(`Unsupported key type: ${keyInfo.keyType}`);
    }
}
exports.getPublicKey = getPublicKey;
function getRSAPublicKey(keyInfo) {
    // Only support PEM-encoded RSA keys
    if (!keyInfo.keyVal.startsWith(PEM_HEADER)) {
        throw new error_1.CryptoError('Invalid key format');
    }
    const key = crypto_1.default.createPublicKey(keyInfo.keyVal);
    switch (keyInfo.scheme) {
        case 'rsassa-pss-sha256':
            return {
                key: key,
                padding: crypto_1.default.constants.RSA_PKCS1_PSS_PADDING,
            };
        default:
            throw new error_1.UnsupportedAlgorithmError(`Unsupported RSA scheme: ${keyInfo.scheme}`);
    }
}
function getED25519PublicKey(keyInfo) {
    let key;
    // If key is already PEM-encoded we can just parse it
    if (keyInfo.keyVal.startsWith(PEM_HEADER)) {
        key = crypto_1.default.createPublicKey(keyInfo.keyVal);
    }
    else {
        // If key is not PEM-encoded it had better be hex
        if (!isHex(keyInfo.keyVal)) {
            throw new error_1.CryptoError('Invalid key format');
        }
        key = crypto_1.default.createPublicKey({
            key: ed25519.hexToDER(keyInfo.keyVal),
            format: 'der',
            type: 'spki',
        });
    }
    return { key };
}
function getECDCSAPublicKey(keyInfo) {
    let key;
    // If key is already PEM-encoded we can just parse it
    if (keyInfo.keyVal.startsWith(PEM_HEADER)) {
        key = crypto_1.default.createPublicKey(keyInfo.keyVal);
    }
    else {
        // If key is not PEM-encoded it had better be hex
        if (!isHex(keyInfo.keyVal)) {
            throw new error_1.CryptoError('Invalid key format');
        }
        key = crypto_1.default.createPublicKey({
            key: ecdsa.hexToDER(keyInfo.keyVal),
            format: 'der',
            type: 'spki',
        });
    }
    return { key };
}
const ed25519 = {
    // Translates a hex key into a crypto KeyObject
    // https://keygen.sh/blog/how-to-use-hexadecimal-ed25519-keys-in-node/
    hexToDER: (hex) => {
        const key = Buffer.from(hex, 'hex');
        const oid = (0, oid_1.encodeOIDString)(OID_EDDSA);
        // Create a byte sequence containing the OID and key
        const elements = Buffer.concat([
            Buffer.concat([
                Buffer.from([ASN1_TAG_SEQUENCE]),
                Buffer.from([oid.length]),
                oid,
            ]),
            Buffer.concat([
                Buffer.from([ANS1_TAG_BIT_STRING]),
                Buffer.from([key.length + 1]),
                Buffer.from([NULL_BYTE]),
                key,
            ]),
        ]);
        // Wrap up by creating a sequence of elements
        const der = Buffer.concat([
            Buffer.from([ASN1_TAG_SEQUENCE]),
            Buffer.from([elements.length]),
            elements,
        ]);
        return der;
    },
};
const ecdsa = {
    hexToDER: (hex) => {
        const key = Buffer.from(hex, 'hex');
        const bitString = Buffer.concat([
            Buffer.from([ANS1_TAG_BIT_STRING]),
            Buffer.from([key.length + 1]),
            Buffer.from([NULL_BYTE]),
            key,
        ]);
        const oids = Buffer.concat([
            (0, oid_1.encodeOIDString)(OID_EC_PUBLIC_KEY),
            (0, oid_1.encodeOIDString)(OID_EC_CURVE_P256V1),
        ]);
        const oidSequence = Buffer.concat([
            Buffer.from([ASN1_TAG_SEQUENCE]),
            Buffer.from([oids.length]),
            oids,
        ]);
        // Wrap up by creating a sequence of elements
        const der = Buffer.concat([
            Buffer.from([ASN1_TAG_SEQUENCE]),
            Buffer.from([oidSequence.length + bitString.length]),
            oidSequence,
            bitString,
        ]);
        return der;
    },
};
const isHex = (key) => /^[0-9a-fA-F]+$/.test(key);