-
-
Notifications
You must be signed in to change notification settings - Fork 15
/
ec_dh.ts
94 lines (85 loc) · 2.93 KB
/
ec_dh.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
import * as graphene from "graphene-pk11";
import * as core from "webcrypto-core";
import { Crypto } from "../../crypto";
import { CryptoKey } from "../../key";
import { EcCrypto } from "./crypto";
import { EcCryptoKey } from "./key";
export class EcdhProvider extends core.EcdhProvider {
constructor(private crypto: Crypto) {
super();
}
public async onGenerateKey(algorithm: EcKeyGenParams, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKeyPair> {
const key = await EcCrypto.generateKey(
this.crypto.session,
{
...algorithm,
name: this.name,
},
extractable,
keyUsages);
return key;
}
public async onExportKey(format: KeyFormat, key: EcCryptoKey): Promise<JsonWebKey | ArrayBuffer> {
return EcCrypto.exportKey(this.crypto.session, format, key);
}
public async onImportKey(format: KeyFormat, keyData: JsonWebKey | ArrayBuffer, algorithm: EcKeyImportParams, extractable: boolean, keyUsages: KeyUsage[]): Promise<CryptoKey> {
const key = await EcCrypto.importKey(this.crypto.session, format, keyData, { ...algorithm, name: this.name }, extractable, keyUsages);
return key;
}
public checkCryptoKey(key: CryptoKey, keyUsage?: KeyUsage) {
super.checkCryptoKey(key, keyUsage);
if (!(key instanceof EcCryptoKey)) {
throw new TypeError("key: Is not EC CryptoKey");
}
}
public async onDeriveBits(algorithm: EcdhKeyDeriveParams, baseKey: EcCryptoKey, length: number): Promise<ArrayBuffer> {
return new Promise<ArrayBuffer>((resolve, reject) => {
let valueLen = 256;
switch (baseKey.algorithm.namedCurve) {
case "P-256":
case "K-256":
valueLen = 256;
break;
case "P-384":
valueLen = 384;
break;
case "P-521":
valueLen = 534;
break;
}
// const curve = EcCrypto.getNamedCurve(baseKey.algorithm.namedCurve);
const template: graphene.ITemplate = {
token: false,
sensitive: false,
class: graphene.ObjectClass.SECRET_KEY,
keyType: graphene.KeyType.GENERIC_SECRET,
extractable: true,
encrypt: true,
decrypt: true,
valueLen: valueLen >> 3,
};
// derive key
const ecPoint = (algorithm.public as EcCryptoKey).key.getAttribute({ pointEC: null }).pointEC!;
this.crypto.session.deriveKey(
{
name: "ECDH1_DERIVE",
params: new graphene.EcdhParams(
graphene.EcKdf.NULL,
null as any,
ecPoint, // CKA_EC_POINT
),
},
baseKey.key,
template,
(err, key) => {
if (err) {
reject(err);
} else {
const secretKey = key.toType<graphene.SecretKey>();
const value = secretKey.getAttribute({ value: null }).value as Buffer;
resolve(new Uint8Array(value.slice(0, length >> 3)).buffer);
}
});
});
}
}