Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-33329

Server and Shell do not emit TLS "protocol_version" alert messages

    • Fully Compatible
    • ALL
    • v3.6, v3.4, v3.2
    • Platforms 2018-03-26, Platforms 2018-04-09, Platforms 2018-04-23, Platforms 2018-05-07

      When connecting a shell which only supports TLS1.0 to an instance of openssl s_server, running with the arguments openssl s_server -port 27017 -cert jstests/libs/server.pem -tls1_2, the following error is emitted:

      sajack@spencerjacksonDesktop /home/sajack/mongo git master () % ./mongo --ssl --sslCAFile jstests/libs/ca.pem --sslPEMKeyFile jstests/libs/server.pem --sslDisabledProtocols=TLS1_1,TLS1_2
      MongoDB shell version v0.0.0
      connecting to: mongodb://127.0.0.1:27017
      2018-02-14T12:11:13.902-0500 E NETWORK  [thread1] SSL: error:1409442E:SSL routines:ssl3_read_bytes:tlsv1 alert protocol version
      2018-02-14T12:11:13.903-0500 E QUERY    [thread1] Error: socket exception [CONNECT_ERROR] :
      connect@src/mongo/shell/mongo.js:251:13
      @(connect):1:6
      exception: connect failed
      

      When connecting the same shell to a mongod which only supports TLS1.2, the following is emitted instead:

      sajack@spencerjacksonDesktop /home/sajack/mongo git master () % ./mongo --ssl --sslCAFile jstests/libs/ca.pem --sslPEMKeyFile jstests/libs/server.pem --sslDisabledProtocols=TLS1_1,TLS1_2
      MongoDB shell version v0.0.0
      connecting to: mongodb://127.0.0.1:27017
      2018-02-14T12:12:52.060-0500 E QUERY    [thread1] Error: socket exception [CLOSED] server [127.0.0.1:27017] :
      connect@src/mongo/shell/mongo.js:251:13
      @(connect):1:6
      exception: connect failed
      

      No "alert protocol version" error was emitted.

      Per RFC 5246 Appendix E, TLS protocol version negotiation is:

      A TLS 1.2 client who wishes to negotiate with such older servers will
      send a normal TLS 1.2 ClientHello, containing { 3, 3 } (TLS 1.2) in
      ClientHello.client_version. If the server does not support this
      version, it will respond with a ServerHello containing an older
      version number. If the client agrees to use this version, the
      negotiation will proceed as appropriate for the negotiated protocol.

      If the client sends a protocol version which is older than the server's oldest supported version, or the server replies with a protocol which is older than the client's oldest supported version:

      If the version chosen by the server is not supported by the client
      (or not acceptable), the client MUST send a "protocol_version" alert
      message and close the connection.

      If server supports (or is
      willing to use) only versions greater than client_version, it MUST
      send a "protocol_version" alert message and close the connection.

      The has logic to print information about any fatal TLS errors it receives during handshake. However on protocol error, the server simply closes the socket without sending the alert message.

      It appears that ASIO does not flush its buffers to the network when "fatal" errors are emitted by OpenSSL. This doesn't seem to be correct.

      The following is how openssl s_server handles the raised error:

                      case SSL_ERROR_SSL:
                          BIO_printf(bio_s_out, "ERROR\n");
                          (void)BIO_flush(bio_s_out);
                          ERR_print_errors(bio_err);
                          ret = 1;
                          goto err;
                          /* break; */
      

            Assignee:
            spencer.jackson@mongodb.com Spencer Jackson
            Reporter:
            spencer.jackson@mongodb.com Spencer Jackson
            Votes:
            0 Vote for this issue
            Watchers:
            13 Start watching this issue

              Created:
              Updated:
              Resolved: