@aiot-toolkit/aiotpack 2.0.1-alpha.0

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.
Files changed (123) hide show
  1. package/README.md +46 -0
  2. package/lib/compiler/c/README.md +1 -0
  3. package/lib/compiler/c++/README.md +1 -0
  4. package/lib/compiler/enum/CompileMode.d.ts +22 -0
  5. package/lib/compiler/enum/CompileMode.js +30 -0
  6. package/lib/compiler/enum/CompileMode.js.map +1 -0
  7. package/lib/compiler/interface/ICompileParam.d.ts +24 -0
  8. package/lib/compiler/interface/ICompileParam.js +4 -0
  9. package/lib/compiler/interface/ICompileParam.js.map +1 -0
  10. package/lib/compiler/interface/ICompiler.d.ts +5 -0
  11. package/lib/compiler/interface/ICompiler.js +4 -0
  12. package/lib/compiler/interface/ICompiler.js.map +1 -0
  13. package/lib/compiler/interface/ISignConfig.d.ts +8 -0
  14. package/lib/compiler/interface/ISignConfig.js +4 -0
  15. package/lib/compiler/interface/ISignConfig.js.map +1 -0
  16. package/lib/compiler/javascript/JavascriptCompiler.d.ts +11 -0
  17. package/lib/compiler/javascript/JavascriptCompiler.js +108 -0
  18. package/lib/compiler/javascript/JavascriptCompiler.js.map +1 -0
  19. package/lib/compiler/javascript/JavascriptDefaultCompileOption.d.ts +3 -0
  20. package/lib/compiler/javascript/JavascriptDefaultCompileOption.js +21 -0
  21. package/lib/compiler/javascript/JavascriptDefaultCompileOption.js.map +1 -0
  22. package/lib/compiler/javascript/interface/IJavascriptCompileOption.d.ts +40 -0
  23. package/lib/compiler/javascript/interface/IJavascriptCompileOption.js +4 -0
  24. package/lib/compiler/javascript/interface/IJavascriptCompileOption.js.map +1 -0
  25. package/lib/compiler/javascript/interface/IWebpackConfigurator.d.ts +40 -0
  26. package/lib/compiler/javascript/interface/IWebpackConfigurator.js +4 -0
  27. package/lib/compiler/javascript/interface/IWebpackConfigurator.js.map +1 -0
  28. package/lib/compiler/javascript/vela/VelaWebpackConfigurator.d.ts +16 -0
  29. package/lib/compiler/javascript/vela/VelaWebpackConfigurator.js +74 -0
  30. package/lib/compiler/javascript/vela/VelaWebpackConfigurator.js.map +1 -0
  31. package/lib/compiler/javascript/vela/enum/BuildNameFormatType.d.ts +25 -0
  32. package/lib/compiler/javascript/vela/enum/BuildNameFormatType.js +47 -0
  33. package/lib/compiler/javascript/vela/enum/BuildNameFormatType.js.map +1 -0
  34. package/lib/compiler/javascript/vela/enum/EntryType.d.ts +30 -0
  35. package/lib/compiler/javascript/vela/enum/EntryType.js +35 -0
  36. package/lib/compiler/javascript/vela/enum/EntryType.js.map +1 -0
  37. package/lib/compiler/javascript/vela/interface/IChunk.d.ts +29 -0
  38. package/lib/compiler/javascript/vela/interface/IChunk.js +4 -0
  39. package/lib/compiler/javascript/vela/interface/IChunk.js.map +1 -0
  40. package/lib/compiler/javascript/vela/interface/IManifest.d.ts +27 -0
  41. package/lib/compiler/javascript/vela/interface/IManifest.js +4 -0
  42. package/lib/compiler/javascript/vela/interface/IManifest.js.map +1 -0
  43. package/lib/compiler/javascript/vela/interface/IQuickAppConfig.d.ts +11 -0
  44. package/lib/compiler/javascript/vela/interface/IQuickAppConfig.js +4 -0
  45. package/lib/compiler/javascript/vela/interface/IQuickAppConfig.js.map +1 -0
  46. package/lib/compiler/javascript/vela/model/Package.d.ts +75 -0
  47. package/lib/compiler/javascript/vela/model/Package.js +62 -0
  48. package/lib/compiler/javascript/vela/model/Package.js.map +1 -0
  49. package/lib/compiler/javascript/vela/plugin/WrapPlugin.d.ts +7 -0
  50. package/lib/compiler/javascript/vela/plugin/WrapPlugin.js +51 -0
  51. package/lib/compiler/javascript/vela/plugin/WrapPlugin.js.map +1 -0
  52. package/lib/compiler/javascript/vela/utils/Jsc.d.ts +10 -0
  53. package/lib/compiler/javascript/vela/utils/Jsc.js +34 -0
  54. package/lib/compiler/javascript/vela/utils/Jsc.js.map +1 -0
  55. package/lib/compiler/javascript/vela/utils/UxCompileUtil.d.ts +29 -0
  56. package/lib/compiler/javascript/vela/utils/UxCompileUtil.js +144 -0
  57. package/lib/compiler/javascript/vela/utils/UxCompileUtil.js.map +1 -0
  58. package/lib/compiler/javascript/vela/utils/ZipUtil.d.ts +75 -0
  59. package/lib/compiler/javascript/vela/utils/ZipUtil.js +278 -0
  60. package/lib/compiler/javascript/vela/utils/ZipUtil.js.map +1 -0
  61. package/lib/compiler/javascript/vela/utils/signature/Base64.d.ts +11 -0
  62. package/lib/compiler/javascript/vela/utils/signature/Base64.js +77 -0
  63. package/lib/compiler/javascript/vela/utils/signature/Base64.js.map +1 -0
  64. package/lib/compiler/javascript/vela/utils/signature/CRC32.d.ts +9 -0
  65. package/lib/compiler/javascript/vela/utils/signature/CRC32.js +45 -0
  66. package/lib/compiler/javascript/vela/utils/signature/CRC32.js.map +1 -0
  67. package/lib/compiler/javascript/vela/utils/signature/SignUtil.d.ts +94 -0
  68. package/lib/compiler/javascript/vela/utils/signature/SignUtil.js +713 -0
  69. package/lib/compiler/javascript/vela/utils/signature/SignUtil.js.map +1 -0
  70. package/lib/compiler/javascript/vela/utils/signature/Signer.d.ts +16 -0
  71. package/lib/compiler/javascript/vela/utils/signature/Signer.js +30 -0
  72. package/lib/compiler/javascript/vela/utils/signature/Signer.js.map +1 -0
  73. package/lib/compiler/javascript/vela/utils/signature/pem/certificate.pem +27 -0
  74. package/lib/compiler/javascript/vela/utils/signature/pem/private.pem +51 -0
  75. package/lib/config/UxConfig.d.ts +30 -0
  76. package/lib/config/UxConfig.js +52 -0
  77. package/lib/config/UxConfig.js.map +1 -0
  78. package/lib/config/XtsConfig.d.ts +18 -0
  79. package/lib/config/XtsConfig.js +28 -0
  80. package/lib/config/XtsConfig.js.map +1 -0
  81. package/lib/followWorks/xts/entryTemplate.d.ts +21 -0
  82. package/lib/followWorks/xts/entryTemplate.js +166 -0
  83. package/lib/followWorks/xts/entryTemplate.js.map +1 -0
  84. package/lib/followWorks/xts/ts2wasm.d.ts +6 -0
  85. package/lib/followWorks/xts/ts2wasm.js +31 -0
  86. package/lib/followWorks/xts/ts2wasm.js.map +1 -0
  87. package/lib/index.d.ts +2 -0
  88. package/lib/index.js +10 -0
  89. package/lib/index.js.map +1 -0
  90. package/lib/interface/IDeviceList.d.ts +7 -0
  91. package/lib/interface/IDeviceList.js +4 -0
  92. package/lib/interface/IDeviceList.js.map +1 -0
  93. package/lib/loader/ux/AppUxLoader.d.ts +10 -0
  94. package/lib/loader/ux/AppUxLoader.js +31 -0
  95. package/lib/loader/ux/AppUxLoader.js.map +1 -0
  96. package/lib/loader/ux/PngLoader.d.ts +10 -0
  97. package/lib/loader/ux/PngLoader.js +70 -0
  98. package/lib/loader/ux/PngLoader.js.map +1 -0
  99. package/lib/loader/ux/UxLoader.d.ts +6 -0
  100. package/lib/loader/ux/UxLoader.js +31 -0
  101. package/lib/loader/ux/UxLoader.js.map +1 -0
  102. package/lib/loader/xts/XtsLoader.d.ts +9 -0
  103. package/lib/loader/xts/XtsLoader.js +55 -0
  104. package/lib/loader/xts/XtsLoader.js.map +1 -0
  105. package/lib/utils/PngUtils.d.ts +20 -0
  106. package/lib/utils/PngUtils.js +45 -0
  107. package/lib/utils/PngUtils.js.map +1 -0
  108. package/lib/utils/PreWorkUtils.d.ts +17 -0
  109. package/lib/utils/PreWorkUtils.js +76 -0
  110. package/lib/utils/PreWorkUtils.js.map +1 -0
  111. package/lib/utils/ux/UxFileUtils.d.ts +22 -0
  112. package/lib/utils/ux/UxFileUtils.js +34 -0
  113. package/lib/utils/ux/UxFileUtils.js.map +1 -0
  114. package/lib/utils/ux/UxFollowWorks.d.ts +35 -0
  115. package/lib/utils/ux/UxFollowWorks.js +200 -0
  116. package/lib/utils/ux/UxFollowWorks.js.map +1 -0
  117. package/lib/utils/ux/UxLoaderUtils.d.ts +60 -0
  118. package/lib/utils/ux/UxLoaderUtils.js +241 -0
  119. package/lib/utils/ux/UxLoaderUtils.js.map +1 -0
  120. package/lib/utils/xts/XtsFollowWorks.d.ts +29 -0
  121. package/lib/utils/xts/XtsFollowWorks.js +149 -0
  122. package/lib/utils/xts/XtsFollowWorks.js.map +1 -0
  123. package/package.json +44 -0
@@ -0,0 +1,713 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const ColorConsole2_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/ColorConsole2"));
16
+ const CommonUtil_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/utils/CommonUtil"));
17
+ const FileUtil_1 = __importDefault(require("@aiot-toolkit/shared-utils/lib/utils/FileUtil"));
18
+ const crypto_1 = __importDefault(require("crypto"));
19
+ const fs_extra_1 = __importDefault(require("fs-extra"));
20
+ const jsrsasign_1 = __importDefault(require("jsrsasign"));
21
+ const jszip_1 = __importDefault(require("jszip"));
22
+ const path_1 = __importDefault(require("path"));
23
+ const CompileMode_1 = __importDefault(require("../../../../enum/CompileMode"));
24
+ const ZipUtil_1 = __importDefault(require("../ZipUtil"));
25
+ const Base64_1 = __importDefault(require("./Base64"));
26
+ const CRC32_1 = __importDefault(require("./CRC32"));
27
+ const Signer_1 = __importDefault(require("./Signer"));
28
+ /**
29
+ * SignUtil
30
+ */
31
+ class SignUtil {
32
+ /**
33
+ * 获取签名相关的配置内容
34
+ * 1. ICompileParam参数中获取编译模式是否为release
35
+ * 2. IJavascriptCompileOption参数中获取签名目录等内容
36
+ * @param param
37
+ */
38
+ static getProjectSignConfig(param) {
39
+ const { mode, projectPath, signRoot } = param;
40
+ let signConfig;
41
+ let privatekeyPath;
42
+ let certificatePath;
43
+ switch (mode) {
44
+ case CompileMode_1.default.DEVELOPMENT:
45
+ privatekeyPath = path_1.default.join(__dirname, 'pem', 'private.pem');
46
+ certificatePath = path_1.default.join(__dirname, 'pem', 'certificate.pem');
47
+ break;
48
+ case CompileMode_1.default.PRODUCTION:
49
+ privatekeyPath = path_1.default.join(projectPath, signRoot, 'private.pem');
50
+ certificatePath = path_1.default.join(projectPath, signRoot, 'certificate.pem');
51
+ break;
52
+ default:
53
+ // 打印信息, 模式未定义
54
+ ColorConsole2_1.default.error(`【SignUtil】Error: mode ${mode} undefined`);
55
+ break;
56
+ }
57
+ // 检查路径是否真实存在
58
+ if (privatekeyPath &&
59
+ certificatePath &&
60
+ FileUtil_1.default.checkFilePath([privatekeyPath, certificatePath])) {
61
+ signConfig = {
62
+ privatekey: fs_extra_1.default.readFileSync(privatekeyPath),
63
+ certificate: fs_extra_1.default.readFileSync(certificatePath)
64
+ };
65
+ }
66
+ else {
67
+ // 报错, 抛出错误
68
+ ColorConsole2_1.default.throw();
69
+ }
70
+ return signConfig;
71
+ }
72
+ static signZipBufferForPackage(zipBuffer, privatekey, certificate) {
73
+ return __awaiter(this, void 0, void 0, function* () {
74
+ // 1. 解压得到文件列表
75
+ const zipInstWrap = yield SignUtil.createFileListFromZipBuffer(zipBuffer);
76
+ // 摘要map
77
+ const fileDigestHash = [];
78
+ const fileList = [];
79
+ // 2. 如果包含META-INF/CERT,则对其解压,增加签名
80
+ const metaBuffer = zipInstWrap.getFileBuffer(ZipUtil_1.default.CERT_PATH);
81
+ if (metaBuffer) {
82
+ const metaHash = {
83
+ name: ZipUtil_1.default.DIGEST_HASH_JSON,
84
+ hash: CommonUtil_1.default.calcDataDigest(metaBuffer)
85
+ };
86
+ const signedMetaBuffer = SignUtil.doSign(metaBuffer, [metaHash], privatekey, certificate);
87
+ if (signedMetaBuffer === false) {
88
+ // 报错,META-INF/CERT签名失败
89
+ console.error('【SignUtil】error: META-INF/CERT signature failed');
90
+ }
91
+ else {
92
+ fileList.push({
93
+ path: ZipUtil_1.default.CERT_PATH,
94
+ content: signedMetaBuffer
95
+ });
96
+ fileDigestHash.push({
97
+ name: ZipUtil_1.default.CERT_PATH,
98
+ hash: CommonUtil_1.default.calcDataDigest(signedMetaBuffer)
99
+ });
100
+ }
101
+ }
102
+ // 3. 对整个zip做签名
103
+ const files = zipInstWrap.fileList;
104
+ files.filter(SignUtil.fileFilter).map((item) => {
105
+ fileList.push(item);
106
+ fileDigestHash.push({
107
+ name: item.path,
108
+ hash: CommonUtil_1.default.calcDataDigest(item.content)
109
+ });
110
+ });
111
+ // 因为META变化,重新创建ZIP流
112
+ const newZipBuffer = yield ZipUtil_1.default.createZipBufferFromFileList(fileList, zipInstWrap.comment);
113
+ // 对新ZIP流重新签名
114
+ const signedZipBuffer = SignUtil.doSign(newZipBuffer, fileDigestHash, privatekey, certificate);
115
+ return signedZipBuffer;
116
+ });
117
+ }
118
+ /**
119
+ * 根据ZIP流获取文件实例
120
+ * @param zipBuffer
121
+ * @returns
122
+ */
123
+ static createFileListFromZipBuffer(zipBuffer) {
124
+ return __awaiter(this, void 0, void 0, function* () {
125
+ const zipInst = yield jszip_1.default.loadAsync(zipBuffer, ZipUtil_1.default.ZIP_OPTION);
126
+ function iterator(filePath) {
127
+ return __awaiter(this, void 0, void 0, function* () {
128
+ const content = yield zipInst.files[filePath].async('nodebuffer');
129
+ return {
130
+ path: filePath,
131
+ content
132
+ };
133
+ });
134
+ }
135
+ const fileList = yield Promise.all(Object.keys(zipInst.files).map(iterator));
136
+ return {
137
+ fileList,
138
+ comment: zipInst.comment,
139
+ getFileBuffer(path) {
140
+ const buffer = fileList.find((item) => item.path === path);
141
+ let content;
142
+ if (buffer) {
143
+ content = buffer.content;
144
+ }
145
+ return content;
146
+ }
147
+ };
148
+ });
149
+ }
150
+ /**
151
+ * 为 zip buffer 签名,返回签名后的buffer
152
+ * @param fileBuffer
153
+ * @param files
154
+ * @param privatekey
155
+ * @param certificate
156
+ */
157
+ static doSign(fileBuffer, files, privatekey, certificate) {
158
+ const result = SignUtil.unZipFiles(fileBuffer, files);
159
+ if (!result) {
160
+ return false;
161
+ }
162
+ const [chunks] = result;
163
+ // 生成整体签名
164
+ SignUtil.signChunk(chunks, privatekey, certificate);
165
+ // 写入zip文件
166
+ const signContent = SignUtil.saveChunk(fileBuffer, chunks);
167
+ return signContent;
168
+ }
169
+ /**
170
+ * 解析buffer
171
+ * @param fileBuffer
172
+ * @param files
173
+ */
174
+ static unZipFiles(fileBuffer, files) {
175
+ // 1. 读取zip文件
176
+ if (!fileBuffer || fileBuffer.length <= 4) {
177
+ // 报错
178
+ console.error('【SignUtil】Zip file open failed');
179
+ return false;
180
+ }
181
+ // 2. 检查文件格式是否正确
182
+ const fileMagic = fileBuffer.readInt32LE(0);
183
+ if (fileMagic !== 0x4034b50) {
184
+ // 报错
185
+ console.error('【SignUtil】Zip file format is wrong');
186
+ return false;
187
+ }
188
+ // 3. 解析数据块
189
+ const chunks = SignUtil.parserZip(fileBuffer);
190
+ chunks.options = { files };
191
+ // 解析成功,生成签名块
192
+ if (chunks.tag) {
193
+ // 分别处理三个签名块
194
+ Object.keys(chunks.sections).forEach((item) => {
195
+ const chunk = chunks.sections[item];
196
+ SignUtil.processChunk(fileBuffer, chunk);
197
+ });
198
+ return [chunks, fileBuffer];
199
+ }
200
+ return false;
201
+ }
202
+ /**
203
+ * 解析ZIP 分解为数据块
204
+ * @param fileBuffer
205
+ */
206
+ static parserZip(fileBuffer) {
207
+ let chunk = {
208
+ signchunk: Buffer.from(''),
209
+ tag: false,
210
+ length: fileBuffer.length,
211
+ options: {
212
+ files: []
213
+ },
214
+ sections: {
215
+ header: {
216
+ tag: false,
217
+ startIndex: 0,
218
+ len: 0,
219
+ previous: 0,
220
+ sign: undefined
221
+ },
222
+ central: {
223
+ tag: false,
224
+ startIndex: 0,
225
+ len: 0,
226
+ previous: 0,
227
+ sign: undefined
228
+ },
229
+ footer: {
230
+ tag: false,
231
+ startIndex: 0,
232
+ len: 0,
233
+ previous: 0,
234
+ sign: undefined
235
+ }
236
+ }
237
+ };
238
+ // fileBuffer至少22个字节
239
+ chunk.sections.footer = SignUtil.readEOCD(fileBuffer);
240
+ if (chunk.sections.footer.tag) {
241
+ chunk.sections.central = SignUtil.readCD(fileBuffer, chunk.sections.footer.previous, chunk.sections.footer.startIndex - chunk.sections.footer.previous);
242
+ if (chunk.sections.central.tag) {
243
+ chunk.sections.header = SignUtil.readFH(fileBuffer, chunk.sections.central.previous, chunk.sections.central.startIndex - chunk.sections.central.previous);
244
+ if (chunk.sections.header.tag) {
245
+ chunk.tag = true;
246
+ }
247
+ }
248
+ }
249
+ return chunk;
250
+ }
251
+ /**
252
+ * 从后往前读取buffer,读取尾部buffer
253
+ * @param buffer
254
+ * @returns
255
+ */
256
+ static readEOCD(buffer) {
257
+ let chunk;
258
+ if (buffer && buffer.length >= 22) {
259
+ let offset = buffer.length - 22;
260
+ let tag;
261
+ // 从开始位置往前单个字节读取,检查
262
+ while (offset >= 0) {
263
+ tag = buffer.readInt32LE(offset);
264
+ if (tag === 0x6054b50) {
265
+ // 如果找到起始位置
266
+ chunk = {
267
+ tag: true,
268
+ startIndex: offset,
269
+ len: buffer.length - offset,
270
+ previous: buffer.readInt32LE(offset + 16)
271
+ };
272
+ break;
273
+ }
274
+ offset -= 1;
275
+ }
276
+ }
277
+ return chunk;
278
+ }
279
+ /**
280
+ * 读取中部buffer
281
+ * @param buffer
282
+ * @param offset
283
+ * @param size
284
+ */
285
+ static readCD(buffer, offset, size) {
286
+ let chunk;
287
+ if (buffer && buffer.length >= offset) {
288
+ const tag = buffer.readInt32LE(offset);
289
+ // 找到起始位置
290
+ if (tag === 0x2014b50) {
291
+ chunk = {
292
+ tag: true,
293
+ startIndex: offset,
294
+ len: size,
295
+ previous: buffer.readInt32LE(offset + 42)
296
+ };
297
+ }
298
+ }
299
+ return chunk;
300
+ }
301
+ /**
302
+ * 读取前部buffer
303
+ * @param buffer
304
+ * @param offset
305
+ * @param size
306
+ * @returns
307
+ */
308
+ static readFH(buffer, offset, size) {
309
+ let chunk;
310
+ if (buffer && buffer.length >= offset) {
311
+ const tag = buffer.readInt32LE(offset);
312
+ // 找到起始位置
313
+ if (tag === 0x4034b50) {
314
+ chunk = {
315
+ tag: true,
316
+ startIndex: offset,
317
+ len: size,
318
+ previous: -1
319
+ };
320
+ }
321
+ }
322
+ return chunk;
323
+ }
324
+ /**
325
+ * 数据块hash
326
+ * @param buffer
327
+ * @param chunk
328
+ */
329
+ static processChunk(buffer, chunk) {
330
+ const cur = chunk.startIndex;
331
+ const end = chunk.startIndex + chunk.len;
332
+ // 取数据块对应的buffer内容
333
+ const chk = buffer.subarray(cur, end);
334
+ // 创建指定长度Buffer对象,并确保分配内存区域被清零
335
+ const header = Buffer.alloc(5 + chunk.len);
336
+ // 给第一个字节赋值
337
+ header[0] = 0xa5;
338
+ // 从第二个字节位置开始填充,长度为4字节,填充内容为chk.length
339
+ header.writeInt32LE(chk.length, 1);
340
+ // 从第六个开始填充chk的内容
341
+ chk.copy(header, 5);
342
+ // 将buffer进行hash计算并存储到chunk对象上
343
+ const signer = crypto_1.default.createHash('SHA256');
344
+ signer.update(header);
345
+ chunk.sign = signer.digest();
346
+ }
347
+ static signChunk(chunks, privatekey, certificate) {
348
+ const { sections } = chunks;
349
+ // 二进制拼接每个块摘要
350
+ let length = 5;
351
+ if (sections.header.sign) {
352
+ length += sections.header.sign.length;
353
+ }
354
+ if (sections.central.sign) {
355
+ length += sections.central.sign.length;
356
+ }
357
+ if (sections.footer.sign) {
358
+ length += sections.footer.sign.length;
359
+ }
360
+ const wholeData = Buffer.alloc(length);
361
+ let offset = 0;
362
+ wholeData.writeInt8(0x5a, 0);
363
+ wholeData.writeInt32LE(3, 1);
364
+ offset += 5;
365
+ function writeBuffer(buf) {
366
+ buf.copy(wholeData, offset);
367
+ offset += buf.length;
368
+ }
369
+ sections.header.sign && writeBuffer(sections.header.sign);
370
+ sections.central.sign && writeBuffer(sections.central.sign);
371
+ sections.footer.sign && writeBuffer(sections.footer.sign);
372
+ // 计算整体摘要
373
+ const signer = crypto_1.default.createHash('SHA256');
374
+ signer.update(wholeData);
375
+ const signature = signer.digest();
376
+ // 生成sign block, 计算block总长度, 向buf中考入数据
377
+ const signchunk = SignUtil.makeSignChunk(chunks.options, signature, privatekey, certificate);
378
+ chunks.signchunk = SignUtil.saveSignChunk(signchunk);
379
+ }
380
+ static makeSignChunk(options, sign, privatekey, certificate) {
381
+ // 提取公钥
382
+ const cert = Buffer.from(Base64_1.default.unarmor(certificate));
383
+ const c = new jsrsasign_1.default.X509();
384
+ c.readCertPEM(certificate.toString());
385
+ const pubKey = jsrsasign_1.default.KEYUTIL.getPEM(c.subjectPublicKeyRSA);
386
+ // 摘要块
387
+ const digestBuf = Buffer.alloc(sign.length + 12);
388
+ digestBuf.writeInt32LE(sign.length + 8, 0);
389
+ digestBuf.writeInt32LE(0x0103, 4);
390
+ digestBuf.writeInt32LE(sign.length, 8);
391
+ sign.copy(digestBuf, 12);
392
+ const digestBlock = {
393
+ len: digestBuf.length,
394
+ buffer: digestBuf
395
+ };
396
+ // 证书块
397
+ const certBuf = Buffer.alloc(cert.length + 4);
398
+ certBuf.writeInt32LE(cert.length, 0);
399
+ cert.copy(certBuf, 4);
400
+ const certBlock = {
401
+ len: certBuf.length,
402
+ buffer: certBuf
403
+ };
404
+ // 签名数据
405
+ const signdataBlock = {
406
+ len: 12,
407
+ digests: {
408
+ size: 0,
409
+ data: []
410
+ },
411
+ certs: {
412
+ size: 0,
413
+ data: []
414
+ },
415
+ additional: 0
416
+ };
417
+ signdataBlock.digests.data.push(digestBlock);
418
+ signdataBlock.digests.size += digestBlock.len;
419
+ signdataBlock.len += digestBlock.len;
420
+ signdataBlock.certs.data.push(certBlock);
421
+ signdataBlock.certs.size += certBlock.len;
422
+ signdataBlock.len += certBlock.len;
423
+ // 将public.pem转化为der
424
+ const pubbuf = Buffer.from(Base64_1.default.unarmor(pubKey));
425
+ const signBlock = {
426
+ len: 16 + pubbuf.length,
427
+ size: 12 + pubbuf.length,
428
+ signdata: {
429
+ size: 0,
430
+ buffer: null
431
+ },
432
+ signatures: {
433
+ size: 0,
434
+ data: []
435
+ },
436
+ pubkey: {
437
+ size: pubbuf.length,
438
+ buffer: pubbuf
439
+ }
440
+ };
441
+ signBlock.signdata.buffer = SignUtil.makeSignDataBuffer(signdataBlock);
442
+ signBlock.signdata.size = signdataBlock.len;
443
+ signBlock.size += signdataBlock.len;
444
+ signBlock.len += signdataBlock.len;
445
+ // 生成签名
446
+ const signature = SignUtil.callCryptoSignFunction(signBlock.signdata.buffer, privatekey, certificate);
447
+ const signatureBlock = {
448
+ len: signature.length + 12,
449
+ size: signature.length + 8,
450
+ id: 0x0103,
451
+ buffer: signature
452
+ };
453
+ signBlock.signatures.data.push(signatureBlock);
454
+ signBlock.signatures.size += signatureBlock.len;
455
+ signBlock.size += signatureBlock.len;
456
+ signBlock.len += signatureBlock.len;
457
+ const signBlocks = {
458
+ len: 4,
459
+ size: 0,
460
+ data: []
461
+ };
462
+ signBlocks.data.push(signBlock);
463
+ signBlocks.size += signBlock.len;
464
+ signBlocks.len += signBlock.len;
465
+ // 生成key-value
466
+ const kvBlock = {
467
+ len: signBlocks.len + 12,
468
+ size: signBlocks.len + 4,
469
+ id: 0x01000101,
470
+ value: signBlocks
471
+ };
472
+ const signchunk = {
473
+ len: 32,
474
+ size: 24,
475
+ data: []
476
+ };
477
+ signchunk.data.push(kvBlock);
478
+ signchunk.size += kvBlock.len;
479
+ signchunk.len += kvBlock.len;
480
+ // 添加文件列表hash kvblock
481
+ if (options.files) {
482
+ const filehashChunk = SignUtil.signFiles(options.files, privatekey, certificate);
483
+ if (filehashChunk) {
484
+ const filesignBlocks = {
485
+ len: 4,
486
+ size: 0,
487
+ data: []
488
+ };
489
+ filesignBlocks.data.push(filehashChunk);
490
+ filesignBlocks.size += filehashChunk.length;
491
+ filesignBlocks.len += filehashChunk.length;
492
+ const filekvBlock = {
493
+ len: filesignBlocks.len + 12,
494
+ size: filesignBlocks.len + 4,
495
+ id: 0x01000201,
496
+ value: filesignBlocks
497
+ };
498
+ signchunk.data.push(filekvBlock);
499
+ signchunk.size += filekvBlock.len;
500
+ signchunk.len += filekvBlock.len;
501
+ }
502
+ }
503
+ return signchunk;
504
+ }
505
+ static makeSignDataBuffer(block) {
506
+ const buffer = Buffer.alloc(block.len);
507
+ let offset = 0;
508
+ buffer.writeInt32LE(block.digests.size, offset);
509
+ offset += 4;
510
+ block.digests.data.forEach((item) => {
511
+ item.buffer.copy(buffer, offset);
512
+ offset += item.len;
513
+ });
514
+ buffer.writeInt32LE(block.certs.size, offset);
515
+ offset += 4;
516
+ block.certs.data.forEach((item) => {
517
+ item.buffer.copy(buffer, offset);
518
+ offset += item.len;
519
+ });
520
+ buffer.writeInt32LE(block.additional, offset);
521
+ return buffer;
522
+ }
523
+ static callCryptoSignFunction(buffer, prikey, certpem) {
524
+ let signature = null;
525
+ if (!Signer_1.default.getRemoteCryptoSignFunction()) {
526
+ // 使用默认
527
+ signature = Signer_1.default.defaultCryptoSignFunction(buffer, prikey);
528
+ }
529
+ else {
530
+ // 使用外部:传递原文件内容、证书内容
531
+ const remoteCryptoSignFunction = Signer_1.default.getRemoteCryptoSignFunction();
532
+ signature = remoteCryptoSignFunction(buffer, certpem);
533
+ }
534
+ return signature;
535
+ }
536
+ /**
537
+ * 加签名文件
538
+ * @param filehashs
539
+ * @param prikey
540
+ * @param certpem
541
+ */
542
+ static signFiles(filehashs, prikey, certpem) {
543
+ const chunk = {
544
+ len: 8,
545
+ size: 4,
546
+ digests: [],
547
+ sign: null
548
+ };
549
+ // 生成hash块
550
+ filehashs.forEach((item) => {
551
+ // name hash
552
+ const namehash = CRC32_1.default.digest(item.name);
553
+ // 计算大小
554
+ const sum = 6 + item.hash.length;
555
+ const chk = Buffer.alloc(sum);
556
+ let offset = 0;
557
+ chk.writeInt32LE(namehash, offset);
558
+ offset += 4;
559
+ chk.writeInt16LE(item.hash.length, offset);
560
+ offset += 2;
561
+ item.hash.copy(chk, offset);
562
+ offset += item.hash.length;
563
+ chunk.digests.push(chk);
564
+ chunk.size += sum;
565
+ chunk.len += sum;
566
+ });
567
+ // 生成整体签名
568
+ SignUtil.signDigestChunk(chunk, prikey, certpem);
569
+ // 写入文件
570
+ return SignUtil.saveDigestChunk(chunk);
571
+ }
572
+ static signDigestChunk(chunk, prikey, certpem) {
573
+ const buf = Buffer.alloc(chunk.size);
574
+ let offset = 0;
575
+ buf.writeInt32LE(0x0103, offset);
576
+ offset += 4;
577
+ chunk.digests.forEach((chk) => {
578
+ chk.copy(buf, offset);
579
+ offset += chk.length;
580
+ });
581
+ chunk.digests = buf.slice();
582
+ // 生成签名
583
+ const signature = SignUtil.callCryptoSignFunction(buf, prikey, certpem);
584
+ chunk.sign = {
585
+ len: 12 + signature.length,
586
+ size: 8 + signature.length,
587
+ id: 0x0103,
588
+ data: signature
589
+ };
590
+ chunk.len += chunk.sign.len;
591
+ }
592
+ static saveDigestChunk(chunk) {
593
+ // 创建新buffer
594
+ const newBuffer = Buffer.alloc(chunk.len);
595
+ let offset = 0;
596
+ newBuffer.writeInt32LE(chunk.size, offset);
597
+ offset += 4;
598
+ // 文件hash列表
599
+ chunk.digests.copy(newBuffer, offset);
600
+ offset += chunk.digests.length;
601
+ // 写入签名
602
+ newBuffer.writeInt32LE(chunk.sign.size, offset);
603
+ offset += 4;
604
+ newBuffer.writeInt32LE(chunk.sign.id, offset);
605
+ offset += 4;
606
+ newBuffer.writeInt32LE(chunk.sign.data.length, offset);
607
+ offset += 4;
608
+ chunk.sign.data.copy(newBuffer, offset);
609
+ offset += chunk.sign.data.length;
610
+ return newBuffer;
611
+ }
612
+ static saveSignChunk(signchunk) {
613
+ const buffer = Buffer.alloc(signchunk.len);
614
+ let offset = 0;
615
+ // 大小
616
+ buffer.writeInt32LE(signchunk.size, offset);
617
+ offset += 4;
618
+ buffer.writeInt32LE(0, offset);
619
+ offset += 4;
620
+ // key-value
621
+ signchunk.data.forEach((kv) => {
622
+ buffer.writeInt32LE(kv.size, offset);
623
+ offset += 4;
624
+ buffer.writeInt32LE(0, offset);
625
+ offset += 4;
626
+ buffer.writeInt32LE(kv.id, offset);
627
+ offset += 4;
628
+ // value
629
+ buffer.writeInt32LE(kv.value.size, offset);
630
+ offset += 4;
631
+ if (kv.id === 0x01000101) {
632
+ // sign blocks
633
+ kv.value.data.forEach((block) => {
634
+ buffer.writeInt32LE(block.size, offset);
635
+ offset += 4;
636
+ // signdata
637
+ buffer.writeInt32LE(block.signdata.size, offset);
638
+ offset += 4;
639
+ block.signdata.buffer.copy(buffer, offset);
640
+ offset += block.signdata.buffer.length;
641
+ // signature
642
+ buffer.writeInt32LE(block.signatures.size, offset);
643
+ offset += 4;
644
+ block.signatures.data.forEach((signature) => {
645
+ buffer.writeInt32LE(signature.size, offset);
646
+ offset += 4;
647
+ buffer.writeInt32LE(signature.id, offset);
648
+ offset += 4;
649
+ buffer.writeInt32LE(signature.buffer.length, offset);
650
+ offset += 4;
651
+ signature.buffer.copy(buffer, offset);
652
+ offset += signature.buffer.length;
653
+ });
654
+ // pubkey
655
+ buffer.writeInt32LE(block.pubkey.size, offset);
656
+ offset += 4;
657
+ block.pubkey.buffer.copy(buffer, offset);
658
+ offset += block.pubkey.buffer.length;
659
+ });
660
+ }
661
+ else if (kv.id === 0x01000201) {
662
+ // files blocks
663
+ kv.value.data.forEach((block) => {
664
+ block.copy(buffer, offset);
665
+ offset += block.length;
666
+ });
667
+ }
668
+ });
669
+ // 大小
670
+ buffer.writeInt32LE(signchunk.size, offset);
671
+ offset += 4;
672
+ buffer.writeInt32LE(0, offset);
673
+ offset += 4;
674
+ // 魔法值
675
+ const magic = Buffer.from(SignUtil.SigMagic);
676
+ magic.copy(buffer, offset);
677
+ return buffer;
678
+ }
679
+ static saveChunk(buf, chunks) {
680
+ // 创建新buffer
681
+ const newBuffer = Buffer.alloc(buf.length + chunks.signchunk.length);
682
+ let offset = 0;
683
+ const sections = chunks.sections;
684
+ // 拷贝header
685
+ buf.copy(newBuffer, offset, sections.header.startIndex, sections.header.startIndex + sections.header.len);
686
+ offset += sections.header.len;
687
+ // 拷贝signblock
688
+ chunks.signchunk.copy(newBuffer, offset);
689
+ offset += chunks.signchunk.length;
690
+ // 拷贝central
691
+ buf.copy(newBuffer, offset, sections.central.startIndex, sections.central.startIndex + sections.central.len);
692
+ offset += sections.central.len;
693
+ // 修改eocd
694
+ buf.writeInt32LE(sections.central.startIndex + chunks.signchunk.length, sections.footer.startIndex + 16);
695
+ // 拷贝eocd
696
+ buf.copy(newBuffer, offset, sections.footer.startIndex, sections.footer.startIndex + sections.footer.len);
697
+ offset += sections.footer.len;
698
+ return newBuffer;
699
+ }
700
+ /**
701
+ * 过滤掉文件夹和META文件
702
+ * @param item
703
+ * @returns
704
+ */
705
+ static fileFilter(item) {
706
+ const path = item.path;
707
+ return !path.endsWith('/') && path !== ZipUtil_1.default.CERT_PATH;
708
+ }
709
+ }
710
+ SignUtil.SigMagic = 'RPK Sig Block 42';
711
+ exports.default = SignUtil;
712
+
713
+ //# sourceMappingURL=SignUtil.js.map