bantou 0.1.0 → 0.2.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 (515) hide show
  1. package/.output/nitro.json +13 -0
  2. package/.output/public/_nuxt/BmGsA4i2.js +1 -0
  3. package/.output/public/_nuxt/D_G6gzEa.js +1 -0
  4. package/.output/public/_nuxt/builds/latest.json +1 -0
  5. package/.output/public/_nuxt/builds/meta/1a8fc623-6671-445b-bdd3-c3d073520a3a.json +1 -0
  6. package/.output/public/_nuxt/entry.CZSvzYhH.css +1 -0
  7. package/.output/public/_nuxt/error-404.C3wqHTJz.css +1 -0
  8. package/.output/public/_nuxt/error-500.D6rBzoDj.css +1 -0
  9. package/.output/public/_nuxt/pdFQkwM_.js +4 -0
  10. package/.output/server/chunks/_/error-500.mjs +20 -0
  11. package/.output/server/chunks/_/error-500.mjs.map +1 -0
  12. package/.output/server/chunks/nitro/nitro.mjs +5870 -0
  13. package/.output/server/chunks/nitro/nitro.mjs.map +1 -0
  14. package/.output/server/chunks/routes/mcp.mjs +22 -0
  15. package/.output/server/chunks/routes/mcp.mjs.map +1 -0
  16. package/.output/server/chunks/routes/renderer.mjs +462 -0
  17. package/.output/server/chunks/routes/renderer.mjs.map +1 -0
  18. package/.output/server/chunks/virtual/_virtual_spa-template.mjs +4 -0
  19. package/.output/server/chunks/virtual/_virtual_spa-template.mjs.map +1 -0
  20. package/.output/server/chunks/virtual/precomputed.mjs +4 -0
  21. package/.output/server/chunks/virtual/precomputed.mjs.map +1 -0
  22. package/.output/server/index.mjs +18 -0
  23. package/.output/server/index.mjs.map +1 -0
  24. package/.output/server/node_modules/@babel/parser/lib/index.js +14657 -0
  25. package/.output/server/node_modules/@babel/parser/package.json +50 -0
  26. package/.output/server/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/helpers.js +64 -0
  27. package/.output/server/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/interfaces.js +16 -0
  28. package/.output/server/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/mcp-server.js +32 -0
  29. package/.output/server/node_modules/@modelcontextprotocol/sdk/dist/esm/experimental/tasks/server.js +246 -0
  30. package/.output/server/node_modules/@modelcontextprotocol/sdk/dist/esm/package.json +1 -0
  31. package/.output/server/node_modules/@modelcontextprotocol/sdk/dist/esm/server/completable.js +41 -0
  32. package/.output/server/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js +429 -0
  33. package/.output/server/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js +971 -0
  34. package/.output/server/node_modules/@modelcontextprotocol/sdk/dist/esm/server/requestBody.js +58 -0
  35. package/.output/server/node_modules/@modelcontextprotocol/sdk/dist/esm/server/sseKeepAlive.js +13 -0
  36. package/.output/server/node_modules/@modelcontextprotocol/sdk/dist/esm/server/webStandardStreamableHttp.js +961 -0
  37. package/.output/server/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js +228 -0
  38. package/.output/server/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js +51 -0
  39. package/.output/server/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/mediaType.js +57 -0
  40. package/.output/server/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js +1137 -0
  41. package/.output/server/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/toolNameValidation.js +92 -0
  42. package/.output/server/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/uriTemplate.js +239 -0
  43. package/.output/server/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js +2065 -0
  44. package/.output/server/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js +87 -0
  45. package/.output/server/node_modules/@modelcontextprotocol/sdk/package.json +165 -0
  46. package/.output/server/node_modules/@parcel/watcher-wasm/index.mjs +349 -0
  47. package/.output/server/node_modules/@parcel/watcher-wasm/package.json +44 -0
  48. package/.output/server/node_modules/@parcel/watcher-wasm/watcher.wasm +0 -0
  49. package/.output/server/node_modules/@parcel/watcher-wasm/wrapper.js +88 -0
  50. package/.output/server/node_modules/@unagents/messenger-broker/dist/index.mjs +12 -0
  51. package/.output/server/node_modules/@unagents/messenger-broker/dist/shared/messenger-broker.B8W77sqB.mjs +1177 -0
  52. package/.output/server/node_modules/@unagents/messenger-broker/package.json +37 -0
  53. package/.output/server/node_modules/@unagents/messenger-client/dist/index.mjs +9 -0
  54. package/.output/server/node_modules/@unagents/messenger-client/dist/shared/messenger-client.CfQVmH_Z.mjs +975 -0
  55. package/.output/server/node_modules/@unagents/messenger-client/dist/shared/messenger-client.CoDKzubj.mjs +1000 -0
  56. package/.output/server/node_modules/@unagents/messenger-client/package.json +37 -0
  57. package/.output/server/node_modules/@unagents/messenger-protocol/dist/index.mjs +103 -0
  58. package/.output/server/node_modules/@unagents/messenger-protocol/package.json +29 -0
  59. package/.output/server/node_modules/@vue/compiler-core/dist/compiler-core.cjs.prod.js +6802 -0
  60. package/.output/server/node_modules/@vue/compiler-core/package.json +58 -0
  61. package/.output/server/node_modules/@vue/compiler-dom/dist/compiler-dom.cjs.prod.js +729 -0
  62. package/.output/server/node_modules/@vue/compiler-dom/package.json +57 -0
  63. package/.output/server/node_modules/@vue/compiler-ssr/dist/compiler-ssr.cjs.js +1420 -0
  64. package/.output/server/node_modules/@vue/compiler-ssr/package.json +34 -0
  65. package/.output/server/node_modules/@vue/reactivity/dist/reactivity.cjs.prod.js +1933 -0
  66. package/.output/server/node_modules/@vue/reactivity/package.json +55 -0
  67. package/.output/server/node_modules/@vue/runtime-core/dist/runtime-core.cjs.prod.js +7085 -0
  68. package/.output/server/node_modules/@vue/runtime-core/package.json +52 -0
  69. package/.output/server/node_modules/@vue/runtime-dom/dist/runtime-dom.cjs.prod.js +1917 -0
  70. package/.output/server/node_modules/@vue/runtime-dom/package.json +60 -0
  71. package/.output/server/node_modules/@vue/server-renderer/dist/server-renderer.cjs.prod.js +951 -0
  72. package/.output/server/node_modules/@vue/server-renderer/package.json +53 -0
  73. package/.output/server/node_modules/@vue/shared/dist/shared.cjs.prod.js +655 -0
  74. package/.output/server/node_modules/@vue/shared/package.json +47 -0
  75. package/.output/server/node_modules/ajv/dist/ajv.js +50 -0
  76. package/.output/server/node_modules/ajv/dist/compile/codegen/code.js +156 -0
  77. package/.output/server/node_modules/ajv/dist/compile/codegen/index.js +697 -0
  78. package/.output/server/node_modules/ajv/dist/compile/codegen/scope.js +143 -0
  79. package/.output/server/node_modules/ajv/dist/compile/errors.js +123 -0
  80. package/.output/server/node_modules/ajv/dist/compile/index.js +242 -0
  81. package/.output/server/node_modules/ajv/dist/compile/names.js +28 -0
  82. package/.output/server/node_modules/ajv/dist/compile/ref_error.js +12 -0
  83. package/.output/server/node_modules/ajv/dist/compile/resolve.js +155 -0
  84. package/.output/server/node_modules/ajv/dist/compile/rules.js +26 -0
  85. package/.output/server/node_modules/ajv/dist/compile/util.js +178 -0
  86. package/.output/server/node_modules/ajv/dist/compile/validate/applicability.js +19 -0
  87. package/.output/server/node_modules/ajv/dist/compile/validate/boolSchema.js +50 -0
  88. package/.output/server/node_modules/ajv/dist/compile/validate/dataType.js +203 -0
  89. package/.output/server/node_modules/ajv/dist/compile/validate/defaults.js +35 -0
  90. package/.output/server/node_modules/ajv/dist/compile/validate/index.js +520 -0
  91. package/.output/server/node_modules/ajv/dist/compile/validate/keyword.js +124 -0
  92. package/.output/server/node_modules/ajv/dist/compile/validate/subschema.js +81 -0
  93. package/.output/server/node_modules/ajv/dist/core.js +618 -0
  94. package/.output/server/node_modules/ajv/dist/refs/data.json +13 -0
  95. package/.output/server/node_modules/ajv/dist/refs/json-schema-draft-07.json +151 -0
  96. package/.output/server/node_modules/ajv/dist/runtime/equal.js +7 -0
  97. package/.output/server/node_modules/ajv/dist/runtime/ucs2length.js +24 -0
  98. package/.output/server/node_modules/ajv/dist/runtime/uri.js +6 -0
  99. package/.output/server/node_modules/ajv/dist/runtime/validation_error.js +11 -0
  100. package/.output/server/node_modules/ajv/dist/vocabularies/applicator/additionalItems.js +49 -0
  101. package/.output/server/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js +106 -0
  102. package/.output/server/node_modules/ajv/dist/vocabularies/applicator/allOf.js +23 -0
  103. package/.output/server/node_modules/ajv/dist/vocabularies/applicator/anyOf.js +12 -0
  104. package/.output/server/node_modules/ajv/dist/vocabularies/applicator/contains.js +95 -0
  105. package/.output/server/node_modules/ajv/dist/vocabularies/applicator/dependencies.js +85 -0
  106. package/.output/server/node_modules/ajv/dist/vocabularies/applicator/if.js +66 -0
  107. package/.output/server/node_modules/ajv/dist/vocabularies/applicator/index.js +44 -0
  108. package/.output/server/node_modules/ajv/dist/vocabularies/applicator/items.js +52 -0
  109. package/.output/server/node_modules/ajv/dist/vocabularies/applicator/items2020.js +30 -0
  110. package/.output/server/node_modules/ajv/dist/vocabularies/applicator/not.js +26 -0
  111. package/.output/server/node_modules/ajv/dist/vocabularies/applicator/oneOf.js +60 -0
  112. package/.output/server/node_modules/ajv/dist/vocabularies/applicator/patternProperties.js +75 -0
  113. package/.output/server/node_modules/ajv/dist/vocabularies/applicator/prefixItems.js +12 -0
  114. package/.output/server/node_modules/ajv/dist/vocabularies/applicator/properties.js +54 -0
  115. package/.output/server/node_modules/ajv/dist/vocabularies/applicator/propertyNames.js +38 -0
  116. package/.output/server/node_modules/ajv/dist/vocabularies/applicator/thenElse.js +13 -0
  117. package/.output/server/node_modules/ajv/dist/vocabularies/code.js +131 -0
  118. package/.output/server/node_modules/ajv/dist/vocabularies/core/id.js +10 -0
  119. package/.output/server/node_modules/ajv/dist/vocabularies/core/index.js +16 -0
  120. package/.output/server/node_modules/ajv/dist/vocabularies/core/ref.js +122 -0
  121. package/.output/server/node_modules/ajv/dist/vocabularies/discriminator/index.js +104 -0
  122. package/.output/server/node_modules/ajv/dist/vocabularies/discriminator/types.js +9 -0
  123. package/.output/server/node_modules/ajv/dist/vocabularies/draft7.js +17 -0
  124. package/.output/server/node_modules/ajv/dist/vocabularies/format/format.js +92 -0
  125. package/.output/server/node_modules/ajv/dist/vocabularies/format/index.js +6 -0
  126. package/.output/server/node_modules/ajv/dist/vocabularies/metadata.js +18 -0
  127. package/.output/server/node_modules/ajv/dist/vocabularies/validation/const.js +25 -0
  128. package/.output/server/node_modules/ajv/dist/vocabularies/validation/enum.js +48 -0
  129. package/.output/server/node_modules/ajv/dist/vocabularies/validation/index.js +33 -0
  130. package/.output/server/node_modules/ajv/dist/vocabularies/validation/limitItems.js +24 -0
  131. package/.output/server/node_modules/ajv/dist/vocabularies/validation/limitLength.js +27 -0
  132. package/.output/server/node_modules/ajv/dist/vocabularies/validation/limitNumber.js +27 -0
  133. package/.output/server/node_modules/ajv/dist/vocabularies/validation/limitProperties.js +24 -0
  134. package/.output/server/node_modules/ajv/dist/vocabularies/validation/multipleOf.js +26 -0
  135. package/.output/server/node_modules/ajv/dist/vocabularies/validation/pattern.js +33 -0
  136. package/.output/server/node_modules/ajv/dist/vocabularies/validation/required.js +79 -0
  137. package/.output/server/node_modules/ajv/dist/vocabularies/validation/uniqueItems.js +64 -0
  138. package/.output/server/node_modules/ajv/package.json +126 -0
  139. package/.output/server/node_modules/ajv-formats/dist/formats.js +208 -0
  140. package/.output/server/node_modules/ajv-formats/dist/index.js +37 -0
  141. package/.output/server/node_modules/ajv-formats/dist/limit.js +69 -0
  142. package/.output/server/node_modules/ajv-formats/package.json +74 -0
  143. package/.output/server/node_modules/consola/dist/chunks/prompt.mjs +280 -0
  144. package/.output/server/node_modules/consola/dist/core.mjs +512 -0
  145. package/.output/server/node_modules/consola/dist/index.mjs +651 -0
  146. package/.output/server/node_modules/consola/dist/shared/consola.DRwqZj3T.mjs +72 -0
  147. package/.output/server/node_modules/consola/dist/shared/consola.DXBYu-KD.mjs +288 -0
  148. package/.output/server/node_modules/consola/dist/utils.mjs +54 -0
  149. package/.output/server/node_modules/consola/package.json +136 -0
  150. package/.output/server/node_modules/content-type/index.js +225 -0
  151. package/.output/server/node_modules/content-type/package.json +42 -0
  152. package/.output/server/node_modules/cookie-es/dist/index.mjs +268 -0
  153. package/.output/server/node_modules/cookie-es/package.json +46 -0
  154. package/.output/server/node_modules/crossws/dist/_chunks/_request.mjs +83 -0
  155. package/.output/server/node_modules/crossws/dist/_chunks/adapter.mjs +234 -0
  156. package/.output/server/node_modules/crossws/dist/_chunks/error.mjs +7 -0
  157. package/.output/server/node_modules/crossws/dist/_chunks/libs/ws.mjs +6 -0
  158. package/.output/server/node_modules/crossws/dist/_chunks/node.mjs +220 -0
  159. package/.output/server/node_modules/crossws/dist/_chunks/peer.mjs +208 -0
  160. package/.output/server/node_modules/crossws/dist/adapters/node.mjs +1 -0
  161. package/.output/server/node_modules/crossws/package.json +115 -0
  162. package/.output/server/node_modules/defu/dist/defu.mjs +69 -0
  163. package/.output/server/node_modules/defu/package.json +48 -0
  164. package/.output/server/node_modules/destr/dist/index.mjs +72 -0
  165. package/.output/server/node_modules/destr/package.json +47 -0
  166. package/.output/server/node_modules/devalue/index.js +17 -0
  167. package/.output/server/node_modules/devalue/package.json +39 -0
  168. package/.output/server/node_modules/devalue/src/base64.js +60 -0
  169. package/.output/server/node_modules/devalue/src/constants.js +12 -0
  170. package/.output/server/node_modules/devalue/src/operations.js +221 -0
  171. package/.output/server/node_modules/devalue/src/parse.js +279 -0
  172. package/.output/server/node_modules/devalue/src/stringify.js +433 -0
  173. package/.output/server/node_modules/devalue/src/uneval.js +698 -0
  174. package/.output/server/node_modules/devalue/src/utils.js +190 -0
  175. package/.output/server/node_modules/entities/dist/commonjs/decode-codepoint.js +77 -0
  176. package/.output/server/node_modules/entities/dist/commonjs/decode.js +568 -0
  177. package/.output/server/node_modules/entities/dist/commonjs/generated/decode-data-html.js +7 -0
  178. package/.output/server/node_modules/entities/dist/commonjs/generated/decode-data-xml.js +7 -0
  179. package/.output/server/node_modules/entities/dist/commonjs/internal/bin-trie-flags.js +21 -0
  180. package/.output/server/node_modules/entities/dist/commonjs/internal/decode-shared.js +31 -0
  181. package/.output/server/node_modules/entities/dist/commonjs/package.json +3 -0
  182. package/.output/server/node_modules/entities/package.json +120 -0
  183. package/.output/server/node_modules/estree-walker/dist/umd/estree-walker.js +344 -0
  184. package/.output/server/node_modules/estree-walker/package.json +37 -0
  185. package/.output/server/node_modules/fast-deep-equal/index.js +46 -0
  186. package/.output/server/node_modules/fast-deep-equal/package.json +61 -0
  187. package/.output/server/node_modules/fast-uri/index.js +711 -0
  188. package/.output/server/node_modules/fast-uri/lib/schemes.js +272 -0
  189. package/.output/server/node_modules/fast-uri/lib/utils.js +799 -0
  190. package/.output/server/node_modules/fast-uri/package.json +68 -0
  191. package/.output/server/node_modules/get-port-please/dist/index.mjs +430 -0
  192. package/.output/server/node_modules/get-port-please/package.json +39 -0
  193. package/.output/server/node_modules/h3/dist/index.mjs +2498 -0
  194. package/.output/server/node_modules/h3/package.json +75 -0
  195. package/.output/server/node_modules/hookable/dist/index.mjs +257 -0
  196. package/.output/server/node_modules/hookable/package.json +54 -0
  197. package/.output/server/node_modules/http-shutdown/index.js +85 -0
  198. package/.output/server/node_modules/http-shutdown/package.json +32 -0
  199. package/.output/server/node_modules/iron-webcrypto/dist/index.js +298 -0
  200. package/.output/server/node_modules/iron-webcrypto/package.json +72 -0
  201. package/.output/server/node_modules/is-extglob/index.js +20 -0
  202. package/.output/server/node_modules/is-extglob/package.json +69 -0
  203. package/.output/server/node_modules/is-glob/index.js +150 -0
  204. package/.output/server/node_modules/is-glob/package.json +81 -0
  205. package/.output/server/node_modules/jiti/dist/jiti.cjs +1 -0
  206. package/.output/server/node_modules/jiti/lib/jiti.mjs +29 -0
  207. package/.output/server/node_modules/jiti/package.json +146 -0
  208. package/.output/server/node_modules/json-schema-traverse/index.js +93 -0
  209. package/.output/server/node_modules/json-schema-traverse/package.json +43 -0
  210. package/.output/server/node_modules/listhen/dist/chunks/xdg-open.mjs +1069 -0
  211. package/.output/server/node_modules/listhen/dist/index.mjs +19 -0
  212. package/.output/server/node_modules/listhen/dist/shared/listhen.tqe5I1Rl.mjs +1040 -0
  213. package/.output/server/node_modules/listhen/package.json +84 -0
  214. package/.output/server/node_modules/napi-wasm/index.mjs +1371 -0
  215. package/.output/server/node_modules/napi-wasm/package.json +33 -0
  216. package/.output/server/node_modules/node-forge/lib/aes.js +1091 -0
  217. package/.output/server/node_modules/node-forge/lib/aesCipherSuites.js +282 -0
  218. package/.output/server/node_modules/node-forge/lib/asn1-validator.js +91 -0
  219. package/.output/server/node_modules/node-forge/lib/asn1.js +1522 -0
  220. package/.output/server/node_modules/node-forge/lib/baseN.js +186 -0
  221. package/.output/server/node_modules/node-forge/lib/cipher.js +230 -0
  222. package/.output/server/node_modules/node-forge/lib/cipherModes.js +1027 -0
  223. package/.output/server/node_modules/node-forge/lib/des.js +496 -0
  224. package/.output/server/node_modules/node-forge/lib/ed25519.js +1091 -0
  225. package/.output/server/node_modules/node-forge/lib/forge.js +13 -0
  226. package/.output/server/node_modules/node-forge/lib/hmac.js +146 -0
  227. package/.output/server/node_modules/node-forge/lib/index.js +33 -0
  228. package/.output/server/node_modules/node-forge/lib/jsbn.js +1294 -0
  229. package/.output/server/node_modules/node-forge/lib/kem.js +168 -0
  230. package/.output/server/node_modules/node-forge/lib/log.js +319 -0
  231. package/.output/server/node_modules/node-forge/lib/md.all.js +13 -0
  232. package/.output/server/node_modules/node-forge/lib/md.js +11 -0
  233. package/.output/server/node_modules/node-forge/lib/md5.js +289 -0
  234. package/.output/server/node_modules/node-forge/lib/mgf.js +12 -0
  235. package/.output/server/node_modules/node-forge/lib/mgf1.js +57 -0
  236. package/.output/server/node_modules/node-forge/lib/oids.js +180 -0
  237. package/.output/server/node_modules/node-forge/lib/pbe.js +1029 -0
  238. package/.output/server/node_modules/node-forge/lib/pbkdf2.js +211 -0
  239. package/.output/server/node_modules/node-forge/lib/pem.js +413 -0
  240. package/.output/server/node_modules/node-forge/lib/pkcs1.js +276 -0
  241. package/.output/server/node_modules/node-forge/lib/pkcs12.js +1081 -0
  242. package/.output/server/node_modules/node-forge/lib/pkcs7.js +1260 -0
  243. package/.output/server/node_modules/node-forge/lib/pkcs7asn1.js +410 -0
  244. package/.output/server/node_modules/node-forge/lib/pki.js +102 -0
  245. package/.output/server/node_modules/node-forge/lib/prime.js +297 -0
  246. package/.output/server/node_modules/node-forge/lib/prng.js +419 -0
  247. package/.output/server/node_modules/node-forge/lib/pss.js +241 -0
  248. package/.output/server/node_modules/node-forge/lib/random.js +191 -0
  249. package/.output/server/node_modules/node-forge/lib/rc2.js +410 -0
  250. package/.output/server/node_modules/node-forge/lib/rsa.js +2014 -0
  251. package/.output/server/node_modules/node-forge/lib/sha1.js +319 -0
  252. package/.output/server/node_modules/node-forge/lib/sha256.js +327 -0
  253. package/.output/server/node_modules/node-forge/lib/sha512.js +561 -0
  254. package/.output/server/node_modules/node-forge/lib/ssh.js +236 -0
  255. package/.output/server/node_modules/node-forge/lib/tls.js +4334 -0
  256. package/.output/server/node_modules/node-forge/lib/util.js +2652 -0
  257. package/.output/server/node_modules/node-forge/lib/x509.js +3257 -0
  258. package/.output/server/node_modules/node-forge/package.json +123 -0
  259. package/.output/server/node_modules/node-mock-http/dist/_polyfill/buffer/node.mjs +1 -0
  260. package/.output/server/node_modules/node-mock-http/dist/_polyfill/events/node.mjs +1 -0
  261. package/.output/server/node_modules/node-mock-http/dist/index.mjs +1 -0
  262. package/.output/server/node_modules/node-mock-http/package.json +63 -0
  263. package/.output/server/node_modules/nostics/dist/formatters/ansi.mjs +19 -0
  264. package/.output/server/node_modules/nostics/dist/index.mjs +194 -0
  265. package/.output/server/node_modules/nostics/package.json +126 -0
  266. package/.output/server/node_modules/pathe/dist/index.mjs +19 -0
  267. package/.output/server/node_modules/pathe/dist/shared/pathe.M-eThtNZ.mjs +249 -0
  268. package/.output/server/node_modules/pathe/package.json +61 -0
  269. package/.output/server/node_modules/picomatch/index.js +17 -0
  270. package/.output/server/node_modules/picomatch/lib/constants.js +184 -0
  271. package/.output/server/node_modules/picomatch/lib/parse.js +1425 -0
  272. package/.output/server/node_modules/picomatch/lib/picomatch.js +361 -0
  273. package/.output/server/node_modules/picomatch/lib/scan.js +403 -0
  274. package/.output/server/node_modules/picomatch/lib/utils.js +72 -0
  275. package/.output/server/node_modules/picomatch/package.json +83 -0
  276. package/.output/server/node_modules/radix3/dist/index.mjs +262 -0
  277. package/.output/server/node_modules/radix3/package.json +52 -0
  278. package/.output/server/node_modules/source-map-js/lib/array-set.js +121 -0
  279. package/.output/server/node_modules/source-map-js/lib/base64-vlq.js +140 -0
  280. package/.output/server/node_modules/source-map-js/lib/base64.js +67 -0
  281. package/.output/server/node_modules/source-map-js/lib/binary-search.js +111 -0
  282. package/.output/server/node_modules/source-map-js/lib/mapping-list.js +79 -0
  283. package/.output/server/node_modules/source-map-js/lib/quick-sort.js +141 -0
  284. package/.output/server/node_modules/source-map-js/lib/source-map-consumer.js +1236 -0
  285. package/.output/server/node_modules/source-map-js/lib/source-map-generator.js +446 -0
  286. package/.output/server/node_modules/source-map-js/lib/source-node.js +420 -0
  287. package/.output/server/node_modules/source-map-js/lib/util.js +594 -0
  288. package/.output/server/node_modules/source-map-js/package.json +71 -0
  289. package/.output/server/node_modules/source-map-js/source-map.js +8 -0
  290. package/.output/server/node_modules/std-env/dist/index.mjs +1 -0
  291. package/.output/server/node_modules/std-env/package.json +43 -0
  292. package/.output/server/node_modules/tinyclip/dist/index.js +143 -0
  293. package/.output/server/node_modules/tinyclip/package.json +48 -0
  294. package/.output/server/node_modules/ufo/dist/index.mjs +645 -0
  295. package/.output/server/node_modules/ufo/package.json +48 -0
  296. package/.output/server/node_modules/uncrypto/dist/crypto.node.mjs +16 -0
  297. package/.output/server/node_modules/uncrypto/package.json +60 -0
  298. package/.output/server/node_modules/unhead/dist/client.mjs +22 -0
  299. package/.output/server/node_modules/unhead/dist/legacy.mjs +33 -0
  300. package/.output/server/node_modules/unhead/dist/minify.mjs +183 -0
  301. package/.output/server/node_modules/unhead/dist/parser.mjs +518 -0
  302. package/.output/server/node_modules/unhead/dist/plugins.mjs +782 -0
  303. package/.output/server/node_modules/unhead/dist/server.mjs +99 -0
  304. package/.output/server/node_modules/unhead/dist/shared/unhead.BEmVMkeA.mjs +673 -0
  305. package/.output/server/node_modules/unhead/dist/shared/unhead.Bf_fPVYA.mjs +6 -0
  306. package/.output/server/node_modules/unhead/dist/shared/unhead.Bm4Y6XQI.mjs +17 -0
  307. package/.output/server/node_modules/unhead/dist/shared/unhead.C5Bksi2B.mjs +49 -0
  308. package/.output/server/node_modules/unhead/dist/shared/unhead.CGPOfp5O.mjs +32 -0
  309. package/.output/server/node_modules/unhead/dist/shared/unhead.CHEy9ana.mjs +7 -0
  310. package/.output/server/node_modules/unhead/dist/shared/unhead.C_7zwq8E.mjs +11 -0
  311. package/.output/server/node_modules/unhead/dist/shared/unhead.CaeaMM5q.mjs +19 -0
  312. package/.output/server/node_modules/unhead/dist/shared/unhead.D7HkBzZn.mjs +59 -0
  313. package/.output/server/node_modules/unhead/dist/shared/unhead.D9VfQWNo.mjs +240 -0
  314. package/.output/server/node_modules/unhead/dist/shared/unhead.DD4N5B4k.mjs +224 -0
  315. package/.output/server/node_modules/unhead/dist/shared/unhead.DGl9jcjg.mjs +196 -0
  316. package/.output/server/node_modules/unhead/dist/shared/unhead.DJuZwX9c.mjs +400 -0
  317. package/.output/server/node_modules/unhead/dist/shared/unhead.DkxnqlHC.mjs +264 -0
  318. package/.output/server/node_modules/unhead/dist/shared/unhead.DspMpm6y.mjs +48 -0
  319. package/.output/server/node_modules/unhead/dist/shared/unhead.o8j9utSy.mjs +208 -0
  320. package/.output/server/node_modules/unhead/dist/stream/client.mjs +33 -0
  321. package/.output/server/node_modules/unhead/dist/stream/iife.mjs +2 -0
  322. package/.output/server/node_modules/unhead/dist/stream/server.mjs +446 -0
  323. package/.output/server/node_modules/unhead/dist/utils.mjs +7 -0
  324. package/.output/server/node_modules/unhead/package.json +179 -0
  325. package/.output/server/node_modules/untun/dist/_chunks/cloudflared.mjs +179 -0
  326. package/.output/server/node_modules/untun/dist/_chunks/log.mjs +27 -0
  327. package/.output/server/node_modules/untun/dist/index.mjs +47 -0
  328. package/.output/server/node_modules/untun/package.json +44 -0
  329. package/.output/server/node_modules/uqr/dist/index.mjs +739 -0
  330. package/.output/server/node_modules/uqr/package.json +69 -0
  331. package/.output/server/node_modules/vue/dist/vue.cjs.js +80 -0
  332. package/.output/server/node_modules/vue/dist/vue.cjs.prod.js +66 -0
  333. package/.output/server/node_modules/vue/index.js +7 -0
  334. package/.output/server/node_modules/vue/index.mjs +1 -0
  335. package/.output/server/node_modules/vue/package.json +112 -0
  336. package/.output/server/node_modules/vue/server-renderer/index.mjs +1 -0
  337. package/.output/server/node_modules/vue-bundle-renderer/dist/runtime.mjs +687 -0
  338. package/.output/server/node_modules/vue-bundle-renderer/package.json +66 -0
  339. package/.output/server/node_modules/zod/index.js +7 -0
  340. package/.output/server/node_modules/zod/package.json +147 -0
  341. package/.output/server/node_modules/zod/v3/ZodError.js +143 -0
  342. package/.output/server/node_modules/zod/v3/errors.js +9 -0
  343. package/.output/server/node_modules/zod/v3/external.js +6 -0
  344. package/.output/server/node_modules/zod/v3/helpers/errorUtil.js +6 -0
  345. package/.output/server/node_modules/zod/v3/helpers/parseUtil.js +109 -0
  346. package/.output/server/node_modules/zod/v3/helpers/typeAliases.js +1 -0
  347. package/.output/server/node_modules/zod/v3/helpers/util.js +133 -0
  348. package/.output/server/node_modules/zod/v3/index.js +4 -0
  349. package/.output/server/node_modules/zod/v3/locales/en.js +109 -0
  350. package/.output/server/node_modules/zod/v3/package.json +7 -0
  351. package/.output/server/node_modules/zod/v3/types.js +3697 -0
  352. package/.output/server/node_modules/zod/v4/classic/checks.js +1 -0
  353. package/.output/server/node_modules/zod/v4/classic/coerce.js +17 -0
  354. package/.output/server/node_modules/zod/v4/classic/compat.js +31 -0
  355. package/.output/server/node_modules/zod/v4/classic/deep-partial.js +13 -0
  356. package/.output/server/node_modules/zod/v4/classic/errors.js +57 -0
  357. package/.output/server/node_modules/zod/v4/classic/external.js +17 -0
  358. package/.output/server/node_modules/zod/v4/classic/from-json-schema.js +881 -0
  359. package/.output/server/node_modules/zod/v4/classic/in-out.js +36 -0
  360. package/.output/server/node_modules/zod/v4/classic/index.js +4 -0
  361. package/.output/server/node_modules/zod/v4/classic/iso.js +15 -0
  362. package/.output/server/node_modules/zod/v4/classic/package.json +7 -0
  363. package/.output/server/node_modules/zod/v4/classic/parse.js +16 -0
  364. package/.output/server/node_modules/zod/v4/classic/schemas.js +1535 -0
  365. package/.output/server/node_modules/zod/v4/core/api.js +1107 -0
  366. package/.output/server/node_modules/zod/v4/core/checks.js +516 -0
  367. package/.output/server/node_modules/zod/v4/core/compile.js +1866 -0
  368. package/.output/server/node_modules/zod/v4/core/core.js +141 -0
  369. package/.output/server/node_modules/zod/v4/core/doc.js +38 -0
  370. package/.output/server/node_modules/zod/v4/core/errors.js +267 -0
  371. package/.output/server/node_modules/zod/v4/core/index.js +19 -0
  372. package/.output/server/node_modules/zod/v4/core/json-schema-generator.js +99 -0
  373. package/.output/server/node_modules/zod/v4/core/json-schema-processors.js +843 -0
  374. package/.output/server/node_modules/zod/v4/core/json-schema.js +1 -0
  375. package/.output/server/node_modules/zod/v4/core/memoizer.js +311 -0
  376. package/.output/server/node_modules/zod/v4/core/package.json +7 -0
  377. package/.output/server/node_modules/zod/v4/core/parse.js +175 -0
  378. package/.output/server/node_modules/zod/v4/core/regexes.js +156 -0
  379. package/.output/server/node_modules/zod/v4/core/registries.js +51 -0
  380. package/.output/server/node_modules/zod/v4/core/schemas.js +2636 -0
  381. package/.output/server/node_modules/zod/v4/core/to-json-schema.js +651 -0
  382. package/.output/server/node_modules/zod/v4/core/util.js +873 -0
  383. package/.output/server/node_modules/zod/v4/core/versions.js +5 -0
  384. package/.output/server/node_modules/zod/v4/core/visit.js +169 -0
  385. package/.output/server/node_modules/zod/v4/index.js +4 -0
  386. package/.output/server/node_modules/zod/v4/locales/ar.js +111 -0
  387. package/.output/server/node_modules/zod/v4/locales/az.js +110 -0
  388. package/.output/server/node_modules/zod/v4/locales/be.js +168 -0
  389. package/.output/server/node_modules/zod/v4/locales/bg.js +125 -0
  390. package/.output/server/node_modules/zod/v4/locales/bn.js +113 -0
  391. package/.output/server/node_modules/zod/v4/locales/ca.js +112 -0
  392. package/.output/server/node_modules/zod/v4/locales/ckb.js +133 -0
  393. package/.output/server/node_modules/zod/v4/locales/cs.js +116 -0
  394. package/.output/server/node_modules/zod/v4/locales/da.js +120 -0
  395. package/.output/server/node_modules/zod/v4/locales/de.js +113 -0
  396. package/.output/server/node_modules/zod/v4/locales/el.js +112 -0
  397. package/.output/server/node_modules/zod/v4/locales/en.js +125 -0
  398. package/.output/server/node_modules/zod/v4/locales/eo.js +114 -0
  399. package/.output/server/node_modules/zod/v4/locales/es.js +136 -0
  400. package/.output/server/node_modules/zod/v4/locales/fa.js +119 -0
  401. package/.output/server/node_modules/zod/v4/locales/fi.js +117 -0
  402. package/.output/server/node_modules/zod/v4/locales/fr-CA.js +112 -0
  403. package/.output/server/node_modules/zod/v4/locales/fr.js +129 -0
  404. package/.output/server/node_modules/zod/v4/locales/gu.js +113 -0
  405. package/.output/server/node_modules/zod/v4/locales/he.js +221 -0
  406. package/.output/server/node_modules/zod/v4/locales/hi.js +111 -0
  407. package/.output/server/node_modules/zod/v4/locales/hr.js +126 -0
  408. package/.output/server/node_modules/zod/v4/locales/hu.js +113 -0
  409. package/.output/server/node_modules/zod/v4/locales/hy.js +158 -0
  410. package/.output/server/node_modules/zod/v4/locales/id.js +111 -0
  411. package/.output/server/node_modules/zod/v4/locales/index.js +63 -0
  412. package/.output/server/node_modules/zod/v4/locales/is.js +114 -0
  413. package/.output/server/node_modules/zod/v4/locales/it.js +113 -0
  414. package/.output/server/node_modules/zod/v4/locales/ja.js +112 -0
  415. package/.output/server/node_modules/zod/v4/locales/ka.js +117 -0
  416. package/.output/server/node_modules/zod/v4/locales/kh.js +5 -0
  417. package/.output/server/node_modules/zod/v4/locales/km.js +115 -0
  418. package/.output/server/node_modules/zod/v4/locales/kn.js +116 -0
  419. package/.output/server/node_modules/zod/v4/locales/ko.js +116 -0
  420. package/.output/server/node_modules/zod/v4/locales/lt.js +207 -0
  421. package/.output/server/node_modules/zod/v4/locales/mk.js +114 -0
  422. package/.output/server/node_modules/zod/v4/locales/ms.js +112 -0
  423. package/.output/server/node_modules/zod/v4/locales/ne.js +111 -0
  424. package/.output/server/node_modules/zod/v4/locales/nl.js +115 -0
  425. package/.output/server/node_modules/zod/v4/locales/nn.js +113 -0
  426. package/.output/server/node_modules/zod/v4/locales/no.js +113 -0
  427. package/.output/server/node_modules/zod/v4/locales/ota.js +114 -0
  428. package/.output/server/node_modules/zod/v4/locales/package.json +7 -0
  429. package/.output/server/node_modules/zod/v4/locales/pl.js +114 -0
  430. package/.output/server/node_modules/zod/v4/locales/ps.js +119 -0
  431. package/.output/server/node_modules/zod/v4/locales/pt-BR.js +143 -0
  432. package/.output/server/node_modules/zod/v4/locales/pt.js +142 -0
  433. package/.output/server/node_modules/zod/v4/locales/ro.js +122 -0
  434. package/.output/server/node_modules/zod/v4/locales/ru.js +168 -0
  435. package/.output/server/node_modules/zod/v4/locales/sk.js +116 -0
  436. package/.output/server/node_modules/zod/v4/locales/sl.js +114 -0
  437. package/.output/server/node_modules/zod/v4/locales/sv.js +115 -0
  438. package/.output/server/node_modules/zod/v4/locales/ta.js +115 -0
  439. package/.output/server/node_modules/zod/v4/locales/tg.js +117 -0
  440. package/.output/server/node_modules/zod/v4/locales/th.js +115 -0
  441. package/.output/server/node_modules/zod/v4/locales/tk.js +107 -0
  442. package/.output/server/node_modules/zod/v4/locales/tr.js +110 -0
  443. package/.output/server/node_modules/zod/v4/locales/ua.js +5 -0
  444. package/.output/server/node_modules/zod/v4/locales/uk.js +113 -0
  445. package/.output/server/node_modules/zod/v4/locales/ur.js +115 -0
  446. package/.output/server/node_modules/zod/v4/locales/uz.js +113 -0
  447. package/.output/server/node_modules/zod/v4/locales/vi.js +113 -0
  448. package/.output/server/node_modules/zod/v4/locales/yo.js +112 -0
  449. package/.output/server/node_modules/zod/v4/locales/zh-CN.js +114 -0
  450. package/.output/server/node_modules/zod/v4/locales/zh-TW.js +112 -0
  451. package/.output/server/node_modules/zod/v4/mini/checks.js +1 -0
  452. package/.output/server/node_modules/zod/v4/mini/coerce.js +22 -0
  453. package/.output/server/node_modules/zod/v4/mini/deep-partial.js +13 -0
  454. package/.output/server/node_modules/zod/v4/mini/external.js +16 -0
  455. package/.output/server/node_modules/zod/v4/mini/in-out.js +36 -0
  456. package/.output/server/node_modules/zod/v4/mini/iso.js +34 -0
  457. package/.output/server/node_modules/zod/v4/mini/package.json +7 -0
  458. package/.output/server/node_modules/zod/v4/mini/parse.js +1 -0
  459. package/.output/server/node_modules/zod/v4/mini/schemas.js +1002 -0
  460. package/.output/server/node_modules/zod/v4/package.json +7 -0
  461. package/.output/server/node_modules/zod/v4-mini/index.js +3 -0
  462. package/.output/server/node_modules/zod/v4-mini/package.json +7 -0
  463. package/.output/server/node_modules/zod-to-json-schema/dist/esm/Options.js +46 -0
  464. package/.output/server/node_modules/zod-to-json-schema/dist/esm/Refs.js +22 -0
  465. package/.output/server/node_modules/zod-to-json-schema/dist/esm/errorMessages.js +14 -0
  466. package/.output/server/node_modules/zod-to-json-schema/dist/esm/getRelativePath.js +8 -0
  467. package/.output/server/node_modules/zod-to-json-schema/dist/esm/index.js +40 -0
  468. package/.output/server/node_modules/zod-to-json-schema/dist/esm/package.json +1 -0
  469. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parseDef.js +62 -0
  470. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parseTypes.js +1 -0
  471. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/any.js +17 -0
  472. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/array.js +26 -0
  473. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/bigint.js +49 -0
  474. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/boolean.js +5 -0
  475. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/branded.js +4 -0
  476. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/catch.js +4 -0
  477. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/date.js +46 -0
  478. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/default.js +7 -0
  479. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/effects.js +7 -0
  480. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/enum.js +6 -0
  481. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/intersection.js +52 -0
  482. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/literal.js +21 -0
  483. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/map.js +26 -0
  484. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/nativeEnum.js +16 -0
  485. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/never.js +11 -0
  486. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/null.js +10 -0
  487. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/nullable.js +33 -0
  488. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/number.js +52 -0
  489. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/object.js +72 -0
  490. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/optional.js +21 -0
  491. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/pipeline.js +20 -0
  492. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/promise.js +4 -0
  493. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/readonly.js +4 -0
  494. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/record.js +61 -0
  495. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/set.js +20 -0
  496. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/string.js +352 -0
  497. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/tuple.js +32 -0
  498. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/undefined.js +6 -0
  499. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/union.js +80 -0
  500. package/.output/server/node_modules/zod-to-json-schema/dist/esm/parsers/unknown.js +4 -0
  501. package/.output/server/node_modules/zod-to-json-schema/dist/esm/selectParser.js +105 -0
  502. package/.output/server/node_modules/zod-to-json-schema/dist/esm/zodToJsonSchema.js +87 -0
  503. package/.output/server/node_modules/zod-to-json-schema/package.json +85 -0
  504. package/.output/server/package.json +64 -0
  505. package/README.md +227 -24
  506. package/bin/bantou.mjs +33 -0
  507. package/package.json +18 -8
  508. package/protocol/PROTOCOL.md +26 -0
  509. package/protocol/protocol.json +92 -0
  510. package/dist/cap.js +0 -7
  511. package/dist/cli.js +0 -27
  512. package/dist/config.js +0 -23
  513. package/dist/daemon.js +0 -23
  514. package/dist/session.js +0 -7
  515. package/dist/workspace.js +0 -8
@@ -0,0 +1,4334 @@
1
+ /**
2
+ * A Javascript implementation of Transport Layer Security (TLS).
3
+ *
4
+ * @author Dave Longley
5
+ *
6
+ * Copyright (c) 2009-2014 Digital Bazaar, Inc.
7
+ *
8
+ * The TLS Handshake Protocol involves the following steps:
9
+ *
10
+ * - Exchange hello messages to agree on algorithms, exchange random values,
11
+ * and check for session resumption.
12
+ *
13
+ * - Exchange the necessary cryptographic parameters to allow the client and
14
+ * server to agree on a premaster secret.
15
+ *
16
+ * - Exchange certificates and cryptographic information to allow the client
17
+ * and server to authenticate themselves.
18
+ *
19
+ * - Generate a master secret from the premaster secret and exchanged random
20
+ * values.
21
+ *
22
+ * - Provide security parameters to the record layer.
23
+ *
24
+ * - Allow the client and server to verify that their peer has calculated the
25
+ * same security parameters and that the handshake occurred without tampering
26
+ * by an attacker.
27
+ *
28
+ * Up to 4 different messages may be sent during a key exchange. The server
29
+ * certificate, the server key exchange, the client certificate, and the
30
+ * client key exchange.
31
+ *
32
+ * A typical handshake (from the client's perspective).
33
+ *
34
+ * 1. Client sends ClientHello.
35
+ * 2. Client receives ServerHello.
36
+ * 3. Client receives optional Certificate.
37
+ * 4. Client receives optional ServerKeyExchange.
38
+ * 5. Client receives ServerHelloDone.
39
+ * 6. Client sends optional Certificate.
40
+ * 7. Client sends ClientKeyExchange.
41
+ * 8. Client sends optional CertificateVerify.
42
+ * 9. Client sends ChangeCipherSpec.
43
+ * 10. Client sends Finished.
44
+ * 11. Client receives ChangeCipherSpec.
45
+ * 12. Client receives Finished.
46
+ * 13. Client sends/receives application data.
47
+ *
48
+ * To reuse an existing session:
49
+ *
50
+ * 1. Client sends ClientHello with session ID for reuse.
51
+ * 2. Client receives ServerHello with same session ID if reusing.
52
+ * 3. Client receives ChangeCipherSpec message if reusing.
53
+ * 4. Client receives Finished.
54
+ * 5. Client sends ChangeCipherSpec.
55
+ * 6. Client sends Finished.
56
+ *
57
+ * Note: Client ignores HelloRequest if in the middle of a handshake.
58
+ *
59
+ * Record Layer:
60
+ *
61
+ * The record layer fragments information blocks into TLSPlaintext records
62
+ * carrying data in chunks of 2^14 bytes or less. Client message boundaries are
63
+ * not preserved in the record layer (i.e., multiple client messages of the
64
+ * same ContentType MAY be coalesced into a single TLSPlaintext record, or a
65
+ * single message MAY be fragmented across several records).
66
+ *
67
+ * struct {
68
+ * uint8 major;
69
+ * uint8 minor;
70
+ * } ProtocolVersion;
71
+ *
72
+ * struct {
73
+ * ContentType type;
74
+ * ProtocolVersion version;
75
+ * uint16 length;
76
+ * opaque fragment[TLSPlaintext.length];
77
+ * } TLSPlaintext;
78
+ *
79
+ * type:
80
+ * The higher-level protocol used to process the enclosed fragment.
81
+ *
82
+ * version:
83
+ * The version of the protocol being employed. TLS Version 1.2 uses version
84
+ * {3, 3}. TLS Version 1.0 uses version {3, 1}. Note that a client that
85
+ * supports multiple versions of TLS may not know what version will be
86
+ * employed before it receives the ServerHello.
87
+ *
88
+ * length:
89
+ * The length (in bytes) of the following TLSPlaintext.fragment. The length
90
+ * MUST NOT exceed 2^14 = 16384 bytes.
91
+ *
92
+ * fragment:
93
+ * The application data. This data is transparent and treated as an
94
+ * independent block to be dealt with by the higher-level protocol specified
95
+ * by the type field.
96
+ *
97
+ * Implementations MUST NOT send zero-length fragments of Handshake, Alert, or
98
+ * ChangeCipherSpec content types. Zero-length fragments of Application data
99
+ * MAY be sent as they are potentially useful as a traffic analysis
100
+ * countermeasure.
101
+ *
102
+ * Note: Data of different TLS record layer content types MAY be interleaved.
103
+ * Application data is generally of lower precedence for transmission than
104
+ * other content types. However, records MUST be delivered to the network in
105
+ * the same order as they are protected by the record layer. Recipients MUST
106
+ * receive and process interleaved application layer traffic during handshakes
107
+ * subsequent to the first one on a connection.
108
+ *
109
+ * struct {
110
+ * ContentType type; // same as TLSPlaintext.type
111
+ * ProtocolVersion version;// same as TLSPlaintext.version
112
+ * uint16 length;
113
+ * opaque fragment[TLSCompressed.length];
114
+ * } TLSCompressed;
115
+ *
116
+ * length:
117
+ * The length (in bytes) of the following TLSCompressed.fragment.
118
+ * The length MUST NOT exceed 2^14 + 1024.
119
+ *
120
+ * fragment:
121
+ * The compressed form of TLSPlaintext.fragment.
122
+ *
123
+ * Note: A CompressionMethod.null operation is an identity operation; no fields
124
+ * are altered. In this implementation, since no compression is supported,
125
+ * uncompressed records are always the same as compressed records.
126
+ *
127
+ * Encryption Information:
128
+ *
129
+ * The encryption and MAC functions translate a TLSCompressed structure into a
130
+ * TLSCiphertext. The decryption functions reverse the process. The MAC of the
131
+ * record also includes a sequence number so that missing, extra, or repeated
132
+ * messages are detectable.
133
+ *
134
+ * struct {
135
+ * ContentType type;
136
+ * ProtocolVersion version;
137
+ * uint16 length;
138
+ * select (SecurityParameters.cipher_type) {
139
+ * case stream: GenericStreamCipher;
140
+ * case block: GenericBlockCipher;
141
+ * case aead: GenericAEADCipher;
142
+ * } fragment;
143
+ * } TLSCiphertext;
144
+ *
145
+ * type:
146
+ * The type field is identical to TLSCompressed.type.
147
+ *
148
+ * version:
149
+ * The version field is identical to TLSCompressed.version.
150
+ *
151
+ * length:
152
+ * The length (in bytes) of the following TLSCiphertext.fragment.
153
+ * The length MUST NOT exceed 2^14 + 2048.
154
+ *
155
+ * fragment:
156
+ * The encrypted form of TLSCompressed.fragment, with the MAC.
157
+ *
158
+ * Note: Only CBC Block Ciphers are supported by this implementation.
159
+ *
160
+ * The TLSCompressed.fragment structures are converted to/from block
161
+ * TLSCiphertext.fragment structures.
162
+ *
163
+ * struct {
164
+ * opaque IV[SecurityParameters.record_iv_length];
165
+ * block-ciphered struct {
166
+ * opaque content[TLSCompressed.length];
167
+ * opaque MAC[SecurityParameters.mac_length];
168
+ * uint8 padding[GenericBlockCipher.padding_length];
169
+ * uint8 padding_length;
170
+ * };
171
+ * } GenericBlockCipher;
172
+ *
173
+ * The MAC is generated as described in Section 6.2.3.1.
174
+ *
175
+ * IV:
176
+ * The Initialization Vector (IV) SHOULD be chosen at random, and MUST be
177
+ * unpredictable. Note that in versions of TLS prior to 1.1, there was no
178
+ * IV field, and the last ciphertext block of the previous record (the "CBC
179
+ * residue") was used as the IV. This was changed to prevent the attacks
180
+ * described in [CBCATT]. For block ciphers, the IV length is of length
181
+ * SecurityParameters.record_iv_length, which is equal to the
182
+ * SecurityParameters.block_size.
183
+ *
184
+ * padding:
185
+ * Padding that is added to force the length of the plaintext to be an
186
+ * integral multiple of the block cipher's block length. The padding MAY be
187
+ * any length up to 255 bytes, as long as it results in the
188
+ * TLSCiphertext.length being an integral multiple of the block length.
189
+ * Lengths longer than necessary might be desirable to frustrate attacks on
190
+ * a protocol that are based on analysis of the lengths of exchanged
191
+ * messages. Each uint8 in the padding data vector MUST be filled with the
192
+ * padding length value. The receiver MUST check this padding and MUST use
193
+ * the bad_record_mac alert to indicate padding errors.
194
+ *
195
+ * padding_length:
196
+ * The padding length MUST be such that the total size of the
197
+ * GenericBlockCipher structure is a multiple of the cipher's block length.
198
+ * Legal values range from zero to 255, inclusive. This length specifies the
199
+ * length of the padding field exclusive of the padding_length field itself.
200
+ *
201
+ * The encrypted data length (TLSCiphertext.length) is one more than the sum of
202
+ * SecurityParameters.block_length, TLSCompressed.length,
203
+ * SecurityParameters.mac_length, and padding_length.
204
+ *
205
+ * Example: If the block length is 8 bytes, the content length
206
+ * (TLSCompressed.length) is 61 bytes, and the MAC length is 20 bytes, then the
207
+ * length before padding is 82 bytes (this does not include the IV. Thus, the
208
+ * padding length modulo 8 must be equal to 6 in order to make the total length
209
+ * an even multiple of 8 bytes (the block length). The padding length can be
210
+ * 6, 14, 22, and so on, through 254. If the padding length were the minimum
211
+ * necessary, 6, the padding would be 6 bytes, each containing the value 6.
212
+ * Thus, the last 8 octets of the GenericBlockCipher before block encryption
213
+ * would be xx 06 06 06 06 06 06 06, where xx is the last octet of the MAC.
214
+ *
215
+ * Note: With block ciphers in CBC mode (Cipher Block Chaining), it is critical
216
+ * that the entire plaintext of the record be known before any ciphertext is
217
+ * transmitted. Otherwise, it is possible for the attacker to mount the attack
218
+ * described in [CBCATT].
219
+ *
220
+ * Implementation note: Canvel et al. [CBCTIME] have demonstrated a timing
221
+ * attack on CBC padding based on the time required to compute the MAC. In
222
+ * order to defend against this attack, implementations MUST ensure that
223
+ * record processing time is essentially the same whether or not the padding
224
+ * is correct. In general, the best way to do this is to compute the MAC even
225
+ * if the padding is incorrect, and only then reject the packet. For instance,
226
+ * if the pad appears to be incorrect, the implementation might assume a
227
+ * zero-length pad and then compute the MAC. This leaves a small timing
228
+ * channel, since MAC performance depends, to some extent, on the size of the
229
+ * data fragment, but it is not believed to be large enough to be exploitable,
230
+ * due to the large block size of existing MACs and the small size of the
231
+ * timing signal.
232
+ */
233
+ var forge = require('./forge');
234
+ require('./asn1');
235
+ require('./hmac');
236
+ require('./md5');
237
+ require('./pem');
238
+ require('./pki');
239
+ require('./random');
240
+ require('./sha1');
241
+ require('./util');
242
+
243
+ /**
244
+ * Generates pseudo random bytes by mixing the result of two hash functions,
245
+ * MD5 and SHA-1.
246
+ *
247
+ * prf_TLS1(secret, label, seed) =
248
+ * P_MD5(S1, label + seed) XOR P_SHA-1(S2, label + seed);
249
+ *
250
+ * Each P_hash function functions as follows:
251
+ *
252
+ * P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
253
+ * HMAC_hash(secret, A(2) + seed) +
254
+ * HMAC_hash(secret, A(3) + seed) + ...
255
+ * A() is defined as:
256
+ * A(0) = seed
257
+ * A(i) = HMAC_hash(secret, A(i-1))
258
+ *
259
+ * The '+' operator denotes concatenation.
260
+ *
261
+ * As many iterations A(N) as are needed are performed to generate enough
262
+ * pseudo random byte output. If an iteration creates more data than is
263
+ * necessary, then it is truncated.
264
+ *
265
+ * Therefore:
266
+ * A(1) = HMAC_hash(secret, A(0))
267
+ * = HMAC_hash(secret, seed)
268
+ * A(2) = HMAC_hash(secret, A(1))
269
+ * = HMAC_hash(secret, HMAC_hash(secret, seed))
270
+ *
271
+ * Therefore:
272
+ * P_hash(secret, seed) =
273
+ * HMAC_hash(secret, HMAC_hash(secret, A(0)) + seed) +
274
+ * HMAC_hash(secret, HMAC_hash(secret, A(1)) + seed) +
275
+ * ...
276
+ *
277
+ * Therefore:
278
+ * P_hash(secret, seed) =
279
+ * HMAC_hash(secret, HMAC_hash(secret, seed) + seed) +
280
+ * HMAC_hash(secret, HMAC_hash(secret, HMAC_hash(secret, seed)) + seed) +
281
+ * ...
282
+ *
283
+ * @param secret the secret to use.
284
+ * @param label the label to use.
285
+ * @param seed the seed value to use.
286
+ * @param length the number of bytes to generate.
287
+ *
288
+ * @return the pseudo random bytes in a byte buffer.
289
+ */
290
+ var prf_TLS1 = function(secret, label, seed, length) {
291
+ var rval = forge.util.createBuffer();
292
+
293
+ /* For TLS 1.0, the secret is split in half, into two secrets of equal
294
+ length. If the secret has an odd length then the last byte of the first
295
+ half will be the same as the first byte of the second. The length of the
296
+ two secrets is half of the secret rounded up. */
297
+ var idx = (secret.length >> 1);
298
+ var slen = idx + (secret.length & 1);
299
+ var s1 = secret.substr(0, slen);
300
+ var s2 = secret.substr(idx, slen);
301
+ var ai = forge.util.createBuffer();
302
+ var hmac = forge.hmac.create();
303
+ seed = label + seed;
304
+
305
+ // determine the number of iterations that must be performed to generate
306
+ // enough output bytes, md5 creates 16 byte hashes, sha1 creates 20
307
+ var md5itr = Math.ceil(length / 16);
308
+ var sha1itr = Math.ceil(length / 20);
309
+
310
+ // do md5 iterations
311
+ hmac.start('MD5', s1);
312
+ var md5bytes = forge.util.createBuffer();
313
+ ai.putBytes(seed);
314
+ for(var i = 0; i < md5itr; ++i) {
315
+ // HMAC_hash(secret, A(i-1))
316
+ hmac.start(null, null);
317
+ hmac.update(ai.getBytes());
318
+ ai.putBuffer(hmac.digest());
319
+
320
+ // HMAC_hash(secret, A(i) + seed)
321
+ hmac.start(null, null);
322
+ hmac.update(ai.bytes() + seed);
323
+ md5bytes.putBuffer(hmac.digest());
324
+ }
325
+
326
+ // do sha1 iterations
327
+ hmac.start('SHA1', s2);
328
+ var sha1bytes = forge.util.createBuffer();
329
+ ai.clear();
330
+ ai.putBytes(seed);
331
+ for(var i = 0; i < sha1itr; ++i) {
332
+ // HMAC_hash(secret, A(i-1))
333
+ hmac.start(null, null);
334
+ hmac.update(ai.getBytes());
335
+ ai.putBuffer(hmac.digest());
336
+
337
+ // HMAC_hash(secret, A(i) + seed)
338
+ hmac.start(null, null);
339
+ hmac.update(ai.bytes() + seed);
340
+ sha1bytes.putBuffer(hmac.digest());
341
+ }
342
+
343
+ // XOR the md5 bytes with the sha1 bytes
344
+ rval.putBytes(forge.util.xorBytes(
345
+ md5bytes.getBytes(), sha1bytes.getBytes(), length));
346
+
347
+ return rval;
348
+ };
349
+
350
+ /**
351
+ * Generates pseudo random bytes using a SHA256 algorithm. For TLS 1.2.
352
+ *
353
+ * @param secret the secret to use.
354
+ * @param label the label to use.
355
+ * @param seed the seed value to use.
356
+ * @param length the number of bytes to generate.
357
+ *
358
+ * @return the pseudo random bytes in a byte buffer.
359
+ */
360
+ var prf_sha256 = function(secret, label, seed, length) {
361
+ // FIXME: implement me for TLS 1.2
362
+ };
363
+
364
+ /**
365
+ * Gets a MAC for a record using the SHA-1 hash algorithm.
366
+ *
367
+ * @param key the mac key.
368
+ * @param state the sequence number (array of two 32-bit integers).
369
+ * @param record the record.
370
+ *
371
+ * @return the sha-1 hash (20 bytes) for the given record.
372
+ */
373
+ var hmac_sha1 = function(key, seqNum, record) {
374
+ /* MAC is computed like so:
375
+ HMAC_hash(
376
+ key, seqNum +
377
+ TLSCompressed.type +
378
+ TLSCompressed.version +
379
+ TLSCompressed.length +
380
+ TLSCompressed.fragment)
381
+ */
382
+ var hmac = forge.hmac.create();
383
+ hmac.start('SHA1', key);
384
+ var b = forge.util.createBuffer();
385
+ b.putInt32(seqNum[0]);
386
+ b.putInt32(seqNum[1]);
387
+ b.putByte(record.type);
388
+ b.putByte(record.version.major);
389
+ b.putByte(record.version.minor);
390
+ b.putInt16(record.length);
391
+ b.putBytes(record.fragment.bytes());
392
+ hmac.update(b.getBytes());
393
+ return hmac.digest().getBytes();
394
+ };
395
+
396
+ /**
397
+ * Compresses the TLSPlaintext record into a TLSCompressed record using the
398
+ * deflate algorithm.
399
+ *
400
+ * @param c the TLS connection.
401
+ * @param record the TLSPlaintext record to compress.
402
+ * @param s the ConnectionState to use.
403
+ *
404
+ * @return true on success, false on failure.
405
+ */
406
+ var deflate = function(c, record, s) {
407
+ var rval = false;
408
+
409
+ try {
410
+ var bytes = c.deflate(record.fragment.getBytes());
411
+ record.fragment = forge.util.createBuffer(bytes);
412
+ record.length = bytes.length;
413
+ rval = true;
414
+ } catch(ex) {
415
+ // deflate error, fail out
416
+ }
417
+
418
+ return rval;
419
+ };
420
+
421
+ /**
422
+ * Decompresses the TLSCompressed record into a TLSPlaintext record using the
423
+ * deflate algorithm.
424
+ *
425
+ * @param c the TLS connection.
426
+ * @param record the TLSCompressed record to decompress.
427
+ * @param s the ConnectionState to use.
428
+ *
429
+ * @return true on success, false on failure.
430
+ */
431
+ var inflate = function(c, record, s) {
432
+ var rval = false;
433
+
434
+ try {
435
+ var bytes = c.inflate(record.fragment.getBytes());
436
+ record.fragment = forge.util.createBuffer(bytes);
437
+ record.length = bytes.length;
438
+ rval = true;
439
+ } catch(ex) {
440
+ // inflate error, fail out
441
+ }
442
+
443
+ return rval;
444
+ };
445
+
446
+ /**
447
+ * Reads a TLS variable-length vector from a byte buffer.
448
+ *
449
+ * Variable-length vectors are defined by specifying a subrange of legal
450
+ * lengths, inclusively, using the notation <floor..ceiling>. When these are
451
+ * encoded, the actual length precedes the vector's contents in the byte
452
+ * stream. The length will be in the form of a number consuming as many bytes
453
+ * as required to hold the vector's specified maximum (ceiling) length. A
454
+ * variable-length vector with an actual length field of zero is referred to
455
+ * as an empty vector.
456
+ *
457
+ * @param b the byte buffer.
458
+ * @param lenBytes the number of bytes required to store the length.
459
+ *
460
+ * @return the resulting byte buffer.
461
+ */
462
+ var readVector = function(b, lenBytes) {
463
+ var len = 0;
464
+ switch(lenBytes) {
465
+ case 1:
466
+ len = b.getByte();
467
+ break;
468
+ case 2:
469
+ len = b.getInt16();
470
+ break;
471
+ case 3:
472
+ len = b.getInt24();
473
+ break;
474
+ case 4:
475
+ len = b.getInt32();
476
+ break;
477
+ }
478
+
479
+ // read vector bytes into a new buffer
480
+ return forge.util.createBuffer(b.getBytes(len));
481
+ };
482
+
483
+ /**
484
+ * Writes a TLS variable-length vector to a byte buffer.
485
+ *
486
+ * @param b the byte buffer.
487
+ * @param lenBytes the number of bytes required to store the length.
488
+ * @param v the byte buffer vector.
489
+ */
490
+ var writeVector = function(b, lenBytes, v) {
491
+ // encode length at the start of the vector, where the number of bytes for
492
+ // the length is the maximum number of bytes it would take to encode the
493
+ // vector's ceiling
494
+ b.putInt(v.length(), lenBytes << 3);
495
+ b.putBuffer(v);
496
+ };
497
+
498
+ /**
499
+ * The tls implementation.
500
+ */
501
+ var tls = {};
502
+
503
+ /**
504
+ * Version: TLS 1.2 = 3.3, TLS 1.1 = 3.2, TLS 1.0 = 3.1. Both TLS 1.1 and
505
+ * TLS 1.2 were still too new (ie: openSSL didn't implement them) at the time
506
+ * of this implementation so TLS 1.0 was implemented instead.
507
+ */
508
+ tls.Versions = {
509
+ TLS_1_0: {major: 3, minor: 1},
510
+ TLS_1_1: {major: 3, minor: 2},
511
+ TLS_1_2: {major: 3, minor: 3}
512
+ };
513
+ tls.SupportedVersions = [
514
+ tls.Versions.TLS_1_1,
515
+ tls.Versions.TLS_1_0
516
+ ];
517
+ tls.Version = tls.SupportedVersions[0];
518
+
519
+ /**
520
+ * Maximum fragment size. True maximum is 16384, but we fragment before that
521
+ * to allow for unusual small increases during compression.
522
+ */
523
+ tls.MaxFragment = 16384 - 1024;
524
+
525
+ /**
526
+ * Whether this entity is considered the "client" or "server".
527
+ * enum { server, client } ConnectionEnd;
528
+ */
529
+ tls.ConnectionEnd = {
530
+ server: 0,
531
+ client: 1
532
+ };
533
+
534
+ /**
535
+ * Pseudo-random function algorithm used to generate keys from the master
536
+ * secret.
537
+ * enum { tls_prf_sha256 } PRFAlgorithm;
538
+ */
539
+ tls.PRFAlgorithm = {
540
+ tls_prf_sha256: 0
541
+ };
542
+
543
+ /**
544
+ * Bulk encryption algorithms.
545
+ * enum { null, rc4, des3, aes } BulkCipherAlgorithm;
546
+ */
547
+ tls.BulkCipherAlgorithm = {
548
+ none: null,
549
+ rc4: 0,
550
+ des3: 1,
551
+ aes: 2
552
+ };
553
+
554
+ /**
555
+ * Cipher types.
556
+ * enum { stream, block, aead } CipherType;
557
+ */
558
+ tls.CipherType = {
559
+ stream: 0,
560
+ block: 1,
561
+ aead: 2
562
+ };
563
+
564
+ /**
565
+ * MAC (Message Authentication Code) algorithms.
566
+ * enum { null, hmac_md5, hmac_sha1, hmac_sha256,
567
+ * hmac_sha384, hmac_sha512} MACAlgorithm;
568
+ */
569
+ tls.MACAlgorithm = {
570
+ none: null,
571
+ hmac_md5: 0,
572
+ hmac_sha1: 1,
573
+ hmac_sha256: 2,
574
+ hmac_sha384: 3,
575
+ hmac_sha512: 4
576
+ };
577
+
578
+ /**
579
+ * Compression algorithms.
580
+ * enum { null(0), deflate(1), (255) } CompressionMethod;
581
+ */
582
+ tls.CompressionMethod = {
583
+ none: 0,
584
+ deflate: 1
585
+ };
586
+
587
+ /**
588
+ * TLS record content types.
589
+ * enum {
590
+ * change_cipher_spec(20), alert(21), handshake(22),
591
+ * application_data(23), (255)
592
+ * } ContentType;
593
+ */
594
+ tls.ContentType = {
595
+ change_cipher_spec: 20,
596
+ alert: 21,
597
+ handshake: 22,
598
+ application_data: 23,
599
+ heartbeat: 24
600
+ };
601
+
602
+ /**
603
+ * TLS handshake types.
604
+ * enum {
605
+ * hello_request(0), client_hello(1), server_hello(2),
606
+ * certificate(11), server_key_exchange (12),
607
+ * certificate_request(13), server_hello_done(14),
608
+ * certificate_verify(15), client_key_exchange(16),
609
+ * finished(20), (255)
610
+ * } HandshakeType;
611
+ */
612
+ tls.HandshakeType = {
613
+ hello_request: 0,
614
+ client_hello: 1,
615
+ server_hello: 2,
616
+ certificate: 11,
617
+ server_key_exchange: 12,
618
+ certificate_request: 13,
619
+ server_hello_done: 14,
620
+ certificate_verify: 15,
621
+ client_key_exchange: 16,
622
+ finished: 20
623
+ };
624
+
625
+ /**
626
+ * TLS Alert Protocol.
627
+ *
628
+ * enum { warning(1), fatal(2), (255) } AlertLevel;
629
+ *
630
+ * enum {
631
+ * close_notify(0),
632
+ * unexpected_message(10),
633
+ * bad_record_mac(20),
634
+ * decryption_failed(21),
635
+ * record_overflow(22),
636
+ * decompression_failure(30),
637
+ * handshake_failure(40),
638
+ * bad_certificate(42),
639
+ * unsupported_certificate(43),
640
+ * certificate_revoked(44),
641
+ * certificate_expired(45),
642
+ * certificate_unknown(46),
643
+ * illegal_parameter(47),
644
+ * unknown_ca(48),
645
+ * access_denied(49),
646
+ * decode_error(50),
647
+ * decrypt_error(51),
648
+ * export_restriction(60),
649
+ * protocol_version(70),
650
+ * insufficient_security(71),
651
+ * internal_error(80),
652
+ * user_canceled(90),
653
+ * no_renegotiation(100),
654
+ * (255)
655
+ * } AlertDescription;
656
+ *
657
+ * struct {
658
+ * AlertLevel level;
659
+ * AlertDescription description;
660
+ * } Alert;
661
+ */
662
+ tls.Alert = {};
663
+ tls.Alert.Level = {
664
+ warning: 1,
665
+ fatal: 2
666
+ };
667
+ tls.Alert.Description = {
668
+ close_notify: 0,
669
+ unexpected_message: 10,
670
+ bad_record_mac: 20,
671
+ decryption_failed: 21,
672
+ record_overflow: 22,
673
+ decompression_failure: 30,
674
+ handshake_failure: 40,
675
+ bad_certificate: 42,
676
+ unsupported_certificate: 43,
677
+ certificate_revoked: 44,
678
+ certificate_expired: 45,
679
+ certificate_unknown: 46,
680
+ illegal_parameter: 47,
681
+ unknown_ca: 48,
682
+ access_denied: 49,
683
+ decode_error: 50,
684
+ decrypt_error: 51,
685
+ export_restriction: 60,
686
+ protocol_version: 70,
687
+ insufficient_security: 71,
688
+ internal_error: 80,
689
+ user_canceled: 90,
690
+ no_renegotiation: 100
691
+ };
692
+
693
+ /**
694
+ * TLS Heartbeat Message types.
695
+ * enum {
696
+ * heartbeat_request(1),
697
+ * heartbeat_response(2),
698
+ * (255)
699
+ * } HeartbeatMessageType;
700
+ */
701
+ tls.HeartbeatMessageType = {
702
+ heartbeat_request: 1,
703
+ heartbeat_response: 2
704
+ };
705
+
706
+ /**
707
+ * Supported cipher suites.
708
+ */
709
+ tls.CipherSuites = {};
710
+
711
+ /**
712
+ * Gets a supported cipher suite from its 2 byte ID.
713
+ *
714
+ * @param twoBytes two bytes in a string.
715
+ *
716
+ * @return the matching supported cipher suite or null.
717
+ */
718
+ tls.getCipherSuite = function(twoBytes) {
719
+ var rval = null;
720
+ for(var key in tls.CipherSuites) {
721
+ var cs = tls.CipherSuites[key];
722
+ if(cs.id[0] === twoBytes.charCodeAt(0) &&
723
+ cs.id[1] === twoBytes.charCodeAt(1)) {
724
+ rval = cs;
725
+ break;
726
+ }
727
+ }
728
+ return rval;
729
+ };
730
+
731
+ /**
732
+ * Called when an unexpected record is encountered.
733
+ *
734
+ * @param c the connection.
735
+ * @param record the record.
736
+ */
737
+ tls.handleUnexpected = function(c, record) {
738
+ // if connection is client and closed, ignore unexpected messages
739
+ var ignore = (!c.open && c.entity === tls.ConnectionEnd.client);
740
+ if(!ignore) {
741
+ c.error(c, {
742
+ message: 'Unexpected message. Received TLS record out of order.',
743
+ send: true,
744
+ alert: {
745
+ level: tls.Alert.Level.fatal,
746
+ description: tls.Alert.Description.unexpected_message
747
+ }
748
+ });
749
+ }
750
+ };
751
+
752
+ /**
753
+ * Called when a client receives a HelloRequest record.
754
+ *
755
+ * @param c the connection.
756
+ * @param record the record.
757
+ * @param length the length of the handshake message.
758
+ */
759
+ tls.handleHelloRequest = function(c, record, length) {
760
+ // ignore renegotiation requests from the server during a handshake, but
761
+ // if handshaking, send a warning alert that renegotiation is denied
762
+ if(!c.handshaking && c.handshakes > 0) {
763
+ // send alert warning
764
+ tls.queue(c, tls.createAlert(c, {
765
+ level: tls.Alert.Level.warning,
766
+ description: tls.Alert.Description.no_renegotiation
767
+ }));
768
+ tls.flush(c);
769
+ }
770
+
771
+ // continue
772
+ c.process();
773
+ };
774
+
775
+ /**
776
+ * Parses a hello message from a ClientHello or ServerHello record.
777
+ *
778
+ * @param record the record to parse.
779
+ *
780
+ * @return the parsed message.
781
+ */
782
+ tls.parseHelloMessage = function(c, record, length) {
783
+ var msg = null;
784
+
785
+ var client = (c.entity === tls.ConnectionEnd.client);
786
+
787
+ // minimum of 38 bytes in message
788
+ if(length < 38) {
789
+ c.error(c, {
790
+ message: client ?
791
+ 'Invalid ServerHello message. Message too short.' :
792
+ 'Invalid ClientHello message. Message too short.',
793
+ send: true,
794
+ alert: {
795
+ level: tls.Alert.Level.fatal,
796
+ description: tls.Alert.Description.illegal_parameter
797
+ }
798
+ });
799
+ } else {
800
+ // use 'remaining' to calculate # of remaining bytes in the message
801
+ var b = record.fragment;
802
+ var remaining = b.length();
803
+ msg = {
804
+ version: {
805
+ major: b.getByte(),
806
+ minor: b.getByte()
807
+ },
808
+ random: forge.util.createBuffer(b.getBytes(32)),
809
+ session_id: readVector(b, 1),
810
+ extensions: []
811
+ };
812
+ if(client) {
813
+ msg.cipher_suite = b.getBytes(2);
814
+ msg.compression_method = b.getByte();
815
+ } else {
816
+ msg.cipher_suites = readVector(b, 2);
817
+ msg.compression_methods = readVector(b, 1);
818
+ }
819
+
820
+ // read extensions if there are any bytes left in the message
821
+ remaining = length - (remaining - b.length());
822
+ if(remaining > 0) {
823
+ // parse extensions
824
+ var exts = readVector(b, 2);
825
+ while(exts.length() > 0) {
826
+ msg.extensions.push({
827
+ type: [exts.getByte(), exts.getByte()],
828
+ data: readVector(exts, 2)
829
+ });
830
+ }
831
+
832
+ // TODO: make extension support modular
833
+ if(!client) {
834
+ for(var i = 0; i < msg.extensions.length; ++i) {
835
+ var ext = msg.extensions[i];
836
+
837
+ // support SNI extension
838
+ if(ext.type[0] === 0x00 && ext.type[1] === 0x00) {
839
+ // get server name list
840
+ var snl = readVector(ext.data, 2);
841
+ while(snl.length() > 0) {
842
+ // read server name type
843
+ var snType = snl.getByte();
844
+
845
+ // only HostName type (0x00) is known, break out if
846
+ // another type is detected
847
+ if(snType !== 0x00) {
848
+ break;
849
+ }
850
+
851
+ // add host name to server name list
852
+ c.session.extensions.server_name.serverNameList.push(
853
+ readVector(snl, 2).getBytes());
854
+ }
855
+ }
856
+ }
857
+ }
858
+ }
859
+
860
+ // version already set, do not allow version change
861
+ if(c.session.version) {
862
+ if(msg.version.major !== c.session.version.major ||
863
+ msg.version.minor !== c.session.version.minor) {
864
+ return c.error(c, {
865
+ message: 'TLS version change is disallowed during renegotiation.',
866
+ send: true,
867
+ alert: {
868
+ level: tls.Alert.Level.fatal,
869
+ description: tls.Alert.Description.protocol_version
870
+ }
871
+ });
872
+ }
873
+ }
874
+
875
+ // get the chosen (ServerHello) cipher suite
876
+ if(client) {
877
+ // FIXME: should be checking configured acceptable cipher suites
878
+ c.session.cipherSuite = tls.getCipherSuite(msg.cipher_suite);
879
+ } else {
880
+ // get a supported preferred (ClientHello) cipher suite
881
+ // choose the first supported cipher suite
882
+ var tmp = forge.util.createBuffer(msg.cipher_suites.bytes());
883
+ while(tmp.length() > 0) {
884
+ // FIXME: should be checking configured acceptable suites
885
+ // cipher suites take up 2 bytes
886
+ c.session.cipherSuite = tls.getCipherSuite(tmp.getBytes(2));
887
+ if(c.session.cipherSuite !== null) {
888
+ break;
889
+ }
890
+ }
891
+ }
892
+
893
+ // cipher suite not supported
894
+ if(c.session.cipherSuite === null) {
895
+ return c.error(c, {
896
+ message: 'No cipher suites in common.',
897
+ send: true,
898
+ alert: {
899
+ level: tls.Alert.Level.fatal,
900
+ description: tls.Alert.Description.handshake_failure
901
+ },
902
+ cipherSuite: forge.util.bytesToHex(msg.cipher_suite)
903
+ });
904
+ }
905
+
906
+ // TODO: handle compression methods
907
+ if(client) {
908
+ c.session.compressionMethod = msg.compression_method;
909
+ } else {
910
+ // no compression
911
+ c.session.compressionMethod = tls.CompressionMethod.none;
912
+ }
913
+ }
914
+
915
+ return msg;
916
+ };
917
+
918
+ /**
919
+ * Creates security parameters for the given connection based on the given
920
+ * hello message.
921
+ *
922
+ * @param c the TLS connection.
923
+ * @param msg the hello message.
924
+ */
925
+ tls.createSecurityParameters = function(c, msg) {
926
+ /* Note: security params are from TLS 1.2, some values like prf_algorithm
927
+ are ignored for TLS 1.0/1.1 and the builtin as specified in the spec is
928
+ used. */
929
+
930
+ // TODO: handle other options from server when more supported
931
+
932
+ // get client and server randoms
933
+ var client = (c.entity === tls.ConnectionEnd.client);
934
+ var msgRandom = msg.random.bytes();
935
+ var cRandom = client ? c.session.sp.client_random : msgRandom;
936
+ var sRandom = client ? msgRandom : tls.createRandom().getBytes();
937
+
938
+ // create new security parameters
939
+ c.session.sp = {
940
+ entity: c.entity,
941
+ prf_algorithm: tls.PRFAlgorithm.tls_prf_sha256,
942
+ bulk_cipher_algorithm: null,
943
+ cipher_type: null,
944
+ enc_key_length: null,
945
+ block_length: null,
946
+ fixed_iv_length: null,
947
+ record_iv_length: null,
948
+ mac_algorithm: null,
949
+ mac_length: null,
950
+ mac_key_length: null,
951
+ compression_algorithm: c.session.compressionMethod,
952
+ pre_master_secret: null,
953
+ master_secret: null,
954
+ client_random: cRandom,
955
+ server_random: sRandom
956
+ };
957
+ };
958
+
959
+ /**
960
+ * Called when a client receives a ServerHello record.
961
+ *
962
+ * When a ServerHello message will be sent:
963
+ * The server will send this message in response to a client hello message
964
+ * when it was able to find an acceptable set of algorithms. If it cannot
965
+ * find such a match, it will respond with a handshake failure alert.
966
+ *
967
+ * uint24 length;
968
+ * struct {
969
+ * ProtocolVersion server_version;
970
+ * Random random;
971
+ * SessionID session_id;
972
+ * CipherSuite cipher_suite;
973
+ * CompressionMethod compression_method;
974
+ * select(extensions_present) {
975
+ * case false:
976
+ * struct {};
977
+ * case true:
978
+ * Extension extensions<0..2^16-1>;
979
+ * };
980
+ * } ServerHello;
981
+ *
982
+ * @param c the connection.
983
+ * @param record the record.
984
+ * @param length the length of the handshake message.
985
+ */
986
+ tls.handleServerHello = function(c, record, length) {
987
+ var msg = tls.parseHelloMessage(c, record, length);
988
+ if(c.fail) {
989
+ return;
990
+ }
991
+
992
+ // ensure server version is compatible
993
+ if(msg.version.minor <= c.version.minor) {
994
+ c.version.minor = msg.version.minor;
995
+ } else {
996
+ return c.error(c, {
997
+ message: 'Incompatible TLS version.',
998
+ send: true,
999
+ alert: {
1000
+ level: tls.Alert.Level.fatal,
1001
+ description: tls.Alert.Description.protocol_version
1002
+ }
1003
+ });
1004
+ }
1005
+
1006
+ // indicate session version has been set
1007
+ c.session.version = c.version;
1008
+
1009
+ // get the session ID from the message
1010
+ var sessionId = msg.session_id.bytes();
1011
+
1012
+ // if the session ID is not blank and matches the cached one, resume
1013
+ // the session
1014
+ if(sessionId.length > 0 && sessionId === c.session.id) {
1015
+ // resuming session, expect a ChangeCipherSpec next
1016
+ c.expect = SCC;
1017
+ c.session.resuming = true;
1018
+
1019
+ // get new server random
1020
+ c.session.sp.server_random = msg.random.bytes();
1021
+ } else {
1022
+ // not resuming, expect a server Certificate message next
1023
+ c.expect = SCE;
1024
+ c.session.resuming = false;
1025
+
1026
+ // create new security parameters
1027
+ tls.createSecurityParameters(c, msg);
1028
+ }
1029
+
1030
+ // set new session ID
1031
+ c.session.id = sessionId;
1032
+
1033
+ // continue
1034
+ c.process();
1035
+ };
1036
+
1037
+ /**
1038
+ * Called when a server receives a ClientHello record.
1039
+ *
1040
+ * When a ClientHello message will be sent:
1041
+ * When a client first connects to a server it is required to send the
1042
+ * client hello as its first message. The client can also send a client
1043
+ * hello in response to a hello request or on its own initiative in order
1044
+ * to renegotiate the security parameters in an existing connection.
1045
+ *
1046
+ * @param c the connection.
1047
+ * @param record the record.
1048
+ * @param length the length of the handshake message.
1049
+ */
1050
+ tls.handleClientHello = function(c, record, length) {
1051
+ var msg = tls.parseHelloMessage(c, record, length);
1052
+ if(c.fail) {
1053
+ return;
1054
+ }
1055
+
1056
+ // get the session ID from the message
1057
+ var sessionId = msg.session_id.bytes();
1058
+
1059
+ // see if the given session ID is in the cache
1060
+ var session = null;
1061
+ if(c.sessionCache) {
1062
+ session = c.sessionCache.getSession(sessionId);
1063
+ if(session === null) {
1064
+ // session ID not found
1065
+ sessionId = '';
1066
+ } else if(session.version.major !== msg.version.major ||
1067
+ session.version.minor > msg.version.minor) {
1068
+ // if session version is incompatible with client version, do not resume
1069
+ session = null;
1070
+ sessionId = '';
1071
+ }
1072
+ }
1073
+
1074
+ // no session found to resume, generate a new session ID
1075
+ if(sessionId.length === 0) {
1076
+ sessionId = forge.random.getBytes(32);
1077
+ }
1078
+
1079
+ // update session
1080
+ c.session.id = sessionId;
1081
+ c.session.clientHelloVersion = msg.version;
1082
+ c.session.sp = {};
1083
+ if(session) {
1084
+ // use version and security parameters from resumed session
1085
+ c.version = c.session.version = session.version;
1086
+ c.session.sp = session.sp;
1087
+ } else {
1088
+ // use highest compatible minor version
1089
+ var version;
1090
+ for(var i = 1; i < tls.SupportedVersions.length; ++i) {
1091
+ version = tls.SupportedVersions[i];
1092
+ if(version.minor <= msg.version.minor) {
1093
+ break;
1094
+ }
1095
+ }
1096
+ c.version = {major: version.major, minor: version.minor};
1097
+ c.session.version = c.version;
1098
+ }
1099
+
1100
+ // if a session is set, resume it
1101
+ if(session !== null) {
1102
+ // resuming session, expect a ChangeCipherSpec next
1103
+ c.expect = CCC;
1104
+ c.session.resuming = true;
1105
+
1106
+ // get new client random
1107
+ c.session.sp.client_random = msg.random.bytes();
1108
+ } else {
1109
+ // not resuming, expect a Certificate or ClientKeyExchange
1110
+ c.expect = (c.verifyClient !== false) ? CCE : CKE;
1111
+ c.session.resuming = false;
1112
+
1113
+ // create new security parameters
1114
+ tls.createSecurityParameters(c, msg);
1115
+ }
1116
+
1117
+ // connection now open
1118
+ c.open = true;
1119
+
1120
+ // queue server hello
1121
+ tls.queue(c, tls.createRecord(c, {
1122
+ type: tls.ContentType.handshake,
1123
+ data: tls.createServerHello(c)
1124
+ }));
1125
+
1126
+ if(c.session.resuming) {
1127
+ // queue change cipher spec message
1128
+ tls.queue(c, tls.createRecord(c, {
1129
+ type: tls.ContentType.change_cipher_spec,
1130
+ data: tls.createChangeCipherSpec()
1131
+ }));
1132
+
1133
+ // create pending state
1134
+ c.state.pending = tls.createConnectionState(c);
1135
+
1136
+ // change current write state to pending write state
1137
+ c.state.current.write = c.state.pending.write;
1138
+
1139
+ // queue finished
1140
+ tls.queue(c, tls.createRecord(c, {
1141
+ type: tls.ContentType.handshake,
1142
+ data: tls.createFinished(c)
1143
+ }));
1144
+ } else {
1145
+ // queue server certificate
1146
+ tls.queue(c, tls.createRecord(c, {
1147
+ type: tls.ContentType.handshake,
1148
+ data: tls.createCertificate(c)
1149
+ }));
1150
+
1151
+ if(!c.fail) {
1152
+ // queue server key exchange
1153
+ tls.queue(c, tls.createRecord(c, {
1154
+ type: tls.ContentType.handshake,
1155
+ data: tls.createServerKeyExchange(c)
1156
+ }));
1157
+
1158
+ // request client certificate if set
1159
+ if(c.verifyClient !== false) {
1160
+ // queue certificate request
1161
+ tls.queue(c, tls.createRecord(c, {
1162
+ type: tls.ContentType.handshake,
1163
+ data: tls.createCertificateRequest(c)
1164
+ }));
1165
+ }
1166
+
1167
+ // queue server hello done
1168
+ tls.queue(c, tls.createRecord(c, {
1169
+ type: tls.ContentType.handshake,
1170
+ data: tls.createServerHelloDone(c)
1171
+ }));
1172
+ }
1173
+ }
1174
+
1175
+ // send records
1176
+ tls.flush(c);
1177
+
1178
+ // continue
1179
+ c.process();
1180
+ };
1181
+
1182
+ /**
1183
+ * Called when a client receives a Certificate record.
1184
+ *
1185
+ * When this message will be sent:
1186
+ * The server must send a certificate whenever the agreed-upon key exchange
1187
+ * method is not an anonymous one. This message will always immediately
1188
+ * follow the server hello message.
1189
+ *
1190
+ * Meaning of this message:
1191
+ * The certificate type must be appropriate for the selected cipher suite's
1192
+ * key exchange algorithm, and is generally an X.509v3 certificate. It must
1193
+ * contain a key which matches the key exchange method, as follows. Unless
1194
+ * otherwise specified, the signing algorithm for the certificate must be
1195
+ * the same as the algorithm for the certificate key. Unless otherwise
1196
+ * specified, the public key may be of any length.
1197
+ *
1198
+ * opaque ASN.1Cert<1..2^24-1>;
1199
+ * struct {
1200
+ * ASN.1Cert certificate_list<1..2^24-1>;
1201
+ * } Certificate;
1202
+ *
1203
+ * @param c the connection.
1204
+ * @param record the record.
1205
+ * @param length the length of the handshake message.
1206
+ */
1207
+ tls.handleCertificate = function(c, record, length) {
1208
+ // minimum of 3 bytes in message
1209
+ if(length < 3) {
1210
+ return c.error(c, {
1211
+ message: 'Invalid Certificate message. Message too short.',
1212
+ send: true,
1213
+ alert: {
1214
+ level: tls.Alert.Level.fatal,
1215
+ description: tls.Alert.Description.illegal_parameter
1216
+ }
1217
+ });
1218
+ }
1219
+
1220
+ var b = record.fragment;
1221
+ var msg = {
1222
+ certificate_list: readVector(b, 3)
1223
+ };
1224
+
1225
+ /* The sender's certificate will be first in the list (chain), each
1226
+ subsequent one that follows will certify the previous one, but root
1227
+ certificates (self-signed) that specify the certificate authority may
1228
+ be omitted under the assumption that clients must already possess it. */
1229
+ var cert, asn1;
1230
+ var certs = [];
1231
+ try {
1232
+ while(msg.certificate_list.length() > 0) {
1233
+ // each entry in msg.certificate_list is a vector with 3 len bytes
1234
+ cert = readVector(msg.certificate_list, 3);
1235
+ asn1 = forge.asn1.fromDer(cert);
1236
+ cert = forge.pki.certificateFromAsn1(asn1, true);
1237
+ certs.push(cert);
1238
+ }
1239
+ } catch(ex) {
1240
+ return c.error(c, {
1241
+ message: 'Could not parse certificate list.',
1242
+ cause: ex,
1243
+ send: true,
1244
+ alert: {
1245
+ level: tls.Alert.Level.fatal,
1246
+ description: tls.Alert.Description.bad_certificate
1247
+ }
1248
+ });
1249
+ }
1250
+
1251
+ // ensure at least 1 certificate was provided if in client-mode
1252
+ // or if verifyClient was set to true to require a certificate
1253
+ // (as opposed to 'optional')
1254
+ var client = (c.entity === tls.ConnectionEnd.client);
1255
+ if((client || c.verifyClient === true) && certs.length === 0) {
1256
+ // error, no certificate
1257
+ c.error(c, {
1258
+ message: client ?
1259
+ 'No server certificate provided.' :
1260
+ 'No client certificate provided.',
1261
+ send: true,
1262
+ alert: {
1263
+ level: tls.Alert.Level.fatal,
1264
+ description: tls.Alert.Description.illegal_parameter
1265
+ }
1266
+ });
1267
+ } else if(certs.length === 0) {
1268
+ // no certs to verify
1269
+ // expect a ServerKeyExchange or ClientKeyExchange message next
1270
+ c.expect = client ? SKE : CKE;
1271
+ } else {
1272
+ // save certificate in session
1273
+ if(client) {
1274
+ c.session.serverCertificate = certs[0];
1275
+ } else {
1276
+ c.session.clientCertificate = certs[0];
1277
+ }
1278
+
1279
+ if(tls.verifyCertificateChain(c, certs)) {
1280
+ // expect a ServerKeyExchange or ClientKeyExchange message next
1281
+ c.expect = client ? SKE : CKE;
1282
+ }
1283
+ }
1284
+
1285
+ // continue
1286
+ c.process();
1287
+ };
1288
+
1289
+ /**
1290
+ * Called when a client receives a ServerKeyExchange record.
1291
+ *
1292
+ * When this message will be sent:
1293
+ * This message will be sent immediately after the server certificate
1294
+ * message (or the server hello message, if this is an anonymous
1295
+ * negotiation).
1296
+ *
1297
+ * The server key exchange message is sent by the server only when the
1298
+ * server certificate message (if sent) does not contain enough data to
1299
+ * allow the client to exchange a premaster secret.
1300
+ *
1301
+ * Meaning of this message:
1302
+ * This message conveys cryptographic information to allow the client to
1303
+ * communicate the premaster secret: either an RSA public key to encrypt
1304
+ * the premaster secret with, or a Diffie-Hellman public key with which the
1305
+ * client can complete a key exchange (with the result being the premaster
1306
+ * secret.)
1307
+ *
1308
+ * enum {
1309
+ * dhe_dss, dhe_rsa, dh_anon, rsa, dh_dss, dh_rsa
1310
+ * } KeyExchangeAlgorithm;
1311
+ *
1312
+ * struct {
1313
+ * opaque dh_p<1..2^16-1>;
1314
+ * opaque dh_g<1..2^16-1>;
1315
+ * opaque dh_Ys<1..2^16-1>;
1316
+ * } ServerDHParams;
1317
+ *
1318
+ * struct {
1319
+ * select(KeyExchangeAlgorithm) {
1320
+ * case dh_anon:
1321
+ * ServerDHParams params;
1322
+ * case dhe_dss:
1323
+ * case dhe_rsa:
1324
+ * ServerDHParams params;
1325
+ * digitally-signed struct {
1326
+ * opaque client_random[32];
1327
+ * opaque server_random[32];
1328
+ * ServerDHParams params;
1329
+ * } signed_params;
1330
+ * case rsa:
1331
+ * case dh_dss:
1332
+ * case dh_rsa:
1333
+ * struct {};
1334
+ * };
1335
+ * } ServerKeyExchange;
1336
+ *
1337
+ * @param c the connection.
1338
+ * @param record the record.
1339
+ * @param length the length of the handshake message.
1340
+ */
1341
+ tls.handleServerKeyExchange = function(c, record, length) {
1342
+ // this implementation only supports RSA, no Diffie-Hellman support
1343
+ // so any length > 0 is invalid
1344
+ if(length > 0) {
1345
+ return c.error(c, {
1346
+ message: 'Invalid key parameters. Only RSA is supported.',
1347
+ send: true,
1348
+ alert: {
1349
+ level: tls.Alert.Level.fatal,
1350
+ description: tls.Alert.Description.unsupported_certificate
1351
+ }
1352
+ });
1353
+ }
1354
+
1355
+ // expect an optional CertificateRequest message next
1356
+ c.expect = SCR;
1357
+
1358
+ // continue
1359
+ c.process();
1360
+ };
1361
+
1362
+ /**
1363
+ * Called when a client receives a ClientKeyExchange record.
1364
+ *
1365
+ * @param c the connection.
1366
+ * @param record the record.
1367
+ * @param length the length of the handshake message.
1368
+ */
1369
+ tls.handleClientKeyExchange = function(c, record, length) {
1370
+ // this implementation only supports RSA, no Diffie-Hellman support
1371
+ // so any length < 48 is invalid
1372
+ if(length < 48) {
1373
+ return c.error(c, {
1374
+ message: 'Invalid key parameters. Only RSA is supported.',
1375
+ send: true,
1376
+ alert: {
1377
+ level: tls.Alert.Level.fatal,
1378
+ description: tls.Alert.Description.unsupported_certificate
1379
+ }
1380
+ });
1381
+ }
1382
+
1383
+ var b = record.fragment;
1384
+ var msg = {
1385
+ enc_pre_master_secret: readVector(b, 2).getBytes()
1386
+ };
1387
+
1388
+ // do rsa decryption
1389
+ var privateKey = null;
1390
+ if(c.getPrivateKey) {
1391
+ try {
1392
+ privateKey = c.getPrivateKey(c, c.session.serverCertificate);
1393
+ privateKey = forge.pki.privateKeyFromPem(privateKey);
1394
+ } catch(ex) {
1395
+ c.error(c, {
1396
+ message: 'Could not get private key.',
1397
+ cause: ex,
1398
+ send: true,
1399
+ alert: {
1400
+ level: tls.Alert.Level.fatal,
1401
+ description: tls.Alert.Description.internal_error
1402
+ }
1403
+ });
1404
+ }
1405
+ }
1406
+
1407
+ if(privateKey === null) {
1408
+ return c.error(c, {
1409
+ message: 'No private key set.',
1410
+ send: true,
1411
+ alert: {
1412
+ level: tls.Alert.Level.fatal,
1413
+ description: tls.Alert.Description.internal_error
1414
+ }
1415
+ });
1416
+ }
1417
+
1418
+ try {
1419
+ // decrypt 48-byte pre-master secret
1420
+ var sp = c.session.sp;
1421
+ sp.pre_master_secret = privateKey.decrypt(msg.enc_pre_master_secret);
1422
+
1423
+ // ensure client hello version matches first 2 bytes
1424
+ var version = c.session.clientHelloVersion;
1425
+ if(version.major !== sp.pre_master_secret.charCodeAt(0) ||
1426
+ version.minor !== sp.pre_master_secret.charCodeAt(1)) {
1427
+ // error, do not send alert (see BLEI attack below)
1428
+ throw new Error('TLS version rollback attack detected.');
1429
+ }
1430
+ } catch(ex) {
1431
+ /* Note: Daniel Bleichenbacher [BLEI] can be used to attack a
1432
+ TLS server which is using PKCS#1 encoded RSA, so instead of
1433
+ failing here, we generate 48 random bytes and use that as
1434
+ the pre-master secret. */
1435
+ sp.pre_master_secret = forge.random.getBytes(48);
1436
+ }
1437
+
1438
+ // expect a CertificateVerify message if a Certificate was received that
1439
+ // does not have fixed Diffie-Hellman params, otherwise expect
1440
+ // ChangeCipherSpec
1441
+ c.expect = CCC;
1442
+ if(c.session.clientCertificate !== null) {
1443
+ // only RSA support, so expect CertificateVerify
1444
+ // TODO: support Diffie-Hellman
1445
+ c.expect = CCV;
1446
+ }
1447
+
1448
+ // continue
1449
+ c.process();
1450
+ };
1451
+
1452
+ /**
1453
+ * Called when a client receives a CertificateRequest record.
1454
+ *
1455
+ * When this message will be sent:
1456
+ * A non-anonymous server can optionally request a certificate from the
1457
+ * client, if appropriate for the selected cipher suite. This message, if
1458
+ * sent, will immediately follow the Server Key Exchange message (if it is
1459
+ * sent; otherwise, the Server Certificate message).
1460
+ *
1461
+ * enum {
1462
+ * rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4),
1463
+ * rsa_ephemeral_dh_RESERVED(5), dss_ephemeral_dh_RESERVED(6),
1464
+ * fortezza_dms_RESERVED(20), (255)
1465
+ * } ClientCertificateType;
1466
+ *
1467
+ * opaque DistinguishedName<1..2^16-1>;
1468
+ *
1469
+ * struct {
1470
+ * ClientCertificateType certificate_types<1..2^8-1>;
1471
+ * SignatureAndHashAlgorithm supported_signature_algorithms<2^16-1>;
1472
+ * DistinguishedName certificate_authorities<0..2^16-1>;
1473
+ * } CertificateRequest;
1474
+ *
1475
+ * @param c the connection.
1476
+ * @param record the record.
1477
+ * @param length the length of the handshake message.
1478
+ */
1479
+ tls.handleCertificateRequest = function(c, record, length) {
1480
+ // minimum of 3 bytes in message
1481
+ if(length < 3) {
1482
+ return c.error(c, {
1483
+ message: 'Invalid CertificateRequest. Message too short.',
1484
+ send: true,
1485
+ alert: {
1486
+ level: tls.Alert.Level.fatal,
1487
+ description: tls.Alert.Description.illegal_parameter
1488
+ }
1489
+ });
1490
+ }
1491
+
1492
+ // TODO: TLS 1.2+ has different format including
1493
+ // SignatureAndHashAlgorithm after cert types
1494
+ var b = record.fragment;
1495
+ var msg = {
1496
+ certificate_types: readVector(b, 1),
1497
+ certificate_authorities: readVector(b, 2)
1498
+ };
1499
+
1500
+ // save certificate request in session
1501
+ c.session.certificateRequest = msg;
1502
+
1503
+ // expect a ServerHelloDone message next
1504
+ c.expect = SHD;
1505
+
1506
+ // continue
1507
+ c.process();
1508
+ };
1509
+
1510
+ /**
1511
+ * Called when a server receives a CertificateVerify record.
1512
+ *
1513
+ * @param c the connection.
1514
+ * @param record the record.
1515
+ * @param length the length of the handshake message.
1516
+ */
1517
+ tls.handleCertificateVerify = function(c, record, length) {
1518
+ if(length < 2) {
1519
+ return c.error(c, {
1520
+ message: 'Invalid CertificateVerify. Message too short.',
1521
+ send: true,
1522
+ alert: {
1523
+ level: tls.Alert.Level.fatal,
1524
+ description: tls.Alert.Description.illegal_parameter
1525
+ }
1526
+ });
1527
+ }
1528
+
1529
+ // rewind to get full bytes for message so it can be manually
1530
+ // digested below (special case for CertificateVerify messages because
1531
+ // they must be digested *after* handling as opposed to all others)
1532
+ var b = record.fragment;
1533
+ b.read -= 4;
1534
+ var msgBytes = b.bytes();
1535
+ b.read += 4;
1536
+
1537
+ var msg = {
1538
+ signature: readVector(b, 2).getBytes()
1539
+ };
1540
+
1541
+ // TODO: add support for DSA
1542
+
1543
+ // generate data to verify
1544
+ var verify = forge.util.createBuffer();
1545
+ verify.putBuffer(c.session.md5.digest());
1546
+ verify.putBuffer(c.session.sha1.digest());
1547
+ verify = verify.getBytes();
1548
+
1549
+ try {
1550
+ var cert = c.session.clientCertificate;
1551
+ /*b = forge.pki.rsa.decrypt(
1552
+ msg.signature, cert.publicKey, true, verify.length);
1553
+ if(b !== verify) {*/
1554
+ if(!cert.publicKey.verify(verify, msg.signature, 'NONE')) {
1555
+ throw new Error('CertificateVerify signature does not match.');
1556
+ }
1557
+
1558
+ // digest message now that it has been handled
1559
+ c.session.md5.update(msgBytes);
1560
+ c.session.sha1.update(msgBytes);
1561
+ } catch(ex) {
1562
+ return c.error(c, {
1563
+ message: 'Bad signature in CertificateVerify.',
1564
+ send: true,
1565
+ alert: {
1566
+ level: tls.Alert.Level.fatal,
1567
+ description: tls.Alert.Description.handshake_failure
1568
+ }
1569
+ });
1570
+ }
1571
+
1572
+ // expect ChangeCipherSpec
1573
+ c.expect = CCC;
1574
+
1575
+ // continue
1576
+ c.process();
1577
+ };
1578
+
1579
+ /**
1580
+ * Called when a client receives a ServerHelloDone record.
1581
+ *
1582
+ * When this message will be sent:
1583
+ * The server hello done message is sent by the server to indicate the end
1584
+ * of the server hello and associated messages. After sending this message
1585
+ * the server will wait for a client response.
1586
+ *
1587
+ * Meaning of this message:
1588
+ * This message means that the server is done sending messages to support
1589
+ * the key exchange, and the client can proceed with its phase of the key
1590
+ * exchange.
1591
+ *
1592
+ * Upon receipt of the server hello done message the client should verify
1593
+ * that the server provided a valid certificate if required and check that
1594
+ * the server hello parameters are acceptable.
1595
+ *
1596
+ * struct {} ServerHelloDone;
1597
+ *
1598
+ * @param c the connection.
1599
+ * @param record the record.
1600
+ * @param length the length of the handshake message.
1601
+ */
1602
+ tls.handleServerHelloDone = function(c, record, length) {
1603
+ // len must be 0 bytes
1604
+ if(length > 0) {
1605
+ return c.error(c, {
1606
+ message: 'Invalid ServerHelloDone message. Invalid length.',
1607
+ send: true,
1608
+ alert: {
1609
+ level: tls.Alert.Level.fatal,
1610
+ description: tls.Alert.Description.record_overflow
1611
+ }
1612
+ });
1613
+ }
1614
+
1615
+ if(c.session.serverCertificate === null) {
1616
+ // no server certificate was provided
1617
+ var error = {
1618
+ message: 'No server certificate provided. Not enough security.',
1619
+ send: true,
1620
+ alert: {
1621
+ level: tls.Alert.Level.fatal,
1622
+ description: tls.Alert.Description.insufficient_security
1623
+ }
1624
+ };
1625
+
1626
+ // call application callback
1627
+ var depth = 0;
1628
+ var ret = c.verify(c, error.alert.description, depth, []);
1629
+ if(ret !== true) {
1630
+ // check for custom alert info
1631
+ if(ret || ret === 0) {
1632
+ // set custom message and alert description
1633
+ if(typeof ret === 'object' && !forge.util.isArray(ret)) {
1634
+ if(ret.message) {
1635
+ error.message = ret.message;
1636
+ }
1637
+ if(ret.alert) {
1638
+ error.alert.description = ret.alert;
1639
+ }
1640
+ } else if(typeof ret === 'number') {
1641
+ // set custom alert description
1642
+ error.alert.description = ret;
1643
+ }
1644
+ }
1645
+ }
1646
+
1647
+ // send error even if accepted, the RSA key exchange needs the server
1648
+ // certificate
1649
+ return c.error(c, error);
1650
+ }
1651
+
1652
+ // create client certificate message if requested
1653
+ if(c.session.certificateRequest !== null) {
1654
+ record = tls.createRecord(c, {
1655
+ type: tls.ContentType.handshake,
1656
+ data: tls.createCertificate(c)
1657
+ });
1658
+ tls.queue(c, record);
1659
+ }
1660
+
1661
+ // create client key exchange message
1662
+ record = tls.createRecord(c, {
1663
+ type: tls.ContentType.handshake,
1664
+ data: tls.createClientKeyExchange(c)
1665
+ });
1666
+ tls.queue(c, record);
1667
+
1668
+ // expect no messages until the following callback has been called
1669
+ c.expect = SER;
1670
+
1671
+ // create callback to handle client signature (for client-certs)
1672
+ var callback = function(c, signature) {
1673
+ if(c.session.certificateRequest !== null &&
1674
+ c.session.clientCertificate !== null) {
1675
+ // create certificate verify message
1676
+ tls.queue(c, tls.createRecord(c, {
1677
+ type: tls.ContentType.handshake,
1678
+ data: tls.createCertificateVerify(c, signature)
1679
+ }));
1680
+ }
1681
+
1682
+ // create change cipher spec message
1683
+ tls.queue(c, tls.createRecord(c, {
1684
+ type: tls.ContentType.change_cipher_spec,
1685
+ data: tls.createChangeCipherSpec()
1686
+ }));
1687
+
1688
+ // create pending state
1689
+ c.state.pending = tls.createConnectionState(c);
1690
+
1691
+ // change current write state to pending write state
1692
+ c.state.current.write = c.state.pending.write;
1693
+
1694
+ // create finished message
1695
+ tls.queue(c, tls.createRecord(c, {
1696
+ type: tls.ContentType.handshake,
1697
+ data: tls.createFinished(c)
1698
+ }));
1699
+
1700
+ // expect a server ChangeCipherSpec message next
1701
+ c.expect = SCC;
1702
+
1703
+ // send records
1704
+ tls.flush(c);
1705
+
1706
+ // continue
1707
+ c.process();
1708
+ };
1709
+
1710
+ // if there is no certificate request or no client certificate, do
1711
+ // callback immediately
1712
+ if(c.session.certificateRequest === null ||
1713
+ c.session.clientCertificate === null) {
1714
+ return callback(c, null);
1715
+ }
1716
+
1717
+ // otherwise get the client signature
1718
+ tls.getClientSignature(c, callback);
1719
+ };
1720
+
1721
+ /**
1722
+ * Called when a ChangeCipherSpec record is received.
1723
+ *
1724
+ * @param c the connection.
1725
+ * @param record the record.
1726
+ */
1727
+ tls.handleChangeCipherSpec = function(c, record) {
1728
+ if(record.fragment.getByte() !== 0x01) {
1729
+ return c.error(c, {
1730
+ message: 'Invalid ChangeCipherSpec message received.',
1731
+ send: true,
1732
+ alert: {
1733
+ level: tls.Alert.Level.fatal,
1734
+ description: tls.Alert.Description.illegal_parameter
1735
+ }
1736
+ });
1737
+ }
1738
+
1739
+ // create pending state if:
1740
+ // 1. Resuming session in client mode OR
1741
+ // 2. NOT resuming session in server mode
1742
+ var client = (c.entity === tls.ConnectionEnd.client);
1743
+ if((c.session.resuming && client) || (!c.session.resuming && !client)) {
1744
+ c.state.pending = tls.createConnectionState(c);
1745
+ }
1746
+
1747
+ // change current read state to pending read state
1748
+ c.state.current.read = c.state.pending.read;
1749
+
1750
+ // clear pending state if:
1751
+ // 1. NOT resuming session in client mode OR
1752
+ // 2. resuming a session in server mode
1753
+ if((!c.session.resuming && client) || (c.session.resuming && !client)) {
1754
+ c.state.pending = null;
1755
+ }
1756
+
1757
+ // expect a Finished record next
1758
+ c.expect = client ? SFI : CFI;
1759
+
1760
+ // continue
1761
+ c.process();
1762
+ };
1763
+
1764
+ /**
1765
+ * Called when a Finished record is received.
1766
+ *
1767
+ * When this message will be sent:
1768
+ * A finished message is always sent immediately after a change
1769
+ * cipher spec message to verify that the key exchange and
1770
+ * authentication processes were successful. It is essential that a
1771
+ * change cipher spec message be received between the other
1772
+ * handshake messages and the Finished message.
1773
+ *
1774
+ * Meaning of this message:
1775
+ * The finished message is the first protected with the just-
1776
+ * negotiated algorithms, keys, and secrets. Recipients of finished
1777
+ * messages must verify that the contents are correct. Once a side
1778
+ * has sent its Finished message and received and validated the
1779
+ * Finished message from its peer, it may begin to send and receive
1780
+ * application data over the connection.
1781
+ *
1782
+ * struct {
1783
+ * opaque verify_data[verify_data_length];
1784
+ * } Finished;
1785
+ *
1786
+ * verify_data
1787
+ * PRF(master_secret, finished_label, Hash(handshake_messages))
1788
+ * [0..verify_data_length-1];
1789
+ *
1790
+ * finished_label
1791
+ * For Finished messages sent by the client, the string
1792
+ * "client finished". For Finished messages sent by the server, the
1793
+ * string "server finished".
1794
+ *
1795
+ * verify_data_length depends on the cipher suite. If it is not specified
1796
+ * by the cipher suite, then it is 12. Versions of TLS < 1.2 always used
1797
+ * 12 bytes.
1798
+ *
1799
+ * @param c the connection.
1800
+ * @param record the record.
1801
+ * @param length the length of the handshake message.
1802
+ */
1803
+ tls.handleFinished = function(c, record, length) {
1804
+ // rewind to get full bytes for message so it can be manually
1805
+ // digested below (special case for Finished messages because they
1806
+ // must be digested *after* handling as opposed to all others)
1807
+ var b = record.fragment;
1808
+ b.read -= 4;
1809
+ var msgBytes = b.bytes();
1810
+ b.read += 4;
1811
+
1812
+ // message contains only verify_data
1813
+ var vd = record.fragment.getBytes();
1814
+
1815
+ // ensure verify data is correct
1816
+ b = forge.util.createBuffer();
1817
+ b.putBuffer(c.session.md5.digest());
1818
+ b.putBuffer(c.session.sha1.digest());
1819
+
1820
+ // set label based on entity type
1821
+ var client = (c.entity === tls.ConnectionEnd.client);
1822
+ var label = client ? 'server finished' : 'client finished';
1823
+
1824
+ // TODO: determine prf function and verify length for TLS 1.2
1825
+ var sp = c.session.sp;
1826
+ var vdl = 12;
1827
+ var prf = prf_TLS1;
1828
+ b = prf(sp.master_secret, label, b.getBytes(), vdl);
1829
+ if(b.getBytes() !== vd) {
1830
+ return c.error(c, {
1831
+ message: 'Invalid verify_data in Finished message.',
1832
+ send: true,
1833
+ alert: {
1834
+ level: tls.Alert.Level.fatal,
1835
+ description: tls.Alert.Description.decrypt_error
1836
+ }
1837
+ });
1838
+ }
1839
+
1840
+ // digest finished message now that it has been handled
1841
+ c.session.md5.update(msgBytes);
1842
+ c.session.sha1.update(msgBytes);
1843
+
1844
+ // resuming session as client or NOT resuming session as server
1845
+ if((c.session.resuming && client) || (!c.session.resuming && !client)) {
1846
+ // create change cipher spec message
1847
+ tls.queue(c, tls.createRecord(c, {
1848
+ type: tls.ContentType.change_cipher_spec,
1849
+ data: tls.createChangeCipherSpec()
1850
+ }));
1851
+
1852
+ // change current write state to pending write state, clear pending
1853
+ c.state.current.write = c.state.pending.write;
1854
+ c.state.pending = null;
1855
+
1856
+ // create finished message
1857
+ tls.queue(c, tls.createRecord(c, {
1858
+ type: tls.ContentType.handshake,
1859
+ data: tls.createFinished(c)
1860
+ }));
1861
+ }
1862
+
1863
+ // expect application data next
1864
+ c.expect = client ? SAD : CAD;
1865
+
1866
+ // handshake complete
1867
+ c.handshaking = false;
1868
+ ++c.handshakes;
1869
+
1870
+ // save access to peer certificate
1871
+ c.peerCertificate = client ?
1872
+ c.session.serverCertificate : c.session.clientCertificate;
1873
+
1874
+ // send records
1875
+ tls.flush(c);
1876
+
1877
+ // now connected
1878
+ c.isConnected = true;
1879
+ c.connected(c);
1880
+
1881
+ // continue
1882
+ c.process();
1883
+ };
1884
+
1885
+ /**
1886
+ * Called when an Alert record is received.
1887
+ *
1888
+ * @param c the connection.
1889
+ * @param record the record.
1890
+ */
1891
+ tls.handleAlert = function(c, record) {
1892
+ // read alert
1893
+ var b = record.fragment;
1894
+ var alert = {
1895
+ level: b.getByte(),
1896
+ description: b.getByte()
1897
+ };
1898
+
1899
+ // TODO: consider using a table?
1900
+ // get appropriate message
1901
+ var msg;
1902
+ switch(alert.description) {
1903
+ case tls.Alert.Description.close_notify:
1904
+ msg = 'Connection closed.';
1905
+ break;
1906
+ case tls.Alert.Description.unexpected_message:
1907
+ msg = 'Unexpected message.';
1908
+ break;
1909
+ case tls.Alert.Description.bad_record_mac:
1910
+ msg = 'Bad record MAC.';
1911
+ break;
1912
+ case tls.Alert.Description.decryption_failed:
1913
+ msg = 'Decryption failed.';
1914
+ break;
1915
+ case tls.Alert.Description.record_overflow:
1916
+ msg = 'Record overflow.';
1917
+ break;
1918
+ case tls.Alert.Description.decompression_failure:
1919
+ msg = 'Decompression failed.';
1920
+ break;
1921
+ case tls.Alert.Description.handshake_failure:
1922
+ msg = 'Handshake failure.';
1923
+ break;
1924
+ case tls.Alert.Description.bad_certificate:
1925
+ msg = 'Bad certificate.';
1926
+ break;
1927
+ case tls.Alert.Description.unsupported_certificate:
1928
+ msg = 'Unsupported certificate.';
1929
+ break;
1930
+ case tls.Alert.Description.certificate_revoked:
1931
+ msg = 'Certificate revoked.';
1932
+ break;
1933
+ case tls.Alert.Description.certificate_expired:
1934
+ msg = 'Certificate expired.';
1935
+ break;
1936
+ case tls.Alert.Description.certificate_unknown:
1937
+ msg = 'Certificate unknown.';
1938
+ break;
1939
+ case tls.Alert.Description.illegal_parameter:
1940
+ msg = 'Illegal parameter.';
1941
+ break;
1942
+ case tls.Alert.Description.unknown_ca:
1943
+ msg = 'Unknown certificate authority.';
1944
+ break;
1945
+ case tls.Alert.Description.access_denied:
1946
+ msg = 'Access denied.';
1947
+ break;
1948
+ case tls.Alert.Description.decode_error:
1949
+ msg = 'Decode error.';
1950
+ break;
1951
+ case tls.Alert.Description.decrypt_error:
1952
+ msg = 'Decrypt error.';
1953
+ break;
1954
+ case tls.Alert.Description.export_restriction:
1955
+ msg = 'Export restriction.';
1956
+ break;
1957
+ case tls.Alert.Description.protocol_version:
1958
+ msg = 'Unsupported protocol version.';
1959
+ break;
1960
+ case tls.Alert.Description.insufficient_security:
1961
+ msg = 'Insufficient security.';
1962
+ break;
1963
+ case tls.Alert.Description.internal_error:
1964
+ msg = 'Internal error.';
1965
+ break;
1966
+ case tls.Alert.Description.user_canceled:
1967
+ msg = 'User canceled.';
1968
+ break;
1969
+ case tls.Alert.Description.no_renegotiation:
1970
+ msg = 'Renegotiation not supported.';
1971
+ break;
1972
+ default:
1973
+ msg = 'Unknown error.';
1974
+ break;
1975
+ }
1976
+
1977
+ // close connection on close_notify, not an error
1978
+ if(alert.description === tls.Alert.Description.close_notify) {
1979
+ return c.close();
1980
+ }
1981
+
1982
+ // call error handler
1983
+ c.error(c, {
1984
+ message: msg,
1985
+ send: false,
1986
+ // origin is the opposite end
1987
+ origin: (c.entity === tls.ConnectionEnd.client) ? 'server' : 'client',
1988
+ alert: alert
1989
+ });
1990
+
1991
+ // continue
1992
+ c.process();
1993
+ };
1994
+
1995
+ /**
1996
+ * Called when a Handshake record is received.
1997
+ *
1998
+ * @param c the connection.
1999
+ * @param record the record.
2000
+ */
2001
+ tls.handleHandshake = function(c, record) {
2002
+ // get the handshake type and message length
2003
+ var b = record.fragment;
2004
+ var type = b.getByte();
2005
+ var length = b.getInt24();
2006
+
2007
+ // see if the record fragment doesn't yet contain the full message
2008
+ if(length > b.length()) {
2009
+ // cache the record, clear its fragment, and reset the buffer read
2010
+ // pointer before the type and length were read
2011
+ c.fragmented = record;
2012
+ record.fragment = forge.util.createBuffer();
2013
+ b.read -= 4;
2014
+
2015
+ // continue
2016
+ return c.process();
2017
+ }
2018
+
2019
+ // full message now available, clear cache, reset read pointer to
2020
+ // before type and length
2021
+ c.fragmented = null;
2022
+ b.read -= 4;
2023
+
2024
+ // save the handshake bytes for digestion after handler is found
2025
+ // (include type and length of handshake msg)
2026
+ var bytes = b.bytes(length + 4);
2027
+
2028
+ // restore read pointer
2029
+ b.read += 4;
2030
+
2031
+ // handle expected message
2032
+ if(type in hsTable[c.entity][c.expect]) {
2033
+ // initialize server session
2034
+ if(c.entity === tls.ConnectionEnd.server && !c.open && !c.fail) {
2035
+ c.handshaking = true;
2036
+ c.session = {
2037
+ version: null,
2038
+ extensions: {
2039
+ server_name: {
2040
+ serverNameList: []
2041
+ }
2042
+ },
2043
+ cipherSuite: null,
2044
+ compressionMethod: null,
2045
+ serverCertificate: null,
2046
+ clientCertificate: null,
2047
+ md5: forge.md.md5.create(),
2048
+ sha1: forge.md.sha1.create()
2049
+ };
2050
+ }
2051
+
2052
+ /* Update handshake messages digest. Finished and CertificateVerify
2053
+ messages are not digested here. They can't be digested as part of
2054
+ the verify_data that they contain. These messages are manually
2055
+ digested in their handlers. HelloRequest messages are simply never
2056
+ included in the handshake message digest according to spec. */
2057
+ if(type !== tls.HandshakeType.hello_request &&
2058
+ type !== tls.HandshakeType.certificate_verify &&
2059
+ type !== tls.HandshakeType.finished) {
2060
+ c.session.md5.update(bytes);
2061
+ c.session.sha1.update(bytes);
2062
+ }
2063
+
2064
+ // handle specific handshake type record
2065
+ hsTable[c.entity][c.expect][type](c, record, length);
2066
+ } else {
2067
+ // unexpected record
2068
+ tls.handleUnexpected(c, record);
2069
+ }
2070
+ };
2071
+
2072
+ /**
2073
+ * Called when an ApplicationData record is received.
2074
+ *
2075
+ * @param c the connection.
2076
+ * @param record the record.
2077
+ */
2078
+ tls.handleApplicationData = function(c, record) {
2079
+ // buffer data, notify that its ready
2080
+ c.data.putBuffer(record.fragment);
2081
+ c.dataReady(c);
2082
+
2083
+ // continue
2084
+ c.process();
2085
+ };
2086
+
2087
+ /**
2088
+ * Called when a Heartbeat record is received.
2089
+ *
2090
+ * @param c the connection.
2091
+ * @param record the record.
2092
+ */
2093
+ tls.handleHeartbeat = function(c, record) {
2094
+ // get the heartbeat type and payload
2095
+ var b = record.fragment;
2096
+ var type = b.getByte();
2097
+ var length = b.getInt16();
2098
+ var payload = b.getBytes(length);
2099
+
2100
+ if(type === tls.HeartbeatMessageType.heartbeat_request) {
2101
+ // discard request before the first handshake is complete, during
2102
+ // handshake, or if length is too large
2103
+ if(c.handshakes === 0 || c.handshaking || length > payload.length) {
2104
+ // continue
2105
+ return c.process();
2106
+ }
2107
+ // retransmit payload
2108
+ tls.queue(c, tls.createRecord(c, {
2109
+ type: tls.ContentType.heartbeat,
2110
+ data: tls.createHeartbeat(
2111
+ tls.HeartbeatMessageType.heartbeat_response, payload)
2112
+ }));
2113
+ tls.flush(c);
2114
+ } else if(type === tls.HeartbeatMessageType.heartbeat_response) {
2115
+ // check payload against expected payload, discard heartbeat if no match
2116
+ if(payload !== c.expectedHeartbeatPayload) {
2117
+ // continue
2118
+ return c.process();
2119
+ }
2120
+
2121
+ // notify that a valid heartbeat was received
2122
+ if(c.heartbeatReceived) {
2123
+ c.heartbeatReceived(c, forge.util.createBuffer(payload));
2124
+ }
2125
+ }
2126
+
2127
+ // continue
2128
+ c.process();
2129
+ };
2130
+
2131
+ /**
2132
+ * The transistional state tables for receiving TLS records. It maps the
2133
+ * current TLS engine state and a received record to a function to handle the
2134
+ * record and update the state.
2135
+ *
2136
+ * For instance, if the current state is SHE, then the TLS engine is expecting
2137
+ * a ServerHello record. Once a record is received, the handler function is
2138
+ * looked up using the state SHE and the record's content type.
2139
+ *
2140
+ * The resulting function will either be an error handler or a record handler.
2141
+ * The function will take whatever action is appropriate and update the state
2142
+ * for the next record.
2143
+ *
2144
+ * The states are all based on possible server record types. Note that the
2145
+ * client will never specifically expect to receive a HelloRequest or an alert
2146
+ * from the server so there is no state that reflects this. These messages may
2147
+ * occur at any time.
2148
+ *
2149
+ * There are two tables for mapping states because there is a second tier of
2150
+ * types for handshake messages. Once a record with a content type of handshake
2151
+ * is received, the handshake record handler will look up the handshake type in
2152
+ * the secondary map to get its appropriate handler.
2153
+ *
2154
+ * Valid message orders are as follows:
2155
+ *
2156
+ * =======================FULL HANDSHAKE======================
2157
+ * Client Server
2158
+ *
2159
+ * ClientHello -------->
2160
+ * ServerHello
2161
+ * Certificate*
2162
+ * ServerKeyExchange*
2163
+ * CertificateRequest*
2164
+ * <-------- ServerHelloDone
2165
+ * Certificate*
2166
+ * ClientKeyExchange
2167
+ * CertificateVerify*
2168
+ * [ChangeCipherSpec]
2169
+ * Finished -------->
2170
+ * [ChangeCipherSpec]
2171
+ * <-------- Finished
2172
+ * Application Data <-------> Application Data
2173
+ *
2174
+ * =====================SESSION RESUMPTION=====================
2175
+ * Client Server
2176
+ *
2177
+ * ClientHello -------->
2178
+ * ServerHello
2179
+ * [ChangeCipherSpec]
2180
+ * <-------- Finished
2181
+ * [ChangeCipherSpec]
2182
+ * Finished -------->
2183
+ * Application Data <-------> Application Data
2184
+ */
2185
+ // client expect states (indicate which records are expected to be received)
2186
+ var SHE = 0; // rcv server hello
2187
+ var SCE = 1; // rcv server certificate
2188
+ var SKE = 2; // rcv server key exchange
2189
+ var SCR = 3; // rcv certificate request
2190
+ var SHD = 4; // rcv server hello done
2191
+ var SCC = 5; // rcv change cipher spec
2192
+ var SFI = 6; // rcv finished
2193
+ var SAD = 7; // rcv application data
2194
+ var SER = 8; // not expecting any messages at this point
2195
+
2196
+ // server expect states
2197
+ var CHE = 0; // rcv client hello
2198
+ var CCE = 1; // rcv client certificate
2199
+ var CKE = 2; // rcv client key exchange
2200
+ var CCV = 3; // rcv certificate verify
2201
+ var CCC = 4; // rcv change cipher spec
2202
+ var CFI = 5; // rcv finished
2203
+ var CAD = 6; // rcv application data
2204
+ var CER = 7; // not expecting any messages at this point
2205
+
2206
+ // map client current expect state and content type to function
2207
+ var __ = tls.handleUnexpected;
2208
+ var R0 = tls.handleChangeCipherSpec;
2209
+ var R1 = tls.handleAlert;
2210
+ var R2 = tls.handleHandshake;
2211
+ var R3 = tls.handleApplicationData;
2212
+ var R4 = tls.handleHeartbeat;
2213
+ var ctTable = [];
2214
+ ctTable[tls.ConnectionEnd.client] = [
2215
+ // CC,AL,HS,AD,HB
2216
+ /*SHE*/[__,R1,R2,__,R4],
2217
+ /*SCE*/[__,R1,R2,__,R4],
2218
+ /*SKE*/[__,R1,R2,__,R4],
2219
+ /*SCR*/[__,R1,R2,__,R4],
2220
+ /*SHD*/[__,R1,R2,__,R4],
2221
+ /*SCC*/[R0,R1,__,__,R4],
2222
+ /*SFI*/[__,R1,R2,__,R4],
2223
+ /*SAD*/[__,R1,R2,R3,R4],
2224
+ /*SER*/[__,R1,R2,__,R4]
2225
+ ];
2226
+
2227
+ // map server current expect state and content type to function
2228
+ ctTable[tls.ConnectionEnd.server] = [
2229
+ // CC,AL,HS,AD
2230
+ /*CHE*/[__,R1,R2,__,R4],
2231
+ /*CCE*/[__,R1,R2,__,R4],
2232
+ /*CKE*/[__,R1,R2,__,R4],
2233
+ /*CCV*/[__,R1,R2,__,R4],
2234
+ /*CCC*/[R0,R1,__,__,R4],
2235
+ /*CFI*/[__,R1,R2,__,R4],
2236
+ /*CAD*/[__,R1,R2,R3,R4],
2237
+ /*CER*/[__,R1,R2,__,R4]
2238
+ ];
2239
+
2240
+ // map client current expect state and handshake type to function
2241
+ var H0 = tls.handleHelloRequest;
2242
+ var H1 = tls.handleServerHello;
2243
+ var H2 = tls.handleCertificate;
2244
+ var H3 = tls.handleServerKeyExchange;
2245
+ var H4 = tls.handleCertificateRequest;
2246
+ var H5 = tls.handleServerHelloDone;
2247
+ var H6 = tls.handleFinished;
2248
+ var hsTable = [];
2249
+ hsTable[tls.ConnectionEnd.client] = [
2250
+ // HR,01,SH,03,04,05,06,07,08,09,10,SC,SK,CR,HD,15,CK,17,18,19,FI
2251
+ /*SHE*/[__,__,H1,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__],
2252
+ /*SCE*/[H0,__,__,__,__,__,__,__,__,__,__,H2,H3,H4,H5,__,__,__,__,__,__],
2253
+ /*SKE*/[H0,__,__,__,__,__,__,__,__,__,__,__,H3,H4,H5,__,__,__,__,__,__],
2254
+ /*SCR*/[H0,__,__,__,__,__,__,__,__,__,__,__,__,H4,H5,__,__,__,__,__,__],
2255
+ /*SHD*/[H0,__,__,__,__,__,__,__,__,__,__,__,__,__,H5,__,__,__,__,__,__],
2256
+ /*SCC*/[H0,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__],
2257
+ /*SFI*/[H0,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,H6],
2258
+ /*SAD*/[H0,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__],
2259
+ /*SER*/[H0,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__]
2260
+ ];
2261
+
2262
+ // map server current expect state and handshake type to function
2263
+ // Note: CAD[CH] does not map to FB because renegotiation is prohibited
2264
+ var H7 = tls.handleClientHello;
2265
+ var H8 = tls.handleClientKeyExchange;
2266
+ var H9 = tls.handleCertificateVerify;
2267
+ hsTable[tls.ConnectionEnd.server] = [
2268
+ // 01,CH,02,03,04,05,06,07,08,09,10,CC,12,13,14,CV,CK,17,18,19,FI
2269
+ /*CHE*/[__,H7,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__],
2270
+ /*CCE*/[__,__,__,__,__,__,__,__,__,__,__,H2,__,__,__,__,__,__,__,__,__],
2271
+ /*CKE*/[__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,H8,__,__,__,__],
2272
+ /*CCV*/[__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,H9,__,__,__,__,__],
2273
+ /*CCC*/[__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__],
2274
+ /*CFI*/[__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,H6],
2275
+ /*CAD*/[__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__],
2276
+ /*CER*/[__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__,__]
2277
+ ];
2278
+
2279
+ /**
2280
+ * Generates the master_secret and keys using the given security parameters.
2281
+ *
2282
+ * The security parameters for a TLS connection state are defined as such:
2283
+ *
2284
+ * struct {
2285
+ * ConnectionEnd entity;
2286
+ * PRFAlgorithm prf_algorithm;
2287
+ * BulkCipherAlgorithm bulk_cipher_algorithm;
2288
+ * CipherType cipher_type;
2289
+ * uint8 enc_key_length;
2290
+ * uint8 block_length;
2291
+ * uint8 fixed_iv_length;
2292
+ * uint8 record_iv_length;
2293
+ * MACAlgorithm mac_algorithm;
2294
+ * uint8 mac_length;
2295
+ * uint8 mac_key_length;
2296
+ * CompressionMethod compression_algorithm;
2297
+ * opaque master_secret[48];
2298
+ * opaque client_random[32];
2299
+ * opaque server_random[32];
2300
+ * } SecurityParameters;
2301
+ *
2302
+ * Note that this definition is from TLS 1.2. In TLS 1.0 some of these
2303
+ * parameters are ignored because, for instance, the PRFAlgorithm is a
2304
+ * builtin-fixed algorithm combining iterations of MD5 and SHA-1 in TLS 1.0.
2305
+ *
2306
+ * The Record Protocol requires an algorithm to generate keys required by the
2307
+ * current connection state.
2308
+ *
2309
+ * The master secret is expanded into a sequence of secure bytes, which is then
2310
+ * split to a client write MAC key, a server write MAC key, a client write
2311
+ * encryption key, and a server write encryption key. In TLS 1.0 a client write
2312
+ * IV and server write IV are also generated. Each of these is generated from
2313
+ * the byte sequence in that order. Unused values are empty. In TLS 1.2, some
2314
+ * AEAD ciphers may additionally require a client write IV and a server write
2315
+ * IV (see Section 6.2.3.3).
2316
+ *
2317
+ * When keys, MAC keys, and IVs are generated, the master secret is used as an
2318
+ * entropy source.
2319
+ *
2320
+ * To generate the key material, compute:
2321
+ *
2322
+ * master_secret = PRF(pre_master_secret, "master secret",
2323
+ * ClientHello.random + ServerHello.random)
2324
+ *
2325
+ * key_block = PRF(SecurityParameters.master_secret,
2326
+ * "key expansion",
2327
+ * SecurityParameters.server_random +
2328
+ * SecurityParameters.client_random);
2329
+ *
2330
+ * until enough output has been generated. Then, the key_block is
2331
+ * partitioned as follows:
2332
+ *
2333
+ * client_write_MAC_key[SecurityParameters.mac_key_length]
2334
+ * server_write_MAC_key[SecurityParameters.mac_key_length]
2335
+ * client_write_key[SecurityParameters.enc_key_length]
2336
+ * server_write_key[SecurityParameters.enc_key_length]
2337
+ * client_write_IV[SecurityParameters.fixed_iv_length]
2338
+ * server_write_IV[SecurityParameters.fixed_iv_length]
2339
+ *
2340
+ * In TLS 1.2, the client_write_IV and server_write_IV are only generated for
2341
+ * implicit nonce techniques as described in Section 3.2.1 of [AEAD]. This
2342
+ * implementation uses TLS 1.0 so IVs are generated.
2343
+ *
2344
+ * Implementation note: The currently defined cipher suite which requires the
2345
+ * most material is AES_256_CBC_SHA256. It requires 2 x 32 byte keys and 2 x 32
2346
+ * byte MAC keys, for a total 128 bytes of key material. In TLS 1.0 it also
2347
+ * requires 2 x 16 byte IVs, so it actually takes 160 bytes of key material.
2348
+ *
2349
+ * @param c the connection.
2350
+ * @param sp the security parameters to use.
2351
+ *
2352
+ * @return the security keys.
2353
+ */
2354
+ tls.generateKeys = function(c, sp) {
2355
+ // TLS_RSA_WITH_AES_128_CBC_SHA (required to be compliant with TLS 1.2) &
2356
+ // TLS_RSA_WITH_AES_256_CBC_SHA are the only cipher suites implemented
2357
+ // at present
2358
+
2359
+ // TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA is required to be compliant with
2360
+ // TLS 1.0 but we don't care right now because AES is better and we have
2361
+ // an implementation for it
2362
+
2363
+ // TODO: TLS 1.2 implementation
2364
+ /*
2365
+ // determine the PRF
2366
+ var prf;
2367
+ switch(sp.prf_algorithm) {
2368
+ case tls.PRFAlgorithm.tls_prf_sha256:
2369
+ prf = prf_sha256;
2370
+ break;
2371
+ default:
2372
+ // should never happen
2373
+ throw new Error('Invalid PRF');
2374
+ }
2375
+ */
2376
+
2377
+ // TLS 1.0/1.1 implementation
2378
+ var prf = prf_TLS1;
2379
+
2380
+ // concatenate server and client random
2381
+ var random = sp.client_random + sp.server_random;
2382
+
2383
+ // only create master secret if session is new
2384
+ if(!c.session.resuming) {
2385
+ // create master secret, clean up pre-master secret
2386
+ sp.master_secret = prf(
2387
+ sp.pre_master_secret, 'master secret', random, 48).bytes();
2388
+ sp.pre_master_secret = null;
2389
+ }
2390
+
2391
+ // generate the amount of key material needed
2392
+ random = sp.server_random + sp.client_random;
2393
+ var length = 2 * sp.mac_key_length + 2 * sp.enc_key_length;
2394
+
2395
+ // include IV for TLS/1.0
2396
+ var tls10 = (c.version.major === tls.Versions.TLS_1_0.major &&
2397
+ c.version.minor === tls.Versions.TLS_1_0.minor);
2398
+ if(tls10) {
2399
+ length += 2 * sp.fixed_iv_length;
2400
+ }
2401
+ var km = prf(sp.master_secret, 'key expansion', random, length);
2402
+
2403
+ // split the key material into the MAC and encryption keys
2404
+ var rval = {
2405
+ client_write_MAC_key: km.getBytes(sp.mac_key_length),
2406
+ server_write_MAC_key: km.getBytes(sp.mac_key_length),
2407
+ client_write_key: km.getBytes(sp.enc_key_length),
2408
+ server_write_key: km.getBytes(sp.enc_key_length)
2409
+ };
2410
+
2411
+ // include TLS 1.0 IVs
2412
+ if(tls10) {
2413
+ rval.client_write_IV = km.getBytes(sp.fixed_iv_length);
2414
+ rval.server_write_IV = km.getBytes(sp.fixed_iv_length);
2415
+ }
2416
+
2417
+ return rval;
2418
+ };
2419
+
2420
+ /**
2421
+ * Creates a new initialized TLS connection state. A connection state has
2422
+ * a read mode and a write mode.
2423
+ *
2424
+ * compression state:
2425
+ * The current state of the compression algorithm.
2426
+ *
2427
+ * cipher state:
2428
+ * The current state of the encryption algorithm. This will consist of the
2429
+ * scheduled key for that connection. For stream ciphers, this will also
2430
+ * contain whatever state information is necessary to allow the stream to
2431
+ * continue to encrypt or decrypt data.
2432
+ *
2433
+ * MAC key:
2434
+ * The MAC key for the connection.
2435
+ *
2436
+ * sequence number:
2437
+ * Each connection state contains a sequence number, which is maintained
2438
+ * separately for read and write states. The sequence number MUST be set to
2439
+ * zero whenever a connection state is made the active state. Sequence
2440
+ * numbers are of type uint64 and may not exceed 2^64-1. Sequence numbers do
2441
+ * not wrap. If a TLS implementation would need to wrap a sequence number,
2442
+ * it must renegotiate instead. A sequence number is incremented after each
2443
+ * record: specifically, the first record transmitted under a particular
2444
+ * connection state MUST use sequence number 0.
2445
+ *
2446
+ * @param c the connection.
2447
+ *
2448
+ * @return the new initialized TLS connection state.
2449
+ */
2450
+ tls.createConnectionState = function(c) {
2451
+ var client = (c.entity === tls.ConnectionEnd.client);
2452
+
2453
+ var createMode = function() {
2454
+ var mode = {
2455
+ // two 32-bit numbers, first is most significant
2456
+ sequenceNumber: [0, 0],
2457
+ macKey: null,
2458
+ macLength: 0,
2459
+ macFunction: null,
2460
+ cipherState: null,
2461
+ cipherFunction: function(record) {return true;},
2462
+ compressionState: null,
2463
+ compressFunction: function(record) {return true;},
2464
+ updateSequenceNumber: function() {
2465
+ if(mode.sequenceNumber[1] === 0xFFFFFFFF) {
2466
+ mode.sequenceNumber[1] = 0;
2467
+ ++mode.sequenceNumber[0];
2468
+ } else {
2469
+ ++mode.sequenceNumber[1];
2470
+ }
2471
+ }
2472
+ };
2473
+ return mode;
2474
+ };
2475
+ var state = {
2476
+ read: createMode(),
2477
+ write: createMode()
2478
+ };
2479
+
2480
+ // update function in read mode will decrypt then decompress a record
2481
+ state.read.update = function(c, record) {
2482
+ if(!state.read.cipherFunction(record, state.read)) {
2483
+ c.error(c, {
2484
+ message: 'Could not decrypt record or bad MAC.',
2485
+ send: true,
2486
+ alert: {
2487
+ level: tls.Alert.Level.fatal,
2488
+ // doesn't matter if decryption failed or MAC was
2489
+ // invalid, return the same error so as not to reveal
2490
+ // which one occurred
2491
+ description: tls.Alert.Description.bad_record_mac
2492
+ }
2493
+ });
2494
+ } else if(!state.read.compressFunction(c, record, state.read)) {
2495
+ c.error(c, {
2496
+ message: 'Could not decompress record.',
2497
+ send: true,
2498
+ alert: {
2499
+ level: tls.Alert.Level.fatal,
2500
+ description: tls.Alert.Description.decompression_failure
2501
+ }
2502
+ });
2503
+ }
2504
+ return !c.fail;
2505
+ };
2506
+
2507
+ // update function in write mode will compress then encrypt a record
2508
+ state.write.update = function(c, record) {
2509
+ if(!state.write.compressFunction(c, record, state.write)) {
2510
+ // error, but do not send alert since it would require
2511
+ // compression as well
2512
+ c.error(c, {
2513
+ message: 'Could not compress record.',
2514
+ send: false,
2515
+ alert: {
2516
+ level: tls.Alert.Level.fatal,
2517
+ description: tls.Alert.Description.internal_error
2518
+ }
2519
+ });
2520
+ } else if(!state.write.cipherFunction(record, state.write)) {
2521
+ // error, but do not send alert since it would require
2522
+ // encryption as well
2523
+ c.error(c, {
2524
+ message: 'Could not encrypt record.',
2525
+ send: false,
2526
+ alert: {
2527
+ level: tls.Alert.Level.fatal,
2528
+ description: tls.Alert.Description.internal_error
2529
+ }
2530
+ });
2531
+ }
2532
+ return !c.fail;
2533
+ };
2534
+
2535
+ // handle security parameters
2536
+ if(c.session) {
2537
+ var sp = c.session.sp;
2538
+ c.session.cipherSuite.initSecurityParameters(sp);
2539
+
2540
+ // generate keys
2541
+ sp.keys = tls.generateKeys(c, sp);
2542
+ state.read.macKey = client ?
2543
+ sp.keys.server_write_MAC_key : sp.keys.client_write_MAC_key;
2544
+ state.write.macKey = client ?
2545
+ sp.keys.client_write_MAC_key : sp.keys.server_write_MAC_key;
2546
+
2547
+ // cipher suite setup
2548
+ c.session.cipherSuite.initConnectionState(state, c, sp);
2549
+
2550
+ // compression setup
2551
+ switch(sp.compression_algorithm) {
2552
+ case tls.CompressionMethod.none:
2553
+ break;
2554
+ case tls.CompressionMethod.deflate:
2555
+ state.read.compressFunction = inflate;
2556
+ state.write.compressFunction = deflate;
2557
+ break;
2558
+ default:
2559
+ throw new Error('Unsupported compression algorithm.');
2560
+ }
2561
+ }
2562
+
2563
+ return state;
2564
+ };
2565
+
2566
+ /**
2567
+ * Creates a Random structure.
2568
+ *
2569
+ * struct {
2570
+ * uint32 gmt_unix_time;
2571
+ * opaque random_bytes[28];
2572
+ * } Random;
2573
+ *
2574
+ * gmt_unix_time:
2575
+ * The current time and date in standard UNIX 32-bit format (seconds since
2576
+ * the midnight starting Jan 1, 1970, UTC, ignoring leap seconds) according
2577
+ * to the sender's internal clock. Clocks are not required to be set
2578
+ * correctly by the basic TLS protocol; higher-level or application
2579
+ * protocols may define additional requirements. Note that, for historical
2580
+ * reasons, the data element is named using GMT, the predecessor of the
2581
+ * current worldwide time base, UTC.
2582
+ * random_bytes:
2583
+ * 28 bytes generated by a secure random number generator.
2584
+ *
2585
+ * @return the Random structure as a byte array.
2586
+ */
2587
+ tls.createRandom = function() {
2588
+ // get UTC milliseconds
2589
+ var d = new Date();
2590
+ var utc = +d + d.getTimezoneOffset() * 60000;
2591
+ var rval = forge.util.createBuffer();
2592
+ rval.putInt32(utc);
2593
+ rval.putBytes(forge.random.getBytes(28));
2594
+ return rval;
2595
+ };
2596
+
2597
+ /**
2598
+ * Creates a TLS record with the given type and data.
2599
+ *
2600
+ * @param c the connection.
2601
+ * @param options:
2602
+ * type: the record type.
2603
+ * data: the plain text data in a byte buffer.
2604
+ *
2605
+ * @return the created record.
2606
+ */
2607
+ tls.createRecord = function(c, options) {
2608
+ if(!options.data) {
2609
+ return null;
2610
+ }
2611
+ var record = {
2612
+ type: options.type,
2613
+ version: {
2614
+ major: c.version.major,
2615
+ minor: c.version.minor
2616
+ },
2617
+ length: options.data.length(),
2618
+ fragment: options.data
2619
+ };
2620
+ return record;
2621
+ };
2622
+
2623
+ /**
2624
+ * Creates a TLS alert record.
2625
+ *
2626
+ * @param c the connection.
2627
+ * @param alert:
2628
+ * level: the TLS alert level.
2629
+ * description: the TLS alert description.
2630
+ *
2631
+ * @return the created alert record.
2632
+ */
2633
+ tls.createAlert = function(c, alert) {
2634
+ var b = forge.util.createBuffer();
2635
+ b.putByte(alert.level);
2636
+ b.putByte(alert.description);
2637
+ return tls.createRecord(c, {
2638
+ type: tls.ContentType.alert,
2639
+ data: b
2640
+ });
2641
+ };
2642
+
2643
+ /* The structure of a TLS handshake message.
2644
+ *
2645
+ * struct {
2646
+ * HandshakeType msg_type; // handshake type
2647
+ * uint24 length; // bytes in message
2648
+ * select(HandshakeType) {
2649
+ * case hello_request: HelloRequest;
2650
+ * case client_hello: ClientHello;
2651
+ * case server_hello: ServerHello;
2652
+ * case certificate: Certificate;
2653
+ * case server_key_exchange: ServerKeyExchange;
2654
+ * case certificate_request: CertificateRequest;
2655
+ * case server_hello_done: ServerHelloDone;
2656
+ * case certificate_verify: CertificateVerify;
2657
+ * case client_key_exchange: ClientKeyExchange;
2658
+ * case finished: Finished;
2659
+ * } body;
2660
+ * } Handshake;
2661
+ */
2662
+
2663
+ /**
2664
+ * Creates a ClientHello message.
2665
+ *
2666
+ * opaque SessionID<0..32>;
2667
+ * enum { null(0), deflate(1), (255) } CompressionMethod;
2668
+ * uint8 CipherSuite[2];
2669
+ *
2670
+ * struct {
2671
+ * ProtocolVersion client_version;
2672
+ * Random random;
2673
+ * SessionID session_id;
2674
+ * CipherSuite cipher_suites<2..2^16-2>;
2675
+ * CompressionMethod compression_methods<1..2^8-1>;
2676
+ * select(extensions_present) {
2677
+ * case false:
2678
+ * struct {};
2679
+ * case true:
2680
+ * Extension extensions<0..2^16-1>;
2681
+ * };
2682
+ * } ClientHello;
2683
+ *
2684
+ * The extension format for extended client hellos and server hellos is:
2685
+ *
2686
+ * struct {
2687
+ * ExtensionType extension_type;
2688
+ * opaque extension_data<0..2^16-1>;
2689
+ * } Extension;
2690
+ *
2691
+ * Here:
2692
+ *
2693
+ * - "extension_type" identifies the particular extension type.
2694
+ * - "extension_data" contains information specific to the particular
2695
+ * extension type.
2696
+ *
2697
+ * The extension types defined in this document are:
2698
+ *
2699
+ * enum {
2700
+ * server_name(0), max_fragment_length(1),
2701
+ * client_certificate_url(2), trusted_ca_keys(3),
2702
+ * truncated_hmac(4), status_request(5), (65535)
2703
+ * } ExtensionType;
2704
+ *
2705
+ * @param c the connection.
2706
+ *
2707
+ * @return the ClientHello byte buffer.
2708
+ */
2709
+ tls.createClientHello = function(c) {
2710
+ // save hello version
2711
+ c.session.clientHelloVersion = {
2712
+ major: c.version.major,
2713
+ minor: c.version.minor
2714
+ };
2715
+
2716
+ // create supported cipher suites
2717
+ var cipherSuites = forge.util.createBuffer();
2718
+ for(var i = 0; i < c.cipherSuites.length; ++i) {
2719
+ var cs = c.cipherSuites[i];
2720
+ cipherSuites.putByte(cs.id[0]);
2721
+ cipherSuites.putByte(cs.id[1]);
2722
+ }
2723
+ var cSuites = cipherSuites.length();
2724
+
2725
+ // create supported compression methods, null always supported, but
2726
+ // also support deflate if connection has inflate and deflate methods
2727
+ var compressionMethods = forge.util.createBuffer();
2728
+ compressionMethods.putByte(tls.CompressionMethod.none);
2729
+ // FIXME: deflate support disabled until issues with raw deflate data
2730
+ // without zlib headers are resolved
2731
+ /*
2732
+ if(c.inflate !== null && c.deflate !== null) {
2733
+ compressionMethods.putByte(tls.CompressionMethod.deflate);
2734
+ }
2735
+ */
2736
+ var cMethods = compressionMethods.length();
2737
+
2738
+ // create TLS SNI (server name indication) extension if virtual host
2739
+ // has been specified, see RFC 3546
2740
+ var extensions = forge.util.createBuffer();
2741
+ if(c.virtualHost) {
2742
+ // create extension struct
2743
+ var ext = forge.util.createBuffer();
2744
+ ext.putByte(0x00); // type server_name (ExtensionType is 2 bytes)
2745
+ ext.putByte(0x00);
2746
+
2747
+ /* In order to provide the server name, clients MAY include an
2748
+ * extension of type "server_name" in the (extended) client hello.
2749
+ * The "extension_data" field of this extension SHALL contain
2750
+ * "ServerNameList" where:
2751
+ *
2752
+ * struct {
2753
+ * NameType name_type;
2754
+ * select(name_type) {
2755
+ * case host_name: HostName;
2756
+ * } name;
2757
+ * } ServerName;
2758
+ *
2759
+ * enum {
2760
+ * host_name(0), (255)
2761
+ * } NameType;
2762
+ *
2763
+ * opaque HostName<1..2^16-1>;
2764
+ *
2765
+ * struct {
2766
+ * ServerName server_name_list<1..2^16-1>
2767
+ * } ServerNameList;
2768
+ */
2769
+ var serverName = forge.util.createBuffer();
2770
+ serverName.putByte(0x00); // type host_name
2771
+ writeVector(serverName, 2, forge.util.createBuffer(c.virtualHost));
2772
+
2773
+ // ServerNameList is in extension_data
2774
+ var snList = forge.util.createBuffer();
2775
+ writeVector(snList, 2, serverName);
2776
+ writeVector(ext, 2, snList);
2777
+ extensions.putBuffer(ext);
2778
+ }
2779
+ var extLength = extensions.length();
2780
+ if(extLength > 0) {
2781
+ // add extension vector length
2782
+ extLength += 2;
2783
+ }
2784
+
2785
+ // determine length of the handshake message
2786
+ // cipher suites and compression methods size will need to be
2787
+ // updated if more get added to the list
2788
+ var sessionId = c.session.id;
2789
+ var length =
2790
+ sessionId.length + 1 + // session ID vector
2791
+ 2 + // version (major + minor)
2792
+ 4 + 28 + // random time and random bytes
2793
+ 2 + cSuites + // cipher suites vector
2794
+ 1 + cMethods + // compression methods vector
2795
+ extLength; // extensions vector
2796
+
2797
+ // build record fragment
2798
+ var rval = forge.util.createBuffer();
2799
+ rval.putByte(tls.HandshakeType.client_hello);
2800
+ rval.putInt24(length); // handshake length
2801
+ rval.putByte(c.version.major); // major version
2802
+ rval.putByte(c.version.minor); // minor version
2803
+ rval.putBytes(c.session.sp.client_random); // random time + bytes
2804
+ writeVector(rval, 1, forge.util.createBuffer(sessionId));
2805
+ writeVector(rval, 2, cipherSuites);
2806
+ writeVector(rval, 1, compressionMethods);
2807
+ if(extLength > 0) {
2808
+ writeVector(rval, 2, extensions);
2809
+ }
2810
+ return rval;
2811
+ };
2812
+
2813
+ /**
2814
+ * Creates a ServerHello message.
2815
+ *
2816
+ * @param c the connection.
2817
+ *
2818
+ * @return the ServerHello byte buffer.
2819
+ */
2820
+ tls.createServerHello = function(c) {
2821
+ // determine length of the handshake message
2822
+ var sessionId = c.session.id;
2823
+ var length =
2824
+ sessionId.length + 1 + // session ID vector
2825
+ 2 + // version (major + minor)
2826
+ 4 + 28 + // random time and random bytes
2827
+ 2 + // chosen cipher suite
2828
+ 1; // chosen compression method
2829
+
2830
+ // build record fragment
2831
+ var rval = forge.util.createBuffer();
2832
+ rval.putByte(tls.HandshakeType.server_hello);
2833
+ rval.putInt24(length); // handshake length
2834
+ rval.putByte(c.version.major); // major version
2835
+ rval.putByte(c.version.minor); // minor version
2836
+ rval.putBytes(c.session.sp.server_random); // random time + bytes
2837
+ writeVector(rval, 1, forge.util.createBuffer(sessionId));
2838
+ rval.putByte(c.session.cipherSuite.id[0]);
2839
+ rval.putByte(c.session.cipherSuite.id[1]);
2840
+ rval.putByte(c.session.compressionMethod);
2841
+ return rval;
2842
+ };
2843
+
2844
+ /**
2845
+ * Creates a Certificate message.
2846
+ *
2847
+ * When this message will be sent:
2848
+ * This is the first message the client can send after receiving a server
2849
+ * hello done message and the first message the server can send after
2850
+ * sending a ServerHello. This client message is only sent if the server
2851
+ * requests a certificate. If no suitable certificate is available, the
2852
+ * client should send a certificate message containing no certificates. If
2853
+ * client authentication is required by the server for the handshake to
2854
+ * continue, it may respond with a fatal handshake failure alert.
2855
+ *
2856
+ * opaque ASN.1Cert<1..2^24-1>;
2857
+ *
2858
+ * struct {
2859
+ * ASN.1Cert certificate_list<0..2^24-1>;
2860
+ * } Certificate;
2861
+ *
2862
+ * @param c the connection.
2863
+ *
2864
+ * @return the Certificate byte buffer.
2865
+ */
2866
+ tls.createCertificate = function(c) {
2867
+ // TODO: check certificate request to ensure types are supported
2868
+
2869
+ // get a certificate (a certificate as a PEM string)
2870
+ var client = (c.entity === tls.ConnectionEnd.client);
2871
+ var cert = null;
2872
+ if(c.getCertificate) {
2873
+ var hint;
2874
+ if(client) {
2875
+ hint = c.session.certificateRequest;
2876
+ } else {
2877
+ hint = c.session.extensions.server_name.serverNameList;
2878
+ }
2879
+ cert = c.getCertificate(c, hint);
2880
+ }
2881
+
2882
+ // buffer to hold certificate list
2883
+ var certList = forge.util.createBuffer();
2884
+ if(cert !== null) {
2885
+ try {
2886
+ // normalize cert to a chain of certificates
2887
+ if(!forge.util.isArray(cert)) {
2888
+ cert = [cert];
2889
+ }
2890
+ var asn1 = null;
2891
+ for(var i = 0; i < cert.length; ++i) {
2892
+ var msg = forge.pem.decode(cert[i])[0];
2893
+ if(msg.type !== 'CERTIFICATE' &&
2894
+ msg.type !== 'X509 CERTIFICATE' &&
2895
+ msg.type !== 'TRUSTED CERTIFICATE') {
2896
+ var error = new Error('Could not convert certificate from PEM; PEM ' +
2897
+ 'header type is not "CERTIFICATE", "X509 CERTIFICATE", or ' +
2898
+ '"TRUSTED CERTIFICATE".');
2899
+ error.headerType = msg.type;
2900
+ throw error;
2901
+ }
2902
+ if(msg.procType && msg.procType.type === 'ENCRYPTED') {
2903
+ throw new Error('Could not convert certificate from PEM; PEM is encrypted.');
2904
+ }
2905
+
2906
+ var der = forge.util.createBuffer(msg.body);
2907
+ if(asn1 === null) {
2908
+ asn1 = forge.asn1.fromDer(der.bytes(), false);
2909
+ }
2910
+
2911
+ // certificate entry is itself a vector with 3 length bytes
2912
+ var certBuffer = forge.util.createBuffer();
2913
+ writeVector(certBuffer, 3, der);
2914
+
2915
+ // add cert vector to cert list vector
2916
+ certList.putBuffer(certBuffer);
2917
+ }
2918
+
2919
+ // save certificate
2920
+ cert = forge.pki.certificateFromAsn1(asn1);
2921
+ if(client) {
2922
+ c.session.clientCertificate = cert;
2923
+ } else {
2924
+ c.session.serverCertificate = cert;
2925
+ }
2926
+ } catch(ex) {
2927
+ return c.error(c, {
2928
+ message: 'Could not send certificate list.',
2929
+ cause: ex,
2930
+ send: true,
2931
+ alert: {
2932
+ level: tls.Alert.Level.fatal,
2933
+ description: tls.Alert.Description.bad_certificate
2934
+ }
2935
+ });
2936
+ }
2937
+ }
2938
+
2939
+ // determine length of the handshake message
2940
+ var length = 3 + certList.length(); // cert list vector
2941
+
2942
+ // build record fragment
2943
+ var rval = forge.util.createBuffer();
2944
+ rval.putByte(tls.HandshakeType.certificate);
2945
+ rval.putInt24(length);
2946
+ writeVector(rval, 3, certList);
2947
+ return rval;
2948
+ };
2949
+
2950
+ /**
2951
+ * Creates a ClientKeyExchange message.
2952
+ *
2953
+ * When this message will be sent:
2954
+ * This message is always sent by the client. It will immediately follow the
2955
+ * client certificate message, if it is sent. Otherwise it will be the first
2956
+ * message sent by the client after it receives the server hello done
2957
+ * message.
2958
+ *
2959
+ * Meaning of this message:
2960
+ * With this message, the premaster secret is set, either though direct
2961
+ * transmission of the RSA-encrypted secret, or by the transmission of
2962
+ * Diffie-Hellman parameters which will allow each side to agree upon the
2963
+ * same premaster secret. When the key exchange method is DH_RSA or DH_DSS,
2964
+ * client certification has been requested, and the client was able to
2965
+ * respond with a certificate which contained a Diffie-Hellman public key
2966
+ * whose parameters (group and generator) matched those specified by the
2967
+ * server in its certificate, this message will not contain any data.
2968
+ *
2969
+ * Meaning of this message:
2970
+ * If RSA is being used for key agreement and authentication, the client
2971
+ * generates a 48-byte premaster secret, encrypts it using the public key
2972
+ * from the server's certificate or the temporary RSA key provided in a
2973
+ * server key exchange message, and sends the result in an encrypted
2974
+ * premaster secret message. This structure is a variant of the client
2975
+ * key exchange message, not a message in itself.
2976
+ *
2977
+ * struct {
2978
+ * select(KeyExchangeAlgorithm) {
2979
+ * case rsa: EncryptedPreMasterSecret;
2980
+ * case diffie_hellman: ClientDiffieHellmanPublic;
2981
+ * } exchange_keys;
2982
+ * } ClientKeyExchange;
2983
+ *
2984
+ * struct {
2985
+ * ProtocolVersion client_version;
2986
+ * opaque random[46];
2987
+ * } PreMasterSecret;
2988
+ *
2989
+ * struct {
2990
+ * public-key-encrypted PreMasterSecret pre_master_secret;
2991
+ * } EncryptedPreMasterSecret;
2992
+ *
2993
+ * A public-key-encrypted element is encoded as a vector <0..2^16-1>.
2994
+ *
2995
+ * @param c the connection.
2996
+ *
2997
+ * @return the ClientKeyExchange byte buffer.
2998
+ */
2999
+ tls.createClientKeyExchange = function(c) {
3000
+ // create buffer to encrypt
3001
+ var b = forge.util.createBuffer();
3002
+
3003
+ // add highest client-supported protocol to help server avoid version
3004
+ // rollback attacks
3005
+ b.putByte(c.session.clientHelloVersion.major);
3006
+ b.putByte(c.session.clientHelloVersion.minor);
3007
+
3008
+ // generate and add 46 random bytes
3009
+ b.putBytes(forge.random.getBytes(46));
3010
+
3011
+ // save pre-master secret
3012
+ var sp = c.session.sp;
3013
+ sp.pre_master_secret = b.getBytes();
3014
+
3015
+ // RSA-encrypt the pre-master secret
3016
+ var key = c.session.serverCertificate.publicKey;
3017
+ b = key.encrypt(sp.pre_master_secret);
3018
+
3019
+ /* Note: The encrypted pre-master secret will be stored in a
3020
+ public-key-encrypted opaque vector that has the length prefixed using
3021
+ 2 bytes, so include those 2 bytes in the handshake message length. This
3022
+ is done as a minor optimization instead of calling writeVector(). */
3023
+
3024
+ // determine length of the handshake message
3025
+ var length = b.length + 2;
3026
+
3027
+ // build record fragment
3028
+ var rval = forge.util.createBuffer();
3029
+ rval.putByte(tls.HandshakeType.client_key_exchange);
3030
+ rval.putInt24(length);
3031
+ // add vector length bytes
3032
+ rval.putInt16(b.length);
3033
+ rval.putBytes(b);
3034
+ return rval;
3035
+ };
3036
+
3037
+ /**
3038
+ * Creates a ServerKeyExchange message.
3039
+ *
3040
+ * @param c the connection.
3041
+ *
3042
+ * @return the ServerKeyExchange byte buffer.
3043
+ */
3044
+ tls.createServerKeyExchange = function(c) {
3045
+ // this implementation only supports RSA, no Diffie-Hellman support,
3046
+ // so this record is empty
3047
+
3048
+ // determine length of the handshake message
3049
+ var length = 0;
3050
+
3051
+ // build record fragment
3052
+ var rval = forge.util.createBuffer();
3053
+ if(length > 0) {
3054
+ rval.putByte(tls.HandshakeType.server_key_exchange);
3055
+ rval.putInt24(length);
3056
+ }
3057
+ return rval;
3058
+ };
3059
+
3060
+ /**
3061
+ * Gets the signed data used to verify a client-side certificate. See
3062
+ * tls.createCertificateVerify() for details.
3063
+ *
3064
+ * @param c the connection.
3065
+ * @param callback the callback to call once the signed data is ready.
3066
+ */
3067
+ tls.getClientSignature = function(c, callback) {
3068
+ // generate data to RSA encrypt
3069
+ var b = forge.util.createBuffer();
3070
+ b.putBuffer(c.session.md5.digest());
3071
+ b.putBuffer(c.session.sha1.digest());
3072
+ b = b.getBytes();
3073
+
3074
+ // create default signing function as necessary
3075
+ c.getSignature = c.getSignature || function(c, b, callback) {
3076
+ // do rsa encryption, call callback
3077
+ var privateKey = null;
3078
+ if(c.getPrivateKey) {
3079
+ try {
3080
+ privateKey = c.getPrivateKey(c, c.session.clientCertificate);
3081
+ privateKey = forge.pki.privateKeyFromPem(privateKey);
3082
+ } catch(ex) {
3083
+ c.error(c, {
3084
+ message: 'Could not get private key.',
3085
+ cause: ex,
3086
+ send: true,
3087
+ alert: {
3088
+ level: tls.Alert.Level.fatal,
3089
+ description: tls.Alert.Description.internal_error
3090
+ }
3091
+ });
3092
+ }
3093
+ }
3094
+ if(privateKey === null) {
3095
+ c.error(c, {
3096
+ message: 'No private key set.',
3097
+ send: true,
3098
+ alert: {
3099
+ level: tls.Alert.Level.fatal,
3100
+ description: tls.Alert.Description.internal_error
3101
+ }
3102
+ });
3103
+ } else {
3104
+ b = privateKey.sign(b, null);
3105
+ }
3106
+ callback(c, b);
3107
+ };
3108
+
3109
+ // get client signature
3110
+ c.getSignature(c, b, callback);
3111
+ };
3112
+
3113
+ /**
3114
+ * Creates a CertificateVerify message.
3115
+ *
3116
+ * Meaning of this message:
3117
+ * This structure conveys the client's Diffie-Hellman public value
3118
+ * (Yc) if it was not already included in the client's certificate.
3119
+ * The encoding used for Yc is determined by the enumerated
3120
+ * PublicValueEncoding. This structure is a variant of the client
3121
+ * key exchange message, not a message in itself.
3122
+ *
3123
+ * When this message will be sent:
3124
+ * This message is used to provide explicit verification of a client
3125
+ * certificate. This message is only sent following a client
3126
+ * certificate that has signing capability (i.e. all certificates
3127
+ * except those containing fixed Diffie-Hellman parameters). When
3128
+ * sent, it will immediately follow the client key exchange message.
3129
+ *
3130
+ * struct {
3131
+ * Signature signature;
3132
+ * } CertificateVerify;
3133
+ *
3134
+ * CertificateVerify.signature.md5_hash
3135
+ * MD5(handshake_messages);
3136
+ *
3137
+ * Certificate.signature.sha_hash
3138
+ * SHA(handshake_messages);
3139
+ *
3140
+ * Here handshake_messages refers to all handshake messages sent or
3141
+ * received starting at client hello up to but not including this
3142
+ * message, including the type and length fields of the handshake
3143
+ * messages.
3144
+ *
3145
+ * select(SignatureAlgorithm) {
3146
+ * case anonymous: struct { };
3147
+ * case rsa:
3148
+ * digitally-signed struct {
3149
+ * opaque md5_hash[16];
3150
+ * opaque sha_hash[20];
3151
+ * };
3152
+ * case dsa:
3153
+ * digitally-signed struct {
3154
+ * opaque sha_hash[20];
3155
+ * };
3156
+ * } Signature;
3157
+ *
3158
+ * In digital signing, one-way hash functions are used as input for a
3159
+ * signing algorithm. A digitally-signed element is encoded as an opaque
3160
+ * vector <0..2^16-1>, where the length is specified by the signing
3161
+ * algorithm and key.
3162
+ *
3163
+ * In RSA signing, a 36-byte structure of two hashes (one SHA and one
3164
+ * MD5) is signed (encrypted with the private key). It is encoded with
3165
+ * PKCS #1 block type 0 or type 1 as described in [PKCS1].
3166
+ *
3167
+ * In DSS, the 20 bytes of the SHA hash are run directly through the
3168
+ * Digital Signing Algorithm with no additional hashing.
3169
+ *
3170
+ * @param c the connection.
3171
+ * @param signature the signature to include in the message.
3172
+ *
3173
+ * @return the CertificateVerify byte buffer.
3174
+ */
3175
+ tls.createCertificateVerify = function(c, signature) {
3176
+ /* Note: The signature will be stored in a "digitally-signed" opaque
3177
+ vector that has the length prefixed using 2 bytes, so include those
3178
+ 2 bytes in the handshake message length. This is done as a minor
3179
+ optimization instead of calling writeVector(). */
3180
+
3181
+ // determine length of the handshake message
3182
+ var length = signature.length + 2;
3183
+
3184
+ // build record fragment
3185
+ var rval = forge.util.createBuffer();
3186
+ rval.putByte(tls.HandshakeType.certificate_verify);
3187
+ rval.putInt24(length);
3188
+ // add vector length bytes
3189
+ rval.putInt16(signature.length);
3190
+ rval.putBytes(signature);
3191
+ return rval;
3192
+ };
3193
+
3194
+ /**
3195
+ * Creates a CertificateRequest message.
3196
+ *
3197
+ * @param c the connection.
3198
+ *
3199
+ * @return the CertificateRequest byte buffer.
3200
+ */
3201
+ tls.createCertificateRequest = function(c) {
3202
+ // TODO: support other certificate types
3203
+ var certTypes = forge.util.createBuffer();
3204
+
3205
+ // common RSA certificate type
3206
+ certTypes.putByte(0x01);
3207
+
3208
+ // add distinguished names from CA store
3209
+ var cAs = forge.util.createBuffer();
3210
+ for(var key in c.caStore.certs) {
3211
+ var cert = c.caStore.certs[key];
3212
+ var dn = forge.pki.distinguishedNameToAsn1(cert.subject);
3213
+ var byteBuffer = forge.asn1.toDer(dn);
3214
+ cAs.putInt16(byteBuffer.length());
3215
+ cAs.putBuffer(byteBuffer);
3216
+ }
3217
+
3218
+ // TODO: TLS 1.2+ has a different format
3219
+
3220
+ // determine length of the handshake message
3221
+ var length =
3222
+ 1 + certTypes.length() +
3223
+ 2 + cAs.length();
3224
+
3225
+ // build record fragment
3226
+ var rval = forge.util.createBuffer();
3227
+ rval.putByte(tls.HandshakeType.certificate_request);
3228
+ rval.putInt24(length);
3229
+ writeVector(rval, 1, certTypes);
3230
+ writeVector(rval, 2, cAs);
3231
+ return rval;
3232
+ };
3233
+
3234
+ /**
3235
+ * Creates a ServerHelloDone message.
3236
+ *
3237
+ * @param c the connection.
3238
+ *
3239
+ * @return the ServerHelloDone byte buffer.
3240
+ */
3241
+ tls.createServerHelloDone = function(c) {
3242
+ // build record fragment
3243
+ var rval = forge.util.createBuffer();
3244
+ rval.putByte(tls.HandshakeType.server_hello_done);
3245
+ rval.putInt24(0);
3246
+ return rval;
3247
+ };
3248
+
3249
+ /**
3250
+ * Creates a ChangeCipherSpec message.
3251
+ *
3252
+ * The change cipher spec protocol exists to signal transitions in
3253
+ * ciphering strategies. The protocol consists of a single message,
3254
+ * which is encrypted and compressed under the current (not the pending)
3255
+ * connection state. The message consists of a single byte of value 1.
3256
+ *
3257
+ * struct {
3258
+ * enum { change_cipher_spec(1), (255) } type;
3259
+ * } ChangeCipherSpec;
3260
+ *
3261
+ * @return the ChangeCipherSpec byte buffer.
3262
+ */
3263
+ tls.createChangeCipherSpec = function() {
3264
+ var rval = forge.util.createBuffer();
3265
+ rval.putByte(0x01);
3266
+ return rval;
3267
+ };
3268
+
3269
+ /**
3270
+ * Creates a Finished message.
3271
+ *
3272
+ * struct {
3273
+ * opaque verify_data[12];
3274
+ * } Finished;
3275
+ *
3276
+ * verify_data
3277
+ * PRF(master_secret, finished_label, MD5(handshake_messages) +
3278
+ * SHA-1(handshake_messages)) [0..11];
3279
+ *
3280
+ * finished_label
3281
+ * For Finished messages sent by the client, the string "client
3282
+ * finished". For Finished messages sent by the server, the
3283
+ * string "server finished".
3284
+ *
3285
+ * handshake_messages
3286
+ * All of the data from all handshake messages up to but not
3287
+ * including this message. This is only data visible at the
3288
+ * handshake layer and does not include record layer headers.
3289
+ * This is the concatenation of all the Handshake structures as
3290
+ * defined in 7.4 exchanged thus far.
3291
+ *
3292
+ * @param c the connection.
3293
+ *
3294
+ * @return the Finished byte buffer.
3295
+ */
3296
+ tls.createFinished = function(c) {
3297
+ // generate verify_data
3298
+ var b = forge.util.createBuffer();
3299
+ b.putBuffer(c.session.md5.digest());
3300
+ b.putBuffer(c.session.sha1.digest());
3301
+
3302
+ // TODO: determine prf function and verify length for TLS 1.2
3303
+ var client = (c.entity === tls.ConnectionEnd.client);
3304
+ var sp = c.session.sp;
3305
+ var vdl = 12;
3306
+ var prf = prf_TLS1;
3307
+ var label = client ? 'client finished' : 'server finished';
3308
+ b = prf(sp.master_secret, label, b.getBytes(), vdl);
3309
+
3310
+ // build record fragment
3311
+ var rval = forge.util.createBuffer();
3312
+ rval.putByte(tls.HandshakeType.finished);
3313
+ rval.putInt24(b.length());
3314
+ rval.putBuffer(b);
3315
+ return rval;
3316
+ };
3317
+
3318
+ /**
3319
+ * Creates a HeartbeatMessage (See RFC 6520).
3320
+ *
3321
+ * struct {
3322
+ * HeartbeatMessageType type;
3323
+ * uint16 payload_length;
3324
+ * opaque payload[HeartbeatMessage.payload_length];
3325
+ * opaque padding[padding_length];
3326
+ * } HeartbeatMessage;
3327
+ *
3328
+ * The total length of a HeartbeatMessage MUST NOT exceed 2^14 or
3329
+ * max_fragment_length when negotiated as defined in [RFC6066].
3330
+ *
3331
+ * type: The message type, either heartbeat_request or heartbeat_response.
3332
+ *
3333
+ * payload_length: The length of the payload.
3334
+ *
3335
+ * payload: The payload consists of arbitrary content.
3336
+ *
3337
+ * padding: The padding is random content that MUST be ignored by the
3338
+ * receiver. The length of a HeartbeatMessage is TLSPlaintext.length
3339
+ * for TLS and DTLSPlaintext.length for DTLS. Furthermore, the
3340
+ * length of the type field is 1 byte, and the length of the
3341
+ * payload_length is 2. Therefore, the padding_length is
3342
+ * TLSPlaintext.length - payload_length - 3 for TLS and
3343
+ * DTLSPlaintext.length - payload_length - 3 for DTLS. The
3344
+ * padding_length MUST be at least 16.
3345
+ *
3346
+ * The sender of a HeartbeatMessage MUST use a random padding of at
3347
+ * least 16 bytes. The padding of a received HeartbeatMessage message
3348
+ * MUST be ignored.
3349
+ *
3350
+ * If the payload_length of a received HeartbeatMessage is too large,
3351
+ * the received HeartbeatMessage MUST be discarded silently.
3352
+ *
3353
+ * @param c the connection.
3354
+ * @param type the tls.HeartbeatMessageType.
3355
+ * @param payload the heartbeat data to send as the payload.
3356
+ * @param [payloadLength] the payload length to use, defaults to the
3357
+ * actual payload length.
3358
+ *
3359
+ * @return the HeartbeatRequest byte buffer.
3360
+ */
3361
+ tls.createHeartbeat = function(type, payload, payloadLength) {
3362
+ if(typeof payloadLength === 'undefined') {
3363
+ payloadLength = payload.length;
3364
+ }
3365
+ // build record fragment
3366
+ var rval = forge.util.createBuffer();
3367
+ rval.putByte(type); // heartbeat message type
3368
+ rval.putInt16(payloadLength); // payload length
3369
+ rval.putBytes(payload); // payload
3370
+ // padding
3371
+ var plaintextLength = rval.length();
3372
+ var paddingLength = Math.max(16, plaintextLength - payloadLength - 3);
3373
+ rval.putBytes(forge.random.getBytes(paddingLength));
3374
+ return rval;
3375
+ };
3376
+
3377
+ /**
3378
+ * Fragments, compresses, encrypts, and queues a record for delivery.
3379
+ *
3380
+ * @param c the connection.
3381
+ * @param record the record to queue.
3382
+ */
3383
+ tls.queue = function(c, record) {
3384
+ // error during record creation
3385
+ if(!record) {
3386
+ return;
3387
+ }
3388
+
3389
+ if(record.fragment.length() === 0) {
3390
+ if(record.type === tls.ContentType.handshake ||
3391
+ record.type === tls.ContentType.alert ||
3392
+ record.type === tls.ContentType.change_cipher_spec) {
3393
+ // Empty handshake, alert of change cipher spec messages are not allowed per the TLS specification and should not be sent.
3394
+ return;
3395
+ }
3396
+ }
3397
+
3398
+ // if the record is a handshake record, update handshake hashes
3399
+ if(record.type === tls.ContentType.handshake) {
3400
+ var bytes = record.fragment.bytes();
3401
+ c.session.md5.update(bytes);
3402
+ c.session.sha1.update(bytes);
3403
+ bytes = null;
3404
+ }
3405
+
3406
+ // handle record fragmentation
3407
+ var records;
3408
+ if(record.fragment.length() <= tls.MaxFragment) {
3409
+ records = [record];
3410
+ } else {
3411
+ // fragment data as long as it is too long
3412
+ records = [];
3413
+ var data = record.fragment.bytes();
3414
+ while(data.length > tls.MaxFragment) {
3415
+ records.push(tls.createRecord(c, {
3416
+ type: record.type,
3417
+ data: forge.util.createBuffer(data.slice(0, tls.MaxFragment))
3418
+ }));
3419
+ data = data.slice(tls.MaxFragment);
3420
+ }
3421
+ // add last record
3422
+ if(data.length > 0) {
3423
+ records.push(tls.createRecord(c, {
3424
+ type: record.type,
3425
+ data: forge.util.createBuffer(data)
3426
+ }));
3427
+ }
3428
+ }
3429
+
3430
+ // compress and encrypt all fragmented records
3431
+ for(var i = 0; i < records.length && !c.fail; ++i) {
3432
+ // update the record using current write state
3433
+ var rec = records[i];
3434
+ var s = c.state.current.write;
3435
+ if(s.update(c, rec)) {
3436
+ // store record
3437
+ c.records.push(rec);
3438
+ }
3439
+ }
3440
+ };
3441
+
3442
+ /**
3443
+ * Flushes all queued records to the output buffer and calls the
3444
+ * tlsDataReady() handler on the given connection.
3445
+ *
3446
+ * @param c the connection.
3447
+ *
3448
+ * @return true on success, false on failure.
3449
+ */
3450
+ tls.flush = function(c) {
3451
+ for(var i = 0; i < c.records.length; ++i) {
3452
+ var record = c.records[i];
3453
+
3454
+ // add record header and fragment
3455
+ c.tlsData.putByte(record.type);
3456
+ c.tlsData.putByte(record.version.major);
3457
+ c.tlsData.putByte(record.version.minor);
3458
+ c.tlsData.putInt16(record.fragment.length());
3459
+ c.tlsData.putBuffer(c.records[i].fragment);
3460
+ }
3461
+ c.records = [];
3462
+ return c.tlsDataReady(c);
3463
+ };
3464
+
3465
+ /**
3466
+ * Maps a pki.certificateError to a tls.Alert.Description.
3467
+ *
3468
+ * @param error the error to map.
3469
+ *
3470
+ * @return the alert description.
3471
+ */
3472
+ var _certErrorToAlertDesc = function(error) {
3473
+ switch(error) {
3474
+ case true:
3475
+ return true;
3476
+ case forge.pki.certificateError.bad_certificate:
3477
+ return tls.Alert.Description.bad_certificate;
3478
+ case forge.pki.certificateError.unsupported_certificate:
3479
+ return tls.Alert.Description.unsupported_certificate;
3480
+ case forge.pki.certificateError.certificate_revoked:
3481
+ return tls.Alert.Description.certificate_revoked;
3482
+ case forge.pki.certificateError.certificate_expired:
3483
+ return tls.Alert.Description.certificate_expired;
3484
+ case forge.pki.certificateError.certificate_unknown:
3485
+ return tls.Alert.Description.certificate_unknown;
3486
+ case forge.pki.certificateError.unknown_ca:
3487
+ return tls.Alert.Description.unknown_ca;
3488
+ default:
3489
+ return tls.Alert.Description.bad_certificate;
3490
+ }
3491
+ };
3492
+
3493
+ /**
3494
+ * Maps a tls.Alert.Description to a pki.certificateError.
3495
+ *
3496
+ * @param desc the alert description.
3497
+ *
3498
+ * @return the certificate error.
3499
+ */
3500
+ var _alertDescToCertError = function(desc) {
3501
+ switch(desc) {
3502
+ case true:
3503
+ return true;
3504
+ case tls.Alert.Description.bad_certificate:
3505
+ return forge.pki.certificateError.bad_certificate;
3506
+ case tls.Alert.Description.unsupported_certificate:
3507
+ return forge.pki.certificateError.unsupported_certificate;
3508
+ case tls.Alert.Description.certificate_revoked:
3509
+ return forge.pki.certificateError.certificate_revoked;
3510
+ case tls.Alert.Description.certificate_expired:
3511
+ return forge.pki.certificateError.certificate_expired;
3512
+ case tls.Alert.Description.certificate_unknown:
3513
+ return forge.pki.certificateError.certificate_unknown;
3514
+ case tls.Alert.Description.unknown_ca:
3515
+ return forge.pki.certificateError.unknown_ca;
3516
+ default:
3517
+ return forge.pki.certificateError.bad_certificate;
3518
+ }
3519
+ };
3520
+
3521
+ /**
3522
+ * Verifies a certificate chain against the given connection's
3523
+ * Certificate Authority store.
3524
+ *
3525
+ * @param c the TLS connection.
3526
+ * @param chain the certificate chain to verify, with the root or highest
3527
+ * authority at the end.
3528
+ *
3529
+ * @return true if successful, false if not.
3530
+ */
3531
+ tls.verifyCertificateChain = function(c, chain) {
3532
+ try {
3533
+ // Make a copy of c.verifyOptions so that we can modify options.verify
3534
+ // without modifying c.verifyOptions.
3535
+ var options = {};
3536
+ for (var key in c.verifyOptions) {
3537
+ options[key] = c.verifyOptions[key];
3538
+ }
3539
+
3540
+ options.verify = function(vfd, depth, chain) {
3541
+ // convert pki.certificateError to tls alert description
3542
+ var desc = _certErrorToAlertDesc(vfd);
3543
+
3544
+ // call application callback
3545
+ var ret = c.verify(c, vfd, depth, chain);
3546
+ if(ret !== true) {
3547
+ if(typeof ret === 'object' && !forge.util.isArray(ret)) {
3548
+ // throw custom error
3549
+ var error = new Error('The application rejected the certificate.');
3550
+ error.send = true;
3551
+ error.alert = {
3552
+ level: tls.Alert.Level.fatal,
3553
+ description: tls.Alert.Description.bad_certificate
3554
+ };
3555
+ if(ret.message) {
3556
+ error.message = ret.message;
3557
+ }
3558
+ if(ret.alert) {
3559
+ error.alert.description = ret.alert;
3560
+ }
3561
+ throw error;
3562
+ }
3563
+
3564
+ // convert tls alert description to pki.certificateError
3565
+ if(ret !== vfd) {
3566
+ ret = _alertDescToCertError(ret);
3567
+ }
3568
+ }
3569
+
3570
+ return ret;
3571
+ };
3572
+
3573
+ // verify chain
3574
+ forge.pki.verifyCertificateChain(c.caStore, chain, options);
3575
+ } catch(ex) {
3576
+ // build tls error if not already customized
3577
+ var err = ex;
3578
+ if(typeof err !== 'object' || forge.util.isArray(err)) {
3579
+ err = {
3580
+ send: true,
3581
+ alert: {
3582
+ level: tls.Alert.Level.fatal,
3583
+ description: _certErrorToAlertDesc(ex)
3584
+ }
3585
+ };
3586
+ }
3587
+ if(!('send' in err)) {
3588
+ err.send = true;
3589
+ }
3590
+ if(!('alert' in err)) {
3591
+ err.alert = {
3592
+ level: tls.Alert.Level.fatal,
3593
+ description: _certErrorToAlertDesc(err.error)
3594
+ };
3595
+ }
3596
+
3597
+ // send error
3598
+ c.error(c, err);
3599
+ }
3600
+
3601
+ return !c.fail;
3602
+ };
3603
+
3604
+ /**
3605
+ * Creates a new TLS session cache.
3606
+ *
3607
+ * @param cache optional map of session ID to cached session.
3608
+ * @param capacity the maximum size for the cache (default: 100).
3609
+ *
3610
+ * @return the new TLS session cache.
3611
+ */
3612
+ tls.createSessionCache = function(cache, capacity) {
3613
+ var rval = null;
3614
+
3615
+ // assume input is already a session cache object
3616
+ if(cache && cache.getSession && cache.setSession && cache.order) {
3617
+ rval = cache;
3618
+ } else {
3619
+ // create cache
3620
+ rval = {};
3621
+ rval.cache = cache || {};
3622
+ rval.capacity = Math.max(capacity || 100, 1);
3623
+ rval.order = [];
3624
+
3625
+ // store order for sessions, delete session overflow
3626
+ for(var key in cache) {
3627
+ if(rval.order.length <= capacity) {
3628
+ rval.order.push(key);
3629
+ } else {
3630
+ delete cache[key];
3631
+ }
3632
+ }
3633
+
3634
+ // get a session from a session ID (or get any session)
3635
+ rval.getSession = function(sessionId) {
3636
+ var session = null;
3637
+ var key = null;
3638
+
3639
+ // if session ID provided, use it
3640
+ if(sessionId) {
3641
+ key = forge.util.bytesToHex(sessionId);
3642
+ } else if(rval.order.length > 0) {
3643
+ // get first session from cache
3644
+ key = rval.order[0];
3645
+ }
3646
+
3647
+ if(key !== null && key in rval.cache) {
3648
+ // get cached session and remove from cache
3649
+ session = rval.cache[key];
3650
+ delete rval.cache[key];
3651
+ for(var i in rval.order) {
3652
+ if(rval.order[i] === key) {
3653
+ rval.order.splice(i, 1);
3654
+ break;
3655
+ }
3656
+ }
3657
+ }
3658
+
3659
+ return session;
3660
+ };
3661
+
3662
+ // set a session in the cache
3663
+ rval.setSession = function(sessionId, session) {
3664
+ // remove session from cache if at capacity
3665
+ if(rval.order.length === rval.capacity) {
3666
+ var key = rval.order.shift();
3667
+ delete rval.cache[key];
3668
+ }
3669
+ // add session to cache
3670
+ var key = forge.util.bytesToHex(sessionId);
3671
+ rval.order.push(key);
3672
+ rval.cache[key] = session;
3673
+ };
3674
+ }
3675
+
3676
+ return rval;
3677
+ };
3678
+
3679
+ /**
3680
+ * Creates a new TLS connection.
3681
+ *
3682
+ * See public createConnection() docs for more details.
3683
+ *
3684
+ * @param options the options for this connection.
3685
+ *
3686
+ * @return the new TLS connection.
3687
+ */
3688
+ tls.createConnection = function(options) {
3689
+ var caStore = null;
3690
+ if(options.caStore) {
3691
+ // if CA store is an array, convert it to a CA store object
3692
+ if(forge.util.isArray(options.caStore)) {
3693
+ caStore = forge.pki.createCaStore(options.caStore);
3694
+ } else {
3695
+ caStore = options.caStore;
3696
+ }
3697
+ } else {
3698
+ // create empty CA store
3699
+ caStore = forge.pki.createCaStore();
3700
+ }
3701
+
3702
+ // setup default cipher suites
3703
+ var cipherSuites = options.cipherSuites || null;
3704
+ if(cipherSuites === null) {
3705
+ cipherSuites = [];
3706
+ for(var key in tls.CipherSuites) {
3707
+ cipherSuites.push(tls.CipherSuites[key]);
3708
+ }
3709
+ }
3710
+
3711
+ // set default entity
3712
+ var entity = (options.server || false) ?
3713
+ tls.ConnectionEnd.server : tls.ConnectionEnd.client;
3714
+
3715
+ // create session cache if requested
3716
+ var sessionCache = options.sessionCache ?
3717
+ tls.createSessionCache(options.sessionCache) : null;
3718
+
3719
+ // create TLS connection
3720
+ var c = {
3721
+ version: {major: tls.Version.major, minor: tls.Version.minor},
3722
+ entity: entity,
3723
+ sessionId: options.sessionId,
3724
+ caStore: caStore,
3725
+ sessionCache: sessionCache,
3726
+ cipherSuites: cipherSuites,
3727
+ connected: options.connected,
3728
+ virtualHost: options.virtualHost || null,
3729
+ verifyClient: options.verifyClient || false,
3730
+ verify: options.verify || function(cn, vfd, dpth, cts) {return vfd;},
3731
+ verifyOptions: options.verifyOptions || {},
3732
+ getCertificate: options.getCertificate || null,
3733
+ getPrivateKey: options.getPrivateKey || null,
3734
+ getSignature: options.getSignature || null,
3735
+ input: forge.util.createBuffer(),
3736
+ tlsData: forge.util.createBuffer(),
3737
+ data: forge.util.createBuffer(),
3738
+ tlsDataReady: options.tlsDataReady,
3739
+ dataReady: options.dataReady,
3740
+ heartbeatReceived: options.heartbeatReceived,
3741
+ closed: options.closed,
3742
+ error: function(c, ex) {
3743
+ // set origin if not set
3744
+ ex.origin = ex.origin ||
3745
+ ((c.entity === tls.ConnectionEnd.client) ? 'client' : 'server');
3746
+
3747
+ // send TLS alert
3748
+ if(ex.send) {
3749
+ tls.queue(c, tls.createAlert(c, ex.alert));
3750
+ tls.flush(c);
3751
+ }
3752
+
3753
+ // error is fatal by default
3754
+ var fatal = (ex.fatal !== false);
3755
+ if(fatal) {
3756
+ // set fail flag
3757
+ c.fail = true;
3758
+ }
3759
+
3760
+ // call error handler first
3761
+ options.error(c, ex);
3762
+
3763
+ if(fatal) {
3764
+ // fatal error, close connection, do not clear fail
3765
+ c.close(false);
3766
+ }
3767
+ },
3768
+ deflate: options.deflate || null,
3769
+ inflate: options.inflate || null
3770
+ };
3771
+
3772
+ /**
3773
+ * Resets a closed TLS connection for reuse. Called in c.close().
3774
+ *
3775
+ * @param clearFail true to clear the fail flag (default: true).
3776
+ */
3777
+ c.reset = function(clearFail) {
3778
+ c.version = {major: tls.Version.major, minor: tls.Version.minor};
3779
+ c.record = null;
3780
+ c.session = null;
3781
+ c.peerCertificate = null;
3782
+ c.state = {
3783
+ pending: null,
3784
+ current: null
3785
+ };
3786
+ c.expect = (c.entity === tls.ConnectionEnd.client) ? SHE : CHE;
3787
+ c.fragmented = null;
3788
+ c.records = [];
3789
+ c.open = false;
3790
+ c.handshakes = 0;
3791
+ c.handshaking = false;
3792
+ c.isConnected = false;
3793
+ c.fail = !(clearFail || typeof(clearFail) === 'undefined');
3794
+ c.input.clear();
3795
+ c.tlsData.clear();
3796
+ c.data.clear();
3797
+ c.state.current = tls.createConnectionState(c);
3798
+ };
3799
+
3800
+ // do initial reset of connection
3801
+ c.reset();
3802
+
3803
+ /**
3804
+ * Updates the current TLS engine state based on the given record.
3805
+ *
3806
+ * @param c the TLS connection.
3807
+ * @param record the TLS record to act on.
3808
+ */
3809
+ var _update = function(c, record) {
3810
+ // get record handler (align type in table by subtracting lowest)
3811
+ var aligned = record.type - tls.ContentType.change_cipher_spec;
3812
+ var handlers = ctTable[c.entity][c.expect];
3813
+ if(aligned in handlers) {
3814
+ handlers[aligned](c, record);
3815
+ } else {
3816
+ // unexpected record
3817
+ tls.handleUnexpected(c, record);
3818
+ }
3819
+ };
3820
+
3821
+ /**
3822
+ * Reads the record header and initializes the next record on the given
3823
+ * connection.
3824
+ *
3825
+ * @param c the TLS connection with the next record.
3826
+ *
3827
+ * @return 0 if the input data could be processed, otherwise the
3828
+ * number of bytes required for data to be processed.
3829
+ */
3830
+ var _readRecordHeader = function(c) {
3831
+ var rval = 0;
3832
+
3833
+ // get input buffer and its length
3834
+ var b = c.input;
3835
+ var len = b.length();
3836
+
3837
+ // need at least 5 bytes to initialize a record
3838
+ if(len < 5) {
3839
+ rval = 5 - len;
3840
+ } else {
3841
+ // enough bytes for header
3842
+ // initialize record
3843
+ c.record = {
3844
+ type: b.getByte(),
3845
+ version: {
3846
+ major: b.getByte(),
3847
+ minor: b.getByte()
3848
+ },
3849
+ length: b.getInt16(),
3850
+ fragment: forge.util.createBuffer(),
3851
+ ready: false
3852
+ };
3853
+
3854
+ // check record version
3855
+ var compatibleVersion = (c.record.version.major === c.version.major);
3856
+ if(compatibleVersion && c.session && c.session.version) {
3857
+ // session version already set, require same minor version
3858
+ compatibleVersion = (c.record.version.minor === c.version.minor);
3859
+ }
3860
+ if(!compatibleVersion) {
3861
+ c.error(c, {
3862
+ message: 'Incompatible TLS version.',
3863
+ send: true,
3864
+ alert: {
3865
+ level: tls.Alert.Level.fatal,
3866
+ description: tls.Alert.Description.protocol_version
3867
+ }
3868
+ });
3869
+ }
3870
+ }
3871
+
3872
+ return rval;
3873
+ };
3874
+
3875
+ /**
3876
+ * Reads the next record's contents and appends its message to any
3877
+ * previously fragmented message.
3878
+ *
3879
+ * @param c the TLS connection with the next record.
3880
+ *
3881
+ * @return 0 if the input data could be processed, otherwise the
3882
+ * number of bytes required for data to be processed.
3883
+ */
3884
+ var _readRecord = function(c) {
3885
+ var rval = 0;
3886
+
3887
+ // ensure there is enough input data to get the entire record
3888
+ var b = c.input;
3889
+ var len = b.length();
3890
+ if(len < c.record.length) {
3891
+ // not enough data yet, return how much is required
3892
+ rval = c.record.length - len;
3893
+ } else {
3894
+ // there is enough data to parse the pending record
3895
+ // fill record fragment and compact input buffer
3896
+ c.record.fragment.putBytes(b.getBytes(c.record.length));
3897
+ b.compact();
3898
+
3899
+ // update record using current read state
3900
+ var s = c.state.current.read;
3901
+ if(s.update(c, c.record)) {
3902
+ // see if there is a previously fragmented message that the
3903
+ // new record's message fragment should be appended to
3904
+ if(c.fragmented !== null) {
3905
+ // if the record type matches a previously fragmented
3906
+ // record, append the record fragment to it
3907
+ if(c.fragmented.type === c.record.type) {
3908
+ // concatenate record fragments
3909
+ c.fragmented.fragment.putBuffer(c.record.fragment);
3910
+ c.record = c.fragmented;
3911
+ } else {
3912
+ // error, invalid fragmented record
3913
+ c.error(c, {
3914
+ message: 'Invalid fragmented record.',
3915
+ send: true,
3916
+ alert: {
3917
+ level: tls.Alert.Level.fatal,
3918
+ description:
3919
+ tls.Alert.Description.unexpected_message
3920
+ }
3921
+ });
3922
+ // fatal error closed and reset the connection (no record)
3923
+ return rval;
3924
+ }
3925
+ }
3926
+
3927
+ // record is now ready
3928
+ c.record.ready = true;
3929
+ }
3930
+ }
3931
+
3932
+ return rval;
3933
+ };
3934
+
3935
+ /**
3936
+ * Performs a handshake using the TLS Handshake Protocol, as a client.
3937
+ *
3938
+ * This method should only be called if the connection is in client mode.
3939
+ *
3940
+ * @param sessionId the session ID to use, null to start a new one.
3941
+ */
3942
+ c.handshake = function(sessionId) {
3943
+ // error to call this in non-client mode
3944
+ if(c.entity !== tls.ConnectionEnd.client) {
3945
+ // not fatal error
3946
+ c.error(c, {
3947
+ message: 'Cannot initiate handshake as a server.',
3948
+ fatal: false
3949
+ });
3950
+ } else if(c.handshaking) {
3951
+ // handshake is already in progress, fail but not fatal error
3952
+ c.error(c, {
3953
+ message: 'Handshake already in progress.',
3954
+ fatal: false
3955
+ });
3956
+ } else {
3957
+ // clear fail flag on reuse
3958
+ if(c.fail && !c.open && c.handshakes === 0) {
3959
+ c.fail = false;
3960
+ }
3961
+
3962
+ // now handshaking
3963
+ c.handshaking = true;
3964
+
3965
+ // default to blank (new session)
3966
+ sessionId = sessionId || '';
3967
+
3968
+ // if a session ID was specified, try to find it in the cache
3969
+ var session = null;
3970
+ if(sessionId.length > 0) {
3971
+ if(c.sessionCache) {
3972
+ session = c.sessionCache.getSession(sessionId);
3973
+ }
3974
+
3975
+ // matching session not found in cache, clear session ID
3976
+ if(session === null) {
3977
+ sessionId = '';
3978
+ }
3979
+ }
3980
+
3981
+ // no session given, grab a session from the cache, if available
3982
+ if(sessionId.length === 0 && c.sessionCache) {
3983
+ session = c.sessionCache.getSession();
3984
+ if(session !== null) {
3985
+ sessionId = session.id;
3986
+ }
3987
+ }
3988
+
3989
+ // set up session
3990
+ c.session = {
3991
+ id: sessionId,
3992
+ version: null,
3993
+ cipherSuite: null,
3994
+ compressionMethod: null,
3995
+ serverCertificate: null,
3996
+ certificateRequest: null,
3997
+ clientCertificate: null,
3998
+ sp: {},
3999
+ md5: forge.md.md5.create(),
4000
+ sha1: forge.md.sha1.create()
4001
+ };
4002
+
4003
+ // use existing session information
4004
+ if(session) {
4005
+ // only update version on connection, session version not yet set
4006
+ c.version = session.version;
4007
+ c.session.sp = session.sp;
4008
+ }
4009
+
4010
+ // generate new client random
4011
+ c.session.sp.client_random = tls.createRandom().getBytes();
4012
+
4013
+ // connection now open
4014
+ c.open = true;
4015
+
4016
+ // send hello
4017
+ tls.queue(c, tls.createRecord(c, {
4018
+ type: tls.ContentType.handshake,
4019
+ data: tls.createClientHello(c)
4020
+ }));
4021
+ tls.flush(c);
4022
+ }
4023
+ };
4024
+
4025
+ // true while c.process() is handling records
4026
+ var _processing = false;
4027
+ // true when c.process() was called again while handling a record
4028
+ var _processNext = false;
4029
+
4030
+ /**
4031
+ * Reads the next record and, once it is complete, passes it to its
4032
+ * handler. Handlers call c.process() to continue with the next record.
4033
+ *
4034
+ * @param c the TLS connection.
4035
+ *
4036
+ * @return 0 if the input data could be processed, otherwise the
4037
+ * number of bytes required for data to be processed.
4038
+ */
4039
+ var _processRecord = function(c) {
4040
+ var rval = 0;
4041
+
4042
+ // process next record if no failure, process will be called after
4043
+ // each record is handled (since handling can be asynchronous)
4044
+ if(!c.fail) {
4045
+ // reset record if ready and now empty
4046
+ if(c.record !== null &&
4047
+ c.record.ready && c.record.fragment.isEmpty()) {
4048
+ c.record = null;
4049
+ }
4050
+
4051
+ // if there is no pending record, try to read record header
4052
+ if(c.record === null) {
4053
+ rval = _readRecordHeader(c);
4054
+ }
4055
+
4056
+ // read the next record (if record not yet ready)
4057
+ if(!c.fail && c.record !== null && !c.record.ready) {
4058
+ rval = _readRecord(c);
4059
+ }
4060
+
4061
+ // record ready to be handled, update engine state
4062
+ if(!c.fail && c.record !== null && c.record.ready) {
4063
+ _update(c, c.record);
4064
+ }
4065
+ }
4066
+
4067
+ return rval;
4068
+ };
4069
+
4070
+ /**
4071
+ * Called when TLS protocol data has been received from somewhere and should
4072
+ * be processed by the TLS engine.
4073
+ *
4074
+ * @param data the TLS protocol data, as a string, to process.
4075
+ *
4076
+ * @return 0 if the data could be processed, otherwise the number of bytes
4077
+ * required for data to be processed.
4078
+ */
4079
+ c.process = function(data) {
4080
+ var rval = 0;
4081
+
4082
+ // buffer input data
4083
+ if(data) {
4084
+ c.input.putBytes(data);
4085
+ }
4086
+
4087
+ // record handlers call c.process() without data to continue with the
4088
+ // next record; while records are being processed, only flag that the
4089
+ // loop below should continue instead of recursing, which could exhaust
4090
+ // the call stack
4091
+ if(_processing && typeof(data) === 'undefined') {
4092
+ _processNext = true;
4093
+ return rval;
4094
+ }
4095
+
4096
+ // new data is processed right away, as before, even in a nested call
4097
+ // (e.g., from a tlsDataReady handler that passes data synchronously
4098
+ // between two connections)
4099
+ var processing = _processing;
4100
+ var processNext = _processNext;
4101
+ _processing = true;
4102
+ _processNext = false;
4103
+ try {
4104
+ // return value is based on the first record, as before
4105
+ rval = _processRecord(c);
4106
+ while(_processNext) {
4107
+ _processNext = false;
4108
+ _processRecord(c);
4109
+ }
4110
+ } finally {
4111
+ _processing = processing;
4112
+ _processNext = processNext;
4113
+ }
4114
+
4115
+ return rval;
4116
+ };
4117
+
4118
+ /**
4119
+ * Requests that application data be packaged into a TLS record. The
4120
+ * tlsDataReady handler will be called when the TLS record(s) have been
4121
+ * prepared.
4122
+ *
4123
+ * @param data the application data, as a raw 'binary' encoded string, to
4124
+ * be sent; to send utf-16/utf-8 string data, use the return value
4125
+ * of util.encodeUtf8(str).
4126
+ *
4127
+ * @return true on success, false on failure.
4128
+ */
4129
+ c.prepare = function(data) {
4130
+ tls.queue(c, tls.createRecord(c, {
4131
+ type: tls.ContentType.application_data,
4132
+ data: forge.util.createBuffer(data)
4133
+ }));
4134
+ return tls.flush(c);
4135
+ };
4136
+
4137
+ /**
4138
+ * Requests that a heartbeat request be packaged into a TLS record for
4139
+ * transmission. The tlsDataReady handler will be called when TLS record(s)
4140
+ * have been prepared.
4141
+ *
4142
+ * When a heartbeat response has been received, the heartbeatReceived
4143
+ * handler will be called with the matching payload. This handler can
4144
+ * be used to clear a retransmission timer, etc.
4145
+ *
4146
+ * @param payload the heartbeat data to send as the payload in the message.
4147
+ * @param [payloadLength] the payload length to use, defaults to the
4148
+ * actual payload length.
4149
+ *
4150
+ * @return true on success, false on failure.
4151
+ */
4152
+ c.prepareHeartbeatRequest = function(payload, payloadLength) {
4153
+ if(payload instanceof forge.util.ByteBuffer) {
4154
+ payload = payload.bytes();
4155
+ }
4156
+ if(typeof payloadLength === 'undefined') {
4157
+ payloadLength = payload.length;
4158
+ }
4159
+ c.expectedHeartbeatPayload = payload;
4160
+ tls.queue(c, tls.createRecord(c, {
4161
+ type: tls.ContentType.heartbeat,
4162
+ data: tls.createHeartbeat(
4163
+ tls.HeartbeatMessageType.heartbeat_request, payload, payloadLength)
4164
+ }));
4165
+ return tls.flush(c);
4166
+ };
4167
+
4168
+ /**
4169
+ * Closes the connection (sends a close_notify alert).
4170
+ *
4171
+ * @param clearFail true to clear the fail flag (default: true).
4172
+ */
4173
+ c.close = function(clearFail) {
4174
+ // save session if connection didn't fail
4175
+ if(!c.fail && c.sessionCache && c.session) {
4176
+ // only need to preserve session ID, version, and security params
4177
+ var session = {
4178
+ id: c.session.id,
4179
+ version: c.session.version,
4180
+ sp: c.session.sp
4181
+ };
4182
+ session.sp.keys = null;
4183
+ c.sessionCache.setSession(session.id, session);
4184
+ }
4185
+
4186
+ if(c.open) {
4187
+ // connection no longer open, clear input
4188
+ c.open = false;
4189
+ c.input.clear();
4190
+
4191
+ // if connected or handshaking, send an alert
4192
+ if(c.isConnected || c.handshaking) {
4193
+ c.isConnected = c.handshaking = false;
4194
+
4195
+ // send close_notify alert
4196
+ tls.queue(c, tls.createAlert(c, {
4197
+ level: tls.Alert.Level.warning,
4198
+ description: tls.Alert.Description.close_notify
4199
+ }));
4200
+ tls.flush(c);
4201
+ }
4202
+
4203
+ // call handler
4204
+ c.closed(c);
4205
+ }
4206
+
4207
+ // reset TLS connection, do not clear fail flag
4208
+ c.reset(clearFail);
4209
+ };
4210
+
4211
+ return c;
4212
+ };
4213
+
4214
+ /* TLS API */
4215
+ module.exports = forge.tls = forge.tls || {};
4216
+
4217
+ // expose non-functions
4218
+ for(var key in tls) {
4219
+ if(typeof tls[key] !== 'function') {
4220
+ forge.tls[key] = tls[key];
4221
+ }
4222
+ }
4223
+
4224
+ // expose prf_tls1 for testing
4225
+ forge.tls.prf_tls1 = prf_TLS1;
4226
+
4227
+ // expose sha1 hmac method
4228
+ forge.tls.hmac_sha1 = hmac_sha1;
4229
+
4230
+ // expose session cache creation
4231
+ forge.tls.createSessionCache = tls.createSessionCache;
4232
+
4233
+ /**
4234
+ * Creates a new TLS connection. This does not make any assumptions about the
4235
+ * transport layer that TLS is working on top of, ie: it does not assume there
4236
+ * is a TCP/IP connection or establish one. A TLS connection is totally
4237
+ * abstracted away from the layer is runs on top of, it merely establishes a
4238
+ * secure channel between a client" and a "server".
4239
+ *
4240
+ * A TLS connection contains 4 connection states: pending read and write, and
4241
+ * current read and write.
4242
+ *
4243
+ * At initialization, the current read and write states will be null. Only once
4244
+ * the security parameters have been set and the keys have been generated can
4245
+ * the pending states be converted into current states. Current states will be
4246
+ * updated for each record processed.
4247
+ *
4248
+ * A custom certificate verify callback may be provided to check information
4249
+ * like the common name on the server's certificate. It will be called for
4250
+ * every certificate in the chain. It has the following signature:
4251
+ *
4252
+ * variable func(c, certs, index, preVerify)
4253
+ * Where:
4254
+ * c The TLS connection
4255
+ * verified Set to true if certificate was verified, otherwise the alert
4256
+ * tls.Alert.Description for why the certificate failed.
4257
+ * depth The current index in the chain, where 0 is the server's cert.
4258
+ * certs The certificate chain, *NOTE* if the server was anonymous then
4259
+ * the chain will be empty.
4260
+ *
4261
+ * The function returns true on success and on failure either the appropriate
4262
+ * tls.Alert.Description or an object with 'alert' set to the appropriate
4263
+ * tls.Alert.Description and 'message' set to a custom error message. If true
4264
+ * is not returned then the connection will abort using, in order of
4265
+ * availability, first the returned alert description, second the preVerify
4266
+ * alert description, and lastly the default 'bad_certificate'.
4267
+ *
4268
+ * There are three callbacks that can be used to make use of client-side
4269
+ * certificates where each takes the TLS connection as the first parameter:
4270
+ *
4271
+ * getCertificate(conn, hint)
4272
+ * The second parameter is a hint as to which certificate should be
4273
+ * returned. If the connection entity is a client, then the hint will be
4274
+ * the CertificateRequest message from the server that is part of the
4275
+ * TLS protocol. If the connection entity is a server, then it will be
4276
+ * the servername list provided via an SNI extension the ClientHello, if
4277
+ * one was provided (empty array if not). The hint can be examined to
4278
+ * determine which certificate to use (advanced). Most implementations
4279
+ * will just return a certificate. The return value must be a
4280
+ * PEM-formatted certificate or an array of PEM-formatted certificates
4281
+ * that constitute a certificate chain, with the first in the array/chain
4282
+ * being the client's certificate.
4283
+ * getPrivateKey(conn, certificate)
4284
+ * The second parameter is an forge.pki X.509 certificate object that
4285
+ * is associated with the requested private key. The return value must
4286
+ * be a PEM-formatted private key.
4287
+ * getSignature(conn, bytes, callback)
4288
+ * This callback can be used instead of getPrivateKey if the private key
4289
+ * is not directly accessible in javascript or should not be. For
4290
+ * instance, a secure external web service could provide the signature
4291
+ * in exchange for appropriate credentials. The second parameter is a
4292
+ * string of bytes to be signed that are part of the TLS protocol. These
4293
+ * bytes are used to verify that the private key for the previously
4294
+ * provided client-side certificate is accessible to the client. The
4295
+ * callback is a function that takes 2 parameters, the TLS connection
4296
+ * and the RSA encrypted (signed) bytes as a string. This callback must
4297
+ * be called once the signature is ready.
4298
+ *
4299
+ * @param options the options for this connection:
4300
+ * server: true if the connection is server-side, false for client.
4301
+ * sessionId: a session ID to reuse, null for a new connection.
4302
+ * caStore: an array of certificates to trust.
4303
+ * sessionCache: a session cache to use.
4304
+ * cipherSuites: an optional array of cipher suites to use,
4305
+ * see tls.CipherSuites.
4306
+ * connected: function(conn) called when the first handshake completes.
4307
+ * virtualHost: the virtual server name to use in a TLS SNI extension.
4308
+ * verifyClient: true to require a client certificate in server mode,
4309
+ * 'optional' to request one, false not to (default: false).
4310
+ * verify: a handler used to custom verify certificates in the chain.
4311
+ * verifyOptions: an object with options for the certificate chain validation.
4312
+ * See documentation of pki.verifyCertificateChain for possible options.
4313
+ * verifyOptions.verify is ignored. If you wish to specify a verify handler
4314
+ * use the verify key.
4315
+ * getCertificate: an optional callback used to get a certificate or
4316
+ * a chain of certificates (as an array).
4317
+ * getPrivateKey: an optional callback used to get a private key.
4318
+ * getSignature: an optional callback used to get a signature.
4319
+ * tlsDataReady: function(conn) called when TLS protocol data has been
4320
+ * prepared and is ready to be used (typically sent over a socket
4321
+ * connection to its destination), read from conn.tlsData buffer.
4322
+ * dataReady: function(conn) called when application data has
4323
+ * been parsed from a TLS record and should be consumed by the
4324
+ * application, read from conn.data buffer.
4325
+ * closed: function(conn) called when the connection has been closed.
4326
+ * error: function(conn, error) called when there was an error.
4327
+ * deflate: function(inBytes) if provided, will deflate TLS records using
4328
+ * the deflate algorithm if the server supports it.
4329
+ * inflate: function(inBytes) if provided, will inflate TLS records using
4330
+ * the deflate algorithm if the server supports it.
4331
+ *
4332
+ * @return the new TLS connection.
4333
+ */
4334
+ forge.tls.createConnection = tls.createConnection;