[erlang-questions] ssl certificate verification in httpc

Ivan Uemlianin ivan@REDACTED
Thu Jul 17 15:31:53 CEST 2014


Dear Camille

Thanks very much for this!  I'll have a go with it this afternoon and 
report back.

Best wishes

Ivan


On 17/07/2014 12:20, Camille Troillard wrote:
> Hello Ivan,
>
> I have the same issue, here is what I came up to. This may not be correct and I would be very happy to discuss the issues anyone may find.  My goal is to check the server certificate is valid using verify_peer, and also implement a check on the server hostname I connect to.
>
> Here are the SSL options I use:
>
> % I know the certificate used by the server requires a depth of 2, you may not need this option in your code.
>
>          {ssl, [
>              {cacertfile, cacert_path()},
>              {depth, 2},
>              {verify_fun, ssl_verify_fun(?SERVER_HOSTNAME)},
>              {verify, verify_peer}
>          ]}
>
> And the verify fun:
>
> ssl_verify_fun(Hostname) ->
>      {
>          fun (_, {bad_cert, _} = Reason, _) ->
>                  {fail, Reason};
>              (_, {extension, _}, UserState) ->
>                  {unknown, UserState};
>              (_, valid, UserState) ->
>                  {valid, UserState};
>              (Cert, valid_peer, UserState) ->
>                  TBSCert = Cert#'OTPCertificate'.tbsCertificate,
>                  Extensions = TBSCert#'OTPTBSCertificate'.extensions,
>                  case lists:keysearch(?'id-ce-subjectAltName', #'Extension'.extnID, Extensions) of
>                      {value, #'Extension'{extnValue = [{dNSName, Hostname}]}} ->
>                          {valid, UserState};
>                      false ->
>                          {fail, invalid_certificate_hostname}
>                  end
>          end,
>          []
>      }.
>
>
> As you can see, I verify the host name matches the one I am connecting to.
>
>
> Best,
> Camille
>
>
>
>
> On 17 Jul 2014, at 11:30, Ivan Uemlianin <ivan@REDACTED> wrote:
>
>> Dear Roger
>>
>> Thank you for your comments.
>>
>> Your comments take us back to my initial question:
>>
>>> In short, what am I missing to be able to verify this certificate?
>>
>> Just providing the CA certificate doesn't seem to be enough:
>>
>>> ...
>>>     SSLOpts = [{verify, verify_peer},
>>>                {cacertfile,"certificates.crt"}],
>>>     httpc:request(get, {Url, []}, [{ssl,SSLOpts}], []).
>>>
>>> But this returns an unknown ca error:
>>>
>>>     {error,{failed_connect,[{to_address,{"bla.org", 443}},
>>>                             {inet,[inet],{tls_alert,"unknown ca"}}]}}
>>>     11:06:04.942 [error] SSL: certify: ssl_handshake.erl:1344:
>>>      Fatal error: unknown ca
>>
>> None of the other ssl options in the erlang ssl documentation look likely, and I have found no examples of verifying an ssl certification from erlang on the web.
>>
>> - are any of the other ssl options relevant here?  Are there other undocumented ssl options?
>>
>> - failing that, it looks like I need to write a verify_fun and access parts of the OTPCertificate and Extension records.  Is that correct, or is more required?
>>
>> - I have scoured the usual sources on the web but found nothing.  If anyone knows of relevant work in this area please let me know.
>>
>> Thanks
>>
>> Ivan
>>
>>
>> On 17/07/2014 08:08, Roger Lipscombe wrote:
>>> SSL encryption is done by the client creating a session key, and using
>>> the server's public key (from the server's certificate) to securely
>>> send it to the server. If you don't verify the server certificate, you
>>> have no way of knowing whether you're subject to a man-in-the-middle
>>> attack, where the attacker can give you a fake certificate, extract
>>> the session key, read/manipulate all your traffic, and then
>>> (optionally) send it to the real server.
>>>
>>> Encryption is only half of the story. SSL also aims to guarantee safe
>>> key exchange, but to do that, you need to verify the server
>>> certificate. This means verifying that the names match, that it's
>>> trusted (or issued by a trusted CA), and that it hasn't expired, been
>>> revoked, etc.
>>>
>>> And there's more than one way (also including DNS spoofing) to
>>> intercept the traffic: transparent proxies, pwned WiFi router, etc..
>>>
>>> On 15 July 2014 15:41, Camille Troillard <lists@REDACTED> wrote:
>>>> Hi Robert,
>>>>
>>>>> SSL essentially does two things at once: encrypts the data and checks if client and/or server are who they say they are. The latter is where certificate verification comes into play, the encryption part is always done and usually automatically negotiated between client and server.
>>>>>
>>>>> So, if all you are aiming for is encrypting the data travelling between client and server, then you don't need the ssl option. Just point your httpc:request at an "https://..." URL and the encryption is handled for you without you having to do anything more.
>>>>
>>>> I think this works only if you trust your DNS, otherwise you have to check that the certificate matches the host.
>>>> Please correct me if I’m wrong.
>>>>
>>>> Cam
>>>>
>>>>
>>>> _______________________________________________
>>>> erlang-questions mailing list
>>>> erlang-questions@REDACTED
>>>> http://erlang.org/mailman/listinfo/erlang-questions
>>> _______________________________________________
>>> erlang-questions mailing list
>>> erlang-questions@REDACTED
>>> http://erlang.org/mailman/listinfo/erlang-questions
>>>
>>
>> --
>> ============================================================
>> Ivan A. Uemlianin PhD
>> Llaisdy
>> Speech Technology Research and Development
>>
>>                     ivan@REDACTED
>>                      www.llaisdy.com
>>                          llaisdy.wordpress.com
>>               github.com/llaisdy
>>                      www.linkedin.com/in/ivanuemlianin
>>
>>                         festina lente
>> ============================================================
>> _______________________________________________
>> erlang-questions mailing list
>> erlang-questions@REDACTED
>> http://erlang.org/mailman/listinfo/erlang-questions
>

-- 
============================================================
Ivan A. Uemlianin PhD
Llaisdy
Speech Technology Research and Development

                     ivan@REDACTED
                      www.llaisdy.com
                          llaisdy.wordpress.com
               github.com/llaisdy
                      www.linkedin.com/in/ivanuemlianin

                         festina lente
============================================================



More information about the erlang-questions mailing list