@sudoplatform/sudo-common 7.0.2 → 8.0.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 (404) hide show
  1. package/cjs/configurationManager/defaultConfigurationManager.d.ts +123 -0
  2. package/cjs/configurationManager/defaultConfigurationManager.js +122 -0
  3. package/cjs/configurationManager/defaultConfigurationManager.js.map +1 -0
  4. package/cjs/errors/error.d.ts +263 -0
  5. package/cjs/errors/error.js +442 -0
  6. package/cjs/errors/error.js.map +1 -0
  7. package/cjs/index.d.ts +9 -0
  8. package/cjs/index.js +13 -0
  9. package/cjs/index.js.map +1 -0
  10. package/cjs/logging/bunyanLogger.d.ts +8 -0
  11. package/cjs/logging/bunyanLogger.js +36 -0
  12. package/cjs/logging/bunyanLogger.js.map +1 -0
  13. package/cjs/logging/logger.d.ts +87 -0
  14. package/cjs/logging/logger.js +77 -0
  15. package/cjs/logging/logger.js.map +1 -0
  16. package/cjs/sudoKeyArchive/index.d.ts +4 -0
  17. package/cjs/sudoKeyArchive/index.js +8 -0
  18. package/cjs/sudoKeyArchive/index.js.map +1 -0
  19. package/cjs/sudoKeyArchive/keyArchive.d.ts +137 -0
  20. package/cjs/sudoKeyArchive/keyArchive.js +84 -0
  21. package/cjs/sudoKeyArchive/keyArchive.js.map +1 -0
  22. package/cjs/sudoKeyArchive/keyInfo.d.ts +41 -0
  23. package/cjs/sudoKeyArchive/keyInfo.js +17 -0
  24. package/cjs/sudoKeyArchive/keyInfo.js.map +1 -0
  25. package/cjs/sudoKeyArchive/keyType.d.ts +13 -0
  26. package/cjs/sudoKeyArchive/keyType.js +39 -0
  27. package/cjs/sudoKeyArchive/keyType.js.map +1 -0
  28. package/cjs/sudoKeyArchive/sudoKeyArchive.d.ts +190 -0
  29. package/cjs/sudoKeyArchive/sudoKeyArchive.js +373 -0
  30. package/cjs/sudoKeyArchive/sudoKeyArchive.js.map +1 -0
  31. package/cjs/sudoKeyManager/index.d.ts +4 -0
  32. package/cjs/sudoKeyManager/index.js +8 -0
  33. package/cjs/sudoKeyManager/index.js.map +1 -0
  34. package/cjs/sudoKeyManager/keyData.d.ts +56 -0
  35. package/cjs/sudoKeyManager/keyData.js +46 -0
  36. package/cjs/sudoKeyManager/keyData.js.map +1 -0
  37. package/cjs/sudoKeyManager/publicKey.d.ts +8 -0
  38. package/cjs/sudoKeyManager/publicKey.js +9 -0
  39. package/cjs/sudoKeyManager/publicKey.js.map +1 -0
  40. package/cjs/sudoKeyManager/sudoCryptoProvider.d.ts +324 -0
  41. package/cjs/sudoKeyManager/sudoCryptoProvider.js +12 -0
  42. package/cjs/sudoKeyManager/sudoCryptoProvider.js.map +1 -0
  43. package/cjs/sudoKeyManager/sudoKeyManager.d.ts +344 -0
  44. package/cjs/sudoKeyManager/sudoKeyManager.js +140 -0
  45. package/cjs/sudoKeyManager/sudoKeyManager.js.map +1 -0
  46. package/cjs/types/types.d.ts +115 -0
  47. package/cjs/types/types.js +45 -0
  48. package/cjs/types/types.js.map +1 -0
  49. package/cjs/utils/base64.d.ts +44 -0
  50. package/cjs/utils/base64.js +71 -0
  51. package/cjs/utils/base64.js.map +1 -0
  52. package/cjs/utils/buffer.d.ts +13 -0
  53. package/cjs/utils/buffer.js +37 -0
  54. package/cjs/utils/buffer.js.map +1 -0
  55. package/cjs/utils/stream.d.ts +6 -0
  56. package/cjs/utils/stream.js +70 -0
  57. package/cjs/utils/stream.js.map +1 -0
  58. package/lib/configurationManager/defaultConfigurationManager.js +106 -158
  59. package/lib/configurationManager/defaultConfigurationManager.js.map +1 -0
  60. package/lib/errors/error.js +226 -438
  61. package/lib/errors/error.js.map +1 -0
  62. package/lib/index.d.ts +1 -0
  63. package/lib/index.js +10 -109
  64. package/lib/index.js.map +1 -0
  65. package/lib/logging/bunyanLogger.js +29 -41
  66. package/lib/logging/bunyanLogger.js.map +1 -0
  67. package/lib/logging/logger.js +66 -92
  68. package/lib/logging/logger.js.map +1 -0
  69. package/lib/sudoKeyArchive/index.js +5 -57
  70. package/lib/sudoKeyArchive/index.js.map +1 -0
  71. package/lib/sudoKeyArchive/keyArchive.d.ts +8 -8
  72. package/lib/sudoKeyArchive/keyArchive.js +69 -96
  73. package/lib/sudoKeyArchive/keyArchive.js.map +1 -0
  74. package/lib/sudoKeyArchive/keyInfo.js +11 -49
  75. package/lib/sudoKeyArchive/keyInfo.js.map +1 -0
  76. package/lib/sudoKeyArchive/keyType.js +27 -37
  77. package/lib/sudoKeyArchive/keyType.js.map +1 -0
  78. package/lib/sudoKeyArchive/sudoKeyArchive.js +351 -444
  79. package/lib/sudoKeyArchive/sudoKeyArchive.js.map +1 -0
  80. package/lib/sudoKeyManager/index.js +5 -57
  81. package/lib/sudoKeyManager/index.js.map +1 -0
  82. package/lib/sudoKeyManager/keyData.js +38 -33
  83. package/lib/sudoKeyManager/keyData.js.map +1 -0
  84. package/lib/sudoKeyManager/publicKey.js +5 -12
  85. package/lib/sudoKeyManager/publicKey.js.map +1 -0
  86. package/lib/sudoKeyManager/sudoCryptoProvider.js +8 -26
  87. package/lib/sudoKeyManager/sudoCryptoProvider.js.map +1 -0
  88. package/lib/sudoKeyManager/sudoKeyManager.js +135 -173
  89. package/lib/sudoKeyManager/sudoKeyManager.js.map +1 -0
  90. package/lib/types/types.js +27 -33
  91. package/lib/types/types.js.map +1 -0
  92. package/lib/utils/base64.d.ts +35 -0
  93. package/lib/utils/base64.js +63 -28
  94. package/lib/utils/base64.js.map +1 -0
  95. package/lib/utils/buffer.js +28 -46
  96. package/lib/utils/buffer.js.map +1 -0
  97. package/lib/utils/stream.d.ts +6 -0
  98. package/lib/utils/stream.js +63 -0
  99. package/lib/utils/stream.js.map +1 -0
  100. package/package.json +36 -29
  101. package/.babelrc +0 -10
  102. package/.eslintrc.js +0 -91
  103. package/.gitignore +0 -14
  104. package/.gitlab-ci.yml +0 -101
  105. package/.npmignore +0 -1
  106. package/.prettierignore +0 -3
  107. package/.prettierrc.js +0 -7
  108. package/.publisher.json +0 -7
  109. package/.vscode/settings.json +0 -5
  110. package/.yarn/releases/yarn-1.22.19.cjs +0 -147529
  111. package/.yarnrc +0 -5
  112. package/dependencies-report.json +0 -640
  113. package/docs/.nojekyll +0 -1
  114. package/docs/assets/highlight.css +0 -57
  115. package/docs/assets/main.js +0 -54
  116. package/docs/assets/search.js +0 -1
  117. package/docs/assets/style.css +0 -1224
  118. package/docs/assets/widgets.png +0 -0
  119. package/docs/assets/widgets@2x.png +0 -0
  120. package/docs/classes/AccountLockedError.html +0 -163
  121. package/docs/classes/AuthenticationError.html +0 -169
  122. package/docs/classes/Base64.html +0 -134
  123. package/docs/classes/Buffer.html +0 -158
  124. package/docs/classes/ConfigurationNotSetError.html +0 -164
  125. package/docs/classes/ConfigurationSetNotFoundError.html +0 -168
  126. package/docs/classes/DecodeError.html +0 -168
  127. package/docs/classes/DefaultConfigurationManager.html +0 -213
  128. package/docs/classes/DefaultLogger.html +0 -291
  129. package/docs/classes/DefaultSudoKeyArchive.html +0 -363
  130. package/docs/classes/DefaultSudoKeyManager.html +0 -814
  131. package/docs/classes/FatalError.html +0 -169
  132. package/docs/classes/IllegalArgumentError.html +0 -168
  133. package/docs/classes/IllegalStateError.html +0 -169
  134. package/docs/classes/InsufficientEntitlementsError.html +0 -164
  135. package/docs/classes/InvalidOwnershipProofError.html +0 -163
  136. package/docs/classes/InvalidTokenError.html +0 -163
  137. package/docs/classes/KeyArchiveDecodingError.html +0 -168
  138. package/docs/classes/KeyArchiveIncorrectPasswordError.html +0 -168
  139. package/docs/classes/KeyArchiveMissingError.html +0 -168
  140. package/docs/classes/KeyArchiveNoPasswordRequiredError.html +0 -168
  141. package/docs/classes/KeyArchivePasswordRequiredError.html +0 -168
  142. package/docs/classes/KeyArchiveTypeError.html +0 -168
  143. package/docs/classes/KeyArchiveUnknownKeyTypeError.html +0 -168
  144. package/docs/classes/KeyArchiveVersionError.html +0 -168
  145. package/docs/classes/KeyNotFoundError.html +0 -168
  146. package/docs/classes/KeyStoreNotExportableError.html +0 -168
  147. package/docs/classes/LimitExceededError.html +0 -164
  148. package/docs/classes/NoEntitlementsError.html +0 -163
  149. package/docs/classes/NotAuthorizedError.html +0 -169
  150. package/docs/classes/NotRegisteredError.html +0 -168
  151. package/docs/classes/NotSignedInError.html +0 -164
  152. package/docs/classes/OperationNotImplementedError.html +0 -168
  153. package/docs/classes/RegisterError.html +0 -169
  154. package/docs/classes/RequestFailedError.html +0 -189
  155. package/docs/classes/ServiceError.html +0 -170
  156. package/docs/classes/SignOutError.html +0 -168
  157. package/docs/classes/SudoCryptoProviderDefaults.html +0 -106
  158. package/docs/classes/UnknownGraphQLError.html +0 -169
  159. package/docs/classes/UnrecognizedAlgorithmError.html +0 -168
  160. package/docs/classes/UserNotConfirmedError.html +0 -164
  161. package/docs/classes/VersionMismatchError.html +0 -166
  162. package/docs/enums/CachePolicy.html +0 -72
  163. package/docs/enums/EncryptionAlgorithm.html +0 -80
  164. package/docs/enums/KeyArchiveKeyType.html +0 -86
  165. package/docs/enums/KeyDataKeyFormat.html +0 -92
  166. package/docs/enums/KeyDataKeyType.html +0 -85
  167. package/docs/enums/ListOperationResultStatus.html +0 -85
  168. package/docs/enums/PublicKeyFormat.html +0 -68
  169. package/docs/functions/isAppSyncNetworkError.html +0 -147
  170. package/docs/functions/isInsecureKeyArchive.html +0 -147
  171. package/docs/functions/isSecureKeyArchive.html +0 -147
  172. package/docs/functions/isUnrecognizedKeyArchive.html +0 -147
  173. package/docs/functions/keyArchiveInfoFromKeyData.html +0 -147
  174. package/docs/functions/keyArchiveKeyTypeFromKeyDataKeyType.html +0 -147
  175. package/docs/functions/mapGraphQLToClientError.html +0 -154
  176. package/docs/functions/mapNetworkErrorToClientError.html +0 -154
  177. package/docs/index.html +0 -146
  178. package/docs/interfaces/AsymmetricEncryptionOptions.html +0 -68
  179. package/docs/interfaces/BooleanFilter.html +0 -75
  180. package/docs/interfaces/ConfigurationManager.html +0 -200
  181. package/docs/interfaces/KeyData.html +0 -106
  182. package/docs/interfaces/ListOperationFailureResult.html +0 -76
  183. package/docs/interfaces/ListOperationPartialResult.html +0 -102
  184. package/docs/interfaces/ListOperationSuccessResult.html +0 -90
  185. package/docs/interfaces/ListOutput.html +0 -80
  186. package/docs/interfaces/Logger.html +0 -251
  187. package/docs/interfaces/Owner.html +0 -72
  188. package/docs/interfaces/PublicKey.html +0 -72
  189. package/docs/interfaces/ServiceCompatibilityInfo.html +0 -110
  190. package/docs/interfaces/StringFilter.html +0 -82
  191. package/docs/interfaces/SudoCryptoProvider.html +0 -865
  192. package/docs/interfaces/SudoKeyArchive.html +0 -257
  193. package/docs/interfaces/SudoKeyManager.html +0 -848
  194. package/docs/interfaces/SymmetricEncryptionOptions.html +0 -75
  195. package/docs/interfaces/ValidationResult.html +0 -83
  196. package/docs/modules.html +0 -248
  197. package/docs/types/AppSyncError.html +0 -138
  198. package/docs/types/AppSyncNetworkError.html +0 -138
  199. package/docs/types/InsecureKeyArchive.html +0 -138
  200. package/docs/types/KeyArchive.html +0 -138
  201. package/docs/types/KeyArchiveKeyInfo.html +0 -154
  202. package/docs/types/KeyArchiveKeyInfoDecoded.html +0 -138
  203. package/docs/types/ListOperationResult.html +0 -148
  204. package/docs/types/SecureKeyArchive.html +0 -138
  205. package/docs/types/Subset.html +0 -144
  206. package/docs/types/UnrecognizedKeyArchive.html +0 -138
  207. package/docs/variables/CURRENT_ARCHIVE_VERSION.html +0 -138
  208. package/docs/variables/InsecureKeyArchiveCodec.html +0 -138
  209. package/docs/variables/InsecureKeyArchiveType.html +0 -138
  210. package/docs/variables/KeyArchiveCodec.html +0 -138
  211. package/docs/variables/KeyArchiveKeyInfoArrayCodec.html +0 -138
  212. package/docs/variables/KeyArchiveKeyInfoCodec.html +0 -138
  213. package/docs/variables/KeyArchiveKeyTypeCodec.html +0 -138
  214. package/docs/variables/SecureKeyArchiveCodec.html +0 -138
  215. package/docs/variables/SecureKeyArchiveType.html +0 -138
  216. package/docs/variables/UnrecognizedKeyArchiveCodec.html +0 -138
  217. package/github/.babelrc +0 -10
  218. package/github/.eslintrc.js +0 -91
  219. package/github/.gitignore +0 -14
  220. package/github/.gitlab-ci.yml +0 -101
  221. package/github/.npmignore +0 -1
  222. package/github/.prettierignore +0 -3
  223. package/github/.prettierrc.js +0 -7
  224. package/github/.publisher.json +0 -7
  225. package/github/.vscode/settings.json +0 -5
  226. package/github/.yarn/releases/yarn-1.22.19.cjs +0 -147529
  227. package/github/.yarnrc +0 -5
  228. package/github/CHANGELOG.md +0 -51
  229. package/github/README.md +0 -8
  230. package/github/bin/outdated-with-suppression.sh +0 -203
  231. package/github/bin/suppress-audit.sh +0 -15
  232. package/github/bin/suppress-outdated.sh +0 -60
  233. package/github/bin/yarn-audit-with-suppression.sh +0 -19
  234. package/github/docs/.nojekyll +0 -1
  235. package/github/docs/assets/highlight.css +0 -57
  236. package/github/docs/assets/main.js +0 -54
  237. package/github/docs/assets/search.js +0 -1
  238. package/github/docs/assets/style.css +0 -1224
  239. package/github/docs/assets/widgets.png +0 -0
  240. package/github/docs/assets/widgets@2x.png +0 -0
  241. package/github/docs/classes/AccountLockedError.html +0 -163
  242. package/github/docs/classes/AuthenticationError.html +0 -169
  243. package/github/docs/classes/Base64.html +0 -134
  244. package/github/docs/classes/Buffer.html +0 -158
  245. package/github/docs/classes/ConfigurationNotSetError.html +0 -164
  246. package/github/docs/classes/ConfigurationSetNotFoundError.html +0 -168
  247. package/github/docs/classes/DecodeError.html +0 -168
  248. package/github/docs/classes/DefaultConfigurationManager.html +0 -213
  249. package/github/docs/classes/DefaultLogger.html +0 -291
  250. package/github/docs/classes/DefaultSudoKeyArchive.html +0 -363
  251. package/github/docs/classes/DefaultSudoKeyManager.html +0 -814
  252. package/github/docs/classes/FatalError.html +0 -169
  253. package/github/docs/classes/IllegalArgumentError.html +0 -168
  254. package/github/docs/classes/IllegalStateError.html +0 -169
  255. package/github/docs/classes/InsufficientEntitlementsError.html +0 -164
  256. package/github/docs/classes/InvalidOwnershipProofError.html +0 -163
  257. package/github/docs/classes/InvalidTokenError.html +0 -163
  258. package/github/docs/classes/KeyArchiveDecodingError.html +0 -168
  259. package/github/docs/classes/KeyArchiveIncorrectPasswordError.html +0 -168
  260. package/github/docs/classes/KeyArchiveMissingError.html +0 -168
  261. package/github/docs/classes/KeyArchiveNoPasswordRequiredError.html +0 -168
  262. package/github/docs/classes/KeyArchivePasswordRequiredError.html +0 -168
  263. package/github/docs/classes/KeyArchiveTypeError.html +0 -168
  264. package/github/docs/classes/KeyArchiveUnknownKeyTypeError.html +0 -168
  265. package/github/docs/classes/KeyArchiveVersionError.html +0 -168
  266. package/github/docs/classes/KeyNotFoundError.html +0 -168
  267. package/github/docs/classes/KeyStoreNotExportableError.html +0 -168
  268. package/github/docs/classes/LimitExceededError.html +0 -164
  269. package/github/docs/classes/NoEntitlementsError.html +0 -163
  270. package/github/docs/classes/NotAuthorizedError.html +0 -169
  271. package/github/docs/classes/NotRegisteredError.html +0 -168
  272. package/github/docs/classes/NotSignedInError.html +0 -164
  273. package/github/docs/classes/OperationNotImplementedError.html +0 -168
  274. package/github/docs/classes/RegisterError.html +0 -169
  275. package/github/docs/classes/RequestFailedError.html +0 -189
  276. package/github/docs/classes/ServiceError.html +0 -170
  277. package/github/docs/classes/SignOutError.html +0 -168
  278. package/github/docs/classes/SudoCryptoProviderDefaults.html +0 -106
  279. package/github/docs/classes/UnknownGraphQLError.html +0 -169
  280. package/github/docs/classes/UnrecognizedAlgorithmError.html +0 -168
  281. package/github/docs/classes/UserNotConfirmedError.html +0 -164
  282. package/github/docs/classes/VersionMismatchError.html +0 -166
  283. package/github/docs/enums/CachePolicy.html +0 -72
  284. package/github/docs/enums/EncryptionAlgorithm.html +0 -80
  285. package/github/docs/enums/KeyArchiveKeyType.html +0 -86
  286. package/github/docs/enums/KeyDataKeyFormat.html +0 -92
  287. package/github/docs/enums/KeyDataKeyType.html +0 -85
  288. package/github/docs/enums/ListOperationResultStatus.html +0 -85
  289. package/github/docs/enums/PublicKeyFormat.html +0 -68
  290. package/github/docs/functions/isAppSyncNetworkError.html +0 -147
  291. package/github/docs/functions/isInsecureKeyArchive.html +0 -147
  292. package/github/docs/functions/isSecureKeyArchive.html +0 -147
  293. package/github/docs/functions/isUnrecognizedKeyArchive.html +0 -147
  294. package/github/docs/functions/keyArchiveInfoFromKeyData.html +0 -147
  295. package/github/docs/functions/keyArchiveKeyTypeFromKeyDataKeyType.html +0 -147
  296. package/github/docs/functions/mapGraphQLToClientError.html +0 -154
  297. package/github/docs/functions/mapNetworkErrorToClientError.html +0 -154
  298. package/github/docs/index.html +0 -146
  299. package/github/docs/interfaces/AsymmetricEncryptionOptions.html +0 -68
  300. package/github/docs/interfaces/BooleanFilter.html +0 -75
  301. package/github/docs/interfaces/ConfigurationManager.html +0 -200
  302. package/github/docs/interfaces/KeyData.html +0 -106
  303. package/github/docs/interfaces/ListOperationFailureResult.html +0 -76
  304. package/github/docs/interfaces/ListOperationPartialResult.html +0 -102
  305. package/github/docs/interfaces/ListOperationSuccessResult.html +0 -90
  306. package/github/docs/interfaces/ListOutput.html +0 -80
  307. package/github/docs/interfaces/Logger.html +0 -251
  308. package/github/docs/interfaces/Owner.html +0 -72
  309. package/github/docs/interfaces/PublicKey.html +0 -72
  310. package/github/docs/interfaces/ServiceCompatibilityInfo.html +0 -110
  311. package/github/docs/interfaces/StringFilter.html +0 -82
  312. package/github/docs/interfaces/SudoCryptoProvider.html +0 -865
  313. package/github/docs/interfaces/SudoKeyArchive.html +0 -257
  314. package/github/docs/interfaces/SudoKeyManager.html +0 -848
  315. package/github/docs/interfaces/SymmetricEncryptionOptions.html +0 -75
  316. package/github/docs/interfaces/ValidationResult.html +0 -83
  317. package/github/docs/modules.html +0 -248
  318. package/github/docs/types/AppSyncError.html +0 -138
  319. package/github/docs/types/AppSyncNetworkError.html +0 -138
  320. package/github/docs/types/InsecureKeyArchive.html +0 -138
  321. package/github/docs/types/KeyArchive.html +0 -138
  322. package/github/docs/types/KeyArchiveKeyInfo.html +0 -154
  323. package/github/docs/types/KeyArchiveKeyInfoDecoded.html +0 -138
  324. package/github/docs/types/ListOperationResult.html +0 -148
  325. package/github/docs/types/SecureKeyArchive.html +0 -138
  326. package/github/docs/types/Subset.html +0 -144
  327. package/github/docs/types/UnrecognizedKeyArchive.html +0 -138
  328. package/github/docs/variables/CURRENT_ARCHIVE_VERSION.html +0 -138
  329. package/github/docs/variables/InsecureKeyArchiveCodec.html +0 -138
  330. package/github/docs/variables/InsecureKeyArchiveType.html +0 -138
  331. package/github/docs/variables/KeyArchiveCodec.html +0 -138
  332. package/github/docs/variables/KeyArchiveKeyInfoArrayCodec.html +0 -138
  333. package/github/docs/variables/KeyArchiveKeyInfoCodec.html +0 -138
  334. package/github/docs/variables/KeyArchiveKeyTypeCodec.html +0 -138
  335. package/github/docs/variables/SecureKeyArchiveCodec.html +0 -138
  336. package/github/docs/variables/SecureKeyArchiveType.html +0 -138
  337. package/github/docs/variables/UnrecognizedKeyArchiveCodec.html +0 -138
  338. package/github/jest.config.json +0 -14
  339. package/github/package.json +0 -91
  340. package/github/src/configurationManager/defaultConfigurationManager.ts +0 -281
  341. package/github/src/errors/error.ts +0 -469
  342. package/github/src/index.ts +0 -8
  343. package/github/src/logging/bunyanLogger.ts +0 -47
  344. package/github/src/logging/logger.ts +0 -164
  345. package/github/src/sudoKeyArchive/index.ts +0 -4
  346. package/github/src/sudoKeyArchive/keyArchive.ts +0 -120
  347. package/github/src/sudoKeyArchive/keyInfo.ts +0 -47
  348. package/github/src/sudoKeyArchive/keyType.ts +0 -50
  349. package/github/src/sudoKeyArchive/sudoKeyArchive.ts +0 -591
  350. package/github/src/sudoKeyManager/index.ts +0 -4
  351. package/github/src/sudoKeyManager/keyData.ts +0 -60
  352. package/github/src/sudoKeyManager/publicKey.ts +0 -9
  353. package/github/src/sudoKeyManager/sudoCryptoProvider.ts +0 -416
  354. package/github/src/sudoKeyManager/sudoKeyManager.ts +0 -609
  355. package/github/src/types/types.ts +0 -129
  356. package/github/src/utils/base64.ts +0 -21
  357. package/github/src/utils/buffer.ts +0 -39
  358. package/github/test/integration/defaultConfigurationManager.spec.ts +0 -85
  359. package/github/test/matchers.ts +0 -122
  360. package/github/test/unit/configurationManager/defaultConfigurationManager.spec.ts +0 -506
  361. package/github/test/unit/errors/error.spec.ts +0 -115
  362. package/github/test/unit/keyType.spec.ts +0 -54
  363. package/github/test/unit/logging/logger.spec.ts +0 -182
  364. package/github/test/unit/sudoKeyArchive.spec.ts +0 -1609
  365. package/github/test/unit/sudoKeyManager.spec.ts +0 -1045
  366. package/github/test/unit/utils/base64.spec.ts +0 -30
  367. package/github/test/unit/utils/buffer.spec.ts +0 -45
  368. package/github/test/unit/utils/listOperationResult.spec.ts +0 -84
  369. package/github/tsconfig.json +0 -20
  370. package/github/tsconfig.test.json +0 -7
  371. package/github/yarn.lock +0 -5922
  372. package/jest.config.json +0 -14
  373. package/src/configurationManager/defaultConfigurationManager.ts +0 -281
  374. package/src/errors/error.ts +0 -469
  375. package/src/index.ts +0 -8
  376. package/src/logging/bunyanLogger.ts +0 -47
  377. package/src/logging/logger.ts +0 -164
  378. package/src/sudoKeyArchive/index.ts +0 -4
  379. package/src/sudoKeyArchive/keyArchive.ts +0 -120
  380. package/src/sudoKeyArchive/keyInfo.ts +0 -47
  381. package/src/sudoKeyArchive/keyType.ts +0 -50
  382. package/src/sudoKeyArchive/sudoKeyArchive.ts +0 -591
  383. package/src/sudoKeyManager/index.ts +0 -4
  384. package/src/sudoKeyManager/keyData.ts +0 -60
  385. package/src/sudoKeyManager/publicKey.ts +0 -9
  386. package/src/sudoKeyManager/sudoCryptoProvider.ts +0 -416
  387. package/src/sudoKeyManager/sudoKeyManager.ts +0 -609
  388. package/src/types/types.ts +0 -129
  389. package/src/utils/base64.ts +0 -21
  390. package/src/utils/buffer.ts +0 -39
  391. package/test/integration/defaultConfigurationManager.spec.ts +0 -85
  392. package/test/matchers.ts +0 -122
  393. package/test/unit/configurationManager/defaultConfigurationManager.spec.ts +0 -506
  394. package/test/unit/errors/error.spec.ts +0 -115
  395. package/test/unit/keyType.spec.ts +0 -54
  396. package/test/unit/logging/logger.spec.ts +0 -182
  397. package/test/unit/sudoKeyArchive.spec.ts +0 -1609
  398. package/test/unit/sudoKeyManager.spec.ts +0 -1045
  399. package/test/unit/utils/base64.spec.ts +0 -30
  400. package/test/unit/utils/buffer.spec.ts +0 -45
  401. package/test/unit/utils/listOperationResult.spec.ts +0 -84
  402. package/tsconfig.json +0 -20
  403. package/tsconfig.test.json +0 -7
  404. package/yarn.lock +0 -5922
@@ -1,1609 +0,0 @@
1
- import { gunzipSync, gzipSync } from 'fflate'
2
- import { isLeft, isRight } from 'fp-ts/lib/Either'
3
- import * as t from 'io-ts'
4
- import {
5
- anything,
6
- capture,
7
- deepEqual,
8
- instance,
9
- mock,
10
- reset,
11
- verify,
12
- when,
13
- } from 'ts-mockito'
14
-
15
- import {
16
- IllegalArgumentError,
17
- KeyArchiveDecodingError,
18
- KeyArchiveIncorrectPasswordError,
19
- KeyArchiveMissingError,
20
- KeyArchiveNoPasswordRequiredError,
21
- KeyArchivePasswordRequiredError,
22
- KeyArchiveTypeError,
23
- KeyArchiveVersionError,
24
- KeyNotFoundError,
25
- } from '../../src/errors/error'
26
- import {
27
- InsecureKeyArchive,
28
- InsecureKeyArchiveCodec,
29
- SecureKeyArchive,
30
- SecureKeyArchiveCodec,
31
- } from '../../src/sudoKeyArchive/keyArchive'
32
- import {
33
- KeyArchiveKeyInfo,
34
- KeyArchiveKeyInfoCodec,
35
- } from '../../src/sudoKeyArchive/keyInfo'
36
- import { KeyArchiveKeyType } from '../../src/sudoKeyArchive/keyType'
37
- import { DefaultSudoKeyArchive } from '../../src/sudoKeyArchive/sudoKeyArchive'
38
- import {
39
- KeyData,
40
- KeyDataKeyFormat,
41
- KeyDataKeyType,
42
- SudoCryptoProviderDefaults,
43
- } from '../../src/sudoKeyManager'
44
- import { SudoKeyManager } from '../../src/sudoKeyManager/sudoKeyManager'
45
- import { Base64 } from '../../src/utils/base64'
46
- import { Buffer as BufferUtil } from '../../src/utils/buffer'
47
-
48
- import '../matchers'
49
-
50
- describe('DefaultSudoKeyArchive tests', () => {
51
- const mockKeyManager1 = mock<SudoKeyManager>()
52
- const mockKeyManager2 = mock<SudoKeyManager>()
53
- const keyManager1Namespace = 'key-manager-1'
54
- const keyManager2Namespace = 'key-manager-2'
55
- const password = BufferUtil.fromString('password')
56
-
57
- beforeEach(() => {
58
- reset(mockKeyManager1)
59
- reset(mockKeyManager2)
60
-
61
- when(mockKeyManager1.namespace).thenReturn(keyManager1Namespace)
62
- when(mockKeyManager1.addPassword(anything(), anything())).thenResolve()
63
- when(mockKeyManager1.addPrivateKey(anything(), anything())).thenResolve()
64
- when(mockKeyManager1.addPublicKey(anything(), anything())).thenResolve()
65
- when(mockKeyManager1.addSymmetricKey(anything(), anything())).thenResolve()
66
-
67
- when(mockKeyManager2.namespace).thenReturn(keyManager2Namespace)
68
- when(mockKeyManager2.addPassword(anything(), anything())).thenResolve()
69
- when(mockKeyManager2.addPrivateKey(anything(), anything())).thenResolve()
70
- when(mockKeyManager2.addPublicKey(anything(), anything())).thenResolve()
71
- when(mockKeyManager2.addSymmetricKey(anything(), anything())).thenResolve()
72
- })
73
-
74
- const iv = BufferUtil.fromString('iv')
75
- const ivB64 = Base64.encode(iv)
76
- const salt = BufferUtil.fromString('salt')
77
- const saltB64 = Base64.encode(salt)
78
- const symmetricKey = BufferUtil.fromString('symmetric-key')
79
-
80
- describe('constructor', () => {
81
- describe('with no options parameter and one key manager', () => {
82
- it('should succeed', () => {
83
- new DefaultSudoKeyArchive(instance(mockKeyManager1))
84
- verify(mockKeyManager1.namespace).atLeast(1)
85
- })
86
-
87
- it('should create a sudo key archive with no meta info', () => {
88
- const sudoKeyArchive = new DefaultSudoKeyArchive(
89
- instance(mockKeyManager1),
90
- )
91
- expect(sudoKeyArchive.getMetaInfo()).toEqual(new Map<string, string>())
92
- verify(mockKeyManager1.namespace).atLeast(1)
93
- })
94
-
95
- it('should create a sudo key archive with no excluded keys', () => {
96
- const sudoKeyArchive = new DefaultSudoKeyArchive(
97
- instance(mockKeyManager1),
98
- )
99
- expect(sudoKeyArchive.getExcludedKeys()).toEqual(new Set<string>())
100
- verify(mockKeyManager1.namespace).atLeast(1)
101
- })
102
-
103
- it('should create a sudo key archive with no excluded key types', () => {
104
- const sudoKeyArchive = new DefaultSudoKeyArchive(
105
- instance(mockKeyManager1),
106
- )
107
- expect(sudoKeyArchive.getExcludedKeyTypes()).toEqual(
108
- new Set<KeyArchiveKeyType>(),
109
- )
110
- verify(mockKeyManager1.namespace).atLeast(1)
111
- })
112
- })
113
-
114
- describe('with no options parameter and array of key managers', () => {
115
- it('should succeed', () => {
116
- new DefaultSudoKeyArchive([
117
- instance(mockKeyManager1),
118
- instance(mockKeyManager2),
119
- ])
120
- verify(mockKeyManager1.namespace).atLeast(1)
121
- verify(mockKeyManager2.namespace).atLeast(1)
122
- })
123
-
124
- it('should throw an IllegalArgumentError if key manager array is empty', () => {
125
- expect(() => new DefaultSudoKeyArchive([])).toThrowErrorMatching(
126
- new IllegalArgumentError('Must provide at least one key manager'),
127
- )
128
- })
129
-
130
- it('should throw an IllegalArgumentError if key manager array has key managers with same namespace', () => {
131
- expect(
132
- () =>
133
- new DefaultSudoKeyArchive([
134
- instance(mockKeyManager1),
135
- instance(mockKeyManager1),
136
- ]),
137
- ).toThrowErrorMatching(
138
- new IllegalArgumentError(
139
- `Multiple key managers provided with namespace ${keyManager1Namespace}`,
140
- ),
141
- )
142
- })
143
- })
144
-
145
- describe('with fully populated options parameter but no archive', () => {
146
- let metaInfo: ReadonlyMap<string, string>
147
- let excludedKeyTypes: ReadonlySet<KeyArchiveKeyType>
148
- let excludedKeys: ReadonlySet<string>
149
-
150
- beforeAll(() => {
151
- const newMetaInfo = new Map<string, string>()
152
- newMetaInfo.set('meta-1', 'value-1')
153
- newMetaInfo.set('meta-2', 'value-2')
154
- metaInfo = newMetaInfo
155
-
156
- const newExcludedKeyTypes = new Set<KeyArchiveKeyType>()
157
- newExcludedKeyTypes.add(KeyArchiveKeyType.PublicKey)
158
- excludedKeyTypes = newExcludedKeyTypes
159
-
160
- const newExcludedKeys = new Set<string>()
161
- newExcludedKeys.add('excluded-key-1')
162
- excludedKeys = newExcludedKeys
163
- })
164
-
165
- it('should succeed', () => {
166
- const keyArchive = new DefaultSudoKeyArchive(
167
- instance(mockKeyManager1),
168
- {
169
- metaInfo,
170
- excludedKeys,
171
- excludedKeyTypes,
172
- },
173
- )
174
- verify(mockKeyManager1.namespace).once()
175
-
176
- expect(keyArchive.getExcludedKeys()).toEqual(excludedKeys)
177
- expect(keyArchive.getExcludedKeyTypes()).toEqual(excludedKeyTypes)
178
- expect(keyArchive.getMetaInfo()).toEqual(metaInfo)
179
- })
180
- })
181
-
182
- describe('with archiveData provided', () => {
183
- it('throws KeyArchiveDecodingError if archive data is not gzip data', () => {
184
- expect(
185
- () =>
186
- new DefaultSudoKeyArchive(instance(mockKeyManager1), {
187
- archiveData: BufferUtil.fromString('not gzipped'),
188
- }),
189
- ).toThrowErrorMatching(new KeyArchiveDecodingError())
190
- })
191
-
192
- it('throws KeyArchiveDecodingError if archive data is not gzipped JSON data', () => {
193
- expect(
194
- () =>
195
- new DefaultSudoKeyArchive(instance(mockKeyManager1), {
196
- archiveData: gzipSync(BufferUtil.fromString('not JSON')),
197
- }),
198
- ).toThrowErrorMatching(new KeyArchiveDecodingError())
199
- })
200
-
201
- it('throws KeyArchiveDecodingError if archive data is gzipped JSON data without a Type or Version field', () => {
202
- expect(
203
- () =>
204
- new DefaultSudoKeyArchive(instance(mockKeyManager1), {
205
- archiveData: gzipSync(
206
- BufferUtil.fromString(JSON.stringify({ Some: 'JSON' })),
207
- ),
208
- }),
209
- ).toThrowErrorMatching(new KeyArchiveDecodingError())
210
- })
211
-
212
- it('throws KeyArchiveTypeError if archive data is gzipped JSON data with Type property of unrecognized value', () => {
213
- const unsupportedType = 'Unsupported'
214
- expect(
215
- () =>
216
- new DefaultSudoKeyArchive(instance(mockKeyManager1), {
217
- archiveData: gzipSync(
218
- BufferUtil.fromString(
219
- JSON.stringify({ Type: unsupportedType }),
220
- ),
221
- ),
222
- }),
223
- ).toThrowErrorMatching(new KeyArchiveTypeError(unsupportedType))
224
- })
225
-
226
- it('throws KeyArchiveVersionError if archive data is gzipped JSON data with Type property of unrecognized value', () => {
227
- const unsupportedVersion =
228
- DefaultSudoKeyArchive.CURRENT_ARCHIVE_VERSION + 1
229
- expect(
230
- () =>
231
- new DefaultSudoKeyArchive(instance(mockKeyManager1), {
232
- archiveData: gzipSync(
233
- BufferUtil.fromString(
234
- JSON.stringify({ Version: unsupportedVersion }),
235
- ),
236
- ),
237
- }),
238
- ).toThrowErrorMatching(new KeyArchiveVersionError(unsupportedVersion))
239
- })
240
- })
241
- })
242
-
243
- describe('unarchive', () => {
244
- const keys: KeyArchiveKeyInfo[] = [
245
- {
246
- Name: 'key-1-password',
247
- NameSpace: keyManager1Namespace,
248
- Data: Base64.encode(BufferUtil.fromString('key-1-password-data')),
249
- Exportable: true,
250
- Synchronizable: false,
251
- Type: KeyArchiveKeyType.Password,
252
- },
253
- {
254
- Name: 'key-2-key-pair',
255
- NameSpace: keyManager1Namespace,
256
- Data: Base64.encode(BufferUtil.fromString('key-2-public-key-data')),
257
- Exportable: true,
258
- Synchronizable: false,
259
- Type: KeyArchiveKeyType.PublicKey,
260
- },
261
- {
262
- Name: 'key-2-key-pair',
263
- NameSpace: keyManager1Namespace,
264
- Data: Base64.encode(BufferUtil.fromString('key-2-private-key-data')),
265
- Exportable: true,
266
- Synchronizable: false,
267
- Type: KeyArchiveKeyType.PrivateKey,
268
- },
269
- {
270
- Name: 'key-3-symmetric',
271
- NameSpace: keyManager1Namespace,
272
- Data: Base64.encode(BufferUtil.fromString('key-3-symmetric-data')),
273
- Exportable: true,
274
- Synchronizable: false,
275
- Type: KeyArchiveKeyType.SymmetricKey,
276
- },
277
- ]
278
-
279
- it('throws KeyArchiveMissingError if constructed without archive data', async () => {
280
- const keyArchive = new DefaultSudoKeyArchive(instance(mockKeyManager1))
281
- await expect(keyArchive.unarchive(undefined)).rejects.toMatchError(
282
- new KeyArchiveMissingError(),
283
- )
284
- })
285
-
286
- it('throws KeyArchiveDecodingError if key data cannot be decoded', async () => {
287
- const keyArchive = new DefaultSudoKeyArchive(instance(mockKeyManager1), {
288
- archiveData: gzipSync(
289
- BufferUtil.fromString(
290
- JSON.stringify({
291
- Type: 'Insecure',
292
- Version: DefaultSudoKeyArchive.CURRENT_ARCHIVE_VERSION,
293
- Keys: [
294
- {
295
- Data: 'not base64',
296
- Type: KeyArchiveKeyType.Password,
297
- Name: 'not-base64',
298
- NameSpace: keyManager1Namespace,
299
- },
300
- ],
301
- }),
302
- ),
303
- ),
304
- })
305
-
306
- await expect(keyArchive.unarchive(undefined)).rejects.toMatchError(
307
- new KeyArchiveDecodingError(
308
- `Unable to decode key ${keyManager1Namespace}:${KeyArchiveKeyType.Password}:not-base64`,
309
- ),
310
- )
311
- })
312
-
313
- describe('with insecure archive', () => {
314
- it('throws KeyArchiveNoPasswordRequiredError if a password is provided', async () => {
315
- const insecureArchive: InsecureKeyArchive = {
316
- Type: 'Insecure',
317
- Version: DefaultSudoKeyArchive.CURRENT_ARCHIVE_VERSION,
318
- Keys: [],
319
- MetaInfo: {},
320
- }
321
-
322
- const keyArchive = new DefaultSudoKeyArchive(
323
- instance(mockKeyManager1),
324
- {
325
- archiveData: gzipSync(
326
- BufferUtil.fromString(JSON.stringify(insecureArchive)),
327
- ),
328
- },
329
- )
330
-
331
- await expect(keyArchive.unarchive(password)).rejects.toMatchError(
332
- new KeyArchiveNoPasswordRequiredError(),
333
- )
334
- })
335
-
336
- it('succeeds with no keys', async () => {
337
- const insecureArchive: InsecureKeyArchive = {
338
- Type: 'Insecure',
339
- Version: DefaultSudoKeyArchive.CURRENT_ARCHIVE_VERSION,
340
- Keys: [],
341
- MetaInfo: {},
342
- }
343
-
344
- const keyArchive = new DefaultSudoKeyArchive(
345
- instance(mockKeyManager1),
346
- {
347
- archiveData: gzipSync(
348
- BufferUtil.fromString(JSON.stringify(insecureArchive)),
349
- ),
350
- },
351
- )
352
-
353
- await expect(keyArchive.unarchive(undefined)).resolves.toBeUndefined()
354
-
355
- verify(mockKeyManager1.addPassword(anything(), anything())).never()
356
- verify(mockKeyManager1.addPrivateKey(anything(), anything())).never()
357
- verify(mockKeyManager1.addPublicKey(anything(), anything())).never()
358
- verify(mockKeyManager1.addSymmetricKey(anything(), anything())).never()
359
- })
360
-
361
- it('succeeds with keys of different types', async () => {
362
- const insecureArchive: InsecureKeyArchive = {
363
- Type: 'Insecure',
364
- Version: DefaultSudoKeyArchive.CURRENT_ARCHIVE_VERSION,
365
- Keys: keys,
366
- MetaInfo: {},
367
- }
368
-
369
- const keyArchive = new DefaultSudoKeyArchive(
370
- instance(mockKeyManager1),
371
- {
372
- archiveData: gzipSync(
373
- BufferUtil.fromString(JSON.stringify(insecureArchive)),
374
- ),
375
- },
376
- )
377
-
378
- await expect(keyArchive.unarchive(undefined)).resolves.toBeUndefined()
379
-
380
- keys.forEach((Key) =>
381
- expect(
382
- keyArchive.getKeyData(keyManager1Namespace, Key.Name, Key.Type),
383
- ).toEqual(Base64.decode(Key.Data)),
384
- )
385
- })
386
- })
387
-
388
- describe('with secure archive', () => {
389
- const emptyKeys: KeyArchiveKeyInfo[] = []
390
- const serializedEmptyKeys = JSON.stringify(emptyKeys)
391
- const compressedSerializedEmptyKeys = gzipSync(
392
- BufferUtil.fromString(serializedEmptyKeys),
393
- )
394
- const serializedKeys = JSON.stringify(keys)
395
- const compressedSerializedKeys = gzipSync(
396
- BufferUtil.fromString(serializedKeys),
397
- )
398
- const encryptedEmptyKeys = BufferUtil.fromString('encrypted-empty-keys')
399
- const encryptedEmptyKeysB64 = Base64.encode(encryptedEmptyKeys)
400
- const encryptedKeys = BufferUtil.fromString('encrypted-keys')
401
- const encryptedKeysB64 = Base64.encode(encryptedKeys)
402
-
403
- beforeEach(() => {
404
- when(
405
- mockKeyManager1.generateSymmetricKeyFromPassword(
406
- anything(),
407
- anything(),
408
- anything(),
409
- ),
410
- ).thenResolve(symmetricKey)
411
- when(
412
- mockKeyManager1.decryptWithSymmetricKey(
413
- anything(),
414
- deepEqual(encryptedEmptyKeys),
415
- anything(),
416
- ),
417
- ).thenResolve(compressedSerializedEmptyKeys)
418
- when(
419
- mockKeyManager1.decryptWithSymmetricKey(
420
- anything(),
421
- deepEqual(encryptedKeys),
422
- anything(),
423
- ),
424
- ).thenResolve(compressedSerializedKeys)
425
- })
426
-
427
- it('throws KeyArchivePasswordRequiredError if no password is provided', async () => {
428
- const secureArchive: SecureKeyArchive = {
429
- Type: 'Secure',
430
- Version: DefaultSudoKeyArchive.CURRENT_ARCHIVE_VERSION,
431
- IV: ivB64,
432
- Salt: saltB64,
433
- Rounds: 1,
434
- Keys: encryptedEmptyKeysB64,
435
- MetaInfo: {},
436
- }
437
-
438
- const keyArchive = new DefaultSudoKeyArchive(
439
- instance(mockKeyManager1),
440
- {
441
- archiveData: gzipSync(
442
- BufferUtil.fromString(JSON.stringify(secureArchive)),
443
- ),
444
- },
445
- )
446
-
447
- await expect(keyArchive.unarchive(undefined)).rejects.toMatchError(
448
- new KeyArchivePasswordRequiredError(),
449
- )
450
-
451
- verify(
452
- mockKeyManager1.generateSymmetricKeyFromPassword(
453
- anything(),
454
- anything(),
455
- anything(),
456
- ),
457
- ).never()
458
- verify(
459
- mockKeyManager1.decryptWithSymmetricKey(
460
- anything(),
461
- anything(),
462
- anything(),
463
- ),
464
- ).never()
465
- })
466
-
467
- it('throws KeyArchiveDecodingError if Salt is not decodable as base 64', async () => {
468
- const secureArchive: SecureKeyArchive = {
469
- Type: 'Secure',
470
- Version: DefaultSudoKeyArchive.CURRENT_ARCHIVE_VERSION,
471
- IV: ivB64,
472
- Salt: 'not base64',
473
- Rounds: 1,
474
- Keys: encryptedEmptyKeysB64,
475
- MetaInfo: {},
476
- }
477
-
478
- const keyArchive = new DefaultSudoKeyArchive(
479
- instance(mockKeyManager1),
480
- {
481
- archiveData: gzipSync(
482
- BufferUtil.fromString(JSON.stringify(secureArchive)),
483
- ),
484
- },
485
- )
486
-
487
- await expect(keyArchive.unarchive(password)).rejects.toMatchError(
488
- new KeyArchiveDecodingError(),
489
- )
490
-
491
- verify(
492
- mockKeyManager1.generateSymmetricKeyFromPassword(
493
- anything(),
494
- anything(),
495
- anything(),
496
- ),
497
- ).never()
498
- verify(
499
- mockKeyManager1.decryptWithSymmetricKey(
500
- anything(),
501
- anything(),
502
- anything(),
503
- ),
504
- ).never()
505
- })
506
-
507
- it('throws KeyArchiveDecodingError if IV is not decodable as base 64', async () => {
508
- const secureArchive: SecureKeyArchive = {
509
- Type: 'Secure',
510
- Version: DefaultSudoKeyArchive.CURRENT_ARCHIVE_VERSION,
511
- IV: 'not base64',
512
- Salt: saltB64,
513
- Rounds: 1,
514
- Keys: encryptedEmptyKeysB64,
515
- MetaInfo: {},
516
- }
517
-
518
- const keyArchive = new DefaultSudoKeyArchive(
519
- instance(mockKeyManager1),
520
- {
521
- archiveData: gzipSync(
522
- BufferUtil.fromString(JSON.stringify(secureArchive)),
523
- ),
524
- },
525
- )
526
-
527
- await expect(keyArchive.unarchive(password)).rejects.toMatchError(
528
- new KeyArchiveDecodingError(),
529
- )
530
-
531
- verify(
532
- mockKeyManager1.generateSymmetricKeyFromPassword(
533
- anything(),
534
- anything(),
535
- anything(),
536
- ),
537
- ).never()
538
- verify(
539
- mockKeyManager1.decryptWithSymmetricKey(
540
- anything(),
541
- anything(),
542
- anything(),
543
- ),
544
- ).never()
545
- })
546
-
547
- it('throws KeyArchiveDecodingError if Keys is not decodable as base 64', async () => {
548
- const secureArchive: SecureKeyArchive = {
549
- Type: 'Secure',
550
- Version: DefaultSudoKeyArchive.CURRENT_ARCHIVE_VERSION,
551
- IV: ivB64,
552
- Salt: saltB64,
553
- Rounds: 1,
554
- Keys: 'not base64',
555
- MetaInfo: {},
556
- }
557
-
558
- const keyArchive = new DefaultSudoKeyArchive(
559
- instance(mockKeyManager1),
560
- {
561
- archiveData: gzipSync(
562
- BufferUtil.fromString(JSON.stringify(secureArchive)),
563
- ),
564
- },
565
- )
566
-
567
- await expect(keyArchive.unarchive(password)).rejects.toMatchError(
568
- new KeyArchiveDecodingError(),
569
- )
570
-
571
- verify(
572
- mockKeyManager1.generateSymmetricKeyFromPassword(
573
- anything(),
574
- anything(),
575
- anything(),
576
- ),
577
- ).never()
578
- verify(
579
- mockKeyManager1.decryptWithSymmetricKey(
580
- anything(),
581
- anything(),
582
- anything(),
583
- ),
584
- ).never()
585
- })
586
-
587
- it('throws KeyArchiveDecodingError if symmetric key is unable to be generated', async () => {
588
- const secureArchive: SecureKeyArchive = {
589
- Type: 'Secure',
590
- Version: DefaultSudoKeyArchive.CURRENT_ARCHIVE_VERSION,
591
- IV: ivB64,
592
- Salt: saltB64,
593
- Rounds: 1,
594
- Keys: encryptedEmptyKeysB64,
595
- MetaInfo: {},
596
- }
597
-
598
- const keyArchive = new DefaultSudoKeyArchive(
599
- instance(mockKeyManager1),
600
- {
601
- archiveData: gzipSync(
602
- BufferUtil.fromString(JSON.stringify(secureArchive)),
603
- ),
604
- },
605
- )
606
-
607
- when(
608
- mockKeyManager1.generateSymmetricKeyFromPassword(
609
- anything(),
610
- anything(),
611
- anything(),
612
- ),
613
- ).thenReject(new Error('symmetric key generation failed'))
614
-
615
- await expect(keyArchive.unarchive(password)).rejects.toMatchError(
616
- new KeyArchiveDecodingError(),
617
- )
618
-
619
- verify(
620
- mockKeyManager1.generateSymmetricKeyFromPassword(
621
- anything(),
622
- anything(),
623
- anything(),
624
- ),
625
- ).once()
626
- const [actualPassword, actualSalt, actualOptions] = capture(
627
- mockKeyManager1.generateSymmetricKeyFromPassword,
628
- ).first()
629
- expect(actualPassword).toEqual(password)
630
- expect(actualSalt).toEqual(salt)
631
- expect(actualOptions).toEqual({ rounds: secureArchive.Rounds })
632
-
633
- verify(
634
- mockKeyManager1.decryptWithSymmetricKey(
635
- anything(),
636
- anything(),
637
- anything(),
638
- ),
639
- ).never()
640
- })
641
-
642
- it('throws KeyArchiveIncorrectPasswordError if encrypted compressed serialized keys are unable to be decrypted', async () => {
643
- const secureArchive: SecureKeyArchive = {
644
- Type: 'Secure',
645
- Version: DefaultSudoKeyArchive.CURRENT_ARCHIVE_VERSION,
646
- IV: ivB64,
647
- Salt: saltB64,
648
- Rounds: 1,
649
- Keys: encryptedEmptyKeysB64,
650
- MetaInfo: {},
651
- }
652
-
653
- const keyArchive = new DefaultSudoKeyArchive(
654
- instance(mockKeyManager1),
655
- {
656
- archiveData: gzipSync(
657
- BufferUtil.fromString(JSON.stringify(secureArchive)),
658
- ),
659
- },
660
- )
661
-
662
- when(
663
- mockKeyManager1.decryptWithSymmetricKey(
664
- anything(),
665
- anything(),
666
- anything(),
667
- ),
668
- ).thenReject(new Error('decryption failed'))
669
-
670
- await expect(keyArchive.unarchive(password)).rejects.toMatchError(
671
- new KeyArchiveIncorrectPasswordError(),
672
- )
673
-
674
- verify(
675
- mockKeyManager1.generateSymmetricKeyFromPassword(
676
- anything(),
677
- anything(),
678
- anything(),
679
- ),
680
- ).once()
681
- const [actualPassword, actualSalt, actualOptions] = capture(
682
- mockKeyManager1.generateSymmetricKeyFromPassword,
683
- ).first()
684
- expect(actualPassword).toEqual(password)
685
- expect(actualSalt).toEqual(salt)
686
- expect(actualOptions).toEqual({ rounds: secureArchive.Rounds })
687
-
688
- verify(
689
- mockKeyManager1.decryptWithSymmetricKey(
690
- anything(),
691
- anything(),
692
- anything(),
693
- ),
694
- ).once()
695
- const [actualKey, actualData, symmetricOptions] = capture(
696
- mockKeyManager1.decryptWithSymmetricKey,
697
- ).first()
698
- expect(actualKey).toEqual(symmetricKey)
699
- expect(actualData).toEqual(encryptedEmptyKeys)
700
- expect(symmetricOptions).toBeDefined()
701
- expect(symmetricOptions.iv).toEqual(iv)
702
- })
703
-
704
- it('throws KeyArchiveDecodingError if compressed serialized keys are unable to be uncompressed', async () => {
705
- const secureArchive: SecureKeyArchive = {
706
- Type: 'Secure',
707
- Version: DefaultSudoKeyArchive.CURRENT_ARCHIVE_VERSION,
708
- IV: ivB64,
709
- Salt: saltB64,
710
- Rounds: 1,
711
- Keys: encryptedEmptyKeysB64,
712
- MetaInfo: {},
713
- }
714
-
715
- const keyArchive = new DefaultSudoKeyArchive(
716
- instance(mockKeyManager1),
717
- {
718
- archiveData: gzipSync(
719
- BufferUtil.fromString(JSON.stringify(secureArchive)),
720
- ),
721
- },
722
- )
723
-
724
- when(
725
- mockKeyManager1.decryptWithSymmetricKey(
726
- anything(),
727
- anything(),
728
- anything(),
729
- ),
730
- ).thenResolve(BufferUtil.fromString('not compressed'))
731
-
732
- await expect(keyArchive.unarchive(password)).rejects.toMatchError(
733
- new KeyArchiveDecodingError(),
734
- )
735
-
736
- verify(
737
- mockKeyManager1.generateSymmetricKeyFromPassword(
738
- anything(),
739
- anything(),
740
- anything(),
741
- ),
742
- ).once()
743
- const [actualPassword, actualSalt, actualOptions] = capture(
744
- mockKeyManager1.generateSymmetricKeyFromPassword,
745
- ).first()
746
- expect(actualPassword).toEqual(password)
747
- expect(actualSalt).toEqual(salt)
748
- expect(actualOptions).toEqual({ rounds: secureArchive.Rounds })
749
-
750
- verify(
751
- mockKeyManager1.decryptWithSymmetricKey(
752
- anything(),
753
- anything(),
754
- anything(),
755
- ),
756
- ).once()
757
- const [actualKey, actualData, symmetricOptions] = capture(
758
- mockKeyManager1.decryptWithSymmetricKey,
759
- ).first()
760
- expect(actualKey).toEqual(symmetricKey)
761
- expect(actualData).toEqual(encryptedEmptyKeys)
762
- expect(symmetricOptions).toBeDefined()
763
- expect(symmetricOptions.iv).toEqual(iv)
764
- })
765
-
766
- it('throws KeyArchiveDecodingError if serialized keys are unable to be deserialized', async () => {
767
- const secureArchive: SecureKeyArchive = {
768
- Type: 'Secure',
769
- Version: DefaultSudoKeyArchive.CURRENT_ARCHIVE_VERSION,
770
- IV: ivB64,
771
- Salt: saltB64,
772
- Rounds: 1,
773
- Keys: encryptedEmptyKeysB64,
774
- MetaInfo: {},
775
- }
776
-
777
- const keyArchive = new DefaultSudoKeyArchive(
778
- instance(mockKeyManager1),
779
- {
780
- archiveData: gzipSync(
781
- BufferUtil.fromString(JSON.stringify(secureArchive)),
782
- ),
783
- },
784
- )
785
-
786
- when(
787
- mockKeyManager1.decryptWithSymmetricKey(
788
- anything(),
789
- anything(),
790
- anything(),
791
- ),
792
- ).thenResolve(gzipSync(BufferUtil.fromString('not JSON')))
793
-
794
- await expect(keyArchive.unarchive(password)).rejects.toMatchError(
795
- new KeyArchiveDecodingError(),
796
- )
797
-
798
- verify(
799
- mockKeyManager1.generateSymmetricKeyFromPassword(
800
- anything(),
801
- anything(),
802
- anything(),
803
- ),
804
- ).once()
805
- const [actualPassword, actualSalt, actualOptions] = capture(
806
- mockKeyManager1.generateSymmetricKeyFromPassword,
807
- ).first()
808
- expect(actualPassword).toEqual(password)
809
- expect(actualSalt).toEqual(salt)
810
- expect(actualOptions).toEqual({ rounds: secureArchive.Rounds })
811
-
812
- verify(
813
- mockKeyManager1.decryptWithSymmetricKey(
814
- anything(),
815
- anything(),
816
- anything(),
817
- ),
818
- ).once()
819
- const [actualKey, actualData, symmetricOptions] = capture(
820
- mockKeyManager1.decryptWithSymmetricKey,
821
- ).first()
822
- expect(actualKey).toEqual(symmetricKey)
823
- expect(actualData).toEqual(encryptedEmptyKeys)
824
- expect(symmetricOptions).toBeDefined()
825
- expect(symmetricOptions.iv).toEqual(iv)
826
- })
827
-
828
- it('succeeds with an empty key array', async () => {
829
- const secureArchive: SecureKeyArchive = {
830
- Type: 'Secure',
831
- Version: DefaultSudoKeyArchive.CURRENT_ARCHIVE_VERSION,
832
- IV: ivB64,
833
- Salt: saltB64,
834
- Rounds: 1,
835
- Keys: encryptedEmptyKeysB64,
836
- MetaInfo: {},
837
- }
838
-
839
- const keyArchive = new DefaultSudoKeyArchive(
840
- instance(mockKeyManager1),
841
- {
842
- archiveData: gzipSync(
843
- BufferUtil.fromString(JSON.stringify(secureArchive)),
844
- ),
845
- },
846
- )
847
-
848
- await expect(keyArchive.unarchive(password)).resolves.toBeUndefined()
849
-
850
- verify(
851
- mockKeyManager1.generateSymmetricKeyFromPassword(
852
- anything(),
853
- anything(),
854
- anything(),
855
- ),
856
- ).once()
857
- const [actualPassword, actualSalt, actualOptions] = capture(
858
- mockKeyManager1.generateSymmetricKeyFromPassword,
859
- ).first()
860
- expect(actualPassword).toEqual(password)
861
- expect(actualSalt).toEqual(salt)
862
- expect(actualOptions).toEqual({ rounds: secureArchive.Rounds })
863
-
864
- verify(
865
- mockKeyManager1.decryptWithSymmetricKey(
866
- anything(),
867
- anything(),
868
- anything(),
869
- ),
870
- ).once()
871
- const [actualKey, actualData, symmetricOptions] = capture(
872
- mockKeyManager1.decryptWithSymmetricKey,
873
- ).first()
874
- expect(actualKey).toEqual(symmetricKey)
875
- expect(actualData).toEqual(encryptedEmptyKeys)
876
- expect(symmetricOptions.iv).toEqual(iv)
877
- })
878
-
879
- it('succeeds with an non-empty key array', async () => {
880
- const secureArchive: SecureKeyArchive = {
881
- Type: 'Secure',
882
- Version: DefaultSudoKeyArchive.CURRENT_ARCHIVE_VERSION,
883
- IV: ivB64,
884
- Salt: saltB64,
885
- Rounds: 1,
886
- Keys: encryptedKeysB64,
887
- MetaInfo: {},
888
- }
889
-
890
- const keyArchive = new DefaultSudoKeyArchive(
891
- instance(mockKeyManager1),
892
- {
893
- archiveData: gzipSync(
894
- BufferUtil.fromString(JSON.stringify(secureArchive)),
895
- ),
896
- },
897
- )
898
-
899
- await expect(keyArchive.unarchive(password)).resolves.toBeUndefined()
900
-
901
- verify(
902
- mockKeyManager1.generateSymmetricKeyFromPassword(
903
- anything(),
904
- anything(),
905
- anything(),
906
- ),
907
- ).once()
908
- const [actualPassword, actualSalt, actualOptions] = capture(
909
- mockKeyManager1.generateSymmetricKeyFromPassword,
910
- ).first()
911
- expect(actualPassword).toEqual(password)
912
- expect(actualSalt).toEqual(salt)
913
- expect(actualOptions).toEqual({ rounds: secureArchive.Rounds })
914
-
915
- verify(
916
- mockKeyManager1.decryptWithSymmetricKey(
917
- anything(),
918
- anything(),
919
- anything(),
920
- ),
921
- ).once()
922
- const [actualKey, actualData, symmetricOptions] = capture(
923
- mockKeyManager1.decryptWithSymmetricKey,
924
- ).first()
925
- expect(actualKey).toEqual(symmetricKey)
926
- expect(actualData).toEqual(encryptedKeys)
927
- expect(symmetricOptions.iv).toEqual(iv)
928
-
929
- keys.forEach((key) =>
930
- expect(
931
- keyArchive.getKeyData(keyManager1Namespace, key.Name, key.Type),
932
- ).toEqual(Base64.decode(key.Data)),
933
- )
934
- })
935
- it('succeeds with an non-empty key array', async () => {
936
- const secureArchive: SecureKeyArchive = {
937
- Type: 'Secure',
938
- Version: DefaultSudoKeyArchive.CURRENT_ARCHIVE_VERSION,
939
- IV: ivB64,
940
- Salt: saltB64,
941
- Rounds: 1,
942
- Keys: encryptedKeysB64,
943
- MetaInfo: {},
944
- }
945
-
946
- const keyArchive = new DefaultSudoKeyArchive(
947
- instance(mockKeyManager1),
948
- {
949
- archiveData: gzipSync(
950
- BufferUtil.fromString(JSON.stringify(secureArchive)),
951
- ),
952
- },
953
- )
954
-
955
- await expect(keyArchive.unarchive(password)).resolves.toBeUndefined()
956
-
957
- verify(
958
- mockKeyManager1.generateSymmetricKeyFromPassword(
959
- anything(),
960
- anything(),
961
- anything(),
962
- ),
963
- ).once()
964
- const [actualPassword, actualSalt, actualOptions] = capture(
965
- mockKeyManager1.generateSymmetricKeyFromPassword,
966
- ).first()
967
- expect(actualPassword).toEqual(password)
968
- expect(actualSalt).toEqual(salt)
969
- expect(actualOptions).toEqual({ rounds: secureArchive.Rounds })
970
-
971
- verify(
972
- mockKeyManager1.decryptWithSymmetricKey(
973
- anything(),
974
- anything(),
975
- anything(),
976
- ),
977
- ).once()
978
- const [actualKey, actualData, symmetricOptions] = capture(
979
- mockKeyManager1.decryptWithSymmetricKey,
980
- ).first()
981
- expect(actualKey).toEqual(symmetricKey)
982
- expect(actualData).toEqual(encryptedKeys)
983
- expect(symmetricOptions.iv).toEqual(iv)
984
-
985
- keys.forEach((key) =>
986
- expect(
987
- keyArchive.getKeyData(keyManager1Namespace, key.Name, key.Type),
988
- ).toEqual(Base64.decode(key.Data)),
989
- )
990
- })
991
- })
992
- })
993
-
994
- type AddFn = (data: ArrayBuffer, name: string) => Promise<void>
995
- function getAddFn(key: KeyArchiveKeyInfo): AddFn {
996
- switch (key.Type) {
997
- case KeyArchiveKeyType.Password:
998
- return key.NameSpace === keyManager1Namespace
999
- ? mockKeyManager1.addPassword
1000
- : mockKeyManager2.addPassword
1001
- case KeyArchiveKeyType.PublicKey:
1002
- return key.NameSpace === keyManager1Namespace
1003
- ? mockKeyManager1.addPublicKey
1004
- : mockKeyManager2.addPublicKey
1005
- case KeyArchiveKeyType.PrivateKey:
1006
- return key.NameSpace === keyManager1Namespace
1007
- ? mockKeyManager1.addPrivateKey
1008
- : mockKeyManager2.addPrivateKey
1009
- case KeyArchiveKeyType.SymmetricKey:
1010
- return key.NameSpace === keyManager1Namespace
1011
- ? mockKeyManager1.addSymmetricKey
1012
- : mockKeyManager2.addSymmetricKey
1013
- }
1014
- }
1015
-
1016
- const password1: KeyArchiveKeyInfo = {
1017
- Name: 'key-1-password',
1018
- NameSpace: keyManager1Namespace,
1019
- Data: Base64.encode(BufferUtil.fromString('1-key-1-password-data')),
1020
- Exportable: true,
1021
- Synchronizable: false,
1022
- Type: KeyArchiveKeyType.Password,
1023
- }
1024
- const publicKey1: KeyArchiveKeyInfo = {
1025
- Name: 'key-2-key-pair',
1026
- NameSpace: keyManager1Namespace,
1027
- Data: Base64.encode(BufferUtil.fromString('1-key-2-public-key-data')),
1028
- Exportable: true,
1029
- Synchronizable: false,
1030
- Type: KeyArchiveKeyType.PublicKey,
1031
- }
1032
- const privateKey1: KeyArchiveKeyInfo = {
1033
- Name: 'key-2-key-pair',
1034
- NameSpace: keyManager1Namespace,
1035
- Data: Base64.encode(BufferUtil.fromString('1-key-2-private-key-data')),
1036
- Exportable: true,
1037
- Synchronizable: false,
1038
- Type: KeyArchiveKeyType.PrivateKey,
1039
- }
1040
- const symmetricKey1: KeyArchiveKeyInfo = {
1041
- Name: 'key-3-symmetric',
1042
- NameSpace: keyManager1Namespace,
1043
- Data: Base64.encode(BufferUtil.fromString('1-key-3-symmetric-data')),
1044
- Exportable: true,
1045
- Synchronizable: false,
1046
- Type: KeyArchiveKeyType.SymmetricKey,
1047
- }
1048
- const password2: KeyArchiveKeyInfo = {
1049
- Name: 'key-1-password',
1050
- NameSpace: keyManager2Namespace,
1051
- Data: Base64.encode(BufferUtil.fromString('2-key-1-password-data')),
1052
- Exportable: true,
1053
- Synchronizable: false,
1054
- Type: KeyArchiveKeyType.Password,
1055
- }
1056
- const publicKey2: KeyArchiveKeyInfo = {
1057
- Name: 'key-2-key-pair',
1058
- NameSpace: keyManager2Namespace,
1059
- Data: Base64.encode(BufferUtil.fromString('2-key-2-public-key-data')),
1060
- Exportable: true,
1061
- Synchronizable: false,
1062
- Type: KeyArchiveKeyType.PublicKey,
1063
- }
1064
- const privateKey2: KeyArchiveKeyInfo = {
1065
- Name: 'key-2-key-pair',
1066
- NameSpace: keyManager2Namespace,
1067
- Data: Base64.encode(BufferUtil.fromString('2-key-2-private-key-data')),
1068
- Exportable: true,
1069
- Synchronizable: false,
1070
- Type: KeyArchiveKeyType.PrivateKey,
1071
- }
1072
-
1073
- const symmetricKey2: KeyArchiveKeyInfo = {
1074
- Name: 'key-3-symmetric',
1075
- NameSpace: keyManager2Namespace,
1076
- Data: Base64.encode(BufferUtil.fromString('2-key-3-symmetric-data')),
1077
- Exportable: true,
1078
- Synchronizable: false,
1079
- Type: KeyArchiveKeyType.SymmetricKey,
1080
- }
1081
- const keys: KeyArchiveKeyInfo[] = [
1082
- password1,
1083
- publicKey1,
1084
- privateKey1,
1085
- symmetricKey1,
1086
- password2,
1087
- publicKey2,
1088
- privateKey2,
1089
- symmetricKey2,
1090
- ]
1091
-
1092
- function keyArchiveKeyTypeToKeyDataKeyType(
1093
- keyArchiveInfoKeyType: KeyArchiveKeyType,
1094
- ): KeyDataKeyType {
1095
- switch (keyArchiveInfoKeyType) {
1096
- case KeyArchiveKeyType.Password:
1097
- return KeyDataKeyType.Password
1098
- case KeyArchiveKeyType.PrivateKey:
1099
- return KeyDataKeyType.RSAPrivateKey
1100
- case KeyArchiveKeyType.PublicKey:
1101
- return KeyDataKeyType.RSAPublicKey
1102
- case KeyArchiveKeyType.SymmetricKey:
1103
- return KeyDataKeyType.SymmetricKey
1104
- }
1105
- }
1106
- function keyArchiveInfoToKeyData(keyInfo: KeyArchiveKeyInfo): KeyData {
1107
- let format: KeyDataKeyFormat
1108
- switch (keyInfo.Type) {
1109
- case KeyArchiveKeyType.Password:
1110
- format = KeyDataKeyFormat.Raw
1111
- break
1112
- case KeyArchiveKeyType.PublicKey:
1113
- format = KeyDataKeyFormat.SPKI
1114
- break
1115
- case KeyArchiveKeyType.PrivateKey:
1116
- format = KeyDataKeyFormat.PKCS8
1117
- break
1118
- case KeyArchiveKeyType.SymmetricKey:
1119
- format = KeyDataKeyFormat.Raw
1120
- break
1121
- }
1122
- return {
1123
- namespace: keyInfo.NameSpace,
1124
- name: keyInfo.Name,
1125
- type: keyArchiveKeyTypeToKeyDataKeyType(keyInfo.Type),
1126
- data: Base64.decode(keyInfo.Data),
1127
- format,
1128
- }
1129
- }
1130
-
1131
- describe('saveKeys', () => {
1132
- let insecureKeyArchiveData: ArrayBuffer
1133
-
1134
- beforeEach(() => {
1135
- const insecureArchive: InsecureKeyArchive = {
1136
- Type: 'Insecure',
1137
- Version: DefaultSudoKeyArchive.CURRENT_ARCHIVE_VERSION,
1138
- Keys: keys,
1139
- MetaInfo: {},
1140
- }
1141
-
1142
- insecureKeyArchiveData = gzipSync(
1143
- BufferUtil.fromString(JSON.stringify(insecureArchive)),
1144
- )
1145
- })
1146
-
1147
- it('should save keys to correct key manager in correct way', async () => {
1148
- const keyArchive = new DefaultSudoKeyArchive(
1149
- [instance(mockKeyManager1), instance(mockKeyManager2)],
1150
- { archiveData: insecureKeyArchiveData },
1151
- )
1152
- await expect(keyArchive.unarchive(undefined)).resolves.toBeUndefined()
1153
- await expect(keyArchive.saveKeys()).resolves.toBeUndefined()
1154
-
1155
- verify(mockKeyManager1.addSymmetricKey(anything(), anything())).once()
1156
- verify(mockKeyManager1.addPublicKey(anything(), anything())).once()
1157
- verify(mockKeyManager1.addPrivateKey(anything(), anything())).once()
1158
- verify(mockKeyManager1.addPassword(anything(), anything())).once()
1159
- verify(mockKeyManager2.addSymmetricKey(anything(), anything())).once()
1160
- verify(mockKeyManager2.addPublicKey(anything(), anything())).once()
1161
- verify(mockKeyManager2.addPrivateKey(anything(), anything())).once()
1162
- verify(mockKeyManager2.addPassword(anything(), anything())).once()
1163
-
1164
- for (const key of keys) {
1165
- const addFn = getAddFn(key)
1166
- const [actualData, actualName] = capture(addFn).first()
1167
- expect(actualData).toEqual(Base64.decode(key.Data))
1168
- expect(actualName).toEqual(key.Name)
1169
- }
1170
- })
1171
-
1172
- it('should omit excluded key types', async () => {
1173
- const keyArchive = new DefaultSudoKeyArchive(
1174
- [instance(mockKeyManager1), instance(mockKeyManager2)],
1175
- {
1176
- archiveData: insecureKeyArchiveData,
1177
- excludedKeyTypes: new Set([KeyArchiveKeyType.PublicKey]),
1178
- },
1179
- )
1180
- await expect(keyArchive.unarchive(undefined)).resolves.toBeUndefined()
1181
- await expect(keyArchive.saveKeys()).resolves.toBeUndefined()
1182
-
1183
- verify(mockKeyManager1.addPublicKey(anything(), anything())).never()
1184
- verify(mockKeyManager2.addPublicKey(anything(), anything())).never()
1185
-
1186
- verify(mockKeyManager1.addSymmetricKey(anything(), anything())).once()
1187
- verify(mockKeyManager1.addPrivateKey(anything(), anything())).once()
1188
- verify(mockKeyManager1.addPassword(anything(), anything())).once()
1189
- verify(mockKeyManager2.addSymmetricKey(anything(), anything())).once()
1190
- verify(mockKeyManager2.addPrivateKey(anything(), anything())).once()
1191
- verify(mockKeyManager2.addPassword(anything(), anything())).once()
1192
-
1193
- for (const key of keys) {
1194
- if (key.Type === KeyArchiveKeyType.PublicKey) continue
1195
-
1196
- const addFn = getAddFn(key)
1197
- const [actualData, actualName] = capture(addFn).first()
1198
- expect(actualData).toEqual(Base64.decode(key.Data))
1199
- expect(actualName).toEqual(key.Name)
1200
- }
1201
- })
1202
-
1203
- it('should omit excluded key names', async () => {
1204
- const keyArchive = new DefaultSudoKeyArchive(
1205
- [instance(mockKeyManager1), instance(mockKeyManager2)],
1206
- {
1207
- archiveData: insecureKeyArchiveData,
1208
- excludedKeys: new Set([password1.Name]),
1209
- },
1210
- )
1211
- await expect(keyArchive.unarchive(undefined)).resolves.toBeUndefined()
1212
- await expect(keyArchive.saveKeys()).resolves.toBeUndefined()
1213
-
1214
- verify(mockKeyManager1.addPassword(anything(), anything())).never()
1215
- verify(mockKeyManager2.addPassword(anything(), anything())).never()
1216
-
1217
- verify(mockKeyManager1.addSymmetricKey(anything(), anything())).once()
1218
- verify(mockKeyManager1.addPublicKey(anything(), anything())).once()
1219
- verify(mockKeyManager1.addPrivateKey(anything(), anything())).once()
1220
- verify(mockKeyManager2.addSymmetricKey(anything(), anything())).once()
1221
- verify(mockKeyManager2.addPublicKey(anything(), anything())).once()
1222
- verify(mockKeyManager2.addPrivateKey(anything(), anything())).once()
1223
-
1224
- for (const key of keys) {
1225
- if (key.Name === password1.Name) continue
1226
-
1227
- const addFn = getAddFn(key)
1228
- const [actualData, actualName] = capture(addFn).first()
1229
- expect(actualData).toEqual(Base64.decode(key.Data))
1230
- expect(actualName).toEqual(key.Name)
1231
- }
1232
- })
1233
-
1234
- it('should omit keys without a matching key manager namespace', async () => {
1235
- const keyArchive = new DefaultSudoKeyArchive(
1236
- [instance(mockKeyManager1)],
1237
- {
1238
- archiveData: insecureKeyArchiveData,
1239
- },
1240
- )
1241
- await expect(keyArchive.unarchive(undefined)).resolves.toBeUndefined()
1242
- await expect(keyArchive.saveKeys()).resolves.toBeUndefined()
1243
-
1244
- verify(mockKeyManager1.addPassword(anything(), anything())).once()
1245
- verify(mockKeyManager1.addSymmetricKey(anything(), anything())).once()
1246
- verify(mockKeyManager1.addPublicKey(anything(), anything())).once()
1247
- verify(mockKeyManager1.addPrivateKey(anything(), anything())).once()
1248
-
1249
- verify(mockKeyManager2.addPassword(anything(), anything())).never()
1250
- verify(mockKeyManager2.addSymmetricKey(anything(), anything())).never()
1251
- verify(mockKeyManager2.addPublicKey(anything(), anything())).never()
1252
- verify(mockKeyManager2.addPrivateKey(anything(), anything())).never()
1253
-
1254
- for (const key of keys) {
1255
- if (key.NameSpace === keyManager2Namespace) continue
1256
-
1257
- const addFn = getAddFn(key)
1258
- const [actualData, actualName] = capture(addFn).first()
1259
- expect(actualData).toEqual(Base64.decode(key.Data))
1260
- expect(actualName).toEqual(key.Name)
1261
- }
1262
- })
1263
- })
1264
-
1265
- describe('loadKeys', () => {
1266
- it('should load keys from all key managers', async () => {
1267
- when(mockKeyManager1.exportKeys()).thenResolve(
1268
- keys
1269
- .filter((key) => key.NameSpace === keyManager1Namespace)
1270
- .map(keyArchiveInfoToKeyData),
1271
- )
1272
- when(mockKeyManager2.exportKeys()).thenResolve(
1273
- keys
1274
- .filter((key) => key.NameSpace === keyManager2Namespace)
1275
- .map(keyArchiveInfoToKeyData),
1276
- )
1277
-
1278
- const keyArchive = new DefaultSudoKeyArchive([
1279
- instance(mockKeyManager1),
1280
- instance(mockKeyManager2),
1281
- ])
1282
-
1283
- await expect(keyArchive.loadKeys()).resolves.toBeUndefined()
1284
-
1285
- keys.forEach((key) =>
1286
- expect(
1287
- keyArchive.containsKey(key.NameSpace, key.Name, key.Type),
1288
- ).toEqual(true),
1289
- )
1290
-
1291
- verify(mockKeyManager1.exportKeys()).once()
1292
- verify(mockKeyManager2.exportKeys()).once()
1293
- })
1294
-
1295
- it('should omit keys from excluded key types', async () => {
1296
- when(mockKeyManager1.exportKeys()).thenResolve(
1297
- keys
1298
- .filter((key) => key.NameSpace === keyManager1Namespace)
1299
- .map(keyArchiveInfoToKeyData),
1300
- )
1301
- when(mockKeyManager2.exportKeys()).thenResolve(
1302
- keys
1303
- .filter((key) => key.NameSpace === keyManager2Namespace)
1304
- .map(keyArchiveInfoToKeyData),
1305
- )
1306
-
1307
- const keyArchive = new DefaultSudoKeyArchive(
1308
- [instance(mockKeyManager1), instance(mockKeyManager2)],
1309
- {
1310
- excludedKeyTypes: new Set([KeyArchiveKeyType.PublicKey]),
1311
- },
1312
- )
1313
-
1314
- await expect(keyArchive.loadKeys()).resolves.toBeUndefined()
1315
-
1316
- keys.forEach((key) =>
1317
- expect(
1318
- keyArchive.containsKey(key.NameSpace, key.Name, key.Type),
1319
- ).toEqual(key.Type !== KeyArchiveKeyType.PublicKey),
1320
- )
1321
-
1322
- verify(mockKeyManager1.exportKeys()).once()
1323
- verify(mockKeyManager2.exportKeys()).once()
1324
- })
1325
-
1326
- it('should omit keys with excluded names', async () => {
1327
- when(mockKeyManager1.exportKeys()).thenResolve(
1328
- keys
1329
- .filter((key) => key.NameSpace === keyManager1Namespace)
1330
- .map(keyArchiveInfoToKeyData),
1331
- )
1332
- when(mockKeyManager2.exportKeys()).thenResolve(
1333
- keys
1334
- .filter((key) => key.NameSpace === keyManager2Namespace)
1335
- .map(keyArchiveInfoToKeyData),
1336
- )
1337
-
1338
- const keyArchive = new DefaultSudoKeyArchive(
1339
- [instance(mockKeyManager1), instance(mockKeyManager2)],
1340
- {
1341
- excludedKeys: new Set([password1.Name]),
1342
- },
1343
- )
1344
-
1345
- await expect(keyArchive.loadKeys()).resolves.toBeUndefined()
1346
-
1347
- keys.forEach((key) =>
1348
- expect(
1349
- keyArchive.containsKey(key.NameSpace, key.Name, key.Type),
1350
- ).toEqual(key.Name !== password1.Name),
1351
- )
1352
-
1353
- verify(mockKeyManager1.exportKeys()).once()
1354
- verify(mockKeyManager2.exportKeys()).once()
1355
- })
1356
- })
1357
-
1358
- describe('archive', () => {
1359
- const metaInfoRecord = { some: 'meta', info: 'provided' }
1360
- const metaInfo = new Map<string, string>(
1361
- Object.entries(metaInfoRecord).map(([k, v]) => [k, v]),
1362
- )
1363
-
1364
- beforeEach(() => {
1365
- when(mockKeyManager1.exportKeys()).thenResolve(
1366
- keys
1367
- .filter((key) => key.NameSpace === keyManager1Namespace)
1368
- .map(keyArchiveInfoToKeyData),
1369
- )
1370
- when(mockKeyManager2.exportKeys()).thenResolve(
1371
- keys
1372
- .filter((key) => key.NameSpace === keyManager2Namespace)
1373
- .map(keyArchiveInfoToKeyData),
1374
- )
1375
- })
1376
-
1377
- describe('without password', () => {
1378
- it.each`
1379
- name | withMetaInfo
1380
- ${'with MetaInfo'} | ${true}
1381
- ${'without MetaInfo'} | ${false}
1382
- `(
1383
- 'should produce an insecure archive $name',
1384
- async ({ withMetaInfo }) => {
1385
- const keyArchive = new DefaultSudoKeyArchive(
1386
- [instance(mockKeyManager1), instance(mockKeyManager2)],
1387
- { metaInfo: withMetaInfo ? metaInfo : undefined },
1388
- )
1389
-
1390
- await expect(keyArchive.loadKeys()).resolves.toBeUndefined()
1391
-
1392
- const archive = await keyArchive.archive(undefined)
1393
- const unzipped = gunzipSync(new Uint8Array(archive))
1394
- const string = BufferUtil.toString(unzipped)
1395
- const deserialized = JSON.parse(string)
1396
- const decoded = InsecureKeyArchiveCodec.decode(deserialized)
1397
- expect(isRight(decoded)).toEqual(true)
1398
- if (!isRight(decoded)) throw new Error('decoded unexpectedly lefty')
1399
- const insecureKeyArchive = decoded.right
1400
- expect(insecureKeyArchive).toMatchObject({
1401
- Type: 'Insecure',
1402
- Version: DefaultSudoKeyArchive.CURRENT_ARCHIVE_VERSION,
1403
- MetaInfo: withMetaInfo ? metaInfoRecord : {},
1404
- })
1405
- expect(insecureKeyArchive.Keys).toHaveLength(keys.length)
1406
- keys.forEach((key) =>
1407
- expect(insecureKeyArchive.Keys).toContainEqual(key),
1408
- )
1409
- },
1410
- )
1411
- })
1412
-
1413
- describe('with password', () => {
1414
- const encryptedKeys = BufferUtil.fromString('encrypted-keys')
1415
-
1416
- it.each`
1417
- name | withMetaInfo
1418
- ${'with MetaInfo'} | ${true}
1419
- ${'without MetaInfo'} | ${false}
1420
- `(
1421
- 'should produce an insecure archive $name',
1422
- async ({ withMetaInfo }) => {
1423
- const keyArchive = new DefaultSudoKeyArchive(
1424
- [instance(mockKeyManager1), instance(mockKeyManager2)],
1425
- { metaInfo: withMetaInfo ? metaInfo : undefined },
1426
- )
1427
-
1428
- await expect(keyArchive.loadKeys()).resolves.toBeUndefined()
1429
-
1430
- when(mockKeyManager1.generateRandomData(anything())).thenResolve(
1431
- salt,
1432
- iv,
1433
- )
1434
- when(
1435
- mockKeyManager1.generateSymmetricKeyFromPassword(
1436
- anything(),
1437
- anything(),
1438
- anything(),
1439
- ),
1440
- ).thenResolve(symmetricKey)
1441
- when(
1442
- mockKeyManager1.encryptWithSymmetricKey(
1443
- anything(),
1444
- anything(),
1445
- anything(),
1446
- ),
1447
- ).thenResolve(encryptedKeys)
1448
-
1449
- const archive = await keyArchive.archive(password)
1450
-
1451
- const unzipped = gunzipSync(new Uint8Array(archive))
1452
- const string = BufferUtil.toString(unzipped)
1453
- const deserialized = JSON.parse(string)
1454
- const decoded = SecureKeyArchiveCodec.decode(deserialized)
1455
- expect(isRight(decoded)).toEqual(true)
1456
- if (!isRight(decoded)) throw new Error('decoded unexpectedly lefty')
1457
- const secureKeyArchive = decoded.right
1458
- expect(secureKeyArchive).toEqual({
1459
- Type: 'Secure',
1460
- Version: DefaultSudoKeyArchive.CURRENT_ARCHIVE_VERSION,
1461
- IV: ivB64,
1462
- Salt: saltB64,
1463
- Rounds: SudoCryptoProviderDefaults.pbkdfRounds,
1464
- Keys: Base64.encode(encryptedKeys),
1465
- MetaInfo: withMetaInfo ? metaInfoRecord : {},
1466
- })
1467
-
1468
- verify(mockKeyManager1.exportKeys()).once()
1469
- verify(mockKeyManager2.exportKeys()).once()
1470
-
1471
- verify(mockKeyManager1.generateRandomData(anything())).twice()
1472
- const [actualSaltSize] = capture(
1473
- mockKeyManager1.generateRandomData,
1474
- ).first()
1475
- expect(actualSaltSize).toEqual(
1476
- SudoCryptoProviderDefaults.pbkdfSaltSize,
1477
- )
1478
- const [actualIVSize] = capture(
1479
- mockKeyManager1.generateRandomData,
1480
- ).second()
1481
- expect(actualIVSize).toEqual(SudoCryptoProviderDefaults.aesIVSize)
1482
-
1483
- verify(
1484
- mockKeyManager1.generateSymmetricKeyFromPassword(
1485
- anything(),
1486
- anything(),
1487
- anything(),
1488
- ),
1489
- ).once()
1490
- const [actualPassword, actualSalt, actualOptions] = capture(
1491
- mockKeyManager1.generateSymmetricKeyFromPassword,
1492
- ).first()
1493
- expect(actualPassword).toEqual(password)
1494
- expect(actualSalt).toEqual(salt)
1495
- expect(actualOptions).toEqual({
1496
- rounds: SudoCryptoProviderDefaults.pbkdfRounds,
1497
- })
1498
-
1499
- verify(
1500
- mockKeyManager1.encryptWithSymmetricKey(
1501
- anything(),
1502
- anything(),
1503
- anything(),
1504
- ),
1505
- ).once()
1506
- const [actualKey, actualData, symmetricOptions] = capture(
1507
- mockKeyManager1.encryptWithSymmetricKey,
1508
- ).first()
1509
- expect(actualKey).toEqual(symmetricKey)
1510
- expect(symmetricOptions.iv).toEqual(iv)
1511
-
1512
- const uncompressedData = gunzipSync(new Uint8Array(actualData))
1513
- const deserializedData = JSON.parse(
1514
- BufferUtil.toString(uncompressedData),
1515
- )
1516
- const decodedData = t
1517
- .array(KeyArchiveKeyInfoCodec)
1518
- .decode(deserializedData)
1519
- expect(isRight(decodedData)).toEqual(true)
1520
- if (isLeft(decodedData)) {
1521
- throw new Error('decodedData unexpectedly lefty')
1522
- }
1523
- const actualKeys = decodedData.right
1524
- expect(actualKeys).toHaveLength(keys.length)
1525
- keys.forEach((key) => expect(actualKeys).toContainEqual(key))
1526
- },
1527
- )
1528
- })
1529
- })
1530
-
1531
- describe('getKeyData', () => {
1532
- it('should throw a KeyNotFoundError if archive does not contain requested key', () => {
1533
- const insecureArchive: InsecureKeyArchive = {
1534
- Type: 'Insecure',
1535
- Version: DefaultSudoKeyArchive.CURRENT_ARCHIVE_VERSION,
1536
- Keys: [],
1537
- MetaInfo: {},
1538
- }
1539
-
1540
- const keyArchive = new DefaultSudoKeyArchive(instance(mockKeyManager1), {
1541
- archiveData: gzipSync(
1542
- BufferUtil.fromString(JSON.stringify(insecureArchive)),
1543
- ),
1544
- })
1545
-
1546
- expect(() =>
1547
- keyArchive.getKeyData(
1548
- keyManager1Namespace,
1549
- 'not-found',
1550
- KeyArchiveKeyType.Password,
1551
- ),
1552
- ).toThrowErrorMatching(new KeyNotFoundError())
1553
- })
1554
-
1555
- it('should return keys from the archive', async () => {
1556
- const insecureArchive: InsecureKeyArchive = {
1557
- Type: 'Insecure',
1558
- Version: DefaultSudoKeyArchive.CURRENT_ARCHIVE_VERSION,
1559
- Keys: keys,
1560
- MetaInfo: {},
1561
- }
1562
-
1563
- const keyArchive = new DefaultSudoKeyArchive(instance(mockKeyManager1), {
1564
- archiveData: gzipSync(
1565
- BufferUtil.fromString(JSON.stringify(insecureArchive)),
1566
- ),
1567
- })
1568
-
1569
- await keyArchive.unarchive(undefined)
1570
-
1571
- keys.forEach((key) =>
1572
- expect(
1573
- keyArchive.getKeyData(key.NameSpace, key.Name, key.Type),
1574
- ).toEqual(Base64.decode(key.Data)),
1575
- )
1576
- })
1577
- })
1578
-
1579
- describe('reset', () => {
1580
- it('should clear out keys from the archive', async () => {
1581
- const insecureArchive: InsecureKeyArchive = {
1582
- Type: 'Insecure',
1583
- Version: DefaultSudoKeyArchive.CURRENT_ARCHIVE_VERSION,
1584
- Keys: keys,
1585
- MetaInfo: {},
1586
- }
1587
-
1588
- const keyArchive = new DefaultSudoKeyArchive(instance(mockKeyManager1), {
1589
- archiveData: gzipSync(
1590
- BufferUtil.fromString(JSON.stringify(insecureArchive)),
1591
- ),
1592
- })
1593
-
1594
- await keyArchive.unarchive(undefined)
1595
-
1596
- keys.forEach((key) =>
1597
- expect(
1598
- keyArchive.containsKey(key.NameSpace, key.Name, key.Type),
1599
- ).toEqual(true),
1600
- )
1601
- keyArchive.reset()
1602
- keys.forEach((key) =>
1603
- expect(
1604
- keyArchive.containsKey(key.NameSpace, key.Name, key.Type),
1605
- ).toEqual(false),
1606
- )
1607
- })
1608
- })
1609
- })