1 | const { publicEncrypt, privateDecrypt, constants } = require('crypto')
|
2 |
|
3 | const { oaepHashSupported } = require('../help/runtime_support')
|
4 | const { KEYOBJECT } = require('../help/consts')
|
5 | const { asInput } = require('../help/key_object')
|
6 |
|
7 | const resolvePadding = (alg) => {
|
8 | switch (alg) {
|
9 | case 'RSA-OAEP':
|
10 | case 'RSA-OAEP-256':
|
11 | case 'RSA-OAEP-384':
|
12 | case 'RSA-OAEP-512':
|
13 | return constants.RSA_PKCS1_OAEP_PADDING
|
14 | case 'RSA1_5':
|
15 | return constants.RSA_PKCS1_PADDING
|
16 | }
|
17 | }
|
18 |
|
19 | const resolveOaepHash = (alg) => {
|
20 | switch (alg) {
|
21 | case 'RSA-OAEP':
|
22 | return 'sha1'
|
23 | case 'RSA-OAEP-256':
|
24 | return 'sha256'
|
25 | case 'RSA-OAEP-384':
|
26 | return 'sha384'
|
27 | case 'RSA-OAEP-512':
|
28 | return 'sha512'
|
29 | default:
|
30 | return undefined
|
31 | }
|
32 | }
|
33 |
|
34 | const wrapKey = (padding, oaepHash, { [KEYOBJECT]: keyObject }, payload) => {
|
35 | const key = asInput(keyObject, true)
|
36 | return { wrapped: publicEncrypt({ key, oaepHash, padding }, payload) }
|
37 | }
|
38 |
|
39 | const unwrapKey = (padding, oaepHash, { [KEYOBJECT]: keyObject }, payload) => {
|
40 | const key = asInput(keyObject, false)
|
41 | return privateDecrypt({ key, oaepHash, padding }, payload)
|
42 | }
|
43 |
|
44 | const LENGTHS = {
|
45 | RSA1_5: 0,
|
46 | 'RSA-OAEP': 592,
|
47 | 'RSA-OAEP-256': 784,
|
48 | 'RSA-OAEP-384': 1040,
|
49 | 'RSA-OAEP-512': 1296
|
50 | }
|
51 |
|
52 | module.exports = (JWA, JWK) => {
|
53 | const algs = ['RSA-OAEP', 'RSA1_5']
|
54 |
|
55 | if (oaepHashSupported) {
|
56 | algs.splice(1, 0, 'RSA-OAEP-256', 'RSA-OAEP-384', 'RSA-OAEP-512')
|
57 | }
|
58 |
|
59 | algs.forEach((jwaAlg) => {
|
60 | const padding = resolvePadding(jwaAlg)
|
61 | const oaepHash = resolveOaepHash(jwaAlg)
|
62 | JWA.keyManagementEncrypt.set(jwaAlg, wrapKey.bind(undefined, padding, oaepHash))
|
63 | JWA.keyManagementDecrypt.set(jwaAlg, unwrapKey.bind(undefined, padding, oaepHash))
|
64 | JWK.RSA.wrapKey[jwaAlg] = key => (key.use === 'enc' || key.use === undefined) && key.length >= LENGTHS[jwaAlg]
|
65 | JWK.RSA.unwrapKey[jwaAlg] = key => key.private && (key.use === 'enc' || key.use === undefined) && key.length >= LENGTHS[jwaAlg]
|
66 | })
|
67 | }
|