@ledgerhq/device-core 0.2.1 → 0.2.2-nightly.1
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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +17 -0
- package/lib/commands/entities/AppStorageInfo.d.ts +8 -0
- package/lib/commands/entities/AppStorageInfo.d.ts.map +1 -0
- package/lib/commands/entities/AppStorageInfo.js +3 -0
- package/lib/commands/entities/AppStorageInfo.js.map +1 -0
- package/lib/commands/use-cases/app-backup/backupAppStorage.d.ts +18 -0
- package/lib/commands/use-cases/app-backup/backupAppStorage.d.ts.map +1 -0
- package/lib/commands/use-cases/app-backup/backupAppStorage.js +98 -0
- package/lib/commands/use-cases/app-backup/backupAppStorage.js.map +1 -0
- package/lib/commands/use-cases/app-backup/backupAppStorage.test.d.ts +2 -0
- package/lib/commands/use-cases/app-backup/backupAppStorage.test.d.ts.map +1 -0
- package/lib/commands/use-cases/app-backup/backupAppStorage.test.js +56 -0
- package/lib/commands/use-cases/app-backup/backupAppStorage.test.js.map +1 -0
- package/lib/commands/use-cases/app-backup/getAppStorageInfo.d.ts +20 -0
- package/lib/commands/use-cases/app-backup/getAppStorageInfo.d.ts.map +1 -0
- package/lib/commands/use-cases/app-backup/getAppStorageInfo.js +104 -0
- package/lib/commands/use-cases/app-backup/getAppStorageInfo.js.map +1 -0
- package/lib/commands/use-cases/app-backup/getAppStorageInfo.test.d.ts +2 -0
- package/lib/commands/use-cases/app-backup/getAppStorageInfo.test.d.ts.map +1 -0
- package/lib/commands/use-cases/app-backup/getAppStorageInfo.test.js +59 -0
- package/lib/commands/use-cases/app-backup/getAppStorageInfo.test.js.map +1 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorage.d.ts +12 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorage.d.ts.map +1 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorage.js +93 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorage.js.map +1 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorage.test.d.ts +2 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorage.test.d.ts.map +1 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorage.test.js +54 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorage.test.js.map +1 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorageCommit.d.ts +11 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorageCommit.d.ts.map +1 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorageCommit.js +83 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorageCommit.js.map +1 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorageCommit.test.d.ts +2 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorageCommit.test.d.ts.map +1 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorageCommit.test.js +49 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorageCommit.test.js.map +1 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorageInit.d.ts +13 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorageInit.d.ts.map +1 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorageInit.js +99 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorageInit.js.map +1 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorageInit.test.d.ts +2 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorageInit.test.d.ts.map +1 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorageInit.test.js +52 -0
- package/lib/commands/use-cases/app-backup/restoreAppStorageInit.test.js.map +1 -0
- package/lib/errors.d.ts +40 -0
- package/lib/errors.d.ts.map +1 -0
- package/lib/errors.js +30 -0
- package/lib/errors.js.map +1 -0
- package/lib/index.d.ts +6 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +11 -1
- package/lib/index.js.map +1 -1
- package/lib-es/commands/entities/AppStorageInfo.d.ts +8 -0
- package/lib-es/commands/entities/AppStorageInfo.d.ts.map +1 -0
- package/lib-es/commands/entities/AppStorageInfo.js +2 -0
- package/lib-es/commands/entities/AppStorageInfo.js.map +1 -0
- package/lib-es/commands/use-cases/app-backup/backupAppStorage.d.ts +18 -0
- package/lib-es/commands/use-cases/app-backup/backupAppStorage.d.ts.map +1 -0
- package/lib-es/commands/use-cases/app-backup/backupAppStorage.js +93 -0
- package/lib-es/commands/use-cases/app-backup/backupAppStorage.js.map +1 -0
- package/lib-es/commands/use-cases/app-backup/backupAppStorage.test.d.ts +2 -0
- package/lib-es/commands/use-cases/app-backup/backupAppStorage.test.d.ts.map +1 -0
- package/lib-es/commands/use-cases/app-backup/backupAppStorage.test.js +54 -0
- package/lib-es/commands/use-cases/app-backup/backupAppStorage.test.js.map +1 -0
- package/lib-es/commands/use-cases/app-backup/getAppStorageInfo.d.ts +20 -0
- package/lib-es/commands/use-cases/app-backup/getAppStorageInfo.d.ts.map +1 -0
- package/lib-es/commands/use-cases/app-backup/getAppStorageInfo.js +99 -0
- package/lib-es/commands/use-cases/app-backup/getAppStorageInfo.js.map +1 -0
- package/lib-es/commands/use-cases/app-backup/getAppStorageInfo.test.d.ts +2 -0
- package/lib-es/commands/use-cases/app-backup/getAppStorageInfo.test.d.ts.map +1 -0
- package/lib-es/commands/use-cases/app-backup/getAppStorageInfo.test.js +57 -0
- package/lib-es/commands/use-cases/app-backup/getAppStorageInfo.test.js.map +1 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorage.d.ts +12 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorage.d.ts.map +1 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorage.js +88 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorage.js.map +1 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorage.test.d.ts +2 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorage.test.d.ts.map +1 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorage.test.js +52 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorage.test.js.map +1 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorageCommit.d.ts +11 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorageCommit.d.ts.map +1 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorageCommit.js +78 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorageCommit.js.map +1 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorageCommit.test.d.ts +2 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorageCommit.test.d.ts.map +1 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorageCommit.test.js +47 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorageCommit.test.js.map +1 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorageInit.d.ts +13 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorageInit.d.ts.map +1 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorageInit.js +94 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorageInit.js.map +1 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorageInit.test.d.ts +2 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorageInit.test.d.ts.map +1 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorageInit.test.js +50 -0
- package/lib-es/commands/use-cases/app-backup/restoreAppStorageInit.test.js.map +1 -0
- package/lib-es/errors.d.ts +40 -0
- package/lib-es/errors.d.ts.map +1 -0
- package/lib-es/errors.js +27 -0
- package/lib-es/errors.js.map +1 -0
- package/lib-es/index.d.ts +6 -0
- package/lib-es/index.d.ts.map +1 -1
- package/lib-es/index.js +5 -0
- package/lib-es/index.js.map +1 -1
- package/package.json +6 -6
- package/src/commands/entities/AppStorageInfo.ts +7 -0
- package/src/commands/use-cases/app-backup/backupAppStorage.test.ts +52 -0
- package/src/commands/use-cases/app-backup/backupAppStorage.ts +97 -0
- package/src/commands/use-cases/app-backup/getAppStorageInfo.test.ts +63 -0
- package/src/commands/use-cases/app-backup/getAppStorageInfo.ts +102 -0
- package/src/commands/use-cases/app-backup/restoreAppStorage.test.ts +57 -0
- package/src/commands/use-cases/app-backup/restoreAppStorage.ts +93 -0
- package/src/commands/use-cases/app-backup/restoreAppStorageCommit.test.ts +45 -0
- package/src/commands/use-cases/app-backup/restoreAppStorageCommit.ts +82 -0
- package/src/commands/use-cases/app-backup/restoreAppStorageInit.test.ts +55 -0
- package/src/commands/use-cases/app-backup/restoreAppStorageInit.ts +96 -0
- package/src/errors.ts +29 -0
- package/src/index.ts +6 -0
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { StatusCodes, TransportStatusError } from "@ledgerhq/hw-transport";
|
|
11
|
+
import { LocalTracer } from "@ledgerhq/logs";
|
|
12
|
+
import { GenerateAesKeyFailed, InternalComputeAesCmacFailed, InternalCryptoOperationFailed, InvalidBackupState, InvalidContext, } from "../../../errors";
|
|
13
|
+
/**
|
|
14
|
+
* Name in documentation: INS_APP_STORAGE_BACKUP
|
|
15
|
+
* cla: 0xe0
|
|
16
|
+
* ins: 0x6b
|
|
17
|
+
* p1: 0x00
|
|
18
|
+
* p2: 0x00
|
|
19
|
+
* lc: 0x00
|
|
20
|
+
*/
|
|
21
|
+
const BACKUP_APP_STORAGE = [0xe0, 0x6b, 0x00, 0x00];
|
|
22
|
+
/**
|
|
23
|
+
* 0x9000: Success.
|
|
24
|
+
* 0x5123: Invalid context, Get Info must be called.
|
|
25
|
+
* 0x5419: Failed to generate AES key.
|
|
26
|
+
* 0x541A: Internal error, crypto operation failed.
|
|
27
|
+
* 0x541B: Internal error, failed to compute AES CMAC.
|
|
28
|
+
* 0x541C: Failed to encrypt the app storage backup.
|
|
29
|
+
* 0x662F: Invalid device state, recovery mode.
|
|
30
|
+
* 0x6642: Invalid backup state, backup already performed.
|
|
31
|
+
*/
|
|
32
|
+
const RESPONSE_STATUS_SET = [
|
|
33
|
+
StatusCodes.OK,
|
|
34
|
+
StatusCodes.APP_NOT_FOUND_OR_INVALID_CONTEXT,
|
|
35
|
+
StatusCodes.GEN_AES_KEY_FAILED,
|
|
36
|
+
StatusCodes.INTERNAL_CRYPTO_OPERATION_FAILED,
|
|
37
|
+
StatusCodes.INTERNAL_COMPUTE_AES_CMAC_FAILED,
|
|
38
|
+
StatusCodes.ENCRYPT_APP_STORAGE_FAILED,
|
|
39
|
+
StatusCodes.DEVICE_IN_RECOVERY_MODE,
|
|
40
|
+
StatusCodes.INVALID_BACKUP_STATE,
|
|
41
|
+
];
|
|
42
|
+
/**
|
|
43
|
+
* Retrieves the app storage information (chunk) from the device and returns it
|
|
44
|
+
* as a buffer.
|
|
45
|
+
*
|
|
46
|
+
* @param transport - The transport object used to communicate with the device.
|
|
47
|
+
* @returns A promise that resolves to the app storage information as a buffer.
|
|
48
|
+
*/
|
|
49
|
+
export function backupAppStorage(transport) {
|
|
50
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
+
const tracer = new LocalTracer("hw", {
|
|
52
|
+
transport: transport.getTraceContext(),
|
|
53
|
+
function: "backupAppStorage",
|
|
54
|
+
});
|
|
55
|
+
tracer.trace("Start");
|
|
56
|
+
const apdu = [...BACKUP_APP_STORAGE, Buffer.from([0x00])];
|
|
57
|
+
const response = yield transport.send(...apdu, RESPONSE_STATUS_SET);
|
|
58
|
+
return parseResponse(response);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Parses the response data buffer, check the status code and return the data.
|
|
63
|
+
*
|
|
64
|
+
* @param data - The response data buffer w/ status code.
|
|
65
|
+
* @returns The response data as a buffer w/o status code.
|
|
66
|
+
*/
|
|
67
|
+
export function parseResponse(data) {
|
|
68
|
+
const tracer = new LocalTracer("hw", {
|
|
69
|
+
function: "parseResponse@backupAppStorage",
|
|
70
|
+
});
|
|
71
|
+
const status = data.readUInt16BE(data.length - 2);
|
|
72
|
+
tracer.trace("Result status from 0xe06b0000", { status });
|
|
73
|
+
switch (status) {
|
|
74
|
+
case StatusCodes.OK:
|
|
75
|
+
return data.subarray(0, data.length - 2);
|
|
76
|
+
case StatusCodes.APP_NOT_FOUND_OR_INVALID_CONTEXT:
|
|
77
|
+
throw new InvalidContext("Invalid context, getAppStorageInfo must be called.");
|
|
78
|
+
case StatusCodes.GEN_AES_KEY_FAILED:
|
|
79
|
+
throw new GenerateAesKeyFailed("Failed to generate AES key.");
|
|
80
|
+
case StatusCodes.INTERNAL_CRYPTO_OPERATION_FAILED:
|
|
81
|
+
throw new InternalCryptoOperationFailed("Internal error, crypto operation failed.");
|
|
82
|
+
case StatusCodes.INTERNAL_COMPUTE_AES_CMAC_FAILED:
|
|
83
|
+
throw new InternalComputeAesCmacFailed("Internal error, failed to compute AES CMAC.");
|
|
84
|
+
case StatusCodes.ENCRYPT_APP_STORAGE_FAILED:
|
|
85
|
+
throw new GenerateAesKeyFailed("Failed to encrypt the app storage backup.");
|
|
86
|
+
case StatusCodes.DEVICE_IN_RECOVERY_MODE:
|
|
87
|
+
break;
|
|
88
|
+
case StatusCodes.INVALID_BACKUP_STATE:
|
|
89
|
+
throw new InvalidBackupState("Invalid backup state, backup already performed.");
|
|
90
|
+
}
|
|
91
|
+
throw new TransportStatusError(status);
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=backupAppStorage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backupAppStorage.js","sourceRoot":"","sources":["../../../../src/commands/use-cases/app-backup/backupAppStorage.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAkB,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EACL,oBAAoB,EACpB,4BAA4B,EAC5B,6BAA6B,EAC7B,kBAAkB,EAClB,cAAc,GACf,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;GAOG;AACH,MAAM,kBAAkB,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAU,CAAC;AAE7D;;;;;;;;;GASG;AACH,MAAM,mBAAmB,GAAa;IACpC,WAAW,CAAC,EAAE;IACd,WAAW,CAAC,gCAAgC;IAC5C,WAAW,CAAC,kBAAkB;IAC9B,WAAW,CAAC,gCAAgC;IAC5C,WAAW,CAAC,gCAAgC;IAC5C,WAAW,CAAC,0BAA0B;IACtC,WAAW,CAAC,uBAAuB;IACnC,WAAW,CAAC,oBAAoB;CACjC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAgB,gBAAgB,CAAC,SAAoB;;QACzD,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,IAAI,EAAE;YACnC,SAAS,EAAE,SAAS,CAAC,eAAe,EAAE;YACtC,QAAQ,EAAE,kBAAkB;SAC7B,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEtB,MAAM,IAAI,GAAmB,CAAC,GAAG,kBAAkB,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAE1E,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,mBAAmB,CAAC,CAAC;QAEpE,OAAO,aAAa,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC;CAAA;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,IAAI,EAAE;QACnC,QAAQ,EAAE,gCAAgC;KAC3C,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAClD,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAE1D,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,WAAW,CAAC,EAAE;YACjB,OAAO,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC3C,KAAK,WAAW,CAAC,gCAAgC;YAC/C,MAAM,IAAI,cAAc,CAAC,oDAAoD,CAAC,CAAC;QACjF,KAAK,WAAW,CAAC,kBAAkB;YACjC,MAAM,IAAI,oBAAoB,CAAC,6BAA6B,CAAC,CAAC;QAChE,KAAK,WAAW,CAAC,gCAAgC;YAC/C,MAAM,IAAI,6BAA6B,CAAC,0CAA0C,CAAC,CAAC;QACtF,KAAK,WAAW,CAAC,gCAAgC;YAC/C,MAAM,IAAI,4BAA4B,CAAC,6CAA6C,CAAC,CAAC;QACxF,KAAK,WAAW,CAAC,0BAA0B;YACzC,MAAM,IAAI,oBAAoB,CAAC,2CAA2C,CAAC,CAAC;QAC9E,KAAK,WAAW,CAAC,uBAAuB;YACtC,MAAM;QACR,KAAK,WAAW,CAAC,oBAAoB;YACnC,MAAM,IAAI,kBAAkB,CAAC,iDAAiD,CAAC,CAAC;IACpF,CAAC;IAED,MAAM,IAAI,oBAAoB,CAAC,MAAM,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backupAppStorage.test.d.ts","sourceRoot":"","sources":["../../../../src/commands/use-cases/app-backup/backupAppStorage.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { StatusCodes } from "@ledgerhq/hw-transport";
|
|
11
|
+
import { backupAppStorage, parseResponse } from "./backupAppStorage";
|
|
12
|
+
import { InternalComputeAesCmacFailed } from "../../../errors";
|
|
13
|
+
jest.mock("@ledgerhq/hw-transport");
|
|
14
|
+
describe("backupAppStorage", () => {
|
|
15
|
+
let transport;
|
|
16
|
+
const response = Buffer.from([
|
|
17
|
+
0x31, 0x30, 0x36, 0x52, 0x75, 0x65, 0x64, 0x75, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x65, 0x90, 0x00,
|
|
18
|
+
]);
|
|
19
|
+
beforeEach(() => {
|
|
20
|
+
transport = {
|
|
21
|
+
send: jest.fn().mockResolvedValue(response),
|
|
22
|
+
getTraceContext: jest.fn().mockResolvedValue(undefined),
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
afterEach(() => {
|
|
26
|
+
jest.clearAllMocks();
|
|
27
|
+
});
|
|
28
|
+
it("should call the send function with correct parameters", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
29
|
+
yield backupAppStorage(transport);
|
|
30
|
+
expect(transport.send).toHaveBeenCalledWith(0xe0, 0x6b, 0x00, 0x00, Buffer.from([0x00]), [
|
|
31
|
+
StatusCodes.OK,
|
|
32
|
+
StatusCodes.APP_NOT_FOUND_OR_INVALID_CONTEXT,
|
|
33
|
+
StatusCodes.GEN_AES_KEY_FAILED,
|
|
34
|
+
StatusCodes.INTERNAL_CRYPTO_OPERATION_FAILED,
|
|
35
|
+
StatusCodes.INTERNAL_COMPUTE_AES_CMAC_FAILED,
|
|
36
|
+
StatusCodes.ENCRYPT_APP_STORAGE_FAILED,
|
|
37
|
+
StatusCodes.DEVICE_IN_RECOVERY_MODE,
|
|
38
|
+
StatusCodes.INVALID_BACKUP_STATE,
|
|
39
|
+
]);
|
|
40
|
+
}));
|
|
41
|
+
describe("parseResponse", () => {
|
|
42
|
+
it("should parse the response data correctly", () => {
|
|
43
|
+
const expected = Buffer.from([
|
|
44
|
+
0x31, 0x30, 0x36, 0x52, 0x75, 0x65, 0x64, 0x75, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x65,
|
|
45
|
+
]);
|
|
46
|
+
expect(parseResponse(response)).toStrictEqual(expected);
|
|
47
|
+
});
|
|
48
|
+
it("should throw TransportStatusError if the response status is invalid", () => {
|
|
49
|
+
const data = Buffer.from([0x54, 0x1b]);
|
|
50
|
+
expect(() => parseResponse(data)).toThrow(new InternalComputeAesCmacFailed("Internal error, failed to compute AES CMAC."));
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
//# sourceMappingURL=backupAppStorage.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"backupAppStorage.test.js","sourceRoot":"","sources":["../../../../src/commands/use-cases/app-backup/backupAppStorage.test.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAkB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACrE,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAE/D,IAAI,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;AAEpC,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,IAAI,SAAoB,CAAC;IACzB,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC;QAC3B,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;KAC/F,CAAC,CAAC;IAEH,UAAU,CAAC,GAAG,EAAE;QACd,SAAS,GAAG;YACV,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC;YAC3C,eAAe,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;SAChC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAS,EAAE;QACrE,MAAM,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAClC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,oBAAoB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE;YACvF,WAAW,CAAC,EAAE;YACd,WAAW,CAAC,gCAAgC;YAC5C,WAAW,CAAC,kBAAkB;YAC9B,WAAW,CAAC,gCAAgC;YAC5C,WAAW,CAAC,gCAAgC;YAC5C,WAAW,CAAC,0BAA0B;YACtC,WAAW,CAAC,uBAAuB;YACnC,WAAW,CAAC,oBAAoB;SACjC,CAAC,CAAC;IACL,CAAC,CAAA,CAAC,CAAC;IAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC;gBAC3B,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;aACnF,CAAC,CAAC;YACH,MAAM,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;YAC7E,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;YACvC,MAAM,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CACvC,IAAI,4BAA4B,CAAC,6CAA6C,CAAC,CAChF,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import Transport from "@ledgerhq/hw-transport";
|
|
3
|
+
import type { AppStorageInfo } from "../../entities/AppStorageInfo";
|
|
4
|
+
/**
|
|
5
|
+
* Retrieves the application storage information from the device.
|
|
6
|
+
*
|
|
7
|
+
* @param transport - The transport object used to communicate with the device.
|
|
8
|
+
* @param appName - The name of the application to retrieve the storage information for.
|
|
9
|
+
* @returns A promise that resolves to the application storage information object.
|
|
10
|
+
* @throws {TransportStatusError} If the response status is invalid.
|
|
11
|
+
*/
|
|
12
|
+
export declare function getAppStorageInfo(transport: Transport, appName: string): Promise<AppStorageInfo>;
|
|
13
|
+
/**
|
|
14
|
+
* Parses the response data from the device into a string.
|
|
15
|
+
*
|
|
16
|
+
* @param data - The response data received from the device.
|
|
17
|
+
* @returns A string representing the parsed response.
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseResponse(data: Buffer): AppStorageInfo;
|
|
20
|
+
//# sourceMappingURL=getAppStorageInfo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getAppStorageInfo.d.ts","sourceRoot":"","sources":["../../../../src/commands/use-cases/app-backup/getAppStorageInfo.ts"],"names":[],"mappings":";AAAA,OAAO,SAAgD,MAAM,wBAAwB,CAAC;AAEtF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AA2BpE;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,cAAc,CAAC,CAgBzB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAqC1D"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { StatusCodes, TransportStatusError } from "@ledgerhq/hw-transport";
|
|
11
|
+
import { LocalTracer } from "@ledgerhq/logs";
|
|
12
|
+
import { AppNotFound, InvalidAppNameLength } from "../../../errors";
|
|
13
|
+
/**
|
|
14
|
+
* Name in documentation: INS_APP_STORAGE_GET_INFO
|
|
15
|
+
* cla: 0xe0
|
|
16
|
+
* ins: 0x6a
|
|
17
|
+
* p1: 0x00
|
|
18
|
+
* p2: 0x00
|
|
19
|
+
* data: APP_NAME_LEN (1 byte) + APP_NAME (variable) to configure at runtime
|
|
20
|
+
*/
|
|
21
|
+
const GET_APP_STORAGE_INFO = [0xe0, 0x6a, 0x00, 0x00];
|
|
22
|
+
/**
|
|
23
|
+
* 0x9000: Success.
|
|
24
|
+
* 0x5123: Application not found.
|
|
25
|
+
* 0x662F: If the device is in recovery mode.
|
|
26
|
+
* 0x670A: Invalid application name length, two chars minimum.
|
|
27
|
+
*/
|
|
28
|
+
const RESPONSE_STATUS_SET = [
|
|
29
|
+
StatusCodes.OK,
|
|
30
|
+
StatusCodes.APP_NOT_FOUND_OR_INVALID_CONTEXT,
|
|
31
|
+
StatusCodes.DEVICE_IN_RECOVERY_MODE,
|
|
32
|
+
StatusCodes.INVALID_APP_NAME_LENGTH,
|
|
33
|
+
];
|
|
34
|
+
/**
|
|
35
|
+
* Retrieves the application storage information from the device.
|
|
36
|
+
*
|
|
37
|
+
* @param transport - The transport object used to communicate with the device.
|
|
38
|
+
* @param appName - The name of the application to retrieve the storage information for.
|
|
39
|
+
* @returns A promise that resolves to the application storage information object.
|
|
40
|
+
* @throws {TransportStatusError} If the response status is invalid.
|
|
41
|
+
*/
|
|
42
|
+
export function getAppStorageInfo(transport, appName) {
|
|
43
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
44
|
+
const tracer = new LocalTracer("hw", {
|
|
45
|
+
transport: transport.getTraceContext(),
|
|
46
|
+
function: "getAppStorageInfo",
|
|
47
|
+
});
|
|
48
|
+
tracer.trace("Start");
|
|
49
|
+
const params = Buffer.concat([
|
|
50
|
+
Buffer.from([appName.length]),
|
|
51
|
+
Buffer.from(appName, "ascii"),
|
|
52
|
+
]);
|
|
53
|
+
const apdu = [...GET_APP_STORAGE_INFO, params];
|
|
54
|
+
const response = yield transport.send(...apdu, RESPONSE_STATUS_SET);
|
|
55
|
+
return parseResponse(response);
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Parses the response data from the device into a string.
|
|
60
|
+
*
|
|
61
|
+
* @param data - The response data received from the device.
|
|
62
|
+
* @returns A string representing the parsed response.
|
|
63
|
+
*/
|
|
64
|
+
export function parseResponse(data) {
|
|
65
|
+
const tracer = new LocalTracer("hw", {
|
|
66
|
+
function: "parseResponse@getAppStorageInfo",
|
|
67
|
+
});
|
|
68
|
+
const status = data.readUInt16BE(data.length - 2);
|
|
69
|
+
tracer.trace("Result status from 0xe06a0000", { status });
|
|
70
|
+
switch (status) {
|
|
71
|
+
case StatusCodes.OK: {
|
|
72
|
+
/**
|
|
73
|
+
* The backup size is a 4-byte unsigned integer.
|
|
74
|
+
* The data version is a 4-byte string.
|
|
75
|
+
* The hasSettings and hasData flags are 1-byte booleans.
|
|
76
|
+
* The hash is a 32-byte string.
|
|
77
|
+
*/
|
|
78
|
+
let offset = 0;
|
|
79
|
+
const size = data.readUInt32BE(offset); // Len = 4
|
|
80
|
+
offset += 4;
|
|
81
|
+
const dataVersion = data.subarray(offset, offset + 4).toString(); // Len = 4
|
|
82
|
+
offset += 4;
|
|
83
|
+
const hasSettings = data.readUIntBE(offset, 1) === 1; // Len = 1
|
|
84
|
+
offset += 1;
|
|
85
|
+
const hasData = data.readUIntBE(offset, 1) === 1; // Len = 1
|
|
86
|
+
offset += 1;
|
|
87
|
+
const hash = data.subarray(offset, offset + 32).toString(); // Len = 32
|
|
88
|
+
return { size, dataVersion, hasSettings, hasData, hash };
|
|
89
|
+
}
|
|
90
|
+
case StatusCodes.APP_NOT_FOUND_OR_INVALID_CONTEXT:
|
|
91
|
+
throw new AppNotFound("Application not found.");
|
|
92
|
+
case StatusCodes.DEVICE_IN_RECOVERY_MODE:
|
|
93
|
+
break;
|
|
94
|
+
case StatusCodes.INVALID_APP_NAME_LENGTH:
|
|
95
|
+
throw new InvalidAppNameLength("Invalid application name length, two chars minimum.");
|
|
96
|
+
}
|
|
97
|
+
throw new TransportStatusError(status);
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=getAppStorageInfo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getAppStorageInfo.js","sourceRoot":"","sources":["../../../../src/commands/use-cases/app-backup/getAppStorageInfo.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getAppStorageInfo.test.d.ts","sourceRoot":"","sources":["../../../../src/commands/use-cases/app-backup/getAppStorageInfo.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { StatusCodes } from "@ledgerhq/hw-transport";
|
|
11
|
+
import { getAppStorageInfo, parseResponse } from "./getAppStorageInfo";
|
|
12
|
+
import { InvalidAppNameLength } from "../../../errors";
|
|
13
|
+
jest.mock("@ledgerhq/hw-transport");
|
|
14
|
+
describe("getAppStorageInfo", () => {
|
|
15
|
+
let transport;
|
|
16
|
+
const response = Buffer.from([
|
|
17
|
+
0x00, 0x00, 0x04, 0xd2, 0x31, 0x2e, 0x30, 0x31, 0x01, 0x01, 0x68, 0x61, 0x73, 0x68, 0x68, 0x61,
|
|
18
|
+
0x73, 0x68, 0x31, 0x32, 0x33, 0x34, 0x68, 0x61, 0x73, 0x68, 0x68, 0x61, 0x73, 0x68, 0x68, 0x61,
|
|
19
|
+
0x73, 0x68, 0x68, 0x61, 0x73, 0x68, 0x68, 0x61, 0x73, 0x68, 0x90, 0x00,
|
|
20
|
+
]);
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
transport = {
|
|
23
|
+
send: jest.fn().mockResolvedValue(response),
|
|
24
|
+
getTraceContext: jest.fn().mockResolvedValue(undefined),
|
|
25
|
+
};
|
|
26
|
+
});
|
|
27
|
+
afterEach(() => {
|
|
28
|
+
jest.clearAllMocks();
|
|
29
|
+
});
|
|
30
|
+
it("should call the send function with correct parameters", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
31
|
+
const appName = "MyApp";
|
|
32
|
+
yield getAppStorageInfo(transport, appName);
|
|
33
|
+
expect(transport.send).toHaveBeenCalledWith(0xe0, 0x6a, 0x00, 0x00, Buffer.from([0x05, 0x4d, 0x79, 0x41, 0x70, 0x70]), [
|
|
34
|
+
StatusCodes.OK,
|
|
35
|
+
StatusCodes.APP_NOT_FOUND_OR_INVALID_CONTEXT,
|
|
36
|
+
StatusCodes.DEVICE_IN_RECOVERY_MODE,
|
|
37
|
+
StatusCodes.INVALID_APP_NAME_LENGTH,
|
|
38
|
+
]);
|
|
39
|
+
}));
|
|
40
|
+
describe("parseResponse", () => {
|
|
41
|
+
it("should parse the response data correctly", () => {
|
|
42
|
+
const expected = {
|
|
43
|
+
size: 1234,
|
|
44
|
+
dataVersion: "1.01",
|
|
45
|
+
hasSettings: true,
|
|
46
|
+
hasData: true,
|
|
47
|
+
hash: "hashhash1234hashhashhashhashhash",
|
|
48
|
+
};
|
|
49
|
+
expect(parseResponse(response)).toStrictEqual(expected);
|
|
50
|
+
});
|
|
51
|
+
it("should throw TransportStatusError if the response status is invalid", () => {
|
|
52
|
+
const data = Buffer.from([0x67, 0x0a]);
|
|
53
|
+
expect(() => parseResponse(data)).toThrow(new InvalidAppNameLength("Invalid application name length, two chars minimum."));
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
//# sourceMappingURL=getAppStorageInfo.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getAppStorageInfo.test.js","sourceRoot":"","sources":["../../../../src/commands/use-cases/app-backup/getAppStorageInfo.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import Transport from "@ledgerhq/hw-transport";
|
|
3
|
+
/**
|
|
4
|
+
* Restores the application storage.
|
|
5
|
+
*
|
|
6
|
+
* @param transport - The transport object used for communication with the device.
|
|
7
|
+
* @param chunk - The chunk of data to restore.
|
|
8
|
+
* @returns A promise that resolves to void.
|
|
9
|
+
*/
|
|
10
|
+
export declare function restoreAppStorage(transport: Transport, chunk: Buffer): Promise<void>;
|
|
11
|
+
export declare function parseResponse(data: Buffer): void;
|
|
12
|
+
//# sourceMappingURL=restoreAppStorage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restoreAppStorage.d.ts","sourceRoot":"","sources":["../../../../src/commands/use-cases/app-backup/restoreAppStorage.ts"],"names":[],"mappings":";AAAA,OAAO,SAAgD,MAAM,wBAAwB,CAAC;AA2CtF;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAa1F;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CA2BhD"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { StatusCodes, TransportStatusError } from "@ledgerhq/hw-transport";
|
|
11
|
+
import { LocalTracer } from "@ledgerhq/logs";
|
|
12
|
+
import { GenerateAesKeyFailed, InternalCryptoOperationFailed, InvalidBackupHeader, InvalidChunkLength, InvalidContext, InvalidRestoreState, } from "../../../errors";
|
|
13
|
+
/**
|
|
14
|
+
* Name in documentation: INS_APP_STORAGE_GET_INFO
|
|
15
|
+
* cla: 0xe0
|
|
16
|
+
* ins: 0x6d
|
|
17
|
+
* p1: 0x00
|
|
18
|
+
* p2: 0x00
|
|
19
|
+
* data: CHUNK_LEN + CHUNK to configure at runtime
|
|
20
|
+
*/
|
|
21
|
+
const RESTORE_APP_STORAGE = [0xe0, 0x6d, 0x00, 0x00];
|
|
22
|
+
/**
|
|
23
|
+
* 0x9000: Success.
|
|
24
|
+
* 0x5123: Invalid context, Restore Init must be called first.
|
|
25
|
+
* 0x5419: Failed to generate AES key.
|
|
26
|
+
* 0x541A: Failed to decrypt the app storage backup.
|
|
27
|
+
* 0x662F: Invalid device state, recovery mode.
|
|
28
|
+
* 0x6643: Invalid restore state, restore already performed.
|
|
29
|
+
* 0x6734: Invalid CHUNK_LEN.
|
|
30
|
+
* 0x684A: Invalid backup, app storage header is not valid.
|
|
31
|
+
*/
|
|
32
|
+
const RESPONSE_STATUS_SET = [
|
|
33
|
+
StatusCodes.OK,
|
|
34
|
+
StatusCodes.APP_NOT_FOUND_OR_INVALID_CONTEXT,
|
|
35
|
+
StatusCodes.GEN_AES_KEY_FAILED,
|
|
36
|
+
StatusCodes.INTERNAL_CRYPTO_OPERATION_FAILED,
|
|
37
|
+
StatusCodes.DEVICE_IN_RECOVERY_MODE,
|
|
38
|
+
StatusCodes.INVALID_RESTORE_STATE,
|
|
39
|
+
StatusCodes.INVALID_CHUNK_LENGTH,
|
|
40
|
+
StatusCodes.INVALID_BACKUP_HEADER,
|
|
41
|
+
];
|
|
42
|
+
/**
|
|
43
|
+
* Restores the application storage.
|
|
44
|
+
*
|
|
45
|
+
* @param transport - The transport object used for communication with the device.
|
|
46
|
+
* @param chunk - The chunk of data to restore.
|
|
47
|
+
* @returns A promise that resolves to void.
|
|
48
|
+
*/
|
|
49
|
+
export function restoreAppStorage(transport, chunk) {
|
|
50
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
+
const tracer = new LocalTracer("hw", {
|
|
52
|
+
transport: transport.getTraceContext(),
|
|
53
|
+
function: "restoreAppStorage",
|
|
54
|
+
});
|
|
55
|
+
tracer.trace("Start");
|
|
56
|
+
const params = Buffer.concat([Buffer.from([chunk.length]), chunk]);
|
|
57
|
+
const apdu = [...RESTORE_APP_STORAGE, params];
|
|
58
|
+
const response = yield transport.send(...apdu, RESPONSE_STATUS_SET);
|
|
59
|
+
parseResponse(response);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
export function parseResponse(data) {
|
|
63
|
+
const tracer = new LocalTracer("hw", {
|
|
64
|
+
function: "parseResponse@restoreAppStorage",
|
|
65
|
+
});
|
|
66
|
+
const status = data.readUInt16BE(data.length - 2);
|
|
67
|
+
tracer.trace("Result status from 0xe06d0000", { status });
|
|
68
|
+
switch (status) {
|
|
69
|
+
case StatusCodes.OK:
|
|
70
|
+
return;
|
|
71
|
+
case StatusCodes.APP_NOT_FOUND_OR_INVALID_CONTEXT:
|
|
72
|
+
throw new InvalidContext("Invalid context, restoreAppStorageInit must be called first.");
|
|
73
|
+
case StatusCodes.GEN_AES_KEY_FAILED:
|
|
74
|
+
throw new GenerateAesKeyFailed("Failed to generate AES key.");
|
|
75
|
+
case StatusCodes.INTERNAL_CRYPTO_OPERATION_FAILED:
|
|
76
|
+
throw new InternalCryptoOperationFailed("Failed to decrypt the app storage backup.");
|
|
77
|
+
case StatusCodes.DEVICE_IN_RECOVERY_MODE:
|
|
78
|
+
break;
|
|
79
|
+
case StatusCodes.INVALID_RESTORE_STATE:
|
|
80
|
+
throw new InvalidRestoreState("Invalid restore state, restore already performed.");
|
|
81
|
+
case StatusCodes.INVALID_CHUNK_LENGTH:
|
|
82
|
+
throw new InvalidChunkLength("Invalid chunk length.");
|
|
83
|
+
case StatusCodes.INVALID_BACKUP_HEADER:
|
|
84
|
+
throw new InvalidBackupHeader("Invalid backup, app storage header is not valid.");
|
|
85
|
+
}
|
|
86
|
+
throw new TransportStatusError(status);
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=restoreAppStorage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restoreAppStorage.js","sourceRoot":"","sources":["../../../../src/commands/use-cases/app-backup/restoreAppStorage.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAkB,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,OAAO,EACL,oBAAoB,EACpB,6BAA6B,EAC7B,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;GAOG;AACH,MAAM,mBAAmB,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAU,CAAC;AAE9D;;;;;;;;;GASG;AACH,MAAM,mBAAmB,GAAa;IACpC,WAAW,CAAC,EAAE;IACd,WAAW,CAAC,gCAAgC;IAC5C,WAAW,CAAC,kBAAkB;IAC9B,WAAW,CAAC,gCAAgC;IAC5C,WAAW,CAAC,uBAAuB;IACnC,WAAW,CAAC,qBAAqB;IACjC,WAAW,CAAC,oBAAoB;IAChC,WAAW,CAAC,qBAAqB;CAClC,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAgB,iBAAiB,CAAC,SAAoB,EAAE,KAAa;;QACzE,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,IAAI,EAAE;YACnC,SAAS,EAAE,SAAS,CAAC,eAAe,EAAE;YACtC,QAAQ,EAAE,mBAAmB;SAC9B,CAAC,CAAC;QACH,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAEtB,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;QACnE,MAAM,IAAI,GAAmB,CAAC,GAAG,mBAAmB,EAAE,MAAM,CAAC,CAAC;QAE9D,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,mBAAmB,CAAC,CAAC;QAEpE,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC;CAAA;AAED,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,IAAI,EAAE;QACnC,QAAQ,EAAE,iCAAiC;KAC5C,CAAC,CAAC;IACH,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAClD,MAAM,CAAC,KAAK,CAAC,+BAA+B,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAE1D,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,WAAW,CAAC,EAAE;YACjB,OAAO;QACT,KAAK,WAAW,CAAC,gCAAgC;YAC/C,MAAM,IAAI,cAAc,CAAC,8DAA8D,CAAC,CAAC;QAC3F,KAAK,WAAW,CAAC,kBAAkB;YACjC,MAAM,IAAI,oBAAoB,CAAC,6BAA6B,CAAC,CAAC;QAChE,KAAK,WAAW,CAAC,gCAAgC;YAC/C,MAAM,IAAI,6BAA6B,CAAC,2CAA2C,CAAC,CAAC;QACvF,KAAK,WAAW,CAAC,uBAAuB;YACtC,MAAM;QACR,KAAK,WAAW,CAAC,qBAAqB;YACpC,MAAM,IAAI,mBAAmB,CAAC,mDAAmD,CAAC,CAAC;QACrF,KAAK,WAAW,CAAC,oBAAoB;YACnC,MAAM,IAAI,kBAAkB,CAAC,uBAAuB,CAAC,CAAC;QACxD,KAAK,WAAW,CAAC,qBAAqB;YACpC,MAAM,IAAI,mBAAmB,CAAC,kDAAkD,CAAC,CAAC;IACtF,CAAC;IAED,MAAM,IAAI,oBAAoB,CAAC,MAAM,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restoreAppStorage.test.d.ts","sourceRoot":"","sources":["../../../../src/commands/use-cases/app-backup/restoreAppStorage.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { StatusCodes } from "@ledgerhq/hw-transport";
|
|
11
|
+
import { restoreAppStorage, parseResponse } from "./restoreAppStorage";
|
|
12
|
+
import { InvalidRestoreState } from "../../../errors";
|
|
13
|
+
jest.mock("@ledgerhq/hw-transport");
|
|
14
|
+
describe("restoreAppStorage", () => {
|
|
15
|
+
let transport;
|
|
16
|
+
const response = Buffer.from([0x90, 0x00]);
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
transport = {
|
|
19
|
+
send: jest.fn().mockResolvedValue(response),
|
|
20
|
+
getTraceContext: jest.fn().mockResolvedValue(undefined),
|
|
21
|
+
};
|
|
22
|
+
});
|
|
23
|
+
afterEach(() => {
|
|
24
|
+
jest.clearAllMocks();
|
|
25
|
+
});
|
|
26
|
+
it("should call the send function with correct parameters", () => __awaiter(void 0, void 0, void 0, function* () {
|
|
27
|
+
const chunk = Buffer.from("106RueduTemple");
|
|
28
|
+
yield restoreAppStorage(transport, chunk);
|
|
29
|
+
expect(transport.send).toHaveBeenCalledWith(0xe0, 0x6d, 0x00, 0x00, Buffer.from([
|
|
30
|
+
0x0e, 0x31, 0x30, 0x36, 0x52, 0x75, 0x65, 0x64, 0x75, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x65,
|
|
31
|
+
]), [
|
|
32
|
+
StatusCodes.OK,
|
|
33
|
+
StatusCodes.APP_NOT_FOUND_OR_INVALID_CONTEXT,
|
|
34
|
+
StatusCodes.GEN_AES_KEY_FAILED,
|
|
35
|
+
StatusCodes.INTERNAL_CRYPTO_OPERATION_FAILED,
|
|
36
|
+
StatusCodes.DEVICE_IN_RECOVERY_MODE,
|
|
37
|
+
StatusCodes.INVALID_RESTORE_STATE,
|
|
38
|
+
StatusCodes.INVALID_CHUNK_LENGTH,
|
|
39
|
+
StatusCodes.INVALID_BACKUP_HEADER,
|
|
40
|
+
]);
|
|
41
|
+
}));
|
|
42
|
+
describe("parseResponse", () => {
|
|
43
|
+
it("should parse the response data correctly", () => {
|
|
44
|
+
expect(() => parseResponse(response)).not.toThrow();
|
|
45
|
+
});
|
|
46
|
+
it("should throw TransportStatusError if the response status is invalid", () => {
|
|
47
|
+
const data = Buffer.from([0x66, 0x43]);
|
|
48
|
+
expect(() => parseResponse(data)).toThrow(new InvalidRestoreState("Invalid restore state, restore already performed."));
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
//# sourceMappingURL=restoreAppStorage.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restoreAppStorage.test.js","sourceRoot":"","sources":["../../../../src/commands/use-cases/app-backup/restoreAppStorage.test.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAkB,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD,IAAI,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;AAEpC,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,IAAI,SAAoB,CAAC;IACzB,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;IAE3C,UAAU,CAAC,GAAG,EAAE;QACd,SAAS,GAAG;YACV,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC;YAC3C,eAAe,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,SAAS,CAAC;SAChC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,aAAa,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAS,EAAE;QACrE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC5C,MAAM,iBAAiB,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAC1C,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,oBAAoB,CACzC,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;SACzF,CAAC,EACF;YACE,WAAW,CAAC,EAAE;YACd,WAAW,CAAC,gCAAgC;YAC5C,WAAW,CAAC,kBAAkB;YAC9B,WAAW,CAAC,gCAAgC;YAC5C,WAAW,CAAC,uBAAuB;YACnC,WAAW,CAAC,qBAAqB;YACjC,WAAW,CAAC,oBAAoB;YAChC,WAAW,CAAC,qBAAqB;SAClC,CACF,CAAC;IACJ,CAAC,CAAA,CAAC,CAAC;IAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;YAClD,MAAM,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;QACtD,CAAC,CAAC,CAAC;QACH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;YAC7E,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;YACvC,MAAM,CAAC,GAAG,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CACvC,IAAI,mBAAmB,CAAC,mDAAmD,CAAC,CAC7E,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import Transport from "@ledgerhq/hw-transport";
|
|
3
|
+
/**
|
|
4
|
+
* Restores the application storage commit.
|
|
5
|
+
*
|
|
6
|
+
* @param transport - The transport object used for communication with the device.
|
|
7
|
+
* @returns A promise that resolves to void.
|
|
8
|
+
*/
|
|
9
|
+
export declare function restoreAppStorageCommit(transport: Transport): Promise<void>;
|
|
10
|
+
export declare function parseResponse(data: Buffer): void;
|
|
11
|
+
//# sourceMappingURL=restoreAppStorageCommit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restoreAppStorageCommit.d.ts","sourceRoot":"","sources":["../../../../src/commands/use-cases/app-backup/restoreAppStorageCommit.ts"],"names":[],"mappings":";AAAA,OAAO,SAAgD,MAAM,wBAAwB,CAAC;AAqCtF;;;;;GAKG;AAEH,wBAAsB,uBAAuB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAYjF;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAuBhD"}
|