Code Monkey home page Code Monkey logo

mint's People

Contributors

ahamez avatar amatalai avatar aquageek avatar bismark avatar dsdshcym avatar dunyakokoschka avatar ericmj avatar exit9 avatar gamache avatar howleysv avatar jayjun avatar jmmk avatar josevalim avatar kianmeng avatar lucaspiller avatar lukebakken avatar mruoss avatar myobie avatar paulswartz avatar pvthuyen avatar qcam avatar scohen avatar slashmili avatar tcrossland avatar the-mikedavis avatar voltone avatar vrcca avatar whatyouhide avatar wojtekmach avatar xanderificnl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mint's Issues

IDNA support

We might want to have a separate library that deals with IDNA and either explain to users how to use it with Mint, or have an interface in Mint that users can adapt to.

Opened this issue from #42.

Fix tests for OTP 21.3

Lots of failures related to the change in formatting of TLS alerts. For example:

  2) test ssl certificate verification bad certificate - badssl.com (Mint.IntegrationTest)
     test/mint/integration_test.exs:78
     match (=) failed
     code:  assert {:error, %TransportError{reason: {:tls_alert, 'unknown ca'}}} = HTTP.connect(:https, "untrusted-root.badssl.com", 443, transport_opts: [log_alert: false, reuse_sessions: false])
     right: {:error,
             %Mint.TransportError{
               reason: {:tls_alert,
                {:unknown_ca, 'received CLIENT ALERT: Fatal - Unknown CA'}}
             }}
     stacktrace:
       test/mint/integration_test.exs:79: (test)

Properly handle header casing and make it consistent

The HTTP/1 spec (section 4.2 "Message Headers") says:

Field names are case-insensitive.

The HTTP/2 spec (section 8.1.2) says:

Just as in HTTP/1.x, header field names are strings of ASCII characters that are compared in a case-insensitive fashion. However, header field names MUST be converted to lowercase prior to their encoding in HTTP/2. A request or response containing uppercase header field names MUST be treated as malformed (Section 8.1.2.6).

Considering this, we should:

  • HTTP/1: downcase all request headers as soon as the user gives them to use (in request/5 or as trailing headers in stream_request_body/3)
  • HTTP/2: downcase all request headers as soon as the user gives them to use (in request/5 or as trailing headers in stream_request_body/3)
  • HTTP/1: downcase all response headers as soon as they are parsed
  • HTTP/2:
    1. assume response headers are downcased and just go about our way or
    2. check the casing of all response headers and error out if they're not downcase?

Add open_request_count/1

We could add a function that returns the number of open (in-flight) requests. In HTTP/1 this tells the number of pipelined requests. In HTTP/2 this tells the number of open streams and is useful for either checking how many streams you can open and also for testing that we close streams correctly without using the internal structure of the connection in tests.

Find a way to correctly garbage collect HTTP/2 streams

Right now we never clean up HTTP/2 streams. The reason is that a stream in the :closed state is still effectively useful because data might still come on that stream. We ignore that data but still. The problem might be that we keep a request ref to stream ID mapping, because if we didn't have that we could just remove a stream and have like a set of closed stream IDs that we can avoid garbage collecting. But with the request ref to stream ID mapping, we would also need to keep the mapping in place for every closed stream and it might leak too much memory. We need to find a way to fix this.

Passive mode support

There should be a way to support blocking request / responses. The problem I had stemmed from trying to integrate mint as the transport to a db_connection connection process. The active mode {:tcp, ... messages were swallowed by db_connection.

Websockets?

Is support for websockets already planned? It seems like the API would be quite similar to how Mint handles HTTP1/2, and it would be a nice alternative to WebSockex/gun.

Use selective receive instead of receiving whatever the first message in process memory block in the document

Hi,

As per mint's document, the receive block that receives mint's messages are written as below

receive do
  message ->
      case Mint.HTTP.stream(conn, message) do
        :unknown -> handle_normal_message(message)
        {:ok, conn, responses} -> handle_responses(conn, responses)
      end
end 

For the above receive block, I think we should use selective receive block in the library document instead of the one shown above. Since by nature of interprocess communication in BEAM languages, any processes can send messages to any other processes. That means, at any time, there might be other messages in front of the process memory block queue, when we are trying to process mint receive block.

By implementing as suggested by mint's document, we might be fetching some messages that should not be fetched out at the time of executing this mint's receive block.

I think we need to use a more specific pattern to match and fetch only mint's messages out to be handled in all of mint's document.

This suggestion is so that, developers can use (or just copied) it without considering that there are might be some messages in the queue before mint's messages

I have created a post on the elixirforum to ask about this, to get some comments also.

I have got a reply from @jwlander, that we could use pattern as below to do what is wanted.

receive do
  {tag, _, _} = msg when tag in [:tcp, :ssl, :tcp_error, :ssl_error] ->
    process_mint_message(msg)
  {tag, _} = msg when tag in [:tcp_closed, :ssl_closed] ->
    process_mint_message(msg)
end

By doing the selective case as above we are not fetching out any non-mint's messages from the process memory block. Which I think, this should be default case written in all mint document.

I realize that there are some drawbacks in term of performance when doing selective receive like above. As also given by @jwlander in link.

So, I would like to ask about putting selective receive block in the document, instead of the ones shown now. If it's acceptable, I could send a pull request for it.

Best
Dev.

Ciphers are blacklisted that are valid for HTTP/1

The 'safe by default' change #46 introduced restrictions on what cipher suites are used for SSL connections. The HTTP/2 spec specifically blacklists certain ciphers, however some of those are still valid for use with HTTP/1 connections.

It seems a lot of Outlook Web Access ISS servers are configured with 'TLS_RSA_WITH_AES_128_CBC_SHA' which is on the blacklist (as it doesn't support forward secrecy), so trying to connect results in this:

iex(8)> Mint.HTTP.connect(:https, "owa.marriott.com", 443, [protocols: [:http1], transport_opts: [verify: :verify_none]])
{:error, :closed}

Although visiting this site in Chrome says it is secure, Qualys SSL Labs does say the cipher is weak, so I believe the way this is implemented now is the right choice.

But for people like me who just want to make HTTP/1 connections to weaker servers this is a problem. I can pass in a list of ciphers, and update them as new ciphers are supported, but maybe there should be an option to use weaker ciphers in Mint?

Pipe `|` symbol in the path

Hi,

I have some problems with sending a request which contains a | symbol in the path. Even if I encode such request with URI.encode (which would make | look like %7C) Mint refuses to send such request.

What am I doing wrong?

Thank you.

If-Modified-Since header not working with http2 connection

Instead of returning the body and status 304, it return error with reason {:server_closed_request, :protocol_error}.

{:ok, conn} = Mint.HTTP2.connect(:https, "varvy.com", 443)
req_headers = [{"If-Modified-Since", "Wed, 26 May 2019 07:43:40 GMT"}]
{:ok, conn, request_ref} = Mint.HTTP2.request(conn, "GET", "/", req_headers)
next_message =
  receive do
    msg -> msg
  end
{:ok, conn, responses} = Mint.HTTP2.stream(conn, next_message)
next_message =
  receive do
    msg -> msg
  end
{:ok, conn, responses} = Mint.HTTP2.stream(conn, next_message)
# responses => {:error, _ref,
#   %Mint.HTTPError{module: Mint.HTTP2, reason: {:server_closed_request, :protocol_error}
# }}
next_message =
  receive do
    msg -> msg
  end
{:ok, conn, responses} = Mint.HTTP2.stream(conn, next_message)
# 18:38:55.849 [debug] Got frame: {:goaway, 0, 0, 0, :no_error, "timeout"}

Doing the same with Mint.HTTP1 and curl works.

{:ok, conn} = Mint.HTTP1.connect(:https, "varvy.com", 443)
req_headers = [{"If-Modified-Since", "Wed, 26 May 2019 07:43:40 GMT"}]
{:ok, conn, request_ref} = Mint.HTTP1.request(conn, "GET", "/", req_headers)
next_message =
  receive do
    msg -> msg
  end
{:ok, conn, responses} = Mint.HTTP1.stream(conn, next_message)
# response => {:ok, ...}

Related ticked appcues/mojito#24

Safe by default HTTPS

  • Safe by default :ssl options
  • Hostname verification for older OTP versions
  • Partial chains
  • Ship with Mozilla CA store Use castore library instead
  • Task for updating CA store Invalid now that we use a dependency instead
  • Extra credit: add support for nested SSL sessions in OTP

Add caching support

This library looks like a great opportunity to bring HTTP caching support to the BEAM. Because caching requires low level access to the request immediately before it is put on the wire it is hard to add to higher level libraries after the fact.

Adding a cache check and short circuit to request/5 and cache upsert in stream/2 would be awesome. @ericmj, is that something you'd be interested in having in this library? If so, i might be to do/help with the implementation.

Properly set or document the "TE" header with trailers

Mint accepts trailing headers from servers. Should we set the TE header to trailers (or add trailers if the user already provided a TE header)? Or should we just document this and have the user decide if they want to deal with trailing headers?

URL-specific operations

Elixir Core seems not to have library to work with URLs, including last specifications with IDNA, punycodes and all related features.

Hackney utilizes IDNA package for this purposes.

Is there a plan to implement something similar in Elixir, may be to use in XHTTP, or even include it into Elixir Core?

For example, Node.JS has URL API inside it's STL.

If it will be valuable, I can try to implement URL related parts of WHATWG specs as a part of this project, or as a separate project, if it's better.

Document all possible error reasons

We should document all possible error reasons in Mint.TransportError and Mint.HTTPError. For Mint.HTTPError, since each module defines its own error reasons, what we can do is have a @type error_reason() :: ... in each module with documentation for it and just link to those typespecs from Mint.HTTPError.

Provide a way to check for current stream/connection window size in HTTP/2

HTTP/2 has the idea of window size for both each stream and the connection, which is how many bytes you can send to the server. The window size is refilled by the server. This is used to provide flow control. You're not supposed to go over the window size but today we have no way of checking that. If you do, we return an :exceeds_stream_window_size or :exceeds_connection_window_size error but there's no way to prevent that.

Also, today if the user tries to send a bunch of data that goes over a window size, we still send the headers and then error out on the data. That's a bug I think.

scheme and method should be both "atom"

While in the function Http.connect the scheme is an atom of value :http or :https, the method in the function Http.request is a string. Why not use atoms in both cases ?
Is there any special reason ?

I got 400 errors for the last hour because I spelled the method "get" instead of "GET" ~

Return good errors to the user on HTTP/2 protocol errors

Today, on HTTP/2 connection-level errors we send errors like this to the server:

"unable to decode headers: ..."
send_connection_error!(conn, :compression_error, debug_data)

and return {:error, :compression_error} to the user. However as you can see we fill in interesting information in the debug data. I think we should return that information to the user somehow (either in text form or atom form) so that they're able to figure out what's wrong.

Add a page in the docs about dealing with decompression

Any plans to support decompression of gzipped, zipped, or deflated bodies?

I'm not sure how this would actually work with streams, since decompressing using erlang's zlib mostly needs the complete content before decompressing.

I've been bitten by this before and handled it myself after the request, and don't want others to be surprised. If you're interested to support this, I'll be happy to research more and contribute; if not code then maybe a small guide on how the user can handle it.

Proxying

  • CONNECT tunnel HTTP2
  • CONNECT tunnel HTTP1
  • AbsoluteURI HTTP2 (it seems the HTTP2 specs only supports CONNECT proxying so we should probably skip this)
  • AbsoluteURI HTTP1

HTTP1 :unexpected_data for 201 JSON response

This is my first time using Mint, and I immediately ran into an issue. I'm interacting with the Asterisk API and it's returning what looks like valid HTML, but Mint doesn't seem to like it, and I'm not sure why. Here is the error being returned.

Also, my browser renders the response just fine.

{
  :error,
  %Mint.HTTP1{
    buffer: "",
    host: "localhost",
    private: %{},
    request: nil,
    requests: {[], []},
    socket: :a_port, #using an atom for formatting, this was an actual port
    state: :closed,
    transport: Mint.Core.Transport.TCP
  },
  %Mint.HTTPError{
    module: Mint.HTTP1,
    reason: {
      :unexpected_data, "HTTP/1.1 201 Created\r\nServer: IVR\r\nDate: Fri, 12 Apr 2019 14:33:53 GMT\r\nCache-Control: no-cache, no-store\r\nLocation: /ari/playbacks/1b0434a4-f4e6-4c84-95c5-a6ac76643822\r\nContent-type: application/json\r\nContent-Length: 147\r\n\r\n{\"id\":\"1b0434a4-f4e6-4c84-95c5-a6ac76643822\",\"media_uri\":\"sound:hello-world\",\"target_uri\":\"channel:1555079632.10\",\"language\":\"en\",\"state\":\"queued\"}"
    }
  },
  []
}

Stricter error contract

The general error contract in xhttp is currently {:error, term()} which is pretty vague.

Looking through the code I think we can make this stricter to {:error, :inet.posix() | atom()} which is equivalent to {:error, atom()}.

Support trailing headers in requests

The problem

Right now (especially after #179), we support trailing headers in responses (both HTTP/1 and HTTP/2). They're returned as a normal :headers response after the :data (and there can only be one of them). However, we don't support sending trailing headers in requests.

Solution

@ericmj discussed a solution. Right now, we can stream the request body with stream_request_body/3. When you're done streaming the body, you can pass :eof to the stream_request_body/3 function as the body. Our solution consists in adding a {:eof, trailing_headers} possible body value. For example:

{:ok, conn, ref} = # open request
stream_request_body(conn, ref, "foo")
stream_request_body(conn, ref, {:eof, [{"x-trailing", "some value"}]})

For now, we thought about keeping the stream_request_body name because trailing headers are kind of part of the request body and so that we don't need to change the name for a smaller thing. However, we can consider changing the name of this function to something else if the community prefers that way.

Restrict which trailing headers we can send

As per section 4.1.2 of RFC 7230:

A sender must not generate a trailer that contains a field necessary for message framing (e.g., Transfer-Encoding and Content-Length), routing (e.g., Host), request modifiers (e.g., controls and conditionals in Section 5 of [RFC7231]), authentication (e.g., see [RFC7235] and [RFC6265]), response control data (e.g., see Section 7.1 of [RFC7231]), or determining how to process the payload (e.g., Content-Encoding, Content-Type, Content-Range, and Trailer).

Should we error out if any of those headers are sent as trailing headers?

This issue should only be tackled after #186 is merged.

Sometime result response's parts do not include {:status, #Reference<...>, response_code}

Hi,

I am having an issue that sometimes Mint doesn't include {:status, #Reference<...>, response_code} in the response.

Given the code below -

  ## Some code has been removed for simplicity
  alias Mint.HTTP
  

  def handle_info(msg, {conn, request_ref}) do
    case HTTP.stream(conn, msg) do
      :unknown ->
        {:noreply, {conn, request_ref}}

      {:ok, conn, response} ->
        if {:done, request_ref} in response do
          {:data, ^request_ref, result} = List.keyfind(response, :data, 0)
          # Debugging          
          IO.inspect List.keyfind(response, :status, 0)
          # sometimes I get nil
          # sometimes I get {:status,#Reference<...>, 200} 

          {:status, ^request_ref, code} = List.keyfind(response, :status, 0)
          handle_result(code, result)
        end
        {:noreply, {conn, request_ref}}
    end
  end

From the above code, I am using handle_info/2 to handle receive messages. I am using Mint.HTTP.stream/2 to fetch out mint's related values and then handle them per case.

If you see from the code I am waiting until {:done, request_ref} is in the response body by testing {:done, request_ref} in response before I continuing to do something with the response.

The issue is that, sometimes this List.keyfind(response, :status, 0) returns nil. In this case, I am not so sure why the status code's tuple is not there in the result response, which should not be happened. As far as I know, all http responses should have accompanied the status code.

--
Dev

validate_target! throws errors for URL encoded query strings

Query strings (and paths?) can contain URL encoded characters, for example http://localhost:3000?data=%7B%22hello%22%3A%22world%22%7D.

When making a request to an URL like this with Mint, it returns an error as validate_target! deems the URL invalid:

iex(1)> {:ok, conn} = Mint.HTTP.connect(:http, "localhost", 3000)                                                                                                                                                                            
iex(2)> {:ok, conn, request_ref} = Mint.HTTP.request(conn, "GET", "/?data=%7B%22hello%22%3A%22world%22%7D", [], "")
** (MatchError) no match of right hand side value: {:error, %Mint.HTTP1{buffer: "", host: "localhost", private: %{}, request: nil, requests: {[], []}, socket: #Port<0.1027>, state: :open, transport: Mint.Core.Transport.TCP}, :invalid_request_target}

The test for this gives the example of a path / /, however curl happily makes a request for this, so is this validation even needed?

$ curl -v "http://localhost:3000/ /"                                                                                                                                                                     
> GET / / HTTP/1.1
> Host: localhost:3000
> User-Agent: curl/7.64.0
> Accept: */*
> 
< HTTP/1.1 400 Bad Request

How to handle redirects

I'm writing a system that will stream huge files and cutout ranges of bytes. I have the streaming method from the examples:

  def read_huge_file(url) do
    uri = URI.parse(url)
    {:ok, conn} = Mint.HTTP.connect(String.to_atom(uri.scheme), uri.host, uri.port)
    {:ok, conn, _request_ref} = Mint.HTTP.request(conn, "GET", uri.path || "/", [])

    receive_and_stream(conn)
  end
  defp handle(conn, ...) do
    # Do cutout stuff or other things with other handle method matches...
  end 
  defp handle(
         conn,
         [
           {:status, _, status},
           {:headers, _, headers},
           {:done, _}
         ]
       )
       when status > 300 and status < 400 do
    location_header = headers |> Enum.find(&match?({"location", _}, &1))

    IO.puts("Checking for redirect...")

    # Do I need to close it when :done is set?
    {:ok, _} = Mint.HTTP.close(conn)

    if is_nil(location_header) do
      raise "No redirect location found."
    else
      location = location_header |> elem(1)
      IO.puts("Moving on to #{location}")
      location |> read_huge_file()
    end
  end
  defp receive_and_stream(conn) do
    receive do
      message ->
        case Mint.HTTP.stream(conn, message) do
          :unknown -> handle_unknown(conn, message)
          {:ok, conn, response} -> 
              handle(conn, response, do_not_scale_image_data, remove_checksums)
              receive_and_stream(conn)
        end
    end
  end

The problem is that when the redirect handle method matches, it opens another connection and then the existing process receives an :unknown. Do I need to handle it differently? Should I somehow kill the existing process when a new connection is made?

Thanks!

SSL Error

Given the following CACerts, Certificate and Host the following SSL Error is produced:

CaCerts

Certificate Content (First the full Certificate List was used which didn't work as well)
SwissSign Gold CA - G2
======================
-----BEGIN CERTIFICATE-----
MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNVBAYTAkNIMRUw
EwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2lnbiBHb2xkIENBIC0gRzIwHhcN
MDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBFMQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dp
c3NTaWduIEFHMR8wHQYDVQQDExZTd2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0B
AQEFAAOCAg8AMIICCgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUq
t2/876LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+bbqBHH5C
jCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c6bM8K8vzARO/Ws/BtQpg
vd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqEemA8atufK+ze3gE/bk3lUIbLtK/tREDF
ylqM2tIrfKjuvqblCqoOpd8FUrdVxyJdMmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvR
AiTysybUa9oEVeXBCsdtMDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuend
jIj3o02yMszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69yFGkO
peUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPiaG59je883WX0XaxR
7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxMgI93e2CaHt+28kgeDrpOVG2Y4OGi
GqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUw
AwEB/zAdBgNVHQ4EFgQUWyV7lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64
OfPAeGZe6Drn8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov
L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe645R88a7A3hfm
5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczOUYrHUDFu4Up+GC9pWbY9ZIEr
44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOf
Mke6UiI0HTJ6CVanfCU2qT1L2sCCbwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6m
Gu6uLftIdxf+u+yvGPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxp
mo/a77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCChdiDyyJk
vC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid392qgQmwLOM7XdVAyksLf
KzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEppLd6leNcG2mqeSz53OiATIgHQv2ieY2Br
NU0LbbqhPcCT4H8js1WtciVORvnSFu+wZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6Lqj
viOvrv1vA+ACOzB2+httQc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
-----END CERTIFICATE-----

Server Certificate

Certificate Content
Certificate chain
 0 s:/C=CH/ST=St. Gallen/L=St. Gallen/O=JOSHMARTIN GmbH/CN=*.joshmartin.ch
   i:/C=CH/O=SwissSign AG/CN=SwissSign Server Gold CA 2014 - G22
-----BEGIN CERTIFICATE-----
MIIHJjCCBg6gAwIBAgIUFvX2oZTCc478FnW6i4PLjdGnzgYwDQYJKoZIhvcNAQEL
BQAwUjELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEsMCoGA1UE
AxMjU3dpc3NTaWduIFNlcnZlciBHb2xkIENBIDIwMTQgLSBHMjIwHhcNMTgwMzAx
MTAxMDUyWhcNMjAwMzAxMTAxMDUyWjBrMQswCQYDVQQGEwJDSDETMBEGA1UECBMK
U3QuIEdhbGxlbjETMBEGA1UEBxMKU3QuIEdhbGxlbjEYMBYGA1UEChMPSk9TSE1B
UlRJTiBHbWJIMRgwFgYDVQQDDA8qLmpvc2htYXJ0aW4uY2gwggIiMA0GCSqGSIb3
DQEBAQUAA4ICDwAwggIKAoICAQCWCpBh8NhMyXf44LHR9HT37Qc91NmuYfQLZvX1
LPmdJE0HMAAIVPCFF0PwCi948i3dzO3fcrFkoc8se1UncFcsFnEOUV8RT8iFWCaF
+O7PJpLDX+hoB+3jiJHmhqppaW5SpjevAs41ojpXbtwagfWAg64rIam54Vj5fk64
JONLDlkIRcUpyV0QGdCiyAgYiEG9iImGV8cEKReJQ495OAnTdhNq21VaWu8Y8/AR
INS5uMbaHl+0FFxw5gG6vXp+rGr9m0g4R40vGXyWAGMse2BL0GZcyv+nMdMNaKOg
0d+aBZWLZE0y1KVwXyZ8Ag8ExNI2dmeyW0uKe97AxQXP8eXXLnOBR1CrcWpJqhI5
PG1UmcDr8/YWbcZ5u4eyvogwRcKEXAvJNjYjNt55NgzqzVo2lW8MtmcNAO6WtMIp
BA76iWG+7dSAPUQP1geMWQmqpuZvQWOs7m3idDRRorUjZ/Icknb/kyN38fqwxfy2
nqzIWCnQaEUJMmp0F6z4LLZCrTQcZdhuEkF6yLNQe4GeLxHsrI+s9vOUkTXdx7y2
19bKtmcFiKKOQVvg1XIWtEgYuspSdlYmX+Hyo+3m/JZ8zuiZBZcTYxwaTSWMBg3D
ktkdrg1WBlKiLFG5CQmsnKq3c27BZMkMyqBqnP+fq4AmNEFXxCGbzAkQSuyvqrjA
rQ9XowIDAQABo4IC2TCCAtUwKQYDVR0RBCIwIIIPKi5qb3NobWFydGluLmNogg1q
b3NobWFydGluLmNoMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcD
AQYIKwYBBQUHAwIwHQYDVR0OBBYEFJd+YO9mpNO11TEwuX5892zGuc2iMB8GA1Ud
IwQYMBaAFOfx5/0uU60R5YEaV6RzjxJ9mMiuMIH/BgNVHR8EgfcwgfQwR6BFoEOG
QWh0dHA6Ly9jcmwuc3dpc3NzaWduLm5ldC9FN0YxRTdGRDJFNTNBRDExRTU4MTFB
NTdBNDczOEYxMjdEOThDOEFFMIGooIGloIGihoGfbGRhcDovL2RpcmVjdG9yeS5z
d2lzc3NpZ24ubmV0L0NOPUU3RjFFN0ZEMkU1M0FEMTFFNTgxMUE1N0E0NzM4RjEy
N0Q5OEM4QUUlMkNPPVN3aXNzU2lnbiUyQ0M9Q0g/Y2VydGlmaWNhdGVSZXZvY2F0
aW9uTGlzdD9iYXNlP29iamVjdENsYXNzPWNSTERpc3RyaWJ1dGlvblBvaW50MF8G
A1UdIARYMFYwVAYJYIV0AVkBAgEGMEcwRQYIKwYBBQUHAgEWOWh0dHA6Ly9yZXBv
c2l0b3J5LnN3aXNzc2lnbi5jb20vU3dpc3NTaWduLUdvbGQtQ1AtQ1BTLnBkZjCB
1QYIKwYBBQUHAQEEgcgwgcUwZAYIKwYBBQUHMAKGWGh0dHA6Ly9zd2lzc3NpZ24u
bmV0L2NnaS1iaW4vYXV0aG9yaXR5L2Rvd25sb2FkL0U3RjFFN0ZEMkU1M0FEMTFF
NTgxMUE1N0E0NzM4RjEyN0Q5OEM4QUUwXQYIKwYBBQUHMAGGUWh0dHA6Ly9nb2xk
LXNlcnZlci1nMi5vY3NwLnN3aXNzc2lnbi5uZXQvRTdGMUU3RkQyRTUzQUQxMUU1
ODExQTU3QTQ3MzhGMTI3RDk4QzhBRTANBgkqhkiG9w0BAQsFAAOCAQEAYEBBZKe/
LzeH8AOM+IMMIWhE8LOOKaXmVLibIYyhIrvXgAxv7jZnqlcLEVehXRigYGILRj9C
2PR46o2YTWzuLTDmGtlsZczkNOMtyEA5332eth8lhodd3vVe2/LKQHLoit/3wXFf
SDKhEmNNJ7vPDIXFOPOEVkuheoqyyirOxJ5PEI0nPxkMB9pC6Vc9gs3LZvLqk21W
L6qObSVqkg1KrRoCutScOaHeRQKZZJ8+n0qIgWhD7Y7aAYQNtzmSoiMNDYTlK3MF
QdNvP/GwmvjoF7L+FgTTd49pMtmtIgZKVg+Md+3ngknyhd5mMAPm/1+Qg5Kowp1l
Et7UqQGh30b4Pg==
-----END CERTIFICATE-----
 1 s:/C=CH/O=SwissSign AG/CN=SwissSign Server Gold CA 2014 - G22
   i:/C=CH/O=SwissSign AG/CN=SwissSign Gold CA - G2
-----BEGIN CERTIFICATE-----
MIIGtzCCBJ+gAwIBAgIQAPodqurJs6X6V5gLmXTaMTANBgkqhkiG9w0BAQsFADBF
MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT
d2lzc1NpZ24gR29sZCBDQSAtIEcyMB4XDTE0MDkxOTE0MDkxMloXDTI5MDkxNTE0
MDkxMlowUjELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEsMCoG
A1UEAxMjU3dpc3NTaWduIFNlcnZlciBHb2xkIENBIDIwMTQgLSBHMjIwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQzxIi30mNQL6Fa6afsl9Fs7it1XQS
fLb+T3omoxS2IJiUNVCoyMeBEVSFB2a0tEUnyOjfcSn++++pWoAOkU5wWp7bbNo4
yq/T5LBg1HcuPm+wH94V4IwAFFatfZIIrmaTfVRzrZ26CrEM2vISb/1u2SVzAnmP
WoY3JVGbDOXw5HEpI6W/zLnd6cetY/ZPwp/9UICzCQxD5PmPiSP18dhTnm8LP4G/
go5VK5JQu52NvH9iStYs9VVXvHiq7+1RdkQa72CmB9wx6MmXqv3MAde/tt03L9o5
uB6VPx2uJQ6G0S+gpyqwKbeUBhJxBZNRRftXyXnZxg48ZBYb26tiPfTVAgMBAAGj
ggKUMIICkDAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNV
HQ4EFgQU5/Hn/S5TrRHlgRpXpHOPEn2YyK4wHwYDVR0jBBgwFoAUWyV7lqRlUX64
OfPAeGZe6Drn8O4wgf8GA1UdHwSB9zCB9DBHoEWgQ4ZBaHR0cDovL2NybC5zd2lz
c3NpZ24ubmV0LzVCMjU3Qjk2QTQ2NTUxN0VCODM5RjNDMDc4NjY1RUU4M0FFN0Yw
RUUwgaiggaWggaKGgZ9sZGFwOi8vZGlyZWN0b3J5LnN3aXNzc2lnbi5uZXQvQ049
NUIyNTdCOTZBNDY1NTE3RUI4MzlGM0MwNzg2NjVFRTgzQUU3RjBFRSUyQ089U3dp
c3NTaWduJTJDQz1DSD9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2Jhc2U/b2Jq
ZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnQwXwYDVR0gBFgwVjBUBglghXQB
WQECAQYwRzBFBggrBgEFBQcCARY5aHR0cDovL3JlcG9zaXRvcnkuc3dpc3NzaWdu
LmNvbS9Td2lzc1NpZ24tR29sZC1DUC1DUFMucGRmMIHGBggrBgEFBQcBAQSBuTCB
tjBkBggrBgEFBQcwAoZYaHR0cDovL3N3aXNzc2lnbi5uZXQvY2dpLWJpbi9hdXRo
b3JpdHkvZG93bmxvYWQvNUIyNTdCOTZBNDY1NTE3RUI4MzlGM0MwNzg2NjVFRTgz
QUU3RjBFRTBOBggrBgEFBQcwAYZCaHR0cDovL29jc3Auc3dpc3NzaWduLm5ldC81
QjI1N0I5NkE0NjU1MTdFQjgzOUYzQzA3ODY2NUVFODNBRTdGMEVFMA0GCSqGSIb3
DQEBCwUAA4ICAQCOLN7o1oxUHESHOxMtyaF0+Mehvb5xp+4BL9kuUI7GQdY9HiGZ
YLSVhQ+gzKK0/TpxZksZ3klVUpyjqmBZruaTWhd5p0K4hTECK6g3zNG7zDkAR9ZZ
S+O991u0FlqASfWNWKc1n6J4Lu/wyGv72NuqNA/SbGscP4+fOX8yelJ2KFONxQNI
jftNyHX8lmlUj2YAh49yiWkPY1tsFfKKzqNJlTEIEFkJkOIM7wVRIPgRu23jhlpa
jCIayCarJ41gn/UHXVgo4oDmrIA1aE9F2prtHWn+Yd8vtQkixPwJroq1Y0na76WS
j7xnQxSEr7/aXUjPn498Pw3iD+76Vub8nislsEFYjn21pXOWGjr5PciCqdivV5kf
HWo+p6isSu5hW6lkEzKa9bEKZsiUF4NzZeobDegyer8TYXkEDP91oD1iDum0i87k
sljy3pKPKr4Aa5HEDof4Kn2ZWckemrbJwVVxHddoQ3LU004zZUjSAfmmhwcPymCk
CnSXAtLkS8Fz40wHvB1HgpBLLu/ds9gmupv3o4ZPlgbYfQelIKes4Vtg8x/23scU
bv4vuScmpyzbjYrqhAmGafUoCbamKTv/1KfIcTHJrWV8eakrrqI8aSkmcY5jBSyg
IZ+muisznpeXBNZI4fJM/jFJF9W4jqLysCU9w9aDacEsRSLeSVUkc1TN7g==
-----END CERTIFICATE-----
 2 s:/C=CH/O=SwissSign AG/CN=SwissSign Gold CA - G2
   i:/C=CH/O=SwissSign AG/CN=SwissSign Gold CA - G2
-----BEGIN CERTIFICATE-----
MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln
biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF
MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT
d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8
76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+
bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c
6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE
emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd
MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt
MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y
MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y
FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi
aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM
gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB
qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7
lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn
8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov
L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6
45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO
UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5
O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC
bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv
GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a
77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC
hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3
92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp
Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w
ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt
Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
-----END CERTIFICATE-----
 3 s:/C=CH/O=SwissSign AG/CN=SwissSign Server Gold CA 2014 - G22
   i:/C=CH/O=SwissSign AG/CN=SwissSign Gold CA - G2
-----BEGIN CERTIFICATE-----
MIIGtzCCBJ+gAwIBAgIQAPodqurJs6X6V5gLmXTaMTANBgkqhkiG9w0BAQsFADBF
MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT
d2lzc1NpZ24gR29sZCBDQSAtIEcyMB4XDTE0MDkxOTE0MDkxMloXDTI5MDkxNTE0
MDkxMlowUjELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEsMCoG
A1UEAxMjU3dpc3NTaWduIFNlcnZlciBHb2xkIENBIDIwMTQgLSBHMjIwggEiMA0G
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDQzxIi30mNQL6Fa6afsl9Fs7it1XQS
fLb+T3omoxS2IJiUNVCoyMeBEVSFB2a0tEUnyOjfcSn++++pWoAOkU5wWp7bbNo4
yq/T5LBg1HcuPm+wH94V4IwAFFatfZIIrmaTfVRzrZ26CrEM2vISb/1u2SVzAnmP
WoY3JVGbDOXw5HEpI6W/zLnd6cetY/ZPwp/9UICzCQxD5PmPiSP18dhTnm8LP4G/
go5VK5JQu52NvH9iStYs9VVXvHiq7+1RdkQa72CmB9wx6MmXqv3MAde/tt03L9o5
uB6VPx2uJQ6G0S+gpyqwKbeUBhJxBZNRRftXyXnZxg48ZBYb26tiPfTVAgMBAAGj
ggKUMIICkDAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNV
HQ4EFgQU5/Hn/S5TrRHlgRpXpHOPEn2YyK4wHwYDVR0jBBgwFoAUWyV7lqRlUX64
OfPAeGZe6Drn8O4wgf8GA1UdHwSB9zCB9DBHoEWgQ4ZBaHR0cDovL2NybC5zd2lz
c3NpZ24ubmV0LzVCMjU3Qjk2QTQ2NTUxN0VCODM5RjNDMDc4NjY1RUU4M0FFN0Yw
RUUwgaiggaWggaKGgZ9sZGFwOi8vZGlyZWN0b3J5LnN3aXNzc2lnbi5uZXQvQ049
NUIyNTdCOTZBNDY1NTE3RUI4MzlGM0MwNzg2NjVFRTgzQUU3RjBFRSUyQ089U3dp
c3NTaWduJTJDQz1DSD9jZXJ0aWZpY2F0ZVJldm9jYXRpb25MaXN0P2Jhc2U/b2Jq
ZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9uUG9pbnQwXwYDVR0gBFgwVjBUBglghXQB
WQECAQYwRzBFBggrBgEFBQcCARY5aHR0cDovL3JlcG9zaXRvcnkuc3dpc3NzaWdu
LmNvbS9Td2lzc1NpZ24tR29sZC1DUC1DUFMucGRmMIHGBggrBgEFBQcBAQSBuTCB
tjBkBggrBgEFBQcwAoZYaHR0cDovL3N3aXNzc2lnbi5uZXQvY2dpLWJpbi9hdXRo
b3JpdHkvZG93bmxvYWQvNUIyNTdCOTZBNDY1NTE3RUI4MzlGM0MwNzg2NjVFRTgz
QUU3RjBFRTBOBggrBgEFBQcwAYZCaHR0cDovL29jc3Auc3dpc3NzaWduLm5ldC81
QjI1N0I5NkE0NjU1MTdFQjgzOUYzQzA3ODY2NUVFODNBRTdGMEVFMA0GCSqGSIb3
DQEBCwUAA4ICAQCOLN7o1oxUHESHOxMtyaF0+Mehvb5xp+4BL9kuUI7GQdY9HiGZ
YLSVhQ+gzKK0/TpxZksZ3klVUpyjqmBZruaTWhd5p0K4hTECK6g3zNG7zDkAR9ZZ
S+O991u0FlqASfWNWKc1n6J4Lu/wyGv72NuqNA/SbGscP4+fOX8yelJ2KFONxQNI
jftNyHX8lmlUj2YAh49yiWkPY1tsFfKKzqNJlTEIEFkJkOIM7wVRIPgRu23jhlpa
jCIayCarJ41gn/UHXVgo4oDmrIA1aE9F2prtHWn+Yd8vtQkixPwJroq1Y0na76WS
j7xnQxSEr7/aXUjPn498Pw3iD+76Vub8nislsEFYjn21pXOWGjr5PciCqdivV5kf
HWo+p6isSu5hW6lkEzKa9bEKZsiUF4NzZeobDegyer8TYXkEDP91oD1iDum0i87k
sljy3pKPKr4Aa5HEDof4Kn2ZWckemrbJwVVxHddoQ3LU004zZUjSAfmmhwcPymCk
CnSXAtLkS8Fz40wHvB1HgpBLLu/ds9gmupv3o4ZPlgbYfQelIKes4Vtg8x/23scU
bv4vuScmpyzbjYrqhAmGafUoCbamKTv/1KfIcTHJrWV8eakrrqI8aSkmcY5jBSyg
IZ+muisznpeXBNZI4fJM/jFJF9W4jqLysCU9w9aDacEsRSLeSVUkc1TN7g==
-----END CERTIFICATE-----
 4 s:/C=CH/O=SwissSign AG/CN=SwissSign Gold CA - G2
   i:/C=CH/O=SwissSign AG/CN=SwissSign Gold CA - G2
-----BEGIN CERTIFICATE-----
MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln
biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF
MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT
d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8
76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+
bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c
6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE
emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd
MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt
MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y
MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y
FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi
aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM
gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB
qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7
lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn
8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov
L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6
45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO
UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5
O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC
bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv
GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a
77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC
hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3
92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp
Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w
ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt
Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
-----END CERTIFICATE-----

Code

{:ok, conn} =
  Mint.HTTP.connect(
    :https,
    "git.joshmartin.ch",
    443,
    transport_opts: [
      cacerts: SSL.cacerts(),
      depth: 99,
      versions: [:"tlsv1.2", :"tlsv1.1"]
    ]
  )

A custom module for the cacerts is used to be able to provide the application as an escript.

defmodule Acme.Utils.SSL do
  @carcerts :certifi.cacerts()

  def cacerts, do: @carcerts
end

Error

11:39:54.528 [info]  ['TLS', 32, 'client', 58, 32, 73, 110, 32, 115, 116, 97, 116, 101, 32, 'certify', 32, 'at ssl_handshake.erl:1378 generated CLIENT ALERT: Fatal - Unknown CA', 10]
{:error, {:tls_alert, 'unknown ca'}}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.