/
node_key.ts
105 lines (89 loc) · 3.2 KB
/
node_key.ts
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
import { constants } from 'crypto'
import type { KeyObject, SignKeyObjectInput } from 'crypto'
import getNamedCurve from './get_named_curve.js'
import { JOSENotSupported } from '../../util/errors.js'
import checkModulusLength from './check_modulus_length.js'
import { rsaPssParams } from './flags.js'
const PSS = {
padding: constants.RSA_PKCS1_PSS_PADDING,
saltLength: constants.RSA_PSS_SALTLEN_DIGEST,
}
const ecCurveAlgMap = new Map([
['ES256', 'P-256'],
['ES256K', 'secp256k1'],
['ES384', 'P-384'],
['ES512', 'P-521'],
])
export default function keyForCrypto(alg: string, key: KeyObject): KeyObject | SignKeyObjectInput {
switch (alg) {
case 'EdDSA':
if (!['ed25519', 'ed448'].includes(key.asymmetricKeyType!)) {
throw new TypeError(
'Invalid key for this operation, its asymmetricKeyType must be ed25519 or ed448',
)
}
return key
case 'RS256':
case 'RS384':
case 'RS512':
if (key.asymmetricKeyType !== 'rsa') {
throw new TypeError('Invalid key for this operation, its asymmetricKeyType must be rsa')
}
checkModulusLength(key, alg)
return key
case rsaPssParams && 'PS256':
case rsaPssParams && 'PS384':
case rsaPssParams && 'PS512':
if (key.asymmetricKeyType === 'rsa-pss') {
const { hashAlgorithm, mgf1HashAlgorithm, saltLength } = key.asymmetricKeyDetails!
const length = parseInt(alg.slice(-3), 10)
if (
hashAlgorithm !== undefined &&
(hashAlgorithm !== `sha${length}` || mgf1HashAlgorithm !== hashAlgorithm)
) {
throw new TypeError(
`Invalid key for this operation, its RSA-PSS parameters do not meet the requirements of "alg" ${alg}`,
)
}
if (saltLength !== undefined && saltLength > length >> 3) {
throw new TypeError(
`Invalid key for this operation, its RSA-PSS parameter saltLength does not meet the requirements of "alg" ${alg}`,
)
}
} else if (key.asymmetricKeyType !== 'rsa') {
throw new TypeError(
'Invalid key for this operation, its asymmetricKeyType must be rsa or rsa-pss',
)
}
checkModulusLength(key, alg)
return { key, ...PSS }
case !rsaPssParams && 'PS256':
case !rsaPssParams && 'PS384':
case !rsaPssParams && 'PS512':
if (key.asymmetricKeyType !== 'rsa') {
throw new TypeError('Invalid key for this operation, its asymmetricKeyType must be rsa')
}
checkModulusLength(key, alg)
return { key, ...PSS }
case 'ES256':
case 'ES256K':
case 'ES384':
case 'ES512': {
if (key.asymmetricKeyType !== 'ec') {
throw new TypeError('Invalid key for this operation, its asymmetricKeyType must be ec')
}
const actual = getNamedCurve(key)
const expected = ecCurveAlgMap.get(alg)
if (actual !== expected) {
throw new TypeError(
`Invalid key curve for the algorithm, its curve must be ${expected}, got ${actual}`,
)
}
return { dsaEncoding: 'ieee-p1363', key }
}
default:
throw new JOSENotSupported(
`alg ${alg} is not supported either by JOSE or your javascript runtime`,
)
}
}