upstream: github.com/mirleft/ocaml-tls
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Delete outdated *.md files

Twelve docs that no longer track real work or describe the current
fork. Removed:

ocaml-tls/{attacks,sni,design}.md — pre-fork architecture notes from
mirleft/ocaml-tls that reference 2014 CVEs, polarssl, Lwt/Async
flows; nothing in the current Eio-based fork's design.

memtrace/CONTRIBUTING.md — Jane Street upstream guide pointing at
github.com PRs, doesn't apply on tangled.

ocaml-requests/HTTP2_{IMPLEMENTATION_PLAN,CONPOOL_INTEGRATION}.md —
1500 lines combined for an HTTP/2 rollout that hasn't moved in 6+
weeks; revive from git history if/when the work restarts.

merlint/TODO.md, merlint/todo/{new_rules,codes,duplication}.md,
ocaml-sqlite/TODO.md, prune/TODO.md — stale TODO/proposal lists,
last touched 6+ weeks ago. Active TODOs (monopam, irmin, jwt,
cookie, chor, requests SPEC-TODO, claude ARCHITECTURE) all kept.

Also drop the now-empty merlint/todo/ directory and roll in dune fmt
fallout for irmin/test/bench/dune.

-603
-293
attacks.md
··· 1 - ### Attacks on TLS 2 - 3 - TLS the most widely deployed security protocol on the Internet and, at 4 - over 15 years, is also showing its age. As such, a flaw is a valuable 5 - commodity due to the commercially sensitive nature of data that is 6 - encrypted with TLS. Various vulnerabilities on different layers of TLS 7 - have been found - [heartbleed][] and others are implementation 8 - specific, advancements in cryptanalysis such as [collisions of 9 - MD5][md5_collision] lead to vulnerabilities, and even others are due 10 - to incorrect usage of TLS ([truncation attack][truncation] or 11 - [BREACH][breach]). Finally, some weaknesses are in the protocol 12 - itself. Extensive [overviews][tls_attacks] of [attacks on 13 - TLS][mitls_attacks] are available. 14 - 15 - We look at protocol level attacks of TLS and how [ocaml-tls][ocaml-tls] 16 - implements mitigations against these. [TLS 1.2 RFC][RFC5246] provides an 17 - overview of attacks and mitigations, and we [track][issue31] our progress in 18 - covering them. This is slightly out of date as the RFC is roughly six years old and 19 - in the meantime more attacks have been published, such as the [renegotiation 20 - flaw][understanding_reneg]. 21 - 22 - We track all our [mitigated][closed] and [open][open] security issues 23 - on our GitHub issue tracker. 24 - 25 - Due to the choice of using OCaml, a memory managed programming 26 - language, we obstruct entire bug classes, namely temporal and spatial 27 - memory safety. 28 - 29 - Cryptanalysis and improvement of computational power weaken some 30 - ciphers, such as RC4 and 3DES (see [issue 8][issue8] and [issue 31 - 10][issue10]). If we phase these two ciphers out, there wouldn't be 32 - any matching ciphersuite left to communicate with some compliant TLS-1.0 33 - implementations, such as Windows XP, that do not support AES. 34 - 35 - [issue8]: https://github.com/mirleft/ocaml-tls/issues/8 36 - [issue10]: https://github.com/mirleft/ocaml-tls/issues/10 37 - [open]: https://github.com/mirleft/ocaml-tls/issues?labels=security+concern&page=1&state=open 38 - [closed]: https://github.com/mirleft/ocaml-tls/issues?labels=security+concern&page=1&state=closed 39 - [ocaml-tls]: https://github.com/mirleft/ocaml-tls 40 - [understanding_reneg]: http://www.educatedguesswork.org/2009/11/understanding_the_tls_renegoti.html 41 - [heartbleed]: https://en.wikipedia.org/wiki/Heartbleed 42 - [md5_collision]: http://eprint.iacr.org/2005/067 43 - [truncation]: http://www.theregister.co.uk/2013/08/01/gmail_hotmail_hijacking/ 44 - [breach]: http://breachattack.com/ 45 - [RFC5246]: https://tools.ietf.org/html/rfc5246#appendix-D.4 46 - [tls_attacks]: http://eprint.iacr.org/2013/049.pdf 47 - [mitls_attacks]: http://www.mitls.org/wsgi/tls-attacks 48 - [issue31]: https://github.com/mirleft/ocaml-tls/issues/31 49 - 50 - **Timing attacks** 51 - 52 - When the timing characteristics between the common case and the error 53 - case are different, this might potentially leak confidential 54 - information. Timing is a very prominent side-channel and there are a huge 55 - variety of timing attacks on different layers, which are observable by 56 - different attackers. Small differences in timing behaviour might 57 - initially be exploitable only by a local attacker, but advancements to 58 - the attack (e.g. increasing the number of tests) might allow a 59 - remote attacker to filter the noise and exploit the different timing 60 - behaviour. 61 - 62 - **Timing of cryptographic primitives** 63 - 64 - We [already mentioned][nocrypto-intro] [cache][] [timing][cache_timing] 65 - attacks on our AES implementation, and that we use [blinding][] 66 - techniques to mitigate RSA timing attacks. 67 - 68 - By using a memory managed programming language, we open the attack 69 - vector of garbage collector (GC) timing attacks (also mentioned [in 70 - our nocrypto introduction][nocrypto-intro]). 71 - 72 - Furthermore, research has been done on virtual machine side channels 73 - ([l3][], [cross vm][cross_vm] and [cache timing][cache_vm]), which we 74 - will need to study and mitigate appropriately. 75 - 76 - **For the time being we suggest to not use the stack on a multi-tenant 77 - shared host or on a shared host which malicious users might have 78 - access to.** 79 - 80 - [blinding]: https://en.wikipedia.org/wiki/Blinding_(cryptography) 81 - [cache]: http://www.cs.tau.ac.il/~tromer/papers/cache.pdf 82 - [cache_timing]: http://cr.yp.to/antiforgery/cachetiming-20050414.pdf 83 - [l3]: http://eprint.iacr.org/2013/448.pdf 84 - [cross_vm]: http://www.cs.unc.edu/~reiter/papers/2012/CCS.pdf 85 - [cache_vm]: http://fc12.ifca.ai/pre-proceedings/paper_70.pdf 86 - 87 - **Bleichenbacher** 88 - 89 - In 1998, Daniel Bleichenbacher discovered a [timing flaw in the 90 - PKCS1][bleichenbacher] encoding of the premaster secret: the TLS server 91 - failed faster when the padding was wrong than when the decryption 92 - failed. Using this timing, an attacker can run an adaptive chosen 93 - ciphertext attack and find out the plain text of a PKCS1 encrypted 94 - message. In TLS, when RSA is used as the key exchange method, this 95 - leads to discovery of the premaster secret, which is used to derive the 96 - keys for the current session. 97 - 98 - The mitigation is to have both padding and decryption failures use the 99 - exact same amount of time, thus there should not be any data-dependent 100 - branches or different memory access patterns in the code. We 101 - implemented this mitigation in [Handshake_server][answer_client_key_exchange]. 102 - 103 - [bleichenbacher]: http://archiv.infsec.ethz.ch/education/fs08/secsem/Bleichenbacher98.pdf 104 - [answer_client_key_exchange]: https://github.com/mirleft/ocaml-tls/blob/c06cbaaffe49024d8570916b70f7839603a54692/lib/handshake_server.ml#L45 105 - 106 - **Padding oracle and CBC timing** 107 - 108 - [Vaudenay][] discovered a vulnerability involving block ciphers: if an 109 - attacker can distinguish between bad mac and bad padding, recovery of 110 - the plaintext is possible (within an adaptive chosen ciphertext 111 - attack). Another approach using the same issue is to use 112 - [timing][practical] information instead of separate error messages. 113 - Further details are described [here][tls_cbc]. 114 - 115 - The countermeasure, which we implement [here][cbc_mit], is to continue 116 - with the mac computation even though the padding is 117 - incorrect. Furthermore, we send the same alert (`bad_record_mac`) 118 - independent of whether the padding is malformed or the mac is 119 - incorrect. 120 - 121 - [tls_cbc]: https://www.openssl.org/~bodo/tls-cbc.txt 122 - [Vaudenay]: http://www.iacr.org/archive/eurocrypt2002/23320530/cbc02_e02d.pdf 123 - [practical]: http://lasecwww.epfl.ch/memo/memo_ssl.shtml 124 - [cbc_mit]: https://github.com/mirleft/ocaml-tls/blob/c06cbaaffe49024d8570916b70f7839603a54692/lib/engine.ml#L100 125 - 126 - **Lucky 13** 127 - 128 - An advancement of the CBC timing attack was discovered in 2013, named 129 - [Lucky 13][Lucky13]. Due to the fact that the mac is computed over the 130 - plaintext without padding, there is a slight (but measurable) 131 - difference in timing between computing the mac of the plaintext and 132 - computing the fake mac of the ciphertext. This leaks information. We 133 - do not have proper mitigation against Lucky 13 in place yet. You can 134 - find further discussion in [issue 7][issue7] and [pull request 135 - 49][pull49]. 136 - 137 - [Lucky13]: http://www.isg.rhul.ac.uk/tls/Lucky13.html 138 - [issue7]: https://github.com/mirleft/ocaml-tls/issues/7 139 - [pull49]: https://github.com/mirleft/ocaml-tls/pull/49 140 - 141 - **Renegotiation not authenticated** 142 - 143 - In 2009, Marsh Ray published a vulnerability of the TLS protocol which 144 - lets an attacker prepend arbitrary data to a session due to 145 - [unauthenticated renegotiation][understanding_reneg]. The attack 146 - exploits the fact that a renegotiation of ciphers and key material is 147 - possible within a session, and this renegotiated handshake is not 148 - authenticated by the previous handshake. A man in the middle can 149 - initiate a session with a server, send some data, and hand over the 150 - session to a client. Neither the client nor the server can detect the 151 - man in the middle. 152 - 153 - A fix for this issue is the [secure renegotiation extension][RFC5746], 154 - which embeds authenticated data of the previous handshake into the 155 - client and server hello messages. Now, if a man in the middle 156 - initiates a renegotiation, the server will not complete it due to 157 - missing authentication data (the client believes this is the first 158 - handshake). 159 - 160 - We implement and require the secure renegotiation extension by 161 - default, but it is possible to configure `ocaml-tls` to not require 162 - it -- to be able to communicate with servers and 163 - clients which do not support this extension. 164 - 165 - Implementation of the mitigation is on the server side in 166 - [ensure_reneg][] and on the client side in [validate_reneg][]. The 167 - data required for the secure renegotiation is stored in 168 - [`handshake_state`][reneg_state] while sending and receiving Finished 169 - messages. You can find further discussion in [issue 3][issue3]. 170 - 171 - [RFC5746]: https://tools.ietf.org/html/rfc5746 172 - [validate_reneg]: https://github.com/mirleft/ocaml-tls/blob/c06cbaaffe49024d8570916b70f7839603a54692/lib/handshake_client.ml#L50 173 - [ensure_reneg]: https://github.com/mirleft/ocaml-tls/blob/c06cbaaffe49024d8570916b70f7839603a54692/lib/handshake_server.ml#L85 174 - [issue3]: https://github.com/mirleft/ocaml-tls/issues/3 175 - [reneg_state]: https://github.com/mirleft/ocaml-tls/blob/c06cbaaffe49024d8570916b70f7839603a54692/lib/state.ml#L97 176 - 177 - **TLS 1.0 and known-plaintext (BEAST)** 178 - 179 - TLS 1.0 reuses the last ciphertext block as IV in CBC mode. If an attacker 180 - has a (partially) known plaintext, she can find the remaining plaintext. 181 - This is known as the [BEAST][] attack and there is a [long discussion][mozilla-bug] 182 - about mitigations. Our mitigation is to prepend each TLS-1.0 183 - application data fragment with an empty fragment to randomize the IV. 184 - We do this exactly [here][empty_iv]. There is further discussion in 185 - [issue 2][issue2]. 186 - 187 - Our mitigation is slightly different from the 1/n-1 splitting proposed 188 - [here][qualys]: we split every application data frame into a 0 byte 189 - and n byte frame, whereas they split into a 1 byte and a n-1 byte 190 - frame. 191 - 192 - Researchers have exploited this vulnerability in 2011, although it was 193 - known since [2006][]. TLS versions 1.1 and 1.2 use an explicit IV, 194 - instead of reusing the last cipher block on the wire. 195 - 196 - [qualys]: https://community.qualys.com/blogs/securitylabs/2013/09/10/is-beast-still-a-threat 197 - [mozilla-bug]: https://bugzilla.mozilla.org/show_bug.cgi?id=665814 198 - [BEAST]: http://vnhacker.blogspot.co.uk/2011/09/beast.html 199 - [empty_iv]: https://github.com/mirleft/ocaml-tls/blob/c06cbaaffe49024d8570916b70f7839603a54692/lib/engine.ml#L375 200 - [2006]: http://eprint.iacr.org/2006/136 201 - [issue2]: https://github.com/mirleft/ocaml-tls/issues/2 202 - 203 - **Compression and information leakage (CRIME)** 204 - 205 - When using compression on a chosen-plaintext, encrypting this can leak 206 - information, known as [CRIME][crime]. [BREACH][breach] furthermore 207 - exploits application layer compression, such as HTTP compression. We 208 - mitigate CRIME by not providing any TLS compression support, while we 209 - cannot do anything to mitigate BREACH. 210 - 211 - [crime]: http://arstechnica.com/security/2012/09/crime-hijacks-https-sessions/ 212 - 213 - **Traffic analysis** 214 - 215 - Due to limited amount of padding data, the actual size of transmitted 216 - data can be recovered. The mitigation is to implement [length hiding 217 - policies][length_hiding]. This is tracked as [issue 162][issue162]. 218 - 219 - [issue162]: https://github.com/mirleft/ocaml-tls/issues/162 220 - [length_hiding]: http://tools.ietf.org/html/draft-pironti-tls-length-hiding-02 221 - 222 - **Version rollback** 223 - 224 - SSL-2.0 is insecure, a man in the middle can downgrade the version to 225 - SSL-2.0. The mitigation we implement is that we do not support 226 - SSL-2.0, and thus cannot be downgraded. Also, we check that the 227 - version of the client hello matches the first two bytes in the 228 - premaster secret [here][client_version]. You can find further discussion in 229 - [issue 5][issue5]. 230 - 231 - [client_version]: https://github.com/mirleft/ocaml-tls/blob/c06cbaaffe49024d8570916b70f7839603a54692/lib/handshake_server.ml#L55 232 - [issue5]: https://github.com/mirleft/ocaml-tls/issues/5 233 - 234 - **Triple handshake** 235 - 236 - A vulnerability including session resumption and renegotiation was 237 - discovered by the [miTLS team][mitls], named [triple 238 - handshake][triple]. Mitigations include disallowing renegotiation, 239 - disallowing modification of the certificate during renegotiation, or 240 - a hello extension. Since we do not support session resumption yet, we 241 - have not yet implemented any of the mentioned mitigations. There is 242 - further discussion in [issue 9][issue9]. 243 - 244 - [mitls]: http://www.mitls.org 245 - [issue9]: https://github.com/mirleft/ocaml-tls/issues/9 246 - [triple]: https://secure-resumption.com/ 247 - 248 - **Alert attack** 249 - 250 - A [fragment of an alert][alert_attack] can be sent by a man in the 251 - middle during the initial handshake. If the fragment is not cleared 252 - once the handshake is finished, the authentication of alerts is 253 - broken. This was discovered in 2012; our mitigation is to discard 254 - fragmented alerts. 255 - 256 - [alert_attack]: http://www.mitls.org/wsgi/alert-attack 257 - 258 - ### EOF. 259 - 260 - Within six months, two hackers managed to develop a clean-slate TLS 261 - stack, together with required crypto primitives, ASN.1, and X.509 262 - handling, in a high-level pure language. We interoperate with widely 263 - deployed TLS stacks, as shown by our [demo server][demo]. The code 264 - size is nearly two orders of magnitude smaller than OpenSSL, the most 265 - widely used open source library (written in C, which a lot of 266 - programming languages wrap instead of providing their own TLS 267 - implementation). Our code base seems to be robust -- the [demo 268 - server][demo] successfully finished over 22500 sessions in less than a 269 - week, with only 11 failing traces. 270 - 271 - There is a huge need for high quality TLS implementations, because 272 - several TLS implementations suffered this year from severe security 273 - problems, such as [heartbleed][], [goto fail][CVE-2014-1266], [session 274 - id][CVE-2014-3466], [Bleichenbacher][java], [change cipher 275 - suite][CVE-2014-0224] and [GCM DoS][polar]. The main cause is 276 - implementation complexity due to lack of abstraction, and memory 277 - safety issues. 278 - 279 - We still need to address some security issues, and improve our performance. We 280 - invite people to do rigorous code audits (both manual and automated) and try 281 - testing our code in their services. 282 - 283 - **Please be aware that this release is a *beta* and is missing external code audits. 284 - It is not yet intended for use in any security critical applications.** 285 - 286 - [demo]: https://tls.openmirage.org 287 - [polar]: https://polarssl.org/tech-updates/security-advisories/polarssl-security-advisory-2014-02 288 - [java]: http://armoredbarista.blogspot.de/2014/04/easter-hack-even-more-critical-bugs-in.html 289 - [CVE-2014-1266]: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-1266 290 - [CVE-2014-3466]: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-3466 291 - [CVE-2014-0224]: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-0224 292 - 293 - [nocrypto-intro]: http://openmirage.org/blog/introducing-nocrypto
-249
design.md
··· 1 - ### The OCaml-TLS architecture 2 - 3 - The OCaml ecosystem has several distinct ways of interacting with the outside world 4 - (and the network in particular): straightforward [unix][ocaml-unix] interfaces 5 - and the asynchronous programming libraries [lwt][] and [async][]. One of the 6 - early considerations was not to restrict ourselves to any of those -- we wanted 7 - to support them all. 8 - 9 - There were also two distinct basic "platforms" we wanted to target from the 10 - outset: the case of a simple executable, and the case of `Mirage` unikernels. 11 - 12 - So one of the first questions we faced was deciding how to represent 13 - interactions with the network in a portable way. This can be done by 14 - systematically abstracting out the API boundary which gives access to network 15 - operations, but we had a third thing in mind as well: we wanted to exploit the 16 - functional nature of OCaml to its fullest extent! 17 - 18 - Our various prior experiences with Haskell and Idris convinced us to adopt 19 - what is called "purely functional" technique. We believe it to be an approach 20 - which first forces the programmer to give principled answers to all the 21 - difficult design questions (errors and global data-flow) *in advance*, and then 22 - leads to far cleaner and composable code later on. A purely functional system 23 - has all the data paths made completely explicit in the form of function 24 - arguments and results. There are no unaccounted-for interactions between 25 - components mediated by shared state, and all the activity of the parts of the 26 - system is exposed through types since, after all, it's only about computing 27 - values from values. 28 - 29 - For these reasons, the library is split into two parts: the directory `/lib` 30 - (and the corresponding findlib package `tls`) contains the core TLS logic, and 31 - `/mirage` and `/lwt` (packaged as `tls.mirage` and `tls.lwt` respectively) 32 - contain front-ends that tie the core to `Mirage` and `Lwt_unix`. 33 - 34 - [ocaml-unix]: http://caml.inria.fr/pub/docs/manual-ocaml/libref/Unix.html 35 - [lwt]: http://ocsigen.org/lwt/ 36 - [async]: https://realworldocaml.org/v1/en/html/concurrent-programming-with-async.html 37 - 38 - ### Core 39 - 40 - The [core][tls-engine-mli] library is purely functional. A TLS session is represented by the 41 - abstract type `Tls.Engine.state`, and various functions consume this session 42 - type together with raw bytes (`Cstruct.t` -- which is by itself mutable, but 43 - `ocaml-tls` eschews this) and produce new session values and resulting buffers. 44 - 45 - The central entry point is [handle_tls][], which transforms an input state and a 46 - buffer to an output state, a (possibly empty) buffer to send to the 47 - communication partner, and an optional buffer of data intended to be received by 48 - the application: 49 - 50 - ```OCaml 51 - type state 52 - 53 - type ret = [ 54 - | `Ok of [ `Ok of state | `Eof | `Alert of alert ] * 55 - [ `Response of Cstruct.t ] * [ `Data of Cstruct.t option ] 56 - | `Fail of alert * [ `Response of Cstruct.t ] 57 - ] 58 - 59 - val handle_tls : state -> Cstruct.t -> ret 60 - ``` 61 - 62 - As the signature shows, errors are signalled through the `ret` type, which is a [polymorphic variant][poly]. This 63 - reflects the actual internal structure: all the errors are represented as 64 - values, and operations are composed using an error [monad][monad-ml]. 65 - 66 - Other entry points share the same basic behaviour: they transform the prior 67 - state and input bytes into the later state and output bytes. 68 - 69 - Here's a rough outline of what happens in `handle_tls`: 70 - 71 - - TLS packets consist of a header, which contains the protocol 72 - version, length, and content type, and the payload of the given 73 - content type. Once inside our [main handler][handle_tls], we 74 - [separate][separate_records] the buffer into TLS records, and 75 - [process][handle_raw_record] each individually. We first check that 76 - the version number is correct, then [decrypt][decrypt], and [verify 77 - the mac][verify_mac]. 78 - 79 - - Decrypted data is then [dispatched][handle_packet] to one of four 80 - sub-protocol handlers (Handshake, Change Cipher Spec, Alert and 81 - Application Data). Each handler can [return][return_types] a new 82 - handshake state, outgoing data, application data, the new decryption 83 - state or an error (with the outgoing data being an interleaved list 84 - of buffers and new encryption states). 85 - 86 - - The outgoing buffers and the encryption states are 87 - [traversed][encrypt] to produce the final output to be sent to the 88 - communication partner, and the final encryption, decryption and 89 - handshake states are combined into a new overall state which is 90 - returned to the caller. 91 - 92 - Handshake is (by far) the most complex TLS sub-protocol, with an elaborate state 93 - machine. Our [client][client_handshake] and [server][server_handshake] encode 94 - this state as a "flat" [sum type][handshake_states], with exactly one incoming 95 - message allowed per state. The handlers first [parse][parse_handshake] the 96 - handshake packet (which fails in case of malformed or unknown data) and then 97 - dispatch it to the handling function. The [handshake state][handshake_state] is 98 - carried around and a fresh one is returned from the handler in case it needs 99 - updates. It consists of a protocol version, the handshake state, configuration, 100 - renegotiation data, and possibly a handshake fragment. 101 - 102 - Logic of both handshake handlers is very localised, and does not mutate any 103 - global data structures. 104 - 105 - [poly]: https://realworldocaml.org/v1/en/html/variants.html#polymorphic-variants 106 - [monad-ml]: https://github.com/mirleft/ocaml-tls/blob/6dc9258a38489665abf2bd6cdbed8a1ba544d522/lib/control.ml 107 - [return_types]: https://github.com/mirleft/ocaml-tls/blob/6dc9258a38489665abf2bd6cdbed8a1ba544d522/lib/state.ml#L109 108 - [encrypt]: https://github.com/mirleft/ocaml-tls/blob/6dc9258a38489665abf2bd6cdbed8a1ba544d522/lib/engine.ml#L48 109 - [handle_packet]: https://github.com/mirleft/ocaml-tls/blob/6dc9258a38489665abf2bd6cdbed8a1ba544d522/lib/engine.ml#L240 110 - [verify_mac]: https://github.com/mirleft/ocaml-tls/blob/6dc9258a38489665abf2bd6cdbed8a1ba544d522/lib/engine.ml#L85 111 - [decrypt]: https://github.com/mirleft/ocaml-tls/blob/6dc9258a38489665abf2bd6cdbed8a1ba544d522/lib/engine.ml#L95 112 - [handle_tls]: https://github.com/mirleft/ocaml-tls/blob/6dc9258a38489665abf2bd6cdbed8a1ba544d522/lib/engine.ml#L321 113 - [handle_raw_record]: https://github.com/mirleft/ocaml-tls/blob/6dc9258a38489665abf2bd6cdbed8a1ba544d522/lib/engine.ml#L275 114 - [separate_records]: https://github.com/mirleft/ocaml-tls/blob/6dc9258a38489665abf2bd6cdbed8a1ba544d522/lib/engine.ml#L150 115 - 116 - [handshake_state]: https://github.com/mirleft/ocaml-tls/blob/6dc9258a38489665abf2bd6cdbed8a1ba544d522/lib/state.ml#L92 117 - [parse_handshake]: https://github.com/mirleft/ocaml-tls/blob/6dc9258a38489665abf2bd6cdbed8a1ba544d522/lib/reader.ml#L361 118 - [separate_handshakes]: https://github.com/mirleft/ocaml-tls/blob/6dc9258a38489665abf2bd6cdbed8a1ba544d522/lib/engine.ml#L217 119 - [handshake_states]: https://github.com/mirleft/ocaml-tls/blob/6dc9258a38489665abf2bd6cdbed8a1ba544d522/lib/state.ml#L61 120 - [server_handshake]: https://github.com/mirleft/ocaml-tls/blob/6dc9258a38489665abf2bd6cdbed8a1ba544d522/lib/handshake_server.ml#L247 121 - [client_handshake]: https://github.com/mirleft/ocaml-tls/blob/6dc9258a38489665abf2bd6cdbed8a1ba544d522/lib/handshake_client.ml#L285 122 - 123 - ### Core API 124 - 125 - OCaml permits the implementation a module to be exported via a more 126 - abstract *signature* that hides the internal representation 127 - details. Our public API for the core library consists of the 128 - [Tls.Engine][tls-engine-mli] and [Tls.Config][tls-config-mli] modules. 129 - 130 - `Tls.Engine` contains the basic reactive function `handle_tls`, mentioned above, 131 - which processes incoming data and optionally produces a response, together with 132 - several operations that allow one to initiate message transfer like 133 - `send_application_data` (which processes application-level messages for 134 - sending), `send_close_notify` (for sending the ending message) and `reneg` 135 - (which initiates full TLS renegotiation). 136 - 137 - The module also contains the only two ways to obtain the initial state: 138 - 139 - ```OCaml 140 - val client : Config.client -> (state * Cstruct.t) 141 - val server : Config.server -> state 142 - ``` 143 - 144 - That is, one needs a configuration value to create it. The `Cstruct.t` 145 - that `client` emits is the initial Client Hello since in TLS, 146 - the client starts the session. 147 - 148 - `Tls.Config` synthesizes configurations, separately for client and server 149 - endpoints, through the functions `client_exn` and `server_exn`. They take a 150 - number of parameters that define a TLS session, check them for consistency, and 151 - return the sanitized `config` value which can be used to create a `state` and, 152 - thus, a session. If the check fails, they raise an exception. 153 - 154 - The parameters include the pair of a certificate and its private key for the 155 - server, and an `X509.Authenticator.t` for the client, both produced by our 156 - [ocaml-x509][] library and described in a [previous article][x509-intro]. 157 - 158 - This design reflects our attempts to make the API as close to "fire and forget" 159 - as we could, given the complexity of TLS: we wanted the library to be relatively 160 - straightforward to use, have a minimal API footprint and, above all, fail very 161 - early and very loudly when misconfigured. 162 - 163 - [tls-engine-mli]: https://github.com/mirleft/ocaml-tls/blob/6dc9258a38489665abf2bd6cdbed8a1ba544d522/lib/engine.mli 164 - 165 - [tls-config-mli]: https://github.com/mirleft/ocaml-tls/blob/6dc9258a38489665abf2bd6cdbed8a1ba544d522/lib/config.mli 166 - 167 - [ocaml-x509]: https://github.com/mirleft/ocaml-x509 168 - 169 - 170 - ### Effectful front-ends 171 - 172 - Clearly, reading and writing network data *does* change the state of the world. 173 - Having a pure value describing the state of a TLS session is not really useful 174 - once we write something onto the network; it is certainly not the case that we 175 - can use more than one distinct `state` to process further data, as only one 176 - value is in sync with the other endpoint at any given time. 177 - 178 - Therefore we wrap the core types into stateful structures loosely inspired by 179 - sockets and provide IO operations on those. The structures of `mirage` and `lwt` 180 - front-ends mirror one another. 181 - 182 - In both cases, the structure is pull-based in the sense that no processing is 183 - done until the client requires a read, as opposed to a callback-driven design 184 - where the client registers a callback and the library starts spinning in a 185 - listening loop and invoking it as soon as there is data to be processed. We do 186 - this because in an asynchronous context, it is easy to create a callback-driven 187 - interface from a demand-driven one, but the opposite is possible only with 188 - unbounded buffering of incoming data. 189 - 190 - One exception to demand-driven design is the initial session creation: the 191 - library will only yield the connection after the first handshake is over, 192 - ensuring the invariant that it is impossible to interact with a connection if it 193 - hasn't already been fully established. 194 - 195 - **Mirage** 196 - 197 - The `Mirage` [interface][tls_mirage_types_mli] matches the [FLOW][flow] 198 - signature (with additional TLS-specific operations). We provide a functor that 199 - needs to be applied to an underlying TCP module, to obtain a TLS transport on 200 - top. For example: 201 - 202 - ```OCaml 203 - module Server (Stack: STACKV4) (KV: KV_RO) = 204 - struct 205 - 206 - module TLS = Tls_mirage.Make (Stack.TCPV4) 207 - module X509 = Tls_mirage.X509 (KV) (Clock) 208 - 209 - let accept conf flow = 210 - TLS.server_of_tcp_flow conf flow >>= function 211 - | `Ok tls -> 212 - TLS.read tls >>= function 213 - | `Ok buf -> 214 - TLS.write tls buf >>= fun () -> TLS.close buf 215 - 216 - let start stack e kv = 217 - lwt authenticator = X509.authenticator kv `Default in 218 - let conf = Tls.Config.server_exn ~authenticator () in 219 - Stack.listen_tcpv4 stack 4433 (accept conf) ; 220 - Stack.listen stack 221 - 222 - end 223 - ``` 224 - 225 - **Lwt** 226 - 227 - The `lwt` interface has [two layers][tls_lwt_mli]. `Tls_lwt.Unix` is loosely based 228 - on read/write operations from `Lwt_unix` and provides in-place update of 229 - buffers. `read`, for example, takes a `Cstruct.t` to write into and returns the 230 - number of bytes read. The surrounding module, `Tls_lwt`, provides a simpler, 231 - `Lwt_io`-compatible API built on top: 232 - 233 - ```OCaml 234 - let main host port = 235 - lwt authenticator = X509_lwt.authenticator (`Ca_dir nss_trusted_ca_dir) in 236 - lwt (ic, oc) = Tls_lwt.connect ~authenticator (host, port) in 237 - let req = String.concat "\r\n" [ 238 - "GET / HTTP/1.1" ; "Host: " ^ host ; "Connection: close" ; "" ; "" 239 - ] in 240 - Lwt_io.(write oc req >>= fun () -> read ic >>= print) 241 - ``` 242 - 243 - We have further plans to provide wrappers for [`Async`][async] and plain [`Unix`][ocaml-unix] in a 244 - similar vein. 245 - 246 - [tls_mirage_types_mli]: https://github.com/mirleft/ocaml-tls/blob/6dc9258a38489665abf2bd6cdbed8a1ba544d522/mirage/tls_mirage_types.mli 247 - [flow]: https://github.com/mirage/mirage/blob/ae3c966f8d726dc97208595b8005e02e39478cb1/types/V1.mli#L136 248 - [example_unikernel]: https://github.com/mirleft/ocaml-tls/blob/6dc9258a38489665abf2bd6cdbed8a1ba544d522/mirage/example/unikernel.ml 249 - [tls_lwt_mli]: https://github.com/mirleft/ocaml-tls/blob/6dc9258a38489665abf2bd6cdbed8a1ba544d522/lwt/tls_lwt.mli
-61
sni.md
··· 1 - ### Server Name Indication 2 - 3 - Some TLS servers might want to provide service for various services, 4 - all on the same port, but with different names. The SNI extension 5 - allows a client to request a specific server name. The server may use 6 - the requested server name to select the X.509 certificate chain which 7 - it presents to the client. 8 - 9 - ### Configuration interface 10 - 11 - A user provides a full certificate chain and a private key 12 - corresponding to the first certificate in the list to OCaml-TLS, 13 - captured by the type `certchain`. 14 - 15 - ```` 16 - type certchain = Certificate.certificate list * Nocrypto.Rsa.priv 17 - ```` 18 - 19 - The `own_cert` polymorphic variant covers the various configuration 20 - options: either no certificate is provided, a single one, multiple 21 - ones (whose common name/subject alternative name are used for 22 - disambiguation), and multiple with a default one. 23 - 24 - ```` 25 - type own_cert = [ 26 - | `None 27 - | `Single of certchain 28 - | `Multiple of certchain list 29 - | `Multiple_default of certchain * certchain list 30 - ] 31 - 32 - ```` 33 - 34 - ### Validation 35 - 36 - The configuration of certificates is intertwined with ciphersuites: 37 - each ciphersuite which requires a certificate furthermore depends on 38 - properties of this certificate - RSA and DHE_RSA require the key to be 39 - RSA, RSA requires the X.509v3 extension key_usage to contain 40 - encipherment, DHE_RSA requires key_usage to contain digital_signature. 41 - There must exist at least one certificate with the mentioned 42 - properties for each configured ciphersuite. 43 - 44 - Furthermore, to avoid ambiguity, the hostnames in ``Multiple` and 45 - ``Multiple_default` certificate lists must be non-overlapping. 46 - 47 - ### Certificate selection 48 - 49 - If the server is configured with only a default certificate, this is 50 - always used. 51 - 52 - If the client does not request for a server name, the default 53 - certificate is used. 54 - 55 - If the client requests a specific server name: 56 - - find a strict match 57 - - find a wildcard match 58 - - use the default one if present 59 - 60 - Only after a certificate is set for the session, the ciphersuite is 61 - selected, depending on the properties of the certificate.