TLSv1.3 client handling of server message "Unknown CA"

TLS client connection result is ok, but Error is expected:

case ssl:connect(Address,Port,TlsOpts,Timeout) of
                {ok,Socket} ->
                   ssl:close(Socket),
                   {ok,Socket};
                Error ->
                    Error

In the test we deliberately send wrong certificate to the server. Which replies with “CA unknown” alert, but that reply arrives later than close notify is sent from the client (ssl:close call).

While TLSv1.2 was used we got the Error with value “CA unknown”.
Now we are using TLSv1.3 and since Finished message is received in Server Hello we get the OK result and it seems that the alert “CA unknown” is not consumed.

I have tried to put some delay when the result is {ok, Socket} and check for ssl:connection_information(Socket):

case ssl:connect(Address,Port,TlsOpts,Timeout) of
           {ok,Socket} ->
                    timer:sleep(1000),
                    case ssl:connection_information(Socket) of
                        {ok, Result} ->
                            ssl:close(Socket),
                            {ok,Socket};
                        Error ->
                            Error
                   end;
           Error ->
                    Error

Then I get Error with value {error,closed} which probably indicates that TLS connection was closed because of the alert from server.

Is there a way to consume the “CA unknown” alert and get “CA unknown” value printed in Error?

3 Likes

I understand your confusion. I think the best you can do is to not use the ssl-socket in passive mode but in active once or n mode. Then you should get the alert as a message to the controlling process. However, there is not much we can do about the possible new timing as the TLS handshake protocol looks quite different in TLS-1.3 vs previous TLS versions.

TLS 1.3:

Key  ^ ClientHello
Exch | + key_share*
     | + signature_algorithms*
     | + psk_key_exchange_modes*
     v + pre_shared_key*       -------->
                                                  ServerHello  ^ Key
                                                 + key_share*  | Exch
                                            + pre_shared_key*  v
                                        {EncryptedExtensions}  ^  Server
                                        {CertificateRequest*}  v  Params
                                               {Certificate*}  ^
                                         {CertificateVerify*}  | Auth
                                                   {Finished}  v
                               <--------  [Application Data*]
     ^ {Certificate*}
Auth | {CertificateVerify*}
     v {Finished}              -------->
       [Application Data]      <------->  [Application Data]

TLS-1.2 (and earlier)

Client Server

  ClientHello                  -------->
                                                  ServerHello
                                                 Certificate*
                                           ServerKeyExchange*
                                          CertificateRequest*
                               <--------      ServerHelloDone
  Certificate*
  ClientKeyExchange
  CertificateVerify*
  [ChangeCipherSpec]
  Finished                     -------->
                                           [ChangeCipherSpec]
                               <--------             Finished
  Application Data             <------->     Application Data
3 Likes