|
18 | 18 | * @module lib/jwk-store |
19 | 19 | */ |
20 | 20 |
|
21 | | -import { KeyObject, randomBytes } from 'node:crypto'; |
| 21 | +import { randomBytes } from 'node:crypto'; |
22 | 22 | import { AssertionError } from 'node:assert'; |
23 | 23 |
|
24 | 24 | import type { GenerateKeyPairOptions } from 'jose'; |
25 | 25 | import { exportJWK, importJWK, generateKeyPair } from 'jose'; |
26 | 26 |
|
27 | 27 | import type { JWK } from './types'; |
28 | 28 | import type { JWKWithKid } from './types-internals'; |
29 | | -import { assertIsPlainObject } from './helpers'; |
| 29 | +import { |
| 30 | + assertIsPlainObject, |
| 31 | + privateToPublicKeyTransformer, |
| 32 | + supportedAlgs, |
| 33 | +} from './helpers'; |
30 | 34 |
|
31 | 35 | const generateRandomKid = () => { |
32 | 36 | return randomBytes(40).toString('hex'); |
33 | 37 | }; |
34 | 38 |
|
35 | | -type JwkTransformer = (jwk: JWK) => JWK; |
36 | | - |
37 | | -const RsaPrivateFieldsRemover: JwkTransformer = (jwk) => { |
38 | | - const x = { ...jwk }; |
39 | | - |
40 | | - delete x.d; |
41 | | - delete x.p; |
42 | | - delete x.q; |
43 | | - delete x.dp; |
44 | | - delete x.dq; |
45 | | - delete x.qi; |
46 | | - |
47 | | - return x; |
48 | | -}; |
49 | | - |
50 | | -const EcdsaPrivateFieldsRemover: JwkTransformer = (jwk) => { |
51 | | - const x = { ...jwk }; |
52 | | - |
53 | | - delete x.d; |
54 | | - |
55 | | - return x; |
56 | | -}; |
57 | | - |
58 | | -const EddsaPrivateFieldsRemover: JwkTransformer = (jwk) => { |
59 | | - const x = { ...jwk }; |
60 | | - |
61 | | - delete x.d; |
62 | | - |
63 | | - return x; |
64 | | -}; |
65 | | - |
66 | | -const privateToPublicTransformerMap: Record<string, JwkTransformer> = { |
67 | | - // RSASSA-PKCS1-v1_5 |
68 | | - RS256: RsaPrivateFieldsRemover, |
69 | | - RS384: RsaPrivateFieldsRemover, |
70 | | - RS512: RsaPrivateFieldsRemover, |
71 | | - |
72 | | - // RSASSA-PSS |
73 | | - PS256: RsaPrivateFieldsRemover, |
74 | | - PS384: RsaPrivateFieldsRemover, |
75 | | - PS512: RsaPrivateFieldsRemover, |
76 | | - |
77 | | - // ECDSA |
78 | | - ES256: EcdsaPrivateFieldsRemover, |
79 | | - ES256K: EcdsaPrivateFieldsRemover, |
80 | | - ES384: EcdsaPrivateFieldsRemover, |
81 | | - ES512: EcdsaPrivateFieldsRemover, |
82 | | - |
83 | | - // Edwards-curve DSA |
84 | | - EdDSA: EddsaPrivateFieldsRemover, |
85 | | -}; |
86 | | - |
87 | | -const supportedAlgs = Object.keys(privateToPublicTransformerMap); |
88 | | - |
89 | 39 | function normalizeKeyKid( |
90 | 40 | jwk: unknown, |
91 | 41 | opts?: { kid?: string }, |
@@ -131,9 +81,20 @@ export class JWKStore { |
131 | 81 | const generateOpts: GenerateKeyPairOptions = |
132 | 82 | opts?.crv !== undefined ? { crv: opts.crv } : {}; |
133 | 83 |
|
| 84 | + generateOpts.extractable = true; |
| 85 | + |
| 86 | + if ( |
| 87 | + alg === 'EdDSA' && |
| 88 | + generateOpts.crv !== undefined && |
| 89 | + generateOpts.crv !== 'Ed25519' |
| 90 | + ) { |
| 91 | + throw new Error( |
| 92 | + 'Invalid or unsupported crv option provided, supported values are: Ed25519', |
| 93 | + ); |
| 94 | + } |
| 95 | + |
134 | 96 | const pair = await generateKeyPair(alg, generateOpts); |
135 | 97 | const joseJwk = await exportJWK(pair.privateKey); |
136 | | - |
137 | 98 | normalizeKeyKid(joseJwk, opts); |
138 | 99 | joseJwk.alg = alg; |
139 | 100 |
|
@@ -162,9 +123,9 @@ export class JWKStore { |
162 | 123 |
|
163 | 124 | const jwk = tempJwk as JWK; |
164 | 125 |
|
165 | | - const privateKey = await importJWK(jwk); |
| 126 | + const privateKey = await importJWK(jwk, jwk.alg, { extractable: false }); |
166 | 127 |
|
167 | | - if (!(privateKey instanceof KeyObject) || privateKey.type !== 'private') { |
| 128 | + if (privateKey instanceof Uint8Array || privateKey.type !== 'private') { |
168 | 129 | throw new Error( |
169 | 130 | `Invalid JWK type. No "private" key related data has been found.`, |
170 | 131 | ); |
@@ -229,13 +190,7 @@ class KeyRotator { |
229 | 190 | continue; |
230 | 191 | } |
231 | 192 |
|
232 | | - const cleaner = privateToPublicTransformerMap[key.alg]; |
233 | | - |
234 | | - if (cleaner === undefined) { |
235 | | - throw new Error(`Unsupported algo '{key.alg}'`); |
236 | | - } |
237 | | - |
238 | | - keys.push(cleaner(key)); |
| 193 | + keys.push(privateToPublicKeyTransformer(key)); |
239 | 194 | } |
240 | 195 |
|
241 | 196 | return keys; |
|
0 commit comments