open Lwt.Syntax
open Xml
exception TLSError
(** [STARTTLSFailure] is thrown if the server doesn't allow the STARTTLS negotiation to
proceed, either by sending back a [] or by unspecified behavior. *)
exception STARTTLSFailure
(** [stanza] is a correct [] stanza as a stream of signals. *)
let stanza =
Markup.of_list
[`Start_element
((Xmlns.tls, "starttls"),
[(("http://www.w3.org/2000/xmlns/", "xmlns"), Xmlns.tls)]);
`End_element]
(** [parse_reply response] parses [response] as a STARTTLS handshake reply. *)
let parse_reply response =
match response with
| {namespace=ns; local_name="proceed";
attributes=[]; children=[]} when ns = Xmlns.tls -> `Proceed
| {namespace=ns; local_name="failure";
attributes=[]; children=[]} when ns = Xmlns.tls -> `Failure
| _ -> `Error
(** [upgrade portal] upgrades the Portal to STARTTLS. *)
let upgrade (portal : Portal.t) : unit Lwt.t =
portal.push (Some stanza);
let* response = Wire.get portal.stream
in match parse_reply response with
| `Failure | `Error -> Lwt.fail STARTTLSFailure
| `Proceed -> Portal.starttls portal