-
-
Notifications
You must be signed in to change notification settings - Fork 299
/
ecdhes.ts
72 lines (64 loc) · 1.98 KB
/
ecdhes.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
import { encoder, concat, uint32be, lengthAndInput, concatKdf } from '../lib/buffer_utils.ts'
import crypto, { isCryptoKey } from './webcrypto.ts'
import { checkEncCryptoKey } from '../lib/crypto_key.ts'
import invalidKeyInput from '../lib/invalid_key_input.ts'
import { types } from './is_key_like.ts'
export async function deriveKey(
publicKey: unknown,
privateKey: unknown,
algorithm: string,
keyLength: number,
apu: Uint8Array = new Uint8Array(0),
apv: Uint8Array = new Uint8Array(0),
) {
if (!isCryptoKey(publicKey)) {
throw new TypeError(invalidKeyInput(publicKey, ...types))
}
checkEncCryptoKey(publicKey, 'ECDH')
if (!isCryptoKey(privateKey)) {
throw new TypeError(invalidKeyInput(privateKey, ...types))
}
checkEncCryptoKey(privateKey, 'ECDH', 'deriveBits')
const value = concat(
lengthAndInput(encoder.encode(algorithm)),
lengthAndInput(apu),
lengthAndInput(apv),
uint32be(keyLength),
)
let length: number
if (publicKey.algorithm.name === 'X25519') {
length = 256
} else if (publicKey.algorithm.name === 'X448') {
length = 448
} else {
length =
Math.ceil(parseInt((<EcKeyAlgorithm>publicKey.algorithm).namedCurve.substr(-3), 10) / 8) << 3
}
const sharedSecret = new Uint8Array(
await crypto.subtle.deriveBits(
{
name: publicKey.algorithm.name,
public: publicKey,
},
privateKey,
length,
),
)
return concatKdf(sharedSecret, keyLength, value)
}
export async function generateEpk(key: unknown) {
if (!isCryptoKey(key)) {
throw new TypeError(invalidKeyInput(key, ...types))
}
return crypto.subtle.generateKey(<EcKeyAlgorithm>key.algorithm, true, ['deriveBits'])
}
export function ecdhAllowed(key: unknown) {
if (!isCryptoKey(key)) {
throw new TypeError(invalidKeyInput(key, ...types))
}
return (
['P-256', 'P-384', 'P-521'].includes((<EcKeyAlgorithm>key.algorithm).namedCurve) ||
key.algorithm.name === 'X25519' ||
key.algorithm.name === 'X448'
)
}