Search code examples
sslerlangsni

Erlang SSL - Certificate not suitable on sni_fun callback


I got this error:

SSL: hello: ssl_handshake.erl:171:Fatal error: internal error - server_has_no_suitable_certificates

when supplying a der-decocded certificate for the callback function in the {sni_fun, CallbackFun} option. The CallbackFun returns [{cacerts, [Cert]}], where Cert is der-encoded. So things comply with Erlang ssl module's documentation.

I tried look into the otp source code. It seems that whatever the callback returns is ignored, thus causing this function clause to be evaluated:

certificate_chain(undefined, _, _) ->
    {error, no_cert};

which leads to that error! But I could be wrong as I kind of lost in browsing the code base...

If it helps, I use a self-signed CA to sign CSRs that are generated as a SNI is found during a TLS handshake (via sni_fun option).

please advise! thanks a lot!

Update: I tried Erlang OTP 20.3 release and get another error:

TLS server: In state hello at tls_connection.erl:739 generated SERVER ALERT: Fatal - Handshake Failure - malformed_handshake_data

Looking at OTP source code, it is result of an exception from this block:

try
Version = ssl_handshake:select_version(tls_record, ClientVersion, Versions),
case ssl_cipher:is_fallback(CipherSuites) of
true -> 
    Highest = tls_record:highest_protocol_version(Versions),
    case tls_record:is_higher(Highest, Version) of
        true ->
        ?ALERT_REC(?FATAL, ?INAPPROPRIATE_FALLBACK);
        false ->                     
        handle_client_hello(Version, Hello, SslOpts, Info, Renegotiation)
    end;
    false ->
    handle_client_hello(Version, Hello, SslOpts, Info, Renegotiation)
end
catch
_:_ ->
    ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE, malformed_handshake_data)
end.

I am sure the cert is fine, I could view it as well as convert it between DER/PEM formats with openssl with no error. Is there a way to reveal what kind of exception it is in this case?


Solution

  • I solved the problem: the sni_fun must return the list of

    [{cert, DerdecodedCert}, {keyfile, PathToTheCsrKeyFile}]
    

    I was returning only

    [{cert, DerdecodedCert}]
    

    (which was so instructed by Erlang ssl doc)

    Hope this helps anyone who bumps into similar problem as I did!