使用ocaml-cohttp Client.post方法请求HTTPS服务器时,如何调试HANDSHAKE_FAILURE? (为什么我会收到此错误?)

时间:2018-10-16 08:16:18

标签: unix ssl https ocaml

我编写了以下OCaml代码,以便向 https 服务器发出 POST 请求。

open Lwt
open Cohttp
open Cohttp_lwt_unix

try
    let headers = Header.init ()
    |> fun h -> Header.add h "content-type" "application/json" in
    let body = Client.post
      ~headers
      ~body:(body_of_credentials nickname secret)
      (uri_of_project project)
    >>= fun (response, body) ->
      let code = response |> Response.status |> Code.code_of_status in
      Printf.printf "Response code: %d\n" code;
      Printf.printf "Headers: %s\n" (response |> Response.headers |> Header.to_string);
      body |> Cohttp_lwt.Body.to_string >|= fun body ->
      Printf.printf "Body of length: %d\n" (String.length body);
      body
    in

    let body = Lwt_main.run body in
      print_endline ("Received body\n" ^ body)

  with
  | Tls_lwt.Tls_alert e ->
    print_endline (Tls.Packet.alert_type_to_string e);
    exit 1

但是当用CONDUIT_TLS=native CONDUIT_DEBUG=true COHTTP_DEBUG=true执行它时,我得到以下响应:

Selected TLS library: Native
Resolver system: https://my_server/auth/tokens/ ((name https) (port 443) (tls true)) -> (TCP ((V4 xx.xxx.xx.xxx) 443))
HANDSHAKE_FAILURE

我已经阅读了所有的Google搜索结果(文档,ocaml / cohttp / ocaml-tls列表和堆栈溢出问题),但没有任何帮助,因此我想从头开始。

如何获得有关此失败的更多详细信息?

如果有帮助,我将使用以下opam配置:

"lwt" {>= "4.1.0"}
"cohttp" {>= "1.1.1"}
"cohttp-lwt"
"cohttp-lwt-unix" {>= "1.1.1"}
"tls" {>= "0.9.2"}

编辑: 如@ivg所建议,我尝试使用CONDUIT_TLS=openssl,但随后收到以下错误消息:

Selected TLS library: OpenSSL
Resolver system: https://my_server/auth/tokens/ ((name https) (port 443) (tls true)) -> (TCP ((V4 xx.xxx.xx.xxx) 443))
...: internal error, uncaught exception:
    SSL: Method error

EDIT²: 如以下讨论中所建议:github.com/savonet/ocaml-ssl/issues/40我向ssl-0.5.5opam pin add ssl 0.5.5添加了一个opam针,以解决此错误。现在,我可以将请求发布到我的https服务器,但是不能使用tls的纯ocaml实现。

1 个答案:

答案 0 :(得分:2)

由于握手过程(身份验证)失败,您将收到此警报。此警报意味着对等方(服务器或客户端)未通过身份验证,因此无法建立安全连接。

要调试该问题,我首先建议确保所有情况都可以使用常规工具(例如opensslwgetcurl)正常运行。

如果您确定配置正确,并且这是ocaml-tls部分的问题,我建议您使用ocaml-tls库的低级接口。显然,conduit不会公开或使用ocaml-tls的任何跟踪功能,因此没有其他选择。

警报类型是从两种更丰富的fatalerror类型中投射出来的,它们具有有关问题性质的更多信息,请参见。 following code会创建警报,并考虑可能导致HANDSHAKE_FAILURE警报的输入值。

要访问特定的错误或警报,建议您使用ocaml-tls的跟踪功能。源存储库中的are examples已启用跟踪并应提供足够的信息。我希望这些示例适合您的用例。