@trustchex/react-native-sdk 1.381.0 → 1.464.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 (204) hide show
  1. package/android/src/main/java/com/trustchex/reactnativesdk/TrustchexSDKModule.kt +2 -8
  2. package/android/src/main/java/com/trustchex/reactnativesdk/camera/TrustchexCameraView.kt +60 -13
  3. package/android/src/main/java/com/trustchex/reactnativesdk/mlkit/MLKitModule.kt +1 -1
  4. package/ios/Camera/TrustchexCameraView.swift +10 -13
  5. package/ios/MLKit/MLKitModule.swift +1 -1
  6. package/lib/module/Screens/Debug/BarcodeTestScreen.js +308 -0
  7. package/lib/module/Screens/Debug/MRZTestScreen.js +105 -13
  8. package/lib/module/Screens/Debug/NFCScanTestScreen.js +635 -0
  9. package/lib/module/Screens/Dynamic/ContractAcceptanceScreen.js +49 -32
  10. package/lib/module/Screens/Dynamic/IdentityDocumentEIDScanningScreen.js +22 -4
  11. package/lib/module/Screens/Dynamic/IdentityDocumentScanningScreen.js +5 -0
  12. package/lib/module/Screens/Dynamic/LivenessDetectionScreen.js +126 -27
  13. package/lib/module/Screens/Dynamic/VerbalConsentScreen.js +1079 -0
  14. package/lib/module/Screens/Dynamic/VideoCallScreen.js +678 -0
  15. package/lib/module/Screens/Static/OTPVerificationScreen.js +6 -0
  16. package/lib/module/Screens/Static/QrCodeScanningScreen.js +7 -1
  17. package/lib/module/Screens/Static/ResultScreen.js +154 -34
  18. package/lib/module/Screens/Static/VerificationSessionCheckScreen.js +59 -51
  19. package/lib/module/Shared/Animations/recording.json +1 -0
  20. package/lib/module/Shared/Animations/video-call.json +1 -0
  21. package/lib/module/Shared/Components/DebugNavigationPanel.js +231 -67
  22. package/lib/module/Shared/Components/EIDScanner.js +213 -112
  23. package/lib/module/Shared/Components/IdentityDocumentCamera.flows.js +5 -3
  24. package/lib/module/Shared/Components/IdentityDocumentCamera.js +77 -39
  25. package/lib/module/Shared/Components/IdentityDocumentCamera.utils.js +13 -4
  26. package/lib/module/Shared/Components/NavigationManager.js +39 -19
  27. package/lib/module/Shared/Contexts/AppContext.js +1 -0
  28. package/lib/module/Shared/EIDReader/aesSecureMessagingWrapper.js +51 -0
  29. package/lib/module/Shared/EIDReader/apduLevelPACECapable.js +3 -0
  30. package/lib/module/Shared/EIDReader/bacKey.js +16 -2
  31. package/lib/module/Shared/EIDReader/eidReader.js +354 -13
  32. package/lib/module/Shared/EIDReader/eidService.js +25 -1
  33. package/lib/module/Shared/EIDReader/nfcManagerCardService.js +4 -7
  34. package/lib/module/Shared/EIDReader/paceInfo.js +85 -0
  35. package/lib/module/Shared/EIDReader/paceKeySpec.js +51 -0
  36. package/lib/module/Shared/EIDReader/protocol/paceAPDUSender.js +100 -0
  37. package/lib/module/Shared/EIDReader/protocol/paceProtocol.js +655 -0
  38. package/lib/module/Shared/EIDReader/protocol/paceResult.js +37 -0
  39. package/lib/module/Shared/EIDReader/secureMessagingWrapper.js +27 -4
  40. package/lib/module/Shared/EIDReader/smartcards/commandAPDU.js +2 -1
  41. package/lib/module/Shared/EIDReader/tlv/tlv.helpers.js +1 -1
  42. package/lib/module/Shared/EIDReader/tlv/tlv.utils.js +6 -3
  43. package/lib/module/Shared/EIDReader/utils/aesCrypto.utils.js +189 -0
  44. package/lib/module/Shared/Libs/SignalingClient.js +128 -0
  45. package/lib/module/Shared/Libs/analytics.utils.js +8 -0
  46. package/lib/module/Shared/Libs/contains.js +1 -40
  47. package/lib/module/Shared/Libs/country-display.utils.js +34 -0
  48. package/lib/module/Shared/Libs/deeplink.utils.js +9 -1
  49. package/lib/module/Shared/Libs/demo.utils.js +8 -0
  50. package/lib/module/Shared/Libs/http-client.js +9 -0
  51. package/lib/module/Shared/Libs/mrz.utils.js +3 -2
  52. package/lib/module/Shared/Libs/promise.utils.js +16 -2
  53. package/lib/module/Shared/Libs/status-bar.utils.js +23 -0
  54. package/lib/module/Shared/Services/DataUploadService.js +294 -0
  55. package/lib/module/Shared/Services/VideoSessionService.js +156 -0
  56. package/lib/module/Shared/Services/WebRTCService.js +510 -0
  57. package/lib/module/Shared/Types/analytics.types.js +4 -0
  58. package/lib/module/Translation/Resources/en.js +61 -2
  59. package/lib/module/Translation/Resources/tr.js +61 -2
  60. package/lib/module/Trustchex.js +64 -20
  61. package/lib/module/version.js +1 -1
  62. package/lib/typescript/src/Screens/Debug/BarcodeTestScreen.d.ts +3 -0
  63. package/lib/typescript/src/Screens/Debug/BarcodeTestScreen.d.ts.map +1 -0
  64. package/lib/typescript/src/Screens/Debug/MRZTestScreen.d.ts.map +1 -1
  65. package/lib/typescript/src/Screens/Debug/NFCScanTestScreen.d.ts +3 -0
  66. package/lib/typescript/src/Screens/Debug/NFCScanTestScreen.d.ts.map +1 -0
  67. package/lib/typescript/src/Screens/Dynamic/ContractAcceptanceScreen.d.ts.map +1 -1
  68. package/lib/typescript/src/Screens/Dynamic/IdentityDocumentEIDScanningScreen.d.ts.map +1 -1
  69. package/lib/typescript/src/Screens/Dynamic/IdentityDocumentScanningScreen.d.ts.map +1 -1
  70. package/lib/typescript/src/Screens/Dynamic/LivenessDetectionScreen.d.ts.map +1 -1
  71. package/lib/typescript/src/Screens/Dynamic/VerbalConsentScreen.d.ts +3 -0
  72. package/lib/typescript/src/Screens/Dynamic/VerbalConsentScreen.d.ts.map +1 -0
  73. package/lib/typescript/src/Screens/Dynamic/VideoCallScreen.d.ts +3 -0
  74. package/lib/typescript/src/Screens/Dynamic/VideoCallScreen.d.ts.map +1 -0
  75. package/lib/typescript/src/Screens/Static/OTPVerificationScreen.d.ts.map +1 -1
  76. package/lib/typescript/src/Screens/Static/QrCodeScanningScreen.d.ts.map +1 -1
  77. package/lib/typescript/src/Screens/Static/ResultScreen.d.ts.map +1 -1
  78. package/lib/typescript/src/Screens/Static/VerificationSessionCheckScreen.d.ts.map +1 -1
  79. package/lib/typescript/src/Shared/Components/DebugNavigationPanel.d.ts.map +1 -1
  80. package/lib/typescript/src/Shared/Components/EIDScanner.d.ts.map +1 -1
  81. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts.map +1 -1
  82. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.flows.d.ts +1 -1
  83. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.flows.d.ts.map +1 -1
  84. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.utils.d.ts +5 -0
  85. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.utils.d.ts.map +1 -1
  86. package/lib/typescript/src/Shared/Components/NavigationManager.d.ts.map +1 -1
  87. package/lib/typescript/src/Shared/Contexts/AppContext.d.ts +1 -0
  88. package/lib/typescript/src/Shared/Contexts/AppContext.d.ts.map +1 -1
  89. package/lib/typescript/src/Shared/EIDReader/aesSecureMessagingWrapper.d.ts +18 -0
  90. package/lib/typescript/src/Shared/EIDReader/aesSecureMessagingWrapper.d.ts.map +1 -0
  91. package/lib/typescript/src/Shared/EIDReader/apduLevelPACECapable.d.ts +23 -0
  92. package/lib/typescript/src/Shared/EIDReader/apduLevelPACECapable.d.ts.map +1 -0
  93. package/lib/typescript/src/Shared/EIDReader/bacKey.d.ts +6 -0
  94. package/lib/typescript/src/Shared/EIDReader/bacKey.d.ts.map +1 -1
  95. package/lib/typescript/src/Shared/EIDReader/eidReader.d.ts.map +1 -1
  96. package/lib/typescript/src/Shared/EIDReader/eidService.d.ts +9 -0
  97. package/lib/typescript/src/Shared/EIDReader/eidService.d.ts.map +1 -1
  98. package/lib/typescript/src/Shared/EIDReader/nfcManagerCardService.d.ts.map +1 -1
  99. package/lib/typescript/src/Shared/EIDReader/paceInfo.d.ts +50 -0
  100. package/lib/typescript/src/Shared/EIDReader/paceInfo.d.ts.map +1 -0
  101. package/lib/typescript/src/Shared/EIDReader/paceKeySpec.d.ts +30 -0
  102. package/lib/typescript/src/Shared/EIDReader/paceKeySpec.d.ts.map +1 -0
  103. package/lib/typescript/src/Shared/EIDReader/protocol/paceAPDUSender.d.ts +17 -0
  104. package/lib/typescript/src/Shared/EIDReader/protocol/paceAPDUSender.d.ts.map +1 -0
  105. package/lib/typescript/src/Shared/EIDReader/protocol/paceProtocol.d.ts +105 -0
  106. package/lib/typescript/src/Shared/EIDReader/protocol/paceProtocol.d.ts.map +1 -0
  107. package/lib/typescript/src/Shared/EIDReader/protocol/paceResult.d.ts +24 -0
  108. package/lib/typescript/src/Shared/EIDReader/protocol/paceResult.d.ts.map +1 -0
  109. package/lib/typescript/src/Shared/EIDReader/secureMessagingWrapper.d.ts +15 -0
  110. package/lib/typescript/src/Shared/EIDReader/secureMessagingWrapper.d.ts.map +1 -1
  111. package/lib/typescript/src/Shared/EIDReader/smartcards/commandAPDU.d.ts.map +1 -1
  112. package/lib/typescript/src/Shared/EIDReader/tlv/tlv.utils.d.ts.map +1 -1
  113. package/lib/typescript/src/Shared/EIDReader/utils/aesCrypto.utils.d.ts +39 -0
  114. package/lib/typescript/src/Shared/EIDReader/utils/aesCrypto.utils.d.ts.map +1 -0
  115. package/lib/typescript/src/Shared/Libs/SignalingClient.d.ts +24 -0
  116. package/lib/typescript/src/Shared/Libs/SignalingClient.d.ts.map +1 -0
  117. package/lib/typescript/src/Shared/Libs/analytics.utils.d.ts.map +1 -1
  118. package/lib/typescript/src/Shared/Libs/contains.d.ts +0 -7
  119. package/lib/typescript/src/Shared/Libs/contains.d.ts.map +1 -1
  120. package/lib/typescript/src/Shared/Libs/country-display.utils.d.ts +2 -0
  121. package/lib/typescript/src/Shared/Libs/country-display.utils.d.ts.map +1 -0
  122. package/lib/typescript/src/Shared/Libs/deeplink.utils.d.ts.map +1 -1
  123. package/lib/typescript/src/Shared/Libs/demo.utils.d.ts.map +1 -1
  124. package/lib/typescript/src/Shared/Libs/http-client.d.ts +1 -1
  125. package/lib/typescript/src/Shared/Libs/http-client.d.ts.map +1 -1
  126. package/lib/typescript/src/Shared/Libs/mrz.utils.d.ts.map +1 -1
  127. package/lib/typescript/src/Shared/Libs/promise.utils.d.ts.map +1 -1
  128. package/lib/typescript/src/Shared/Libs/status-bar.utils.d.ts +9 -0
  129. package/lib/typescript/src/Shared/Libs/status-bar.utils.d.ts.map +1 -0
  130. package/lib/typescript/src/Shared/Services/DataUploadService.d.ts +25 -0
  131. package/lib/typescript/src/Shared/Services/DataUploadService.d.ts.map +1 -0
  132. package/lib/typescript/src/Shared/Services/VideoSessionService.d.ts +33 -0
  133. package/lib/typescript/src/Shared/Services/VideoSessionService.d.ts.map +1 -0
  134. package/lib/typescript/src/Shared/Services/WebRTCService.d.ts +58 -0
  135. package/lib/typescript/src/Shared/Services/WebRTCService.d.ts.map +1 -0
  136. package/lib/typescript/src/Shared/Types/analytics.types.d.ts +4 -0
  137. package/lib/typescript/src/Shared/Types/analytics.types.d.ts.map +1 -1
  138. package/lib/typescript/src/Shared/Types/identificationInfo.d.ts +13 -1
  139. package/lib/typescript/src/Shared/Types/identificationInfo.d.ts.map +1 -1
  140. package/lib/typescript/src/Translation/Resources/en.d.ts +60 -1
  141. package/lib/typescript/src/Translation/Resources/en.d.ts.map +1 -1
  142. package/lib/typescript/src/Translation/Resources/tr.d.ts +60 -1
  143. package/lib/typescript/src/Translation/Resources/tr.d.ts.map +1 -1
  144. package/lib/typescript/src/Trustchex.d.ts.map +1 -1
  145. package/lib/typescript/src/version.d.ts +1 -1
  146. package/package.json +35 -5
  147. package/src/Screens/Debug/BarcodeTestScreen.tsx +317 -0
  148. package/src/Screens/Debug/MRZTestScreen.tsx +107 -13
  149. package/src/Screens/Debug/NFCScanTestScreen.tsx +692 -0
  150. package/src/Screens/Dynamic/ContractAcceptanceScreen.tsx +58 -35
  151. package/src/Screens/Dynamic/IdentityDocumentEIDScanningScreen.tsx +27 -4
  152. package/src/Screens/Dynamic/IdentityDocumentScanningScreen.tsx +6 -0
  153. package/src/Screens/Dynamic/LivenessDetectionScreen.tsx +156 -27
  154. package/src/Screens/Dynamic/VerbalConsentScreen.tsx +1401 -0
  155. package/src/Screens/Dynamic/VideoCallScreen.tsx +766 -0
  156. package/src/Screens/Static/OTPVerificationScreen.tsx +6 -0
  157. package/src/Screens/Static/QrCodeScanningScreen.tsx +7 -1
  158. package/src/Screens/Static/ResultScreen.tsx +235 -48
  159. package/src/Screens/Static/VerificationSessionCheckScreen.tsx +67 -72
  160. package/src/Shared/Animations/recording.json +1 -0
  161. package/src/Shared/Animations/video-call.json +1 -0
  162. package/src/Shared/Components/DebugNavigationPanel.tsx +252 -51
  163. package/src/Shared/Components/EIDScanner.tsx +223 -116
  164. package/src/Shared/Components/IdentityDocumentCamera.flows.ts +7 -4
  165. package/src/Shared/Components/IdentityDocumentCamera.tsx +224 -188
  166. package/src/Shared/Components/IdentityDocumentCamera.utils.ts +13 -4
  167. package/src/Shared/Components/NavigationManager.tsx +41 -19
  168. package/src/Shared/Contexts/AppContext.ts +2 -0
  169. package/src/Shared/EIDReader/aesSecureMessagingWrapper.ts +69 -0
  170. package/src/Shared/EIDReader/apduLevelPACECapable.ts +34 -0
  171. package/src/Shared/EIDReader/bacKey.ts +24 -8
  172. package/src/Shared/EIDReader/eidReader.ts +398 -12
  173. package/src/Shared/EIDReader/eidService.ts +49 -1
  174. package/src/Shared/EIDReader/nfcManagerCardService.ts +4 -6
  175. package/src/Shared/EIDReader/paceInfo.ts +159 -0
  176. package/src/Shared/EIDReader/paceKeySpec.ts +56 -0
  177. package/src/Shared/EIDReader/protocol/paceAPDUSender.ts +163 -0
  178. package/src/Shared/EIDReader/protocol/paceProtocol.ts +946 -0
  179. package/src/Shared/EIDReader/protocol/paceResult.ts +62 -0
  180. package/src/Shared/EIDReader/secureMessagingWrapper.ts +28 -10
  181. package/src/Shared/EIDReader/smartcards/commandAPDU.ts +2 -1
  182. package/src/Shared/EIDReader/tlv/tlv.helpers.ts +1 -1
  183. package/src/Shared/EIDReader/tlv/tlv.utils.ts +8 -5
  184. package/src/Shared/EIDReader/utils/aesCrypto.utils.ts +217 -0
  185. package/src/Shared/Libs/SignalingClient.ts +189 -0
  186. package/src/Shared/Libs/analytics.utils.ts +8 -0
  187. package/src/Shared/Libs/contains.ts +0 -53
  188. package/src/Shared/Libs/country-display.utils.ts +55 -0
  189. package/src/Shared/Libs/crypto.utils.ts +2 -2
  190. package/src/Shared/Libs/deeplink.utils.ts +12 -1
  191. package/src/Shared/Libs/demo.utils.ts +10 -0
  192. package/src/Shared/Libs/http-client.ts +19 -1
  193. package/src/Shared/Libs/mrz.utils.ts +3 -2
  194. package/src/Shared/Libs/promise.utils.ts +16 -2
  195. package/src/Shared/Libs/status-bar.utils.ts +21 -0
  196. package/src/Shared/Services/DataUploadService.ts +395 -0
  197. package/src/Shared/Services/VideoSessionService.ts +190 -0
  198. package/src/Shared/Services/WebRTCService.ts +636 -0
  199. package/src/Shared/Types/analytics.types.ts +4 -0
  200. package/src/Shared/Types/identificationInfo.ts +16 -1
  201. package/src/Translation/Resources/en.ts +88 -3
  202. package/src/Translation/Resources/tr.ts +89 -3
  203. package/src/Trustchex.tsx +65 -19
  204. package/src/version.ts +1 -1
@@ -1,4 +1,5 @@
1
1
  import { BACKey } from './bacKey';
2
+ import { PACEKeySpec } from './paceKeySpec';
2
3
  import { NFCManagerCardService } from './nfcManagerCardService';
3
4
  import { EIDService } from './eidService';
4
5
  import { DG1File } from './lds/icao/dg1File';
@@ -8,6 +9,283 @@ import { Buffer } from 'buffer';
8
9
  import { MRZInfo } from './lds/icao/mrzInfo';
9
10
  import { InputStream } from './java/inputStream';
10
11
 
12
+ // --- Minimal PNG encoder (pure JS, no native deps) ---
13
+ // Uses deflate stored (uncompressed) blocks for O(n) encoding speed.
14
+ // A naive DCT-based JPEG encoder would be O(n²) and freeze the JS thread
15
+ // on real passport photos (400×500+ pixels).
16
+
17
+ /** Standard CRC32 lookup table */
18
+ const CRC_TABLE = new Uint32Array(256);
19
+ for (let n = 0; n < 256; n++) {
20
+ let c = n;
21
+ for (let k = 0; k < 8; k++) {
22
+ c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
23
+ }
24
+ CRC_TABLE[n] = c;
25
+ }
26
+
27
+ function crc32(data: Uint8Array): number {
28
+ let crc = 0xffffffff;
29
+ for (let i = 0; i < data.length; i++) {
30
+ crc = CRC_TABLE[(crc ^ data[i]!) & 0xff]! ^ (crc >>> 8);
31
+ }
32
+ return (crc ^ 0xffffffff) >>> 0;
33
+ }
34
+
35
+ function adler32(data: Uint8Array): number {
36
+ let a = 1;
37
+ let b = 0;
38
+ for (let i = 0; i < data.length; i++) {
39
+ a = (a + data[i]!) % 65521;
40
+ b = (b + a) % 65521;
41
+ }
42
+ return ((b << 16) | a) >>> 0;
43
+ }
44
+
45
+ function writeU32BE(arr: Uint8Array, offset: number, val: number) {
46
+ arr[offset] = (val >>> 24) & 0xff;
47
+ arr[offset + 1] = (val >>> 16) & 0xff;
48
+ arr[offset + 2] = (val >>> 8) & 0xff;
49
+ arr[offset + 3] = val & 0xff;
50
+ }
51
+
52
+ /**
53
+ * Encode raw RGB/RGBA pixels as an uncompressed PNG.
54
+ * Uses deflate stored blocks (no compression) for maximum compatibility.
55
+ */
56
+ function pixelsToPng(
57
+ pixels: Uint8ClampedArray | Uint8Array,
58
+ width: number,
59
+ height: number,
60
+ channels: number
61
+ ): Uint8Array {
62
+ // Build raw scanlines: filter byte (0) + RGB data per row
63
+ const rawRowLen = 1 + width * 3; // filter byte + RGB
64
+ const rawData = new Uint8Array(rawRowLen * height);
65
+ for (let y = 0; y < height; y++) {
66
+ const rowOff = y * rawRowLen;
67
+ rawData[rowOff] = 0; // filter: None
68
+ for (let x = 0; x < width; x++) {
69
+ const srcIdx = (y * width + x) * channels;
70
+ const dstIdx = rowOff + 1 + x * 3;
71
+ rawData[dstIdx] = pixels[srcIdx]!; // R
72
+ rawData[dstIdx + 1] = pixels[srcIdx + 1]!; // G
73
+ rawData[dstIdx + 2] = pixels[srcIdx + 2]!; // B
74
+ }
75
+ }
76
+
77
+ // Wrap raw data in zlib stored (uncompressed) format
78
+ const MAX_BLOCK = 65535;
79
+ const numBlocks = Math.ceil(rawData.length / MAX_BLOCK) || 1;
80
+ const zlibSize = 2 + rawData.length + numBlocks * 5 + 4;
81
+ const zlib = new Uint8Array(zlibSize);
82
+ let zOff = 0;
83
+ // zlib header: CMF=0x78 (deflate, 32K window), FLG=0x01 (check bits, no dict, level 0)
84
+ zlib[zOff++] = 0x78;
85
+ zlib[zOff++] = 0x01;
86
+
87
+ let remaining = rawData.length;
88
+ let srcOff = 0;
89
+ while (remaining > 0) {
90
+ const blockLen = Math.min(remaining, MAX_BLOCK);
91
+ const isFinal = remaining <= MAX_BLOCK ? 1 : 0;
92
+ zlib[zOff++] = isFinal; // BFINAL + BTYPE=00 (stored)
93
+ zlib[zOff++] = blockLen & 0xff;
94
+ zlib[zOff++] = (blockLen >>> 8) & 0xff;
95
+ zlib[zOff++] = ~blockLen & 0xff;
96
+ zlib[zOff++] = (~blockLen >>> 8) & 0xff;
97
+ zlib.set(rawData.subarray(srcOff, srcOff + blockLen), zOff);
98
+ zOff += blockLen;
99
+ srcOff += blockLen;
100
+ remaining -= blockLen;
101
+ }
102
+ // Adler32 of uncompressed data
103
+ const adl = adler32(rawData);
104
+ writeU32BE(zlib, zOff, adl);
105
+ zOff += 4;
106
+ const zlibData = zlib.subarray(0, zOff);
107
+
108
+ // Build PNG chunks
109
+ const PNG_SIG = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]);
110
+
111
+ function makeChunk(type: string, data: Uint8Array): Uint8Array {
112
+ const chunk = new Uint8Array(4 + 4 + data.length + 4);
113
+ writeU32BE(chunk, 0, data.length);
114
+ chunk[4] = type.charCodeAt(0);
115
+ chunk[5] = type.charCodeAt(1);
116
+ chunk[6] = type.charCodeAt(2);
117
+ chunk[7] = type.charCodeAt(3);
118
+ chunk.set(data, 8);
119
+ const crcInput = chunk.subarray(4, 8 + data.length);
120
+ writeU32BE(chunk, 8 + data.length, crc32(crcInput));
121
+ return chunk;
122
+ }
123
+
124
+ // IHDR: width, height, bit depth 8, color type 2 (RGB)
125
+ const ihdrData = new Uint8Array(13);
126
+ writeU32BE(ihdrData, 0, width);
127
+ writeU32BE(ihdrData, 4, height);
128
+ ihdrData[8] = 8; // bit depth
129
+ ihdrData[9] = 2; // color type: RGB
130
+ ihdrData[10] = 0; // compression
131
+ ihdrData[11] = 0; // filter
132
+ ihdrData[12] = 0; // interlace
133
+
134
+ const ihdrChunk = makeChunk('IHDR', ihdrData);
135
+ const idatChunk = makeChunk('IDAT', zlibData);
136
+ const iendChunk = makeChunk('IEND', new Uint8Array(0));
137
+
138
+ const png = new Uint8Array(
139
+ PNG_SIG.length + ihdrChunk.length + idatChunk.length + iendChunk.length
140
+ );
141
+ let off = 0;
142
+ png.set(PNG_SIG, off);
143
+ off += PNG_SIG.length;
144
+ png.set(ihdrChunk, off);
145
+ off += ihdrChunk.length;
146
+ png.set(idatChunk, off);
147
+ off += idatChunk.length;
148
+ png.set(iendChunk, off);
149
+ return png;
150
+ }
151
+
152
+ /**
153
+ * If the image is JPEG 2000, decode and convert to PNG so React Native can display it.
154
+ * Returns { base64, mimeType } with the converted image, or the original if not JP2.
155
+ */
156
+ function convertJP2IfNeeded(
157
+ imageBuffer: Buffer,
158
+ mimeType: string
159
+ ): { base64: string; mimeType: string } {
160
+ if (mimeType !== 'image/jp2') {
161
+ return { base64: imageBuffer.toString('base64'), mimeType };
162
+ }
163
+
164
+ console.debug('[EID] Face image is JP2, attempting conversion…');
165
+ try {
166
+ // Lazy-load jpeg2000 to avoid crashing if it fails to import
167
+ const { JpxImage } = require('jpeg2000');
168
+ const jpx = new JpxImage();
169
+ jpx.parse(imageBuffer);
170
+ const tile = jpx.tiles[0];
171
+ console.debug(
172
+ `[EID] JP2 decoded: ${tile.width}x${tile.height}, ${jpx.componentsCount} channels, ${tile.items.length} bytes`
173
+ );
174
+ const pngBytes = pixelsToPng(
175
+ tile.items,
176
+ tile.width,
177
+ tile.height,
178
+ jpx.componentsCount
179
+ );
180
+ const pngBase64 = Buffer.from(pngBytes).toString('base64');
181
+ console.debug(
182
+ `[EID] Converted JP2 → PNG (${pngBytes.length} bytes, ${pngBase64.length} base64 chars)`
183
+ );
184
+ return { base64: pngBase64, mimeType: 'image/png' };
185
+ } catch (err) {
186
+ console.debug('[EID] JP2 conversion failed:', err);
187
+ return { base64: imageBuffer.toString('base64'), mimeType };
188
+ }
189
+ }
190
+
191
+ /**
192
+ * Try to parse PACE OID and parameter ID from EF.CardAccess data.
193
+ * Returns null if no PACE info is found.
194
+ */
195
+ function parsePACEInfoFromCardAccess(
196
+ data: Buffer
197
+ ): { oid: string; parameterId: number } | null {
198
+ try {
199
+ // EF.CardAccess is a SET of SecurityInfo sequences (ASN.1 DER)
200
+ // Each SecurityInfo: SEQUENCE { OID, INTEGER (version), optional INTEGER (parameterId) }
201
+ let offset = 0;
202
+ if (data[offset] === 0x31) {
203
+ // SET tag
204
+ offset++;
205
+ const setLen = readASN1Length(data, offset);
206
+ offset = setLen.nextOffset;
207
+ }
208
+
209
+ while (offset < data.length) {
210
+ if (data[offset] !== 0x30) break; // SEQUENCE tag
211
+ offset++;
212
+ const seqLen = readASN1Length(data, offset);
213
+ const seqEnd = seqLen.nextOffset + seqLen.length;
214
+ offset = seqLen.nextOffset;
215
+
216
+ // Read OID
217
+ if (data[offset] !== 0x06) {
218
+ offset = seqEnd;
219
+ continue;
220
+ }
221
+ offset++;
222
+ const oidLen = readASN1Length(data, offset);
223
+ offset = oidLen.nextOffset;
224
+ const oidBytes = data.subarray(offset, offset + oidLen.length);
225
+ const oid = decodeOID(oidBytes);
226
+ offset += oidLen.length;
227
+
228
+ // Check if this is a PACE OID
229
+ if (oid.startsWith('0.4.0.127.0.7.2.2.4.')) {
230
+ // Read version (INTEGER)
231
+ let parameterId = 13; // default brainpoolP256r1
232
+ if (offset < seqEnd && data[offset] === 0x02) {
233
+ offset++;
234
+ const intLen = readASN1Length(data, offset);
235
+ offset = intLen.nextOffset + intLen.length;
236
+ }
237
+ // Read optional parameterId (INTEGER)
238
+ if (offset < seqEnd && data[offset] === 0x02) {
239
+ offset++;
240
+ const intLen = readASN1Length(data, offset);
241
+ offset = intLen.nextOffset;
242
+ parameterId = 0;
243
+ for (let i = 0; i < intLen.length; i++) {
244
+ parameterId = (parameterId << 8) | data[offset + i];
245
+ }
246
+ }
247
+ return { oid, parameterId };
248
+ }
249
+
250
+ offset = seqEnd;
251
+ }
252
+ } catch {
253
+ // Failed to parse, PACE not available
254
+ }
255
+ return null;
256
+ }
257
+
258
+ function readASN1Length(
259
+ data: Buffer,
260
+ offset: number
261
+ ): { length: number; nextOffset: number } {
262
+ const firstByte = data[offset];
263
+ if ((firstByte & 0x80) === 0) {
264
+ return { length: firstByte, nextOffset: offset + 1 };
265
+ }
266
+ const numBytes = firstByte & 0x7f;
267
+ let length = 0;
268
+ for (let i = 0; i < numBytes; i++) {
269
+ length = (length << 8) | data[offset + 1 + i];
270
+ }
271
+ return { length, nextOffset: offset + 1 + numBytes };
272
+ }
273
+
274
+ function decodeOID(bytes: Buffer): string {
275
+ const components: number[] = [];
276
+ components.push(Math.floor(bytes[0] / 40));
277
+ components.push(bytes[0] % 40);
278
+ let value = 0;
279
+ for (let i = 1; i < bytes.length; i++) {
280
+ value = (value << 7) | (bytes[i] & 0x7f);
281
+ if ((bytes[i] & 0x80) === 0) {
282
+ components.push(value);
283
+ value = 0;
284
+ }
285
+ }
286
+ return components.join('.');
287
+ }
288
+
11
289
  const eidReader = async (
12
290
  documentNumber: string,
13
291
  dateOfBirth: string,
@@ -29,23 +307,129 @@ const eidReader = async (
29
307
  try {
30
308
  await passportService.open();
31
309
 
310
+ progress = 1;
311
+ if (progressCallback) {
312
+ progressCallback(progress);
313
+ }
314
+
315
+ // Try to read EF.CardAccess before selecting applet to check for PACE.
316
+ // Explicitly SELECT MF first so the SFI=0x1C context is correct,
317
+ // regardless of which application the chip activates on power-on.
318
+ let hasPACESucceeded = false;
319
+
320
+ try {
321
+ await passportService.sendSelectMF();
322
+ console.debug('[EID] SELECT MF OK');
323
+ } catch (mfErr) {
324
+ const mfMsg = mfErr instanceof Error ? mfErr.message : String(mfErr);
325
+ console.debug(
326
+ `[EID] SELECT MF failed (${mfMsg}), continuing with SFI read anyway`
327
+ );
328
+ }
329
+
330
+ progress = 2;
331
+ if (progressCallback) {
332
+ progressCallback(progress);
333
+ }
334
+
335
+ // Read EF.CardAccess — kept in a separate try/catch so we can distinguish
336
+ // "file read failure" from "PACE protocol failure" in the logs.
337
+ let cardAccessBuf: Buffer | null = null;
338
+ try {
339
+ const cardAccessStream = passportService.getInputStream(
340
+ EIDService.EF_CARD_ACCESS
341
+ );
342
+ await cardAccessStream.init();
343
+ const cardAccessLen = cardAccessStream.getLength();
344
+ const buf = Buffer.alloc(cardAccessLen);
345
+ for (let i = 0; i < cardAccessLen; i++) {
346
+ buf[i] = await cardAccessStream.read();
347
+ }
348
+ cardAccessBuf = buf;
349
+ console.debug(
350
+ `[EID] EF.CardAccess read OK: ${cardAccessLen} bytes = ${cardAccessBuf.toString('hex')}`
351
+ );
352
+ } catch (readErr) {
353
+ const readMsg =
354
+ readErr instanceof Error ? readErr.message : String(readErr);
355
+ console.debug(
356
+ `[EID] EF.CardAccess read FAILED: ${readMsg} — falling back to BAC`
357
+ );
358
+ }
359
+
360
+ progress = 3;
361
+ if (progressCallback) {
362
+ progressCallback(progress);
363
+ }
364
+
365
+ // If EF.CardAccess was read successfully, attempt PACE.
366
+ if (cardAccessBuf !== null) {
367
+ try {
368
+ const paceInfo = parsePACEInfoFromCardAccess(cardAccessBuf);
369
+
370
+ if (paceInfo) {
371
+ console.debug(
372
+ `[EID] PACE available: oid=${paceInfo.oid} parameterId=${paceInfo.parameterId}`
373
+ );
374
+ // PACE is available - derive key from MRZ and perform PACE
375
+ const bacKey = new BACKey(documentNumber, dateOfBirth, dateOfExpiry);
376
+ const paceKey = PACEKeySpec.createMRZKey(bacKey.getKeySeedForPACE());
377
+
378
+ progress = 4;
379
+ if (progressCallback) {
380
+ progressCallback(progress);
381
+ }
382
+
383
+ await passportService.doPACE(
384
+ paceKey,
385
+ paceInfo.oid,
386
+ paceInfo.parameterId,
387
+ progressCallback
388
+ );
389
+ hasPACESucceeded = true;
390
+ console.debug('[EID] PACE succeeded');
391
+ } else {
392
+ console.debug(
393
+ '[EID] EF.CardAccess read OK but no PACE SecurityInfo found — document does not support PACE, falling back to BAC'
394
+ );
395
+ }
396
+ } catch (paceError) {
397
+ // PACE protocol exchange failed — fall back to BAC
398
+ const msg =
399
+ paceError instanceof Error ? paceError.message : String(paceError);
400
+ console.debug(
401
+ `[EID] PACE protocol failed (${msg}), falling back to BAC`
402
+ );
403
+ if (paceError instanceof Error && paceError.stack) {
404
+ console.debug('[EID] PACE error stack:', paceError.stack);
405
+ }
406
+ }
407
+ }
408
+
409
+ progress = 9;
410
+ if (progressCallback) {
411
+ progressCallback(progress);
412
+ }
413
+
32
414
  // Select Applet for MRTD
33
- await passportService.sendSelectApplet(false);
415
+ await passportService.sendSelectApplet(hasPACESucceeded);
34
416
 
35
417
  progress = 10;
36
418
  if (progressCallback) {
37
419
  progressCallback(progress);
38
420
  }
39
421
 
40
- // Check if EF_COM is available
41
- try {
42
- const efComStream = passportService.getInputStream(EIDService.EF_COM);
43
- await efComStream.init();
44
- await efComStream.read();
45
- } catch (error) {
46
- // EF_COM not available -> try to do BAC
47
- const bacKey = new BACKey(documentNumber, dateOfBirth, dateOfExpiry);
48
- await passportService.doBAC(bacKey);
422
+ if (!hasPACESucceeded) {
423
+ // Check if EF_COM is available
424
+ try {
425
+ const efComStream = passportService.getInputStream(EIDService.EF_COM);
426
+ await efComStream.init();
427
+ await efComStream.read();
428
+ } catch (error) {
429
+ // EF_COM not available -> try to do BAC
430
+ const bacKey = new BACKey(documentNumber, dateOfBirth, dateOfExpiry);
431
+ await passportService.doBAC(bacKey);
432
+ }
49
433
  }
50
434
 
51
435
  progress = 20;
@@ -89,8 +473,10 @@ const eidReader = async (
89
473
  const imageInputStream = await faceImageInfo.getImageInputStream();
90
474
  const buffer = Buffer.alloc(imageLength);
91
475
  await imageInputStream.readBytesWithOffset(buffer, 0, imageLength);
92
- imageAsBase64 = buffer.toString('base64');
93
- mimeType = faceImageInfo.getMimeType();
476
+ const rawMimeType = faceImageInfo.getMimeType();
477
+ const converted = convertJP2IfNeeded(buffer, rawMimeType);
478
+ imageAsBase64 = converted.base64;
479
+ mimeType = converted.mimeType;
94
480
  }
95
481
 
96
482
  progress = 100;
@@ -9,6 +9,9 @@ import { BACAPDUSender } from './protocol/bacAPDUSender';
9
9
  import { ReadBinaryAPDUSender } from './protocol/readBinaryAPDUSender';
10
10
  import { BACResult } from './protocol/bacResult';
11
11
  import { BACProtocol } from './protocol/bacProtocol';
12
+ import { PACEAPDUSender } from './protocol/paceAPDUSender';
13
+ import { PACEProtocol } from './protocol/paceProtocol';
14
+ import { PACEResult } from './protocol/paceResult';
12
15
  import { CommandAPDU } from './smartcards/commandAPDU';
13
16
  import type { APDUListener } from './smartcards/apduListener';
14
17
  import { APDUEvent } from './smartcards/apduEvent';
@@ -209,7 +212,20 @@ export class EIDService extends AbstractMRTDCardService {
209
212
  this.shouldCheckMAC = shouldCheckMAC;
210
213
  this.isAppletSelected = false;
211
214
  this.isOpen = false;
212
- this.rootFileSystem = new DefaultFileSystem(this.readBinarySender, false);
215
+ // EF.CardAccess and EF.CardSecurity live in the MF (Master File), outside
216
+ // the ICAO applet. They must be read via SFI-based READ BINARY (no SELECT
217
+ // needed). Without SFI, the implementation falls back to SELECT-by-FID
218
+ // which many passport chips reject at MF level before applet selection,
219
+ // causing PACE to be falsely reported as "not available".
220
+ const rootFidToSFI = new Map<number, number>([
221
+ [EID_CONSTANTS.EF_CARD_ACCESS, EID_CONSTANTS.SFI_CARD_ACCESS],
222
+ [EID_CONSTANTS.EF_CARD_SECURITY, EID_CONSTANTS.SFI_CARD_SECURITY],
223
+ ]);
224
+ this.rootFileSystem = new DefaultFileSystem(
225
+ this.readBinarySender,
226
+ true,
227
+ rootFidToSFI
228
+ );
213
229
  this.appletFileSystem = new DefaultFileSystem(
214
230
  this.readBinarySender,
215
231
  isSFIEnabled
@@ -261,6 +277,38 @@ export class EIDService extends AbstractMRTDCardService {
261
277
  return bacResult;
262
278
  }
263
279
 
280
+ /**
281
+ * Performs the PACE protocol.
282
+ *
283
+ * @param accessKey the access key (MRZ or CAN based)
284
+ * @param oid the PACE OID string from EF.CardAccess
285
+ * @param parameterId the standard domain parameter ID (e.g. 13 for brainpoolP256r1)
286
+ */
287
+ public async doPACE(
288
+ accessKey: AccessKeySpec,
289
+ oid: string,
290
+ parameterId: number | null,
291
+ progressCallback?: (progress: number) => void
292
+ ): Promise<PACEResult> {
293
+ const paceSender = new PACEAPDUSender(this.service);
294
+ const paceProtocol = new PACEProtocol(
295
+ paceSender,
296
+ this.wrapper,
297
+ EIDService.NORMAL_MAX_TRANSCEIVE_LENGTH,
298
+ this.maxTransceiveLengthForSecureMessaging,
299
+ this.shouldCheckMAC
300
+ );
301
+ const paceResult = await paceProtocol.doPACE(
302
+ accessKey,
303
+ oid,
304
+ parameterId,
305
+ progressCallback
306
+ );
307
+ this.wrapper = paceResult.getWrapper();
308
+ this.appletFileSystem.setWrapper(this.wrapper);
309
+ return paceResult;
310
+ }
311
+
264
312
  public async close(): Promise<void> {
265
313
  try {
266
314
  await this.service.close();
@@ -13,7 +13,10 @@ export class NFCManagerCardService extends CardService {
13
13
  NfcTech.NfcA,
14
14
  NfcTech.NfcB,
15
15
  ]);
16
- // await NFCManager.setTimeout(5000);
16
+ // Increase transceive timeout for slow curves (e.g. brainpoolP512r1 ECDH on passport chip)
17
+ if (Platform.OS === 'android') {
18
+ await NFCManager.setTimeout(10000);
19
+ }
17
20
  this.isOpened = true;
18
21
  }
19
22
 
@@ -22,10 +25,6 @@ export class NFCManagerCardService extends CardService {
22
25
  }
23
26
 
24
27
  public async transmit(commandAPDU: CommandAPDU): Promise<ResponseAPDU> {
25
- // console.debug(
26
- // `T[${ISO7816_INS[commandAPDU.getINS()]}]:`,
27
- // Buffer.from(commandAPDU.getBytes()).toString('hex').toUpperCase(),
28
- // );
29
28
  let response: number[];
30
29
 
31
30
  if (Platform.OS === 'ios') {
@@ -38,7 +37,6 @@ export class NFCManagerCardService extends CardService {
38
37
  Array.from(commandAPDU.getBytes())
39
38
  );
40
39
  }
41
- // console.debug('R:', Buffer.from(response).toString('hex').toUpperCase());
42
40
 
43
41
  return new ResponseAPDU(response);
44
42
  }
@@ -0,0 +1,159 @@
1
+ /**
2
+ * PACE (Password Authenticated Connection Establishment) protocol info.
3
+ * Parses PACE OIDs to extract mapping type, cipher, digest, key agreement algorithm, and key length.
4
+ *
5
+ * Based on ICAO Doc 9303 Part 11 and BSI TR-03110.
6
+ */
7
+
8
+ export enum MappingType {
9
+ GM = 'GM',
10
+ IM = 'IM',
11
+ CAM = 'CAM',
12
+ }
13
+
14
+ // PACE OID constants (BSI TR-03110 / ICAO 9303)
15
+ export const ID_PACE = '0.4.0.127.0.7.2.2.4';
16
+
17
+ export const ID_PACE_DH_GM = '0.4.0.127.0.7.2.2.4.1';
18
+ export const ID_PACE_DH_GM_3DES_CBC_CBC = '0.4.0.127.0.7.2.2.4.1.1';
19
+ export const ID_PACE_DH_GM_AES_CBC_CMAC_128 = '0.4.0.127.0.7.2.2.4.1.2';
20
+ export const ID_PACE_DH_GM_AES_CBC_CMAC_192 = '0.4.0.127.0.7.2.2.4.1.3';
21
+ export const ID_PACE_DH_GM_AES_CBC_CMAC_256 = '0.4.0.127.0.7.2.2.4.1.4';
22
+
23
+ export const ID_PACE_ECDH_GM = '0.4.0.127.0.7.2.2.4.2';
24
+ export const ID_PACE_ECDH_GM_3DES_CBC_CBC = '0.4.0.127.0.7.2.2.4.2.1';
25
+ export const ID_PACE_ECDH_GM_AES_CBC_CMAC_128 = '0.4.0.127.0.7.2.2.4.2.2';
26
+ export const ID_PACE_ECDH_GM_AES_CBC_CMAC_192 = '0.4.0.127.0.7.2.2.4.2.3';
27
+ export const ID_PACE_ECDH_GM_AES_CBC_CMAC_256 = '0.4.0.127.0.7.2.2.4.2.4';
28
+
29
+ export const ID_PACE_DH_IM = '0.4.0.127.0.7.2.2.4.3';
30
+ export const ID_PACE_DH_IM_3DES_CBC_CBC = '0.4.0.127.0.7.2.2.4.3.1';
31
+ export const ID_PACE_DH_IM_AES_CBC_CMAC_128 = '0.4.0.127.0.7.2.2.4.3.2';
32
+ export const ID_PACE_DH_IM_AES_CBC_CMAC_192 = '0.4.0.127.0.7.2.2.4.3.3';
33
+ export const ID_PACE_DH_IM_AES_CBC_CMAC_256 = '0.4.0.127.0.7.2.2.4.3.4';
34
+
35
+ export const ID_PACE_ECDH_IM = '0.4.0.127.0.7.2.2.4.4';
36
+ export const ID_PACE_ECDH_IM_3DES_CBC_CBC = '0.4.0.127.0.7.2.2.4.4.1';
37
+ export const ID_PACE_ECDH_IM_AES_CBC_CMAC_128 = '0.4.0.127.0.7.2.2.4.4.2';
38
+ export const ID_PACE_ECDH_IM_AES_CBC_CMAC_192 = '0.4.0.127.0.7.2.2.4.4.3';
39
+ export const ID_PACE_ECDH_IM_AES_CBC_CMAC_256 = '0.4.0.127.0.7.2.2.4.4.4';
40
+
41
+ export const ID_PACE_ECDH_CAM = '0.4.0.127.0.7.2.2.4.6';
42
+ export const ID_PACE_ECDH_CAM_AES_CBC_CMAC_128 = '0.4.0.127.0.7.2.2.4.6.2';
43
+ export const ID_PACE_ECDH_CAM_AES_CBC_CMAC_192 = '0.4.0.127.0.7.2.2.4.6.3';
44
+ export const ID_PACE_ECDH_CAM_AES_CBC_CMAC_256 = '0.4.0.127.0.7.2.2.4.6.4';
45
+
46
+ // Standard domain parameter identifiers
47
+ export const PARAM_ID_ECP_NIST_P256_R1 = 12;
48
+ export const PARAM_ID_ECP_BRAINPOOL_P256_R1 = 13;
49
+ export const PARAM_ID_ECP_BRAINPOOL_P384_R1 = 16;
50
+ export const PARAM_ID_ECP_BRAINPOOL_P512_R1 = 17;
51
+ export const PARAM_ID_ECP_NIST_P384_R1 = 15;
52
+ export const PARAM_ID_ECP_NIST_P521_R1 = 18;
53
+
54
+ const GM_OIDS = new Set([
55
+ ID_PACE_DH_GM_3DES_CBC_CBC,
56
+ ID_PACE_DH_GM_AES_CBC_CMAC_128,
57
+ ID_PACE_DH_GM_AES_CBC_CMAC_192,
58
+ ID_PACE_DH_GM_AES_CBC_CMAC_256,
59
+ ID_PACE_ECDH_GM_3DES_CBC_CBC,
60
+ ID_PACE_ECDH_GM_AES_CBC_CMAC_128,
61
+ ID_PACE_ECDH_GM_AES_CBC_CMAC_192,
62
+ ID_PACE_ECDH_GM_AES_CBC_CMAC_256,
63
+ ]);
64
+
65
+ const IM_OIDS = new Set([
66
+ ID_PACE_DH_IM_3DES_CBC_CBC,
67
+ ID_PACE_DH_IM_AES_CBC_CMAC_128,
68
+ ID_PACE_DH_IM_AES_CBC_CMAC_192,
69
+ ID_PACE_DH_IM_AES_CBC_CMAC_256,
70
+ ID_PACE_ECDH_IM_3DES_CBC_CBC,
71
+ ID_PACE_ECDH_IM_AES_CBC_CMAC_128,
72
+ ID_PACE_ECDH_IM_AES_CBC_CMAC_192,
73
+ ID_PACE_ECDH_IM_AES_CBC_CMAC_256,
74
+ ]);
75
+
76
+ const CAM_OIDS = new Set([
77
+ ID_PACE_ECDH_CAM_AES_CBC_CMAC_128,
78
+ ID_PACE_ECDH_CAM_AES_CBC_CMAC_192,
79
+ ID_PACE_ECDH_CAM_AES_CBC_CMAC_256,
80
+ ]);
81
+
82
+ const DH_OIDS = new Set([
83
+ ID_PACE_DH_GM_3DES_CBC_CBC,
84
+ ID_PACE_DH_GM_AES_CBC_CMAC_128,
85
+ ID_PACE_DH_GM_AES_CBC_CMAC_192,
86
+ ID_PACE_DH_GM_AES_CBC_CMAC_256,
87
+ ID_PACE_DH_IM_3DES_CBC_CBC,
88
+ ID_PACE_DH_IM_AES_CBC_CMAC_128,
89
+ ID_PACE_DH_IM_AES_CBC_CMAC_192,
90
+ ID_PACE_DH_IM_AES_CBC_CMAC_256,
91
+ ]);
92
+
93
+ const DES_OIDS = new Set([
94
+ ID_PACE_DH_GM_3DES_CBC_CBC,
95
+ ID_PACE_DH_IM_3DES_CBC_CBC,
96
+ ID_PACE_ECDH_GM_3DES_CBC_CBC,
97
+ ID_PACE_ECDH_IM_3DES_CBC_CBC,
98
+ ]);
99
+
100
+ const KEY_128_OIDS = new Set([
101
+ ID_PACE_DH_GM_3DES_CBC_CBC,
102
+ ID_PACE_DH_IM_3DES_CBC_CBC,
103
+ ID_PACE_ECDH_GM_3DES_CBC_CBC,
104
+ ID_PACE_ECDH_IM_3DES_CBC_CBC,
105
+ ID_PACE_DH_GM_AES_CBC_CMAC_128,
106
+ ID_PACE_DH_IM_AES_CBC_CMAC_128,
107
+ ID_PACE_ECDH_GM_AES_CBC_CMAC_128,
108
+ ID_PACE_ECDH_IM_AES_CBC_CMAC_128,
109
+ ID_PACE_ECDH_CAM_AES_CBC_CMAC_128,
110
+ ]);
111
+
112
+ const KEY_192_OIDS = new Set([
113
+ ID_PACE_DH_GM_AES_CBC_CMAC_192,
114
+ ID_PACE_DH_IM_AES_CBC_CMAC_192,
115
+ ID_PACE_ECDH_GM_AES_CBC_CMAC_192,
116
+ ID_PACE_ECDH_IM_AES_CBC_CMAC_192,
117
+ ID_PACE_ECDH_CAM_AES_CBC_CMAC_192,
118
+ ]);
119
+
120
+ const KEY_256_OIDS = new Set([
121
+ ID_PACE_DH_GM_AES_CBC_CMAC_256,
122
+ ID_PACE_DH_IM_AES_CBC_CMAC_256,
123
+ ID_PACE_ECDH_GM_AES_CBC_CMAC_256,
124
+ ID_PACE_ECDH_IM_AES_CBC_CMAC_256,
125
+ ID_PACE_ECDH_CAM_AES_CBC_CMAC_256,
126
+ ]);
127
+
128
+ const SHA256_OIDS = new Set([...KEY_192_OIDS, ...KEY_256_OIDS]);
129
+
130
+ export class PACEInfo {
131
+ public static toMappingType(oid: string): MappingType {
132
+ if (GM_OIDS.has(oid)) return MappingType.GM;
133
+ if (IM_OIDS.has(oid)) return MappingType.IM;
134
+ if (CAM_OIDS.has(oid)) return MappingType.CAM;
135
+ throw new Error(`Unknown PACE OID: ${oid}`);
136
+ }
137
+
138
+ public static toKeyAgreementAlgorithm(oid: string): 'DH' | 'ECDH' {
139
+ if (DH_OIDS.has(oid)) return 'DH';
140
+ return 'ECDH';
141
+ }
142
+
143
+ public static toCipherAlgorithm(oid: string): 'DESede' | 'AES' {
144
+ if (DES_OIDS.has(oid)) return 'DESede';
145
+ return 'AES';
146
+ }
147
+
148
+ public static toDigestAlgorithm(oid: string): 'SHA-1' | 'SHA-256' {
149
+ if (SHA256_OIDS.has(oid)) return 'SHA-256';
150
+ return 'SHA-1';
151
+ }
152
+
153
+ public static toKeyLength(oid: string): 128 | 192 | 256 {
154
+ if (KEY_128_OIDS.has(oid)) return 128;
155
+ if (KEY_192_OIDS.has(oid)) return 192;
156
+ if (KEY_256_OIDS.has(oid)) return 256;
157
+ throw new Error(`Unknown PACE OID: ${oid}`);
158
+ }
159
+ }