@wirebench/engine 2.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (583) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +3 -0
  3. package/dist/assert/contract.d.ts +3 -0
  4. package/dist/assert/contract.js +17 -0
  5. package/dist/assert/index.d.ts +4 -0
  6. package/dist/assert/index.js +27 -0
  7. package/dist/assert/match.d.ts +3 -0
  8. package/dist/assert/match.js +58 -0
  9. package/dist/assert/model.d.ts +73 -0
  10. package/dist/assert/model.js +8 -0
  11. package/dist/assert/schema.d.ts +34 -0
  12. package/dist/assert/schema.js +46 -0
  13. package/dist/assert/sla.d.ts +3 -0
  14. package/dist/assert/sla.js +8 -0
  15. package/dist/assert/soap-fault.d.ts +3 -0
  16. package/dist/assert/soap-fault.js +20 -0
  17. package/dist/assert/status.d.ts +3 -0
  18. package/dist/assert/status.js +14 -0
  19. package/dist/errors.d.ts +77 -0
  20. package/dist/errors.js +121 -0
  21. package/dist/fs.d.ts +35 -0
  22. package/dist/fs.js +64 -0
  23. package/dist/generate.d.ts +12 -0
  24. package/dist/generate.js +14 -0
  25. package/dist/grpc/browser.d.ts +11 -0
  26. package/dist/grpc/browser.js +9 -0
  27. package/dist/grpc/cache.d.ts +113 -0
  28. package/dist/grpc/cache.js +244 -0
  29. package/dist/grpc/call.d.ts +64 -0
  30. package/dist/grpc/call.js +72 -0
  31. package/dist/grpc/codec.d.ts +29 -0
  32. package/dist/grpc/codec.js +416 -0
  33. package/dist/grpc/command.d.ts +23 -0
  34. package/dist/grpc/command.js +91 -0
  35. package/dist/grpc/expand.d.ts +25 -0
  36. package/dist/grpc/expand.js +52 -0
  37. package/dist/grpc/framing.d.ts +28 -0
  38. package/dist/grpc/framing.js +61 -0
  39. package/dist/grpc/import.d.ts +47 -0
  40. package/dist/grpc/import.js +88 -0
  41. package/dist/grpc/model.d.ts +179 -0
  42. package/dist/grpc/model.js +91 -0
  43. package/dist/grpc/proto/describe.d.ts +92 -0
  44. package/dist/grpc/proto/describe.js +205 -0
  45. package/dist/grpc/proto/load.d.ts +35 -0
  46. package/dist/grpc/proto/load.js +112 -0
  47. package/dist/grpc/proto/sample.d.ts +21 -0
  48. package/dist/grpc/proto/sample.js +79 -0
  49. package/dist/grpc/proto/well-known.d.ts +42 -0
  50. package/dist/grpc/proto/well-known.js +143 -0
  51. package/dist/grpc/reconcile.d.ts +42 -0
  52. package/dist/grpc/reconcile.js +153 -0
  53. package/dist/grpc/reflection/client.d.ts +70 -0
  54. package/dist/grpc/reflection/client.js +197 -0
  55. package/dist/grpc/reflection/descriptors.d.ts +69 -0
  56. package/dist/grpc/reflection/descriptors.js +140 -0
  57. package/dist/grpc/reflection/proto.d.ts +33 -0
  58. package/dist/grpc/reflection/proto.js +144 -0
  59. package/dist/grpc/send.d.ts +132 -0
  60. package/dist/grpc/send.js +435 -0
  61. package/dist/grpc/shape.d.ts +29 -0
  62. package/dist/grpc/shape.js +36 -0
  63. package/dist/grpc/status.d.ts +21 -0
  64. package/dist/grpc/status.js +62 -0
  65. package/dist/grpc/target.d.ts +21 -0
  66. package/dist/grpc/target.js +66 -0
  67. package/dist/http/auth/apply.d.ts +37 -0
  68. package/dist/http/auth/apply.js +74 -0
  69. package/dist/http/auth/basic.d.ts +36 -0
  70. package/dist/http/auth/basic.js +69 -0
  71. package/dist/http/auth/md4.d.ts +13 -0
  72. package/dist/http/auth/md4.js +81 -0
  73. package/dist/http/auth/ntlm-transport.d.ts +61 -0
  74. package/dist/http/auth/ntlm-transport.js +97 -0
  75. package/dist/http/auth/ntlm.d.ts +190 -0
  76. package/dist/http/auth/ntlm.js +377 -0
  77. package/dist/http/client.d.ts +73 -0
  78. package/dist/http/client.js +403 -0
  79. package/dist/http/curl-flags.d.ts +15 -0
  80. package/dist/http/curl-flags.js +95 -0
  81. package/dist/http/curl.d.ts +94 -0
  82. package/dist/http/curl.js +245 -0
  83. package/dist/http/decompress.d.ts +7 -0
  84. package/dist/http/decompress.js +22 -0
  85. package/dist/http/errors.d.ts +22 -0
  86. package/dist/http/errors.js +144 -0
  87. package/dist/http/failed-request.d.ts +27 -0
  88. package/dist/http/failed-request.js +48 -0
  89. package/dist/http/headers.d.ts +15 -0
  90. package/dist/http/headers.js +50 -0
  91. package/dist/http/heredoc.d.ts +25 -0
  92. package/dist/http/heredoc.js +74 -0
  93. package/dist/http/proxy.d.ts +103 -0
  94. package/dist/http/proxy.js +168 -0
  95. package/dist/http/raw-capture.d.ts +23 -0
  96. package/dist/http/raw-capture.js +57 -0
  97. package/dist/http/timings.d.ts +79 -0
  98. package/dist/http/timings.js +212 -0
  99. package/dist/http/tls.d.ts +111 -0
  100. package/dist/http/tls.js +167 -0
  101. package/dist/http/types.d.ts +125 -0
  102. package/dist/http/types.js +6 -0
  103. package/dist/import-detect.d.ts +26 -0
  104. package/dist/import-detect.js +169 -0
  105. package/dist/import.d.ts +20 -0
  106. package/dist/import.js +163 -0
  107. package/dist/index.d.ts +272 -0
  108. package/dist/index.js +157 -0
  109. package/dist/json/cursor.d.ts +43 -0
  110. package/dist/json/cursor.js +168 -0
  111. package/dist/operations.d.ts +12 -0
  112. package/dist/operations.js +52 -0
  113. package/dist/project/attachments-cache.d.ts +80 -0
  114. package/dist/project/attachments-cache.js +186 -0
  115. package/dist/project/endpoints.d.ts +23 -0
  116. package/dist/project/endpoints.js +47 -0
  117. package/dist/project/environments.d.ts +68 -0
  118. package/dist/project/environments.js +124 -0
  119. package/dist/project/fs.d.ts +45 -0
  120. package/dist/project/fs.js +78 -0
  121. package/dist/project/history.d.ts +171 -0
  122. package/dist/project/history.js +179 -0
  123. package/dist/project/keystores.d.ts +24 -0
  124. package/dist/project/keystores.js +66 -0
  125. package/dist/project/load.d.ts +44 -0
  126. package/dist/project/load.js +634 -0
  127. package/dist/project/migrate.d.ts +27 -0
  128. package/dist/project/migrate.js +46 -0
  129. package/dist/project/model.d.ts +401 -0
  130. package/dist/project/model.js +126 -0
  131. package/dist/project/paths.d.ts +134 -0
  132. package/dist/project/paths.js +259 -0
  133. package/dist/project/preferences.d.ts +318 -0
  134. package/dist/project/preferences.js +239 -0
  135. package/dist/project/properties.d.ts +97 -0
  136. package/dist/project/properties.js +356 -0
  137. package/dist/project/save.d.ts +65 -0
  138. package/dist/project/save.js +295 -0
  139. package/dist/project/schema.d.ts +1329 -0
  140. package/dist/project/schema.js +737 -0
  141. package/dist/project/serialize.d.ts +42 -0
  142. package/dist/project/serialize.js +385 -0
  143. package/dist/project/wss-configs.d.ts +40 -0
  144. package/dist/project/wss-configs.js +142 -0
  145. package/dist/project/yaml.d.ts +17 -0
  146. package/dist/project/yaml.js +39 -0
  147. package/dist/redact/index.d.ts +77 -0
  148. package/dist/redact/index.js +328 -0
  149. package/dist/redact/literal.d.ts +12 -0
  150. package/dist/redact/literal.js +68 -0
  151. package/dist/rest/auth.d.ts +53 -0
  152. package/dist/rest/auth.js +80 -0
  153. package/dist/rest/body.d.ts +61 -0
  154. package/dist/rest/body.js +184 -0
  155. package/dist/rest/browser.d.ts +12 -0
  156. package/dist/rest/browser.js +11 -0
  157. package/dist/rest/cookies.d.ts +41 -0
  158. package/dist/rest/cookies.js +102 -0
  159. package/dist/rest/curl.d.ts +75 -0
  160. package/dist/rest/curl.js +417 -0
  161. package/dist/rest/expand.d.ts +35 -0
  162. package/dist/rest/expand.js +104 -0
  163. package/dist/rest/model.d.ts +247 -0
  164. package/dist/rest/model.js +118 -0
  165. package/dist/rest/oauth2.d.ts +118 -0
  166. package/dist/rest/oauth2.js +212 -0
  167. package/dist/rest/openapi/cache.d.ts +54 -0
  168. package/dist/rest/openapi/cache.js +128 -0
  169. package/dist/rest/openapi/import.d.ts +67 -0
  170. package/dist/rest/openapi/import.js +91 -0
  171. package/dist/rest/openapi/map.d.ts +102 -0
  172. package/dist/rest/openapi/map.js +477 -0
  173. package/dist/rest/openapi/model.d.ts +203 -0
  174. package/dist/rest/openapi/model.js +37 -0
  175. package/dist/rest/openapi/parse.d.ts +44 -0
  176. package/dist/rest/openapi/parse.js +1530 -0
  177. package/dist/rest/openapi/refs.d.ts +63 -0
  178. package/dist/rest/openapi/refs.js +258 -0
  179. package/dist/rest/openapi/sample.d.ts +68 -0
  180. package/dist/rest/openapi/sample.js +336 -0
  181. package/dist/rest/postman/import.d.ts +21 -0
  182. package/dist/rest/postman/import.js +47 -0
  183. package/dist/rest/postman/index.d.ts +7 -0
  184. package/dist/rest/postman/index.js +7 -0
  185. package/dist/rest/postman/map.d.ts +28 -0
  186. package/dist/rest/postman/map.js +427 -0
  187. package/dist/rest/postman/model.d.ts +118 -0
  188. package/dist/rest/postman/model.js +7 -0
  189. package/dist/rest/postman/parse.d.ts +29 -0
  190. package/dist/rest/postman/parse.js +518 -0
  191. package/dist/rest/response.d.ts +72 -0
  192. package/dist/rest/response.js +221 -0
  193. package/dist/rest/send.d.ts +102 -0
  194. package/dist/rest/send.js +148 -0
  195. package/dist/rest/url.d.ts +92 -0
  196. package/dist/rest/url.js +213 -0
  197. package/dist/run/effective-auth.d.ts +10 -0
  198. package/dist/run/effective-auth.js +19 -0
  199. package/dist/run/index.d.ts +8 -0
  200. package/dist/run/index.js +4 -0
  201. package/dist/run/prepare.d.ts +43 -0
  202. package/dist/run/prepare.js +280 -0
  203. package/dist/run/run.d.ts +53 -0
  204. package/dist/run/run.js +223 -0
  205. package/dist/run/secret-needs.d.ts +13 -0
  206. package/dist/run/secret-needs.js +125 -0
  207. package/dist/run/select.d.ts +34 -0
  208. package/dist/run/select.js +76 -0
  209. package/dist/secrets/env-names.d.ts +27 -0
  210. package/dist/secrets/env-names.js +40 -0
  211. package/dist/secrets/resolve.d.ts +58 -0
  212. package/dist/secrets/resolve.js +136 -0
  213. package/dist/send-options.d.ts +141 -0
  214. package/dist/send-options.js +228 -0
  215. package/dist/send.d.ts +53 -0
  216. package/dist/send.js +210 -0
  217. package/dist/soap/body-builder.d.ts +38 -0
  218. package/dist/soap/body-builder.js +250 -0
  219. package/dist/soap/build-problems.d.ts +12 -0
  220. package/dist/soap/build-problems.js +2 -0
  221. package/dist/soap/charset.d.ts +23 -0
  222. package/dist/soap/charset.js +47 -0
  223. package/dist/soap/envelope.d.ts +44 -0
  224. package/dist/soap/envelope.js +76 -0
  225. package/dist/soap/fault.d.ts +46 -0
  226. package/dist/soap/fault.js +129 -0
  227. package/dist/soap/form-request.d.ts +34 -0
  228. package/dist/soap/form-request.js +251 -0
  229. package/dist/soap/legacy-project/definition-fetcher.d.ts +21 -0
  230. package/dist/soap/legacy-project/definition-fetcher.js +43 -0
  231. package/dist/soap/legacy-project/format.d.ts +18 -0
  232. package/dist/soap/legacy-project/format.js +24 -0
  233. package/dist/soap/legacy-project/import.d.ts +21 -0
  234. package/dist/soap/legacy-project/import.js +46 -0
  235. package/dist/soap/legacy-project/index.d.ts +9 -0
  236. package/dist/soap/legacy-project/index.js +5 -0
  237. package/dist/soap/legacy-project/map.d.ts +91 -0
  238. package/dist/soap/legacy-project/map.js +290 -0
  239. package/dist/soap/legacy-project/model.d.ts +98 -0
  240. package/dist/soap/legacy-project/model.js +5 -0
  241. package/dist/soap/legacy-project/parse.d.ts +16 -0
  242. package/dist/soap/legacy-project/parse.js +325 -0
  243. package/dist/soap/mime/cid-scan.d.ts +36 -0
  244. package/dist/soap/mime/cid-scan.js +52 -0
  245. package/dist/soap/mime/inline-files.d.ts +39 -0
  246. package/dist/soap/mime/inline-files.js +71 -0
  247. package/dist/soap/mime/mtom.d.ts +74 -0
  248. package/dist/soap/mime/mtom.js +134 -0
  249. package/dist/soap/mime/multipart.d.ts +66 -0
  250. package/dist/soap/mime/multipart.js +329 -0
  251. package/dist/soap/mime/send-pipeline.d.ts +61 -0
  252. package/dist/soap/mime/send-pipeline.js +145 -0
  253. package/dist/soap/mime/swa.d.ts +45 -0
  254. package/dist/soap/mime/swa.js +62 -0
  255. package/dist/soap/mime/types.d.ts +69 -0
  256. package/dist/soap/mime/types.js +10 -0
  257. package/dist/soap/namespace-scope.d.ts +32 -0
  258. package/dist/soap/namespace-scope.js +85 -0
  259. package/dist/soap/prefixes.d.ts +24 -0
  260. package/dist/soap/prefixes.js +70 -0
  261. package/dist/soap/recreate.d.ts +28 -0
  262. package/dist/soap/recreate.js +168 -0
  263. package/dist/soap/request-builder.d.ts +63 -0
  264. package/dist/soap/request-builder.js +161 -0
  265. package/dist/soap/response-parser.d.ts +29 -0
  266. package/dist/soap/response-parser.js +71 -0
  267. package/dist/soap/soap-action.d.ts +31 -0
  268. package/dist/soap/soap-action.js +28 -0
  269. package/dist/soap/transforms.d.ts +52 -0
  270. package/dist/soap/transforms.js +164 -0
  271. package/dist/types.d.ts +307 -0
  272. package/dist/types.js +6 -0
  273. package/dist/validate/index.d.ts +61 -0
  274. package/dist/validate/index.js +72 -0
  275. package/dist/validate/schema-file-set.d.ts +51 -0
  276. package/dist/validate/schema-file-set.js +288 -0
  277. package/dist/validate/schema-validator.d.ts +53 -0
  278. package/dist/validate/schema-validator.js +251 -0
  279. package/dist/validate/soap-structure.d.ts +34 -0
  280. package/dist/validate/soap-structure.js +255 -0
  281. package/dist/validate/types.d.ts +47 -0
  282. package/dist/validate/types.js +8 -0
  283. package/dist/validate/wsi/assertions/helpers.d.ts +145 -0
  284. package/dist/validate/wsi/assertions/helpers.js +387 -0
  285. package/dist/validate/wsi/assertions/index.d.ts +44 -0
  286. package/dist/validate/wsi/assertions/index.js +77 -0
  287. package/dist/validate/wsi/assertions/message/helpers.d.ts +63 -0
  288. package/dist/validate/wsi/assertions/message/helpers.js +168 -0
  289. package/dist/validate/wsi/assertions/message/index.d.ts +39 -0
  290. package/dist/validate/wsi/assertions/message/index.js +62 -0
  291. package/dist/validate/wsi/assertions/message/r1001.d.ts +10 -0
  292. package/dist/validate/wsi/assertions/message/r1001.js +38 -0
  293. package/dist/validate/wsi/assertions/message/r1003.d.ts +14 -0
  294. package/dist/validate/wsi/assertions/message/r1003.js +45 -0
  295. package/dist/validate/wsi/assertions/message/r1005.d.ts +12 -0
  296. package/dist/validate/wsi/assertions/message/r1005.js +37 -0
  297. package/dist/validate/wsi/assertions/message/r1006.d.ts +10 -0
  298. package/dist/validate/wsi/assertions/message/r1006.js +49 -0
  299. package/dist/validate/wsi/assertions/message/r1007.d.ts +10 -0
  300. package/dist/validate/wsi/assertions/message/r1007.js +30 -0
  301. package/dist/validate/wsi/assertions/message/r1011.d.ts +10 -0
  302. package/dist/validate/wsi/assertions/message/r1011.js +33 -0
  303. package/dist/validate/wsi/assertions/message/r1012.d.ts +13 -0
  304. package/dist/validate/wsi/assertions/message/r1012.js +37 -0
  305. package/dist/validate/wsi/assertions/message/r1013.d.ts +9 -0
  306. package/dist/validate/wsi/assertions/message/r1013.js +42 -0
  307. package/dist/validate/wsi/assertions/message/r1014.d.ts +10 -0
  308. package/dist/validate/wsi/assertions/message/r1014.js +30 -0
  309. package/dist/validate/wsi/assertions/message/r1015.d.ts +12 -0
  310. package/dist/validate/wsi/assertions/message/r1015.js +36 -0
  311. package/dist/validate/wsi/assertions/message/r1017.d.ts +10 -0
  312. package/dist/validate/wsi/assertions/message/r1017.js +30 -0
  313. package/dist/validate/wsi/assertions/message/r1100.d.ts +10 -0
  314. package/dist/validate/wsi/assertions/message/r1100.js +39 -0
  315. package/dist/validate/wsi/assertions/message/r1101.d.ts +10 -0
  316. package/dist/validate/wsi/assertions/message/r1101.js +37 -0
  317. package/dist/validate/wsi/assertions/message/r1102.d.ts +10 -0
  318. package/dist/validate/wsi/assertions/message/r1102.js +41 -0
  319. package/dist/validate/wsi/assertions/message/r1103.d.ts +10 -0
  320. package/dist/validate/wsi/assertions/message/r1103.js +28 -0
  321. package/dist/validate/wsi/assertions/message/r1107.d.ts +10 -0
  322. package/dist/validate/wsi/assertions/message/r1107.js +38 -0
  323. package/dist/validate/wsi/assertions/message/r1109.d.ts +10 -0
  324. package/dist/validate/wsi/assertions/message/r1109.js +32 -0
  325. package/dist/validate/wsi/assertions/message/r1124.d.ts +10 -0
  326. package/dist/validate/wsi/assertions/message/r1124.js +31 -0
  327. package/dist/validate/wsi/assertions/message/r1132.d.ts +9 -0
  328. package/dist/validate/wsi/assertions/message/r1132.js +23 -0
  329. package/dist/validate/wsi/assertions/message/r1140.d.ts +10 -0
  330. package/dist/validate/wsi/assertions/message/r1140.js +42 -0
  331. package/dist/validate/wsi/assertions/message/r1141.d.ts +10 -0
  332. package/dist/validate/wsi/assertions/message/r1141.js +32 -0
  333. package/dist/validate/wsi/assertions/message/r2113.d.ts +11 -0
  334. package/dist/validate/wsi/assertions/message/r2113.js +33 -0
  335. package/dist/validate/wsi/assertions/message/r2211.d.ts +7 -0
  336. package/dist/validate/wsi/assertions/message/r2211.js +42 -0
  337. package/dist/validate/wsi/assertions/r2001.d.ts +15 -0
  338. package/dist/validate/wsi/assertions/r2001.js +47 -0
  339. package/dist/validate/wsi/assertions/r2002.d.ts +11 -0
  340. package/dist/validate/wsi/assertions/r2002.js +38 -0
  341. package/dist/validate/wsi/assertions/r2003.d.ts +7 -0
  342. package/dist/validate/wsi/assertions/r2003.js +32 -0
  343. package/dist/validate/wsi/assertions/r2005.d.ts +7 -0
  344. package/dist/validate/wsi/assertions/r2005.js +40 -0
  345. package/dist/validate/wsi/assertions/r2101.d.ts +14 -0
  346. package/dist/validate/wsi/assertions/r2101.js +65 -0
  347. package/dist/validate/wsi/assertions/r2102.d.ts +10 -0
  348. package/dist/validate/wsi/assertions/r2102.js +41 -0
  349. package/dist/validate/wsi/assertions/r2105.d.ts +8 -0
  350. package/dist/validate/wsi/assertions/r2105.js +39 -0
  351. package/dist/validate/wsi/assertions/r2110.d.ts +8 -0
  352. package/dist/validate/wsi/assertions/r2110.js +38 -0
  353. package/dist/validate/wsi/assertions/r2111.d.ts +6 -0
  354. package/dist/validate/wsi/assertions/r2111.js +30 -0
  355. package/dist/validate/wsi/assertions/r2112.d.ts +7 -0
  356. package/dist/validate/wsi/assertions/r2112.js +35 -0
  357. package/dist/validate/wsi/assertions/r2201.d.ts +7 -0
  358. package/dist/validate/wsi/assertions/r2201.js +28 -0
  359. package/dist/validate/wsi/assertions/r2203.d.ts +7 -0
  360. package/dist/validate/wsi/assertions/r2203.js +30 -0
  361. package/dist/validate/wsi/assertions/r2204.d.ts +6 -0
  362. package/dist/validate/wsi/assertions/r2204.js +29 -0
  363. package/dist/validate/wsi/assertions/r2205.d.ts +8 -0
  364. package/dist/validate/wsi/assertions/r2205.js +46 -0
  365. package/dist/validate/wsi/assertions/r2206.d.ts +7 -0
  366. package/dist/validate/wsi/assertions/r2206.js +36 -0
  367. package/dist/validate/wsi/assertions/r2209.d.ts +12 -0
  368. package/dist/validate/wsi/assertions/r2209.js +37 -0
  369. package/dist/validate/wsi/assertions/r2210.d.ts +7 -0
  370. package/dist/validate/wsi/assertions/r2210.js +30 -0
  371. package/dist/validate/wsi/assertions/r2303.d.ts +7 -0
  372. package/dist/validate/wsi/assertions/r2303.js +44 -0
  373. package/dist/validate/wsi/assertions/r2304.d.ts +6 -0
  374. package/dist/validate/wsi/assertions/r2304.js +32 -0
  375. package/dist/validate/wsi/assertions/r2401.d.ts +12 -0
  376. package/dist/validate/wsi/assertions/r2401.js +31 -0
  377. package/dist/validate/wsi/assertions/r2701.d.ts +7 -0
  378. package/dist/validate/wsi/assertions/r2701.js +28 -0
  379. package/dist/validate/wsi/assertions/r2702.d.ts +6 -0
  380. package/dist/validate/wsi/assertions/r2702.js +26 -0
  381. package/dist/validate/wsi/assertions/r2705.d.ts +11 -0
  382. package/dist/validate/wsi/assertions/r2705.js +31 -0
  383. package/dist/validate/wsi/assertions/r2706.d.ts +7 -0
  384. package/dist/validate/wsi/assertions/r2706.js +29 -0
  385. package/dist/validate/wsi/assertions/r2710.d.ts +13 -0
  386. package/dist/validate/wsi/assertions/r2710.js +37 -0
  387. package/dist/validate/wsi/assertions/r2716.d.ts +7 -0
  388. package/dist/validate/wsi/assertions/r2716.js +29 -0
  389. package/dist/validate/wsi/assertions/r2717.d.ts +9 -0
  390. package/dist/validate/wsi/assertions/r2717.js +31 -0
  391. package/dist/validate/wsi/assertions/r2718.d.ts +7 -0
  392. package/dist/validate/wsi/assertions/r2718.js +41 -0
  393. package/dist/validate/wsi/assertions/r2720.d.ts +7 -0
  394. package/dist/validate/wsi/assertions/r2720.js +29 -0
  395. package/dist/validate/wsi/assertions/r2721.d.ts +6 -0
  396. package/dist/validate/wsi/assertions/r2721.js +27 -0
  397. package/dist/validate/wsi/assertions/r2722.d.ts +6 -0
  398. package/dist/validate/wsi/assertions/r2722.js +29 -0
  399. package/dist/validate/wsi/assertions/r2801.d.ts +7 -0
  400. package/dist/validate/wsi/assertions/r2801.js +39 -0
  401. package/dist/validate/wsi/assertions/r2803.d.ts +7 -0
  402. package/dist/validate/wsi/assertions/r2803.js +29 -0
  403. package/dist/validate/wsi/docs.d.ts +29 -0
  404. package/dist/validate/wsi/docs.js +167 -0
  405. package/dist/validate/wsi/index.d.ts +16 -0
  406. package/dist/validate/wsi/index.js +11 -0
  407. package/dist/validate/wsi/report-html.d.ts +36 -0
  408. package/dist/validate/wsi/report-html.js +135 -0
  409. package/dist/validate/wsi/run-message.d.ts +50 -0
  410. package/dist/validate/wsi/run-message.js +190 -0
  411. package/dist/validate/wsi/run-wsdl.d.ts +48 -0
  412. package/dist/validate/wsi/run-wsdl.js +99 -0
  413. package/dist/validate/wsi/types.d.ts +173 -0
  414. package/dist/validate/wsi/types.js +17 -0
  415. package/dist/workspace/commit-message.d.ts +47 -0
  416. package/dist/workspace/commit-message.js +195 -0
  417. package/dist/workspace/environments.d.ts +79 -0
  418. package/dist/workspace/environments.js +115 -0
  419. package/dist/workspace/index.d.ts +28 -0
  420. package/dist/workspace/index.js +19 -0
  421. package/dist/workspace/load.d.ts +45 -0
  422. package/dist/workspace/load.js +155 -0
  423. package/dist/workspace/local-state.d.ts +37 -0
  424. package/dist/workspace/local-state.js +59 -0
  425. package/dist/workspace/migrate.d.ts +38 -0
  426. package/dist/workspace/migrate.js +50 -0
  427. package/dist/workspace/model.d.ts +86 -0
  428. package/dist/workspace/model.js +54 -0
  429. package/dist/workspace/paths.d.ts +64 -0
  430. package/dist/workspace/paths.js +97 -0
  431. package/dist/workspace/reidentify.d.ts +22 -0
  432. package/dist/workspace/reidentify.js +122 -0
  433. package/dist/workspace/save.d.ts +31 -0
  434. package/dist/workspace/save.js +84 -0
  435. package/dist/workspace/schema.d.ts +93 -0
  436. package/dist/workspace/schema.js +115 -0
  437. package/dist/workspace/serialize.d.ts +24 -0
  438. package/dist/workspace/serialize.js +60 -0
  439. package/dist/workspace/share.d.ts +52 -0
  440. package/dist/workspace/share.js +89 -0
  441. package/dist/ws/browser.d.ts +13 -0
  442. package/dist/ws/browser.js +11 -0
  443. package/dist/ws/call.d.ts +53 -0
  444. package/dist/ws/call.js +106 -0
  445. package/dist/ws/command.d.ts +19 -0
  446. package/dist/ws/command.js +28 -0
  447. package/dist/ws/expand.d.ts +38 -0
  448. package/dist/ws/expand.js +76 -0
  449. package/dist/ws/model.d.ts +191 -0
  450. package/dist/ws/model.js +83 -0
  451. package/dist/ws/pretty.d.ts +12 -0
  452. package/dist/ws/pretty.js +25 -0
  453. package/dist/ws/session.d.ts +50 -0
  454. package/dist/ws/session.js +333 -0
  455. package/dist/ws/shape.d.ts +18 -0
  456. package/dist/ws/shape.js +28 -0
  457. package/dist/ws/transcript.d.ts +14 -0
  458. package/dist/ws/transcript.js +29 -0
  459. package/dist/ws/url.d.ts +3 -0
  460. package/dist/ws/url.js +44 -0
  461. package/dist/wsa/headers.d.ts +78 -0
  462. package/dist/wsa/headers.js +244 -0
  463. package/dist/wsa/model.d.ts +66 -0
  464. package/dist/wsa/model.js +52 -0
  465. package/dist/wsa/policy-detect.d.ts +81 -0
  466. package/dist/wsa/policy-detect.js +245 -0
  467. package/dist/wsdl/cache-naming.d.ts +39 -0
  468. package/dist/wsdl/cache-naming.js +90 -0
  469. package/dist/wsdl/cache.d.ts +48 -0
  470. package/dist/wsdl/cache.js +141 -0
  471. package/dist/wsdl/docs-generator.d.ts +47 -0
  472. package/dist/wsdl/docs-generator.js +439 -0
  473. package/dist/wsdl/dom-utils.d.ts +15 -0
  474. package/dist/wsdl/dom-utils.js +50 -0
  475. package/dist/wsdl/export-definition.d.ts +38 -0
  476. package/dist/wsdl/export-definition.js +100 -0
  477. package/dist/wsdl/fetch.d.ts +13 -0
  478. package/dist/wsdl/fetch.js +60 -0
  479. package/dist/wsdl/merge.d.ts +17 -0
  480. package/dist/wsdl/merge.js +57 -0
  481. package/dist/wsdl/model.d.ts +176 -0
  482. package/dist/wsdl/model.js +17 -0
  483. package/dist/wsdl/parse-binding.d.ts +6 -0
  484. package/dist/wsdl/parse-binding.js +150 -0
  485. package/dist/wsdl/parse-wsdl.d.ts +47 -0
  486. package/dist/wsdl/parse-wsdl.js +161 -0
  487. package/dist/wsdl/qname.d.ts +28 -0
  488. package/dist/wsdl/qname.js +41 -0
  489. package/dist/wsdl/ref-policy.d.ts +54 -0
  490. package/dist/wsdl/ref-policy.js +87 -0
  491. package/dist/wsdl/resolver.d.ts +81 -0
  492. package/dist/wsdl/resolver.js +276 -0
  493. package/dist/wsdl/update-definition.d.ts +106 -0
  494. package/dist/wsdl/update-definition.js +314 -0
  495. package/dist/wss/apply.d.ts +40 -0
  496. package/dist/wss/apply.js +212 -0
  497. package/dist/wss/c14n-prefixes.d.ts +27 -0
  498. package/dist/wss/c14n-prefixes.js +95 -0
  499. package/dist/wss/incoming/decrypt.d.ts +35 -0
  500. package/dist/wss/incoming/decrypt.js +57 -0
  501. package/dist/wss/incoming/index.d.ts +56 -0
  502. package/dist/wss/incoming/index.js +189 -0
  503. package/dist/wss/incoming/verify.d.ts +74 -0
  504. package/dist/wss/incoming/verify.js +440 -0
  505. package/dist/wss/key-identifiers.d.ts +76 -0
  506. package/dist/wss/key-identifiers.js +139 -0
  507. package/dist/wss/keystore/certificate.d.ts +45 -0
  508. package/dist/wss/keystore/certificate.js +134 -0
  509. package/dist/wss/keystore/index.d.ts +50 -0
  510. package/dist/wss/keystore/index.js +80 -0
  511. package/dist/wss/keystore/model.d.ts +83 -0
  512. package/dist/wss/keystore/model.js +27 -0
  513. package/dist/wss/keystore/pem.d.ts +21 -0
  514. package/dist/wss/keystore/pem.js +140 -0
  515. package/dist/wss/keystore/pkcs12.d.ts +21 -0
  516. package/dist/wss/keystore/pkcs12.js +125 -0
  517. package/dist/wss/model.d.ts +160 -0
  518. package/dist/wss/model.js +37 -0
  519. package/dist/wss/outgoing/encryption.d.ts +76 -0
  520. package/dist/wss/outgoing/encryption.js +618 -0
  521. package/dist/wss/outgoing/signature.d.ts +73 -0
  522. package/dist/wss/outgoing/signature.js +239 -0
  523. package/dist/wss/outgoing/timestamp.d.ts +29 -0
  524. package/dist/wss/outgoing/timestamp.js +39 -0
  525. package/dist/wss/outgoing/username-token.d.ts +36 -0
  526. package/dist/wss/outgoing/username-token.js +68 -0
  527. package/dist/wss/security-header.d.ts +31 -0
  528. package/dist/wss/security-header.js +83 -0
  529. package/dist/xml/index.d.ts +7 -0
  530. package/dist/xml/index.js +7 -0
  531. package/dist/xml/namespaces.d.ts +36 -0
  532. package/dist/xml/namespaces.js +60 -0
  533. package/dist/xml/parse.d.ts +79 -0
  534. package/dist/xml/parse.js +109 -0
  535. package/dist/xml/positions.d.ts +26 -0
  536. package/dist/xml/positions.js +71 -0
  537. package/dist/xml/pretty.d.ts +37 -0
  538. package/dist/xml/pretty.js +137 -0
  539. package/dist/xml/serialize.d.ts +6 -0
  540. package/dist/xml/serialize.js +8 -0
  541. package/dist/xml/tolerant-tree.d.ts +56 -0
  542. package/dist/xml/tolerant-tree.js +134 -0
  543. package/dist/xpath/evaluate-async.d.ts +31 -0
  544. package/dist/xpath/evaluate-async.js +81 -0
  545. package/dist/xpath/evaluate.d.ts +98 -0
  546. package/dist/xpath/evaluate.js +340 -0
  547. package/dist/xpath/jsonpath.d.ts +40 -0
  548. package/dist/xpath/jsonpath.js +109 -0
  549. package/dist/xpath/namespaces.d.ts +29 -0
  550. package/dist/xpath/namespaces.js +101 -0
  551. package/dist/xpath/worker.d.ts +7 -0
  552. package/dist/xpath/worker.js +26 -0
  553. package/dist/xsd/builtins.d.ts +36 -0
  554. package/dist/xsd/builtins.js +108 -0
  555. package/dist/xsd/check-references.d.ts +25 -0
  556. package/dist/xsd/check-references.js +145 -0
  557. package/dist/xsd/form-edits.d.ts +57 -0
  558. package/dist/xsd/form-edits.js +153 -0
  559. package/dist/xsd/form-model.d.ts +153 -0
  560. package/dist/xsd/form-model.js +691 -0
  561. package/dist/xsd/locate.d.ts +42 -0
  562. package/dist/xsd/locate.js +249 -0
  563. package/dist/xsd/model.d.ts +249 -0
  564. package/dist/xsd/model.js +1 -0
  565. package/dist/xsd/parse-particles.d.ts +48 -0
  566. package/dist/xsd/parse-particles.js +320 -0
  567. package/dist/xsd/parse-schema.d.ts +21 -0
  568. package/dist/xsd/parse-schema.js +143 -0
  569. package/dist/xsd/resolve-content.d.ts +18 -0
  570. package/dist/xsd/resolve-content.js +242 -0
  571. package/dist/xsd/sample-generator.d.ts +51 -0
  572. package/dist/xsd/sample-generator.js +291 -0
  573. package/dist/xsd/sample-types.d.ts +21 -0
  574. package/dist/xsd/sample-types.js +69 -0
  575. package/dist/xsd/sample-values.d.ts +54 -0
  576. package/dist/xsd/sample-values.js +267 -0
  577. package/dist/xsd/schema-set.d.ts +51 -0
  578. package/dist/xsd/schema-set.js +203 -0
  579. package/dist/xsd/xml-scan.d.ts +64 -0
  580. package/dist/xsd/xml-scan.js +286 -0
  581. package/dist/xsd/xml-writer.d.ts +56 -0
  582. package/dist/xsd/xml-writer.js +103 -0
  583. package/package.json +69 -0
@@ -0,0 +1,440 @@
1
+ /**
2
+ * Verification of an *incoming* message: every `ds:Signature` in a `wsse:Security` header, and
3
+ * the header's `wsu:Timestamp`.
4
+ *
5
+ * Two questions are answered separately, because they fail for different reasons and a user
6
+ * has to be able to tell them apart:
7
+ *
8
+ * - **validity** — does the signature actually hold over the bytes that arrived? That is
9
+ * Task 38's {@link verifySignature}, run against the certificate the message's own `KeyInfo`
10
+ * points at.
11
+ * - **trust** — is that certificate one we accept? A signature verifies perfectly against the
12
+ * key that made it, including a key an attacker owns, so the certificate is checked against
13
+ * the configured truststore: stored verbatim, or (with `verifyChain`) chaining to one of its
14
+ * certificates.
15
+ *
16
+ * `KeyInfo` is therefore a *hint* about which key to look up, never a source of trust.
17
+ */
18
+ import forge from 'node-forge';
19
+ import { NS } from '../../xml/namespaces.js';
20
+ import { parseXml } from '../../xml/parse.js';
21
+ import { serializeXml } from '../../xml/serialize.js';
22
+ import { renderDn, renderDnRfc2253 } from '../keystore/certificate.js';
23
+ import { certificateBase64, subjectKeyIdentifierBase64, thumbprintSha1Base64, WSS_TOKEN_TYPES, } from '../key-identifiers.js';
24
+ import { childElement, findElement } from '../security-header.js';
25
+ import { verifySignature } from '../outgoing/signature.js';
26
+ /** Every descendant-or-self of `root` in `namespace` with local name `localName`, in document order. */
27
+ function findAll(root, namespace, localName) {
28
+ const found = [];
29
+ const walk = (node) => {
30
+ if (node.namespaceURI === namespace && node.localName === localName) {
31
+ found.push(node);
32
+ }
33
+ for (let child = node.firstChild; child !== null; child = child.nextSibling) {
34
+ if (child.nodeType === 1) {
35
+ walk(child);
36
+ }
37
+ }
38
+ };
39
+ walk(root);
40
+ return found;
41
+ }
42
+ /**
43
+ * Every element under `root` by the value of its `Id` attribute (in any namespace, or none),
44
+ * built once per document.
45
+ *
46
+ * A *list* per id rather than the first match: a duplicated id is how a signature-wrapping
47
+ * attack hides a second element behind a reference, so ambiguity has to be visible rather than
48
+ * resolved by document order.
49
+ */
50
+ function idIndex(root) {
51
+ const index = new Map();
52
+ const walk = (node) => {
53
+ for (let position = 0; position < node.attributes.length; position += 1) {
54
+ const attribute = node.attributes.item(position);
55
+ if (attribute !== null && attribute.localName === 'Id' && attribute.value !== '') {
56
+ const found = index.get(attribute.value);
57
+ if (found === undefined) {
58
+ index.set(attribute.value, [node]);
59
+ }
60
+ else {
61
+ found.push(node);
62
+ }
63
+ }
64
+ }
65
+ for (let child = node.firstChild; child !== null; child = child.nextSibling) {
66
+ if (child.nodeType === 1) {
67
+ walk(child);
68
+ }
69
+ }
70
+ };
71
+ walk(root);
72
+ return index;
73
+ }
74
+ /** The one element carrying `id`, or `undefined` when no element — or more than one — does. */
75
+ function uniqueById(index, id) {
76
+ const found = index.get(id);
77
+ return found?.length === 1 ? found[0] : undefined;
78
+ }
79
+ /** The text of `element` with every whitespace character removed, so wrapped base64 compares. */
80
+ function textOf(element) {
81
+ return element === undefined ? '' : (element.textContent ?? '').replace(/\s+/g, '');
82
+ }
83
+ /** A forge certificate from base64 DER, or `undefined` when the bytes are not one. */
84
+ function certificateFromBase64(value) {
85
+ if (value === '') {
86
+ return undefined;
87
+ }
88
+ try {
89
+ const der = forge.util.createBuffer(Buffer.from(value, 'base64').toString('binary'));
90
+ return forge.pki.certificateFromAsn1(forge.asn1.fromDer(der));
91
+ }
92
+ catch {
93
+ return undefined;
94
+ }
95
+ }
96
+ /**
97
+ * The leaf of an `X509PKIPathv1` value: a DER `SEQUENCE OF Certificate`, leaf first (as
98
+ * `pkiPathBase64` writes it). `undefined` when the bytes are not such a sequence.
99
+ */
100
+ function certificateFromPkiPath(value) {
101
+ try {
102
+ const der = forge.util.createBuffer(Buffer.from(value, 'base64').toString('binary'));
103
+ const sequence = forge.asn1.fromDer(der);
104
+ const first = Array.isArray(sequence.value) ? sequence.value[0] : undefined;
105
+ return first === undefined ? undefined : forge.pki.certificateFromAsn1(first);
106
+ }
107
+ catch {
108
+ return undefined;
109
+ }
110
+ }
111
+ /**
112
+ * Every certificate the truststore holds, parsed — and rendered to PEM and DER — once per call.
113
+ * Re-deriving these per signature is what made a large truststore quadratic.
114
+ */
115
+ function truststoreCertificates(truststore) {
116
+ if (truststore === undefined) {
117
+ return [];
118
+ }
119
+ const certificates = [];
120
+ for (const alias of truststore.aliases) {
121
+ for (const pem of [alias.certPem, ...alias.chainPem]) {
122
+ try {
123
+ const cert = forge.pki.certificateFromPem(pem);
124
+ const normalized = forge.pki.certificateToPem(cert);
125
+ certificates.push({ cert, pem: normalized, der: certificateBase64(normalized) });
126
+ }
127
+ catch {
128
+ // A truststore entry this build cannot parse simply trusts nothing.
129
+ }
130
+ }
131
+ }
132
+ return certificates;
133
+ }
134
+ /**
135
+ * Parses an RFC 2253/4514 distinguished name into its attributes: split on unescaped `,` (and
136
+ * `+`, which joins a multi-valued RDN), then on the first unescaped `=`, unescaping `\x` and
137
+ * `\XX` hex pairs in the value.
138
+ *
139
+ * Needed because an `X509IssuerName` is only *semantically* equal to the DN this build renders:
140
+ * a peer is free to space, order and escape it differently, and comparing the rendered strings
141
+ * would reject a certificate we do hold.
142
+ */
143
+ function parseRfc2253(dn) {
144
+ const parts = [];
145
+ let current = '';
146
+ for (let index = 0; index < dn.length; index += 1) {
147
+ const char = dn.charAt(index);
148
+ if (char === '\\') {
149
+ current += char + dn.charAt(index + 1);
150
+ index += 1;
151
+ }
152
+ else if (char === ',' || char === '+') {
153
+ parts.push(current);
154
+ current = '';
155
+ }
156
+ else {
157
+ current += char;
158
+ }
159
+ }
160
+ parts.push(current);
161
+ const attributes = [];
162
+ for (const part of parts) {
163
+ const separator = part.indexOf('=');
164
+ if (separator <= 0) {
165
+ continue;
166
+ }
167
+ attributes.push({
168
+ type: part.slice(0, separator).trim(),
169
+ value: unescapeRfc2253(part.slice(separator + 1).trim()),
170
+ });
171
+ }
172
+ return attributes;
173
+ }
174
+ /** Undoes RFC 2253 escaping: `\c` is `c`, `\XX` is the byte `XX`. */
175
+ function unescapeRfc2253(value) {
176
+ let out = '';
177
+ for (let index = 0; index < value.length; index += 1) {
178
+ const char = value.charAt(index);
179
+ if (char !== '\\') {
180
+ out += char;
181
+ continue;
182
+ }
183
+ const pair = value.slice(index + 1, index + 3);
184
+ if (/^[0-9a-fA-F]{2}$/.test(pair)) {
185
+ out += String.fromCharCode(Number.parseInt(pair, 16));
186
+ index += 2;
187
+ }
188
+ else {
189
+ out += value.charAt(index + 1);
190
+ index += 1;
191
+ }
192
+ }
193
+ return out;
194
+ }
195
+ /** A DN's attributes as a sorted, comparable key: type case-insensitive, value verbatim. */
196
+ function dnKey(attributes) {
197
+ return attributes
198
+ .map((attribute) => `${attribute.type.toLowerCase()}=${attribute.value}`)
199
+ .sort()
200
+ .join(',');
201
+ }
202
+ /** Whether `issuerName` names the same DN as `attributes`, whatever rendering it arrived in. */
203
+ function sameDn(issuerName, attributes) {
204
+ const rendered = renderDnRfc2253(attributes);
205
+ // Fast path: the common case is a peer that renders the DN exactly as this build does.
206
+ return rendered === issuerName || dnKey(parseRfc2253(rendered)) === dnKey(parseRfc2253(issuerName));
207
+ }
208
+ /**
209
+ * The certificate a `ds:KeyInfo` names. Every X.509 token profile form is understood: the ones
210
+ * that *carry* the certificate (a `wsse:Reference` to a `BinarySecurityToken`, an `X509v3`
211
+ * `KeyIdentifier`, an inline `ds:X509Certificate`) yield it directly; the ones that merely
212
+ * *name* it (`IssuerSerial`, `SubjectKeyIdentifier`, `ThumbprintSHA1`) are looked up among
213
+ * `trusted`, which is why an untrusted signer using one of them cannot be resolved at all.
214
+ */
215
+ function certificateFromKeyInfo(ids, keyInfo, trusted) {
216
+ if (keyInfo === undefined) {
217
+ return undefined;
218
+ }
219
+ const reference = findElement(keyInfo, NS.WSSE, 'Reference');
220
+ if (reference !== undefined) {
221
+ const uri = reference.getAttribute('URI') ?? '';
222
+ const token = uri.startsWith('#') ? uniqueById(ids, uri.slice(1)) : undefined;
223
+ const value = textOf(token);
224
+ return certificateFromBase64(value) ?? certificateFromPkiPath(value);
225
+ }
226
+ const identifier = findElement(keyInfo, NS.WSSE, 'KeyIdentifier');
227
+ if (identifier !== undefined) {
228
+ const valueType = identifier.getAttribute('ValueType') ?? '';
229
+ const value = textOf(identifier);
230
+ if (valueType === WSS_TOKEN_TYPES.THUMBPRINT_SHA1) {
231
+ return lookup(trusted, (pem) => thumbprintSha1Base64(pem) === value);
232
+ }
233
+ if (valueType === WSS_TOKEN_TYPES.X509_SUBJECT_KEY_IDENTIFIER) {
234
+ return lookup(trusted, (pem) => subjectKeyIdentifierBase64(pem) === value);
235
+ }
236
+ return certificateFromBase64(value) ?? certificateFromPkiPath(value);
237
+ }
238
+ const issuerSerial = findElement(keyInfo, NS.DS, 'X509IssuerSerial');
239
+ if (issuerSerial !== undefined) {
240
+ const issuer = (childElement(issuerSerial, NS.DS, 'X509IssuerName')?.textContent ?? '').trim();
241
+ const serial = (childElement(issuerSerial, NS.DS, 'X509SerialNumber')?.textContent ?? '').trim();
242
+ return trusted.find((candidate) => sameDn(issuer, candidate.cert.issuer.attributes) &&
243
+ BigInt(`0x${candidate.cert.serialNumber}`).toString(10) === serial)?.cert;
244
+ }
245
+ const inline = findElement(keyInfo, NS.DS, 'X509Certificate');
246
+ return inline === undefined ? undefined : certificateFromBase64(textOf(inline));
247
+ }
248
+ /** The first trusted certificate whose PEM satisfies `matches`; a form it cannot compute never matches. */
249
+ function lookup(trusted, matches) {
250
+ return trusted.find((candidate) => {
251
+ try {
252
+ return matches(candidate.pem);
253
+ }
254
+ catch {
255
+ return false;
256
+ }
257
+ })?.cert;
258
+ }
259
+ /**
260
+ * Whether `certificate` is trusted: byte-identical to a truststore certificate, or — with
261
+ * `verifyChain` — issued (transitively) by one of them, with every certificate in the path
262
+ * valid at `at`.
263
+ */
264
+ function isTrusted(certificate, trusted, verifyChain, at) {
265
+ if (trusted.length === 0) {
266
+ return false;
267
+ }
268
+ const der = certificateBase64(forge.pki.certificateToPem(certificate));
269
+ if (trusted.some((candidate) => candidate.der === der)) {
270
+ // Pinned, but an expired certificate is not a trusted one: the equality path has to judge
271
+ // validity against the injected clock exactly as the chain path does.
272
+ return (certificate.validity.notBefore.getTime() <= at.getTime() &&
273
+ at.getTime() <= certificate.validity.notAfter.getTime());
274
+ }
275
+ if (!verifyChain) {
276
+ return false;
277
+ }
278
+ try {
279
+ const caStore = forge.pki.createCaStore(trusted.map((candidate) => candidate.cert));
280
+ // `validityCheckDate` is what makes the injected clock reach forge; without it the chain
281
+ // would be judged against the wall clock and a frozen-clock test could not exist.
282
+ return forge.pki.verifyCertificateChain(caStore, [certificate], { validityCheckDate: at });
283
+ }
284
+ catch {
285
+ return false;
286
+ }
287
+ }
288
+ /** The `URI`s of a `ds:Signature`'s references, without their leading `#`. */
289
+ function referenceIds(signature) {
290
+ const signedInfo = childElement(signature, NS.DS, 'SignedInfo');
291
+ if (signedInfo === undefined) {
292
+ return [];
293
+ }
294
+ return findAll(signedInfo, NS.DS, 'Reference')
295
+ .map((reference) => reference.getAttribute('URI') ?? '')
296
+ .filter((uri) => uri.startsWith('#'))
297
+ .map((uri) => uri.slice(1));
298
+ }
299
+ /** The envelope's `soap:Body`, in either SOAP version, or `undefined` for a non-SOAP document. */
300
+ function bodyElement(root) {
301
+ return findElement(root, NS.SOAP11_ENV, 'Body') ?? findElement(root, NS.SOAP12_ENV, 'Body');
302
+ }
303
+ /** Parses `wsu:Created`/`wsu:Expires`, returning `undefined` for anything not a date. */
304
+ function parseInstant(value) {
305
+ if (value === undefined || value.trim() === '') {
306
+ return undefined;
307
+ }
308
+ const parsed = new Date(value.trim());
309
+ return Number.isNaN(parsed.getTime()) ? undefined : parsed;
310
+ }
311
+ /** Judges the `wsu:Timestamp` under `security`, or `undefined` when there is none. */
312
+ function readTimestamp(security, options) {
313
+ const timestamp = findElement(security, NS.WSU, 'Timestamp');
314
+ if (timestamp === undefined) {
315
+ return undefined;
316
+ }
317
+ const createdText = childElement(timestamp, NS.WSU, 'Created')?.textContent ?? '';
318
+ const expiresElement = childElement(timestamp, NS.WSU, 'Expires');
319
+ const expiresText = expiresElement?.textContent ?? undefined;
320
+ const created = parseInstant(createdText);
321
+ const expires = parseInstant(expiresText);
322
+ const base = {
323
+ created: createdText.trim(),
324
+ ...(expiresText !== undefined ? { expires: expiresText.trim() } : {}),
325
+ };
326
+ if (created === undefined) {
327
+ return { ...base, fresh: false, error: 'The timestamp has no readable wsu:Created.' };
328
+ }
329
+ const skewMs = options.skewSeconds * 1000;
330
+ const now = options.clock().getTime();
331
+ if (now + skewMs < created.getTime()) {
332
+ return { ...base, fresh: false, error: 'The message was created in the future.' };
333
+ }
334
+ if (expires !== undefined) {
335
+ return now - skewMs > expires.getTime()
336
+ ? { ...base, fresh: false, error: 'The message expired.' }
337
+ : { ...base, fresh: true };
338
+ }
339
+ // No `Expires`: the skew window is all there is to judge against, so a `Created` older than
340
+ // it is stale rather than merely unbounded.
341
+ return now - skewMs > created.getTime()
342
+ ? { ...base, fresh: false, error: 'The message is older than the tolerated clock skew.' }
343
+ : { ...base, fresh: true };
344
+ }
345
+ /**
346
+ * Verifies every `ds:Signature` in `xml`'s `wsse:Security` headers and reads its
347
+ * `wsu:Timestamp`.
348
+ *
349
+ * Never throws: an unparsable, unsigned or non-SOAP message simply produces no signatures and
350
+ * no timestamp, which is what "this response had no WS-Security" has to look like.
351
+ *
352
+ * @param xml the (already decrypted) response envelope
353
+ * @param options the truststore, the clock, the tolerated skew and whether to follow chains
354
+ * @returns one result per signature, plus the timestamp when the message carries one
355
+ */
356
+ export function verifyIncoming(xml, options) {
357
+ let doc;
358
+ let root;
359
+ try {
360
+ doc = parseXml(xml, { location: 'envelope' });
361
+ root = doc.documentElement ?? undefined;
362
+ }
363
+ catch {
364
+ return { signatures: [] };
365
+ }
366
+ if (doc === undefined || root === undefined) {
367
+ return { signatures: [] };
368
+ }
369
+ const securities = findAll(root, NS.WSSE, 'Security');
370
+ const securitySignatures = new Set(securities.flatMap((security) => findAll(security, NS.DS, 'Signature')));
371
+ // Document order, and every `ds:Signature` — including one planted outside a `wsse:Security`
372
+ // header, which is reported as a failure rather than quietly ignored, because a wrapping
373
+ // payload the user cannot see is worse than one that reads as broken.
374
+ const signatures = findAll(root, NS.DS, 'Signature');
375
+ const trusted = truststoreCertificates(options.truststore);
376
+ const ids = idIndex(root);
377
+ const body = bodyElement(root);
378
+ const at = options.clock();
379
+ // A `ds:Signature` outside every `wsse:Security` header is never itself validated (see the
380
+ // early return below) — it is noise a wrapping attack planted to be picked up as content, not
381
+ // a signature this build ever trusts. Removing that noise once, up front, is not the isolation
382
+ // this code once did per signature (which stripped *every other* signature, including a
383
+ // legitimate sibling in the same `wsse:Security` header, corrupting the digest of any
384
+ // reference — such as an enveloped-signature transform over the header itself — that
385
+ // legitimately covered that sibling). A header signature is always verified against the
386
+ // document exactly as its Security header holds it; only content that could never have been
387
+ // part of a real signature's input is taken out first.
388
+ const headerSignatures = signatures.filter((signature) => securitySignatures.has(signature));
389
+ for (const signature of signatures) {
390
+ if (!securitySignatures.has(signature)) {
391
+ signature.parentNode?.removeChild(signature);
392
+ }
393
+ }
394
+ const sanitizedXml = serializeXml(doc);
395
+ const results = signatures.map((signature) => {
396
+ const empty = { references: [], referenceNames: [], coversBody: false, trusted: false };
397
+ if (!securitySignatures.has(signature)) {
398
+ return { ...empty, ok: false, error: 'A ds:Signature outside the wsse:Security header is not accepted.' };
399
+ }
400
+ const referenced = referenceIds(signature);
401
+ const duplicated = referenced.filter((id) => (ids.get(id)?.length ?? 0) > 1);
402
+ if (duplicated.length > 0) {
403
+ return {
404
+ ...empty,
405
+ ok: false,
406
+ references: referenced,
407
+ error: `duplicate-id: more than one element carries the referenced id "${duplicated[0] ?? ''}".`,
408
+ };
409
+ }
410
+ const certificate = certificateFromKeyInfo(ids, childElement(signature, NS.DS, 'KeyInfo'), trusted);
411
+ if (certificate === undefined) {
412
+ return {
413
+ ...empty,
414
+ ok: false,
415
+ error: 'The signing certificate could not be resolved from the message or the truststore.',
416
+ };
417
+ }
418
+ const certPem = forge.pki.certificateToPem(certificate);
419
+ // Verified by the signature's position among `wsse:Security` header signatures — never by
420
+ // isolating it from its own header siblings, which would change the bytes a signature whose
421
+ // own references cover the wsse:Security header (an enveloped-signature transform over a
422
+ // header that holds a second signature) was actually computed over.
423
+ const result = verifySignature(sanitizedXml, {
424
+ certPem,
425
+ signature: { index: headerSignatures.indexOf(signature) },
426
+ });
427
+ const covered = result.references.map((id) => uniqueById(ids, id));
428
+ return {
429
+ ok: result.ok,
430
+ references: result.references,
431
+ referenceNames: covered.map((element, index) => element?.localName ?? result.references[index] ?? ''),
432
+ coversBody: result.ok && body !== undefined && covered.includes(body),
433
+ signerSubject: renderDn(certificate.subject.attributes),
434
+ trusted: isTrusted(certificate, trusted, options.verifyChain, at),
435
+ ...(result.error !== undefined ? { error: result.error } : {}),
436
+ };
437
+ });
438
+ const timestamp = securities.map((security) => readTimestamp(security, options)).find((found) => found !== undefined);
439
+ return { signatures: results, ...(timestamp !== undefined ? { timestamp } : {}) };
440
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * The `<ds:KeyInfo>` content an outgoing signature carries: a `wsse:SecurityTokenReference`
3
+ * (or a bare `ds:X509Data`) pointing at the signing certificate in one of the five forms the
4
+ * X.509 token profile defines.
5
+ *
6
+ * These are produced as XML *strings* rather than DOM nodes because `xml-crypto` builds the
7
+ * whole `<ds:Signature>` element by string concatenation and asks for the KeyInfo contents the
8
+ * same way. Every element therefore declares the prefixes it uses on itself.
9
+ */
10
+ import type { WssKeyIdentifierType } from './model.js';
11
+ /** `ValueType`/`EncodingType` URIs from the WS-Security X.509 token profile. */
12
+ export declare const WSS_TOKEN_TYPES: {
13
+ /** A single DER-encoded certificate. */
14
+ readonly X509V3: "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3";
15
+ /** An ordered DER PKIPath of certificates. */
16
+ readonly X509_PKI_PATH_V1: "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1";
17
+ /** The certificate's subject key identifier extension value. */
18
+ readonly X509_SUBJECT_KEY_IDENTIFIER: "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier";
19
+ /** SHA-1 of the DER encoding of the certificate. */
20
+ readonly THUMBPRINT_SHA1: "http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1";
21
+ /** Base64 content encoding. */
22
+ readonly BASE64_BINARY: "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary";
23
+ };
24
+ /** What every key-identifier builder needs about the signing certificate. */
25
+ export interface KeyIdentifierInput {
26
+ /** The signing (leaf) certificate, PEM encoded. */
27
+ readonly certPem: string;
28
+ /** The issuing chain, nearest first; only used for `X509PKIPathv1`. */
29
+ readonly chainPem: readonly string[];
30
+ /** Emit only the leaf rather than the whole path. */
31
+ readonly useSingleCertificate: boolean;
32
+ /** The `wsu:Id` a `BinarySecurityToken` gets (and the `wsse:Reference` points at). */
33
+ readonly tokenId: string;
34
+ }
35
+ /** The KeyInfo content plus, for `BinarySecurityToken`, the token that must precede the signature. */
36
+ export interface KeyIdentifier {
37
+ /** The XML that goes inside `<ds:KeyInfo>`. */
38
+ readonly keyInfoXml: string;
39
+ /** The `<wsse:BinarySecurityToken>` to insert into `wsse:Security`, when this form needs one. */
40
+ readonly binarySecurityTokenXml?: string;
41
+ }
42
+ /** The DER bytes of a PEM certificate. */
43
+ export declare function certificateDer(certPem: string): Buffer;
44
+ /** Base64 of the DER encoding of `certPem`, unwrapped (one line). */
45
+ export declare function certificateBase64(certPem: string): string;
46
+ /**
47
+ * Base64 of the DER `PKIPath` (an ASN.1 SEQUENCE OF Certificate) holding the leaf and its chain.
48
+ *
49
+ * @param certPems the certificates, leaf first
50
+ * @returns the base64 the `X509PKIPathv1` value type expects
51
+ */
52
+ export declare function pkiPathBase64(certPems: readonly string[]): string;
53
+ /** SHA-1 of the certificate's DER encoding, base64 encoded (the `ThumbprintSHA1` value). */
54
+ export declare function thumbprintSha1Base64(certPem: string): string;
55
+ /**
56
+ * The certificate's subject key identifier extension value, base64 encoded.
57
+ *
58
+ * @param certPem the certificate to read
59
+ * @returns the base64 `X509SubjectKeyIdentifier` value
60
+ * @throws WssError `wss-ski-missing` when the certificate carries no such extension
61
+ */
62
+ export declare function subjectKeyIdentifierBase64(certPem: string): string;
63
+ /** The certificate's issuer as an RFC 2253 distinguished name (most specific attribute first). */
64
+ export declare function issuerDnRfc2253(certPem: string): string;
65
+ /** The certificate's serial number in decimal, as `ds:X509SerialNumber` requires. */
66
+ export declare function serialNumberDecimal(certPem: string): string;
67
+ /**
68
+ * Builds the `ds:KeyInfo` content (and any `wsse:BinarySecurityToken`) for one key identifier
69
+ * form.
70
+ *
71
+ * @param type which of the five X.509 token profile forms to emit
72
+ * @param input the signing certificate, its chain and the token id to use
73
+ * @returns the KeyInfo XML, plus the binary security token when the form needs one
74
+ * @throws WssError `wss-ski-missing` for `SubjectKeyIdentifier` on a certificate without one
75
+ */
76
+ export declare function buildKeyIdentifier(type: WssKeyIdentifierType, input: KeyIdentifierInput): KeyIdentifier;
@@ -0,0 +1,139 @@
1
+ /**
2
+ * The `<ds:KeyInfo>` content an outgoing signature carries: a `wsse:SecurityTokenReference`
3
+ * (or a bare `ds:X509Data`) pointing at the signing certificate in one of the five forms the
4
+ * X.509 token profile defines.
5
+ *
6
+ * These are produced as XML *strings* rather than DOM nodes because `xml-crypto` builds the
7
+ * whole `<ds:Signature>` element by string concatenation and asks for the KeyInfo contents the
8
+ * same way. Every element therefore declares the prefixes it uses on itself.
9
+ */
10
+ import { createHash } from 'node:crypto';
11
+ import forge from 'node-forge';
12
+ import { WssError } from '../errors.js';
13
+ import { NS } from '../xml/namespaces.js';
14
+ import { renderDnRfc2253 } from './keystore/certificate.js';
15
+ /** `ValueType`/`EncodingType` URIs from the WS-Security X.509 token profile. */
16
+ export const WSS_TOKEN_TYPES = {
17
+ /** A single DER-encoded certificate. */
18
+ X509V3: 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3',
19
+ /** An ordered DER PKIPath of certificates. */
20
+ X509_PKI_PATH_V1: 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509PKIPathv1',
21
+ /** The certificate's subject key identifier extension value. */
22
+ X509_SUBJECT_KEY_IDENTIFIER: 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509SubjectKeyIdentifier',
23
+ /** SHA-1 of the DER encoding of the certificate. */
24
+ THUMBPRINT_SHA1: 'http://docs.oasis-open.org/wss/oasis-wss-soap-message-security-1.1#ThumbprintSHA1',
25
+ /** Base64 content encoding. */
26
+ BASE64_BINARY: 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary',
27
+ };
28
+ /** Escapes the five XML significant characters in attribute/text content. */
29
+ function escapeXml(value) {
30
+ return value
31
+ .replace(/&/g, '&amp;')
32
+ .replace(/</g, '&lt;')
33
+ .replace(/>/g, '&gt;')
34
+ .replace(/"/g, '&quot;')
35
+ .replace(/'/g, '&apos;');
36
+ }
37
+ /** The DER bytes of a PEM certificate. */
38
+ export function certificateDer(certPem) {
39
+ const der = forge.asn1.toDer(forge.pki.certificateToAsn1(forge.pki.certificateFromPem(certPem))).getBytes();
40
+ return Buffer.from(der, 'binary');
41
+ }
42
+ /** Base64 of the DER encoding of `certPem`, unwrapped (one line). */
43
+ export function certificateBase64(certPem) {
44
+ return certificateDer(certPem).toString('base64');
45
+ }
46
+ /**
47
+ * Base64 of the DER `PKIPath` (an ASN.1 SEQUENCE OF Certificate) holding the leaf and its chain.
48
+ *
49
+ * @param certPems the certificates, leaf first
50
+ * @returns the base64 the `X509PKIPathv1` value type expects
51
+ */
52
+ export function pkiPathBase64(certPems) {
53
+ const certificates = certPems.map((pem) => forge.pki.certificateToAsn1(forge.pki.certificateFromPem(pem)));
54
+ const sequence = forge.asn1.create(forge.asn1.Class.UNIVERSAL, forge.asn1.Type.SEQUENCE, true, certificates);
55
+ return Buffer.from(forge.asn1.toDer(sequence).getBytes(), 'binary').toString('base64');
56
+ }
57
+ /** SHA-1 of the certificate's DER encoding, base64 encoded (the `ThumbprintSHA1` value). */
58
+ export function thumbprintSha1Base64(certPem) {
59
+ return createHash('sha1').update(certificateDer(certPem)).digest('base64');
60
+ }
61
+ /**
62
+ * The certificate's subject key identifier extension value, base64 encoded.
63
+ *
64
+ * @param certPem the certificate to read
65
+ * @returns the base64 `X509SubjectKeyIdentifier` value
66
+ * @throws WssError `wss-ski-missing` when the certificate carries no such extension
67
+ */
68
+ export function subjectKeyIdentifierBase64(certPem) {
69
+ const cert = forge.pki.certificateFromPem(certPem);
70
+ const extension = cert.extensions.find((candidate) => candidate.name === 'subjectKeyIdentifier' || candidate.id === '2.5.29.14');
71
+ const hex = extension?.subjectKeyIdentifier;
72
+ if (typeof hex !== 'string' || hex.length === 0) {
73
+ throw new WssError('wss-ski-missing', 'The signing certificate has no Subject Key Identifier extension; choose another key identifier type.');
74
+ }
75
+ return Buffer.from(hex, 'hex').toString('base64');
76
+ }
77
+ /** The certificate's issuer as an RFC 2253 distinguished name (most specific attribute first). */
78
+ export function issuerDnRfc2253(certPem) {
79
+ const cert = forge.pki.certificateFromPem(certPem);
80
+ return renderDnRfc2253(cert.issuer.attributes);
81
+ }
82
+ /** The certificate's serial number in decimal, as `ds:X509SerialNumber` requires. */
83
+ export function serialNumberDecimal(certPem) {
84
+ const cert = forge.pki.certificateFromPem(certPem);
85
+ return BigInt(`0x${cert.serialNumber}`).toString(10);
86
+ }
87
+ /** Opens a `wsse:SecurityTokenReference`, declaring both WS-Security prefixes on itself. */
88
+ function securityTokenReference(inner) {
89
+ return `<wsse:SecurityTokenReference xmlns:wsse="${NS.WSSE}" xmlns:wsu="${NS.WSU}">${inner}</wsse:SecurityTokenReference>`;
90
+ }
91
+ /** A `<wsse:KeyIdentifier>` carrying base64 content of the given value type. */
92
+ function keyIdentifierElement(valueType, value) {
93
+ return (`<wsse:KeyIdentifier ValueType="${valueType}" EncodingType="${WSS_TOKEN_TYPES.BASE64_BINARY}">` +
94
+ `${value}</wsse:KeyIdentifier>`);
95
+ }
96
+ /**
97
+ * Builds the `ds:KeyInfo` content (and any `wsse:BinarySecurityToken`) for one key identifier
98
+ * form.
99
+ *
100
+ * @param type which of the five X.509 token profile forms to emit
101
+ * @param input the signing certificate, its chain and the token id to use
102
+ * @returns the KeyInfo XML, plus the binary security token when the form needs one
103
+ * @throws WssError `wss-ski-missing` for `SubjectKeyIdentifier` on a certificate without one
104
+ */
105
+ export function buildKeyIdentifier(type, input) {
106
+ switch (type) {
107
+ case 'BinarySecurityToken': {
108
+ const valueType = input.useSingleCertificate ? WSS_TOKEN_TYPES.X509V3 : WSS_TOKEN_TYPES.X509_PKI_PATH_V1;
109
+ const value = input.useSingleCertificate
110
+ ? certificateBase64(input.certPem)
111
+ : pkiPathBase64([input.certPem, ...input.chainPem]);
112
+ return {
113
+ keyInfoXml: securityTokenReference(`<wsse:Reference URI="#${input.tokenId}" ValueType="${valueType}"/>`),
114
+ binarySecurityTokenXml: `<wsse:BinarySecurityToken xmlns:wsse="${NS.WSSE}" xmlns:wsu="${NS.WSU}" ` +
115
+ `wsu:Id="${input.tokenId}" EncodingType="${WSS_TOKEN_TYPES.BASE64_BINARY}" ` +
116
+ `ValueType="${valueType}">${value}</wsse:BinarySecurityToken>`,
117
+ };
118
+ }
119
+ case 'IssuerSerial':
120
+ return {
121
+ keyInfoXml: `<ds:X509Data xmlns:ds="${NS.DS}"><ds:X509IssuerSerial>` +
122
+ `<ds:X509IssuerName>${escapeXml(issuerDnRfc2253(input.certPem))}</ds:X509IssuerName>` +
123
+ `<ds:X509SerialNumber>${serialNumberDecimal(input.certPem)}</ds:X509SerialNumber>` +
124
+ `</ds:X509IssuerSerial></ds:X509Data>`,
125
+ };
126
+ case 'SubjectKeyIdentifier':
127
+ return {
128
+ keyInfoXml: securityTokenReference(keyIdentifierElement(WSS_TOKEN_TYPES.X509_SUBJECT_KEY_IDENTIFIER, subjectKeyIdentifierBase64(input.certPem))),
129
+ };
130
+ case 'X509KeyIdentifier':
131
+ return {
132
+ keyInfoXml: securityTokenReference(keyIdentifierElement(WSS_TOKEN_TYPES.X509V3, certificateBase64(input.certPem))),
133
+ };
134
+ case 'Thumbprint':
135
+ return {
136
+ keyInfoXml: securityTokenReference(keyIdentifierElement(WSS_TOKEN_TYPES.THUMBPRINT_SHA1, thumbprintSha1Base64(input.certPem))),
137
+ };
138
+ }
139
+ }