@microsoft/ccf-app 5.0.0-dev5 → 5.0.0-dev6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/crypto.d.ts CHANGED
@@ -18,6 +18,10 @@ export declare const generateEddsaKeyPair: (curve: string) => import("./global.j
18
18
  * @inheritDoc global!CCFCrypto.wrapKey
19
19
  */
20
20
  export declare const wrapKey: (key: ArrayBuffer, wrappingKey: ArrayBuffer, wrapAlgo: import("./global.js").WrapAlgoParams) => ArrayBuffer;
21
+ /**
22
+ * @inheritDoc global!CCFCrypto.unwrapKey
23
+ */
24
+ export declare const unwrapKey: (key: ArrayBuffer, wrappingKey: ArrayBuffer, wrapAlgo: import("./global.js").WrapAlgoParams) => ArrayBuffer;
21
25
  /**
22
26
  * @inheritDoc global!CCFCrypto.sign
23
27
  */
package/crypto.js CHANGED
@@ -34,6 +34,10 @@ export const generateEddsaKeyPair = ccf.crypto.generateEddsaKeyPair;
34
34
  * @inheritDoc global!CCFCrypto.wrapKey
35
35
  */
36
36
  export const wrapKey = ccf.crypto.wrapKey;
37
+ /**
38
+ * @inheritDoc global!CCFCrypto.unwrapKey
39
+ */
40
+ export const unwrapKey = ccf.crypto.unwrapKey;
37
41
  /**
38
42
  * @inheritDoc global!CCFCrypto.sign
39
43
  */
package/global.d.ts CHANGED
@@ -308,6 +308,13 @@ export interface CCFCrypto {
308
308
  * on the wrapping algorithm that is used (`wrapAlgo`).
309
309
  */
310
310
  wrapKey(key: ArrayBuffer, wrappingKey: ArrayBuffer, wrapAlgo: WrapAlgoParams): ArrayBuffer;
311
+ /**
312
+ * Unwraps a key using a wrapping key.
313
+ *
314
+ * Constraints on the `key` and `wrappingKey` parameters depend
315
+ * on the wrapping algorithm that is used (`wrapAlgo`).
316
+ */
317
+ unwrapKey(key: ArrayBuffer, wrappingKey: ArrayBuffer, wrapAlgo: WrapAlgoParams): ArrayBuffer;
311
318
  /**
312
319
  * Generate a digest (hash) of the given data.
313
320
  */
package/kv.d.ts CHANGED
@@ -36,11 +36,10 @@
36
36
  import { KvMap } from "./global.js";
37
37
  import { DataConverter } from "./converters.js";
38
38
  export declare class TypedKvMap<K, V> {
39
- private nameOrMap;
39
+ private kv;
40
40
  private kt;
41
41
  private vt;
42
- private _kv;
43
- constructor(nameOrMap: string | KvMap, kt: DataConverter<K>, vt: DataConverter<V>);
42
+ constructor(kv: KvMap, kt: DataConverter<K>, vt: DataConverter<V>);
44
43
  has(key: K): boolean;
45
44
  get(key: K): V | undefined;
46
45
  getVersionOfPreviousWrite(key: K): number | undefined;
package/kv.js CHANGED
@@ -37,47 +37,41 @@
37
37
  */
38
38
  import { ccf } from "./global.js";
39
39
  export class TypedKvMap {
40
- _kv() {
41
- const kvMap = typeof this.nameOrMap === "string"
42
- ? ccf.kv[this.nameOrMap]
43
- : this.nameOrMap;
44
- return kvMap;
45
- }
46
- constructor(nameOrMap, kt, vt) {
47
- this.nameOrMap = nameOrMap;
40
+ constructor(kv, kt, vt) {
41
+ this.kv = kv;
48
42
  this.kt = kt;
49
43
  this.vt = vt;
50
44
  }
51
45
  has(key) {
52
- return this._kv().has(this.kt.encode(key));
46
+ return this.kv.has(this.kt.encode(key));
53
47
  }
54
48
  get(key) {
55
- const v = this._kv().get(this.kt.encode(key));
49
+ const v = this.kv.get(this.kt.encode(key));
56
50
  return v === undefined ? undefined : this.vt.decode(v);
57
51
  }
58
52
  getVersionOfPreviousWrite(key) {
59
- return this._kv().getVersionOfPreviousWrite(this.kt.encode(key));
53
+ return this.kv.getVersionOfPreviousWrite(this.kt.encode(key));
60
54
  }
61
55
  set(key, value) {
62
- this._kv().set(this.kt.encode(key), this.vt.encode(value));
56
+ this.kv.set(this.kt.encode(key), this.vt.encode(value));
63
57
  return this;
64
58
  }
65
59
  delete(key) {
66
- this._kv().delete(this.kt.encode(key));
60
+ this.kv.delete(this.kt.encode(key));
67
61
  }
68
62
  clear() {
69
- this._kv().clear();
63
+ this.kv.clear();
70
64
  }
71
65
  forEach(callback) {
72
66
  let kt = this.kt;
73
67
  let vt = this.vt;
74
68
  let typedMap = this;
75
- this._kv().forEach(function (raw_v, raw_k, table) {
69
+ this.kv.forEach(function (raw_v, raw_k, table) {
76
70
  callback(vt.decode(raw_v), kt.decode(raw_k), typedMap);
77
71
  });
78
72
  }
79
73
  get size() {
80
- return this._kv().size;
74
+ return this.kv.size;
81
75
  }
82
76
  }
83
77
  /**
@@ -94,7 +88,8 @@ export class TypedKvMap {
94
88
  * @param vt The converter to use for map values.
95
89
  */
96
90
  export function typedKv(nameOrMap, kt, vt) {
97
- return new TypedKvMap(nameOrMap, kt, vt);
91
+ const kvMap = typeof nameOrMap === "string" ? ccf.kv[nameOrMap] : nameOrMap;
92
+ return new TypedKvMap(kvMap, kt, vt);
98
93
  }
99
94
  /**
100
95
  * @inheritDoc global!CCF.kv
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@microsoft/ccf-app",
3
- "version": "5.0.0-dev5",
3
+ "version": "5.0.0-dev6",
4
4
  "description": "CCF app support package",
5
5
  "main": "index.js",
6
6
  "files": [
package/polyfill.js CHANGED
@@ -252,6 +252,41 @@ class CCFPolyfill {
252
252
  throw new Error("unsupported wrapAlgo.name");
253
253
  }
254
254
  },
255
+ unwrapKey(wrappedKey, unwrappingKey, unwrapAlgo) {
256
+ if (unwrapAlgo.name == "RSA-OAEP") {
257
+ return nodeBufToArrBuf(jscrypto.privateDecrypt({
258
+ key: Buffer.from(unwrappingKey),
259
+ oaepHash: "sha256",
260
+ padding: jscrypto.constants.RSA_PKCS1_OAEP_PADDING,
261
+ }, new Uint8Array(wrappedKey)));
262
+ }
263
+ else if (unwrapAlgo.name == "AES-KWP") {
264
+ const iv = Buffer.from("A65959A6", "hex"); // defined in RFC 5649
265
+ const decipher = jscrypto.createDecipheriv("id-aes256-wrap-pad", new Uint8Array(unwrappingKey), iv);
266
+ return nodeBufToArrBuf(Buffer.concat([
267
+ decipher.update(new Uint8Array(wrappedKey)),
268
+ decipher.final(),
269
+ ]));
270
+ }
271
+ else if (unwrapAlgo.name == "RSA-OAEP-AES-KWP") {
272
+ const keyInfo = jscrypto.createPrivateKey(Buffer.from(unwrappingKey));
273
+ // asymmetricKeyDetails added in Node.js 15.7.0, we're at 16.
274
+ console.log(`Modulus length: `, keyInfo?.asymmetricKeyDetails?.modulusLength);
275
+ const modulusLengthInBytes = (keyInfo?.asymmetricKeyDetails?.modulusLength || 2048) / 8;
276
+ const wrap1 = wrappedKey.slice(0, modulusLengthInBytes);
277
+ const wrap2 = wrappedKey.slice(modulusLengthInBytes);
278
+ const aesKey = this.unwrapKey(wrap1, unwrappingKey, {
279
+ name: "RSA-OAEP",
280
+ label: unwrapAlgo.label,
281
+ });
282
+ return this.unwrapKey(wrap2, aesKey, {
283
+ name: "AES-KWP",
284
+ });
285
+ }
286
+ else {
287
+ throw new Error("unsupported unwrapAlgo.name");
288
+ }
289
+ },
255
290
  digest(algorithm, data) {
256
291
  if (algorithm === "SHA-256") {
257
292
  return nodeBufToArrBuf(jscrypto.createHash("sha256").update(new Uint8Array(data)).digest());
@@ -456,6 +491,9 @@ class CCFPolyfill {
456
491
  wrapKey(key, wrappingKey, parameters) {
457
492
  return this.crypto.wrapKey(key, wrappingKey, parameters);
458
493
  }
494
+ unwrapKey(key, wrappingKey, parameters) {
495
+ return this.crypto.unwrapKey(key, wrappingKey, parameters);
496
+ }
459
497
  digest(algorithm, data) {
460
498
  return this.crypto.digest(algorithm, data);
461
499
  }