What’s new in MariaDB Connector/C 3.0 – Part I: SSL

New SSL alternatives

SSL connections in previous versions of MariaDB Connector/C are based on the OpenSSL library. But because of the OpenSSL heartbleed bug, licensing problems and the lack of support for different transport layers, we decided to add support for alternative SSL implementations.

That’s why Connector/C 3.0 can use not only OpenSSL, but also

  • GnuTLS (http://www.gnutls.org)
  • SChannel (Windows only)

On Windows Connector/C 3.0 uses SChannel by default and does not require any external SSL libraries.

Currently the SSL implementation must be selected when Connector/C is compiled. One does it by setting WITH_SSL cmake variable to one of the OPENSSL, GNUTLS, SCHANNEL, or OFF to have no SSL support at all.

If no WITH_SSL was specified, Connector/C will use SChannel on Windows and OpenSSL everywhere else.

Example:

cmake . -DWITH_SSL=GNUTLS

The CMake parameter WITH_OPENSSL=ON/OFF used in previous versions of Connector/C is no longer supported.

mariadb_get_info() api function returns the kind of SSL library MariaDB Connector/C is using:

const char *library;
mariadb_get_info(mysql, MARIADB_CONNECTION_SSL_LIBRARY, (void *)&library);
printf("SSL library: %s\n", library);

Security

Preventing MTM attacks

Identity not encryption is the most important part of cryptographic protocol. Strongest encryption is worthless, if you aren’t speaking to whom you’re intending – just because data is encrypted doesn’t mean, that it can’t be spied on.

To prevent man in the middle attacks (MTM) both MariaDB Connector/C and libmysql from MariaDB’s server package offer the option of checking the server’s common name (CN) in the certificate which server sends to the client.

The client verifies the CN against hostname the client uses to connect to the server:

my_bool verify= 1;
mysql_options(mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &verify);

However verifying the host name might not be secure enough:

  • The client verification routine only verifies the hostname against CN entry of the certificate, but not against one or multiple SAN (Subject Alternative Name) entries, which makes it hard to use SSL in failover environment.
  • Except when using GnuTLS, host name verification with wild card is not supported yet
  • In the past, unaudited certificates have been issued repeatedly, particularly by resellers, that have been used for attacks.

Therefore the verification of host names is no 100 % protection.

Fingerprint verification

In addition to host name verification MariaDB Connector/C 3.0 offers an additional verification method: checking the fingerprint of server certificate. A fingerprint is a short sequence of bytes used to identify a longer (public) key. A fingerprint can be created by applying a cryptographic hash function to a key. MariaDB Connector/C supports the SHA1 hash function only.

Creating a fingerprint:

1) OpenSSL

openssl x509 -in server-cert.pem -sha1 -fingerprint -noout
SHA1 Fingerprint=3A:07:9E:1A:14:AD:32:69:53:A5:D2:80:F9:96:B9:3D:77:2A:5B:EA

2) GnuTLS

certtool -i --infile=server-cert.pem

Look for SHA1 fingerprint in output:
Other Information:
SHA1 fingerprint:
3a079e1a14ad326953a5d280f996b93d772a5bea
Verifying fingerprints

To verify fingerprint of server certificate you can either specify a single fingerprint or a file with multiple finger prints. Fingerprints need to be specified in hex format without colons.

mysql_options(mysql, MARIADB_OPT_SSL_FP, "3a079e1a14ad326953a5d280f996b93d772a5bea");

or

mysql_options(mysql, MARIADB_OPT_SSL_FP_LIST, "./fingerprint.list");

Transport Layer Security (TLS)

As Sergei Golubchik wrote in a previous blog post The state of SSL in MariaDB newer MariaDB server versions (> 5.5.41 and > 10.0.15) now support the newer security standards TLSv_1.1 and preferrable TLS_v_1.2 (as required by PCI DSS v_3.1)

In version 3.0 of Connector/C we now also added support for TLSv_1.1 and TLSv_1.2. Both MariaDB Server and Connector/C offer an option to determine the version of TLS in use.

Server:

MariaDB [(none)]> show session status like 'ssl_version';
+---------------+---------+
| Variable_name | Value |
+---------------+---------+
| Ssl_version | TLSv1.2 |
+---------------+---------+

Client:

const char *tls_version;
mariadb_get_info(mysql, MARIADB_CONNECTION_SSL_VERSION, (void *)&tls_version);
printf("Ssl_version: %s\n", tls_version);

Password protected private keys

Usually a private key is encrypted using a passphrase in order to protect it from loss(?).
Passphrase protected keys are recommended for security but in versions prior to MariaDB Connector/C 3.0 are often impracticable since passphrase protected keys could only be used after entering the passphrase manually:

./my_test --ssl-ca=ca-cert.pem --ssl-key=client-key-enc.pem --ssl-cert=client-cert.pem
Enter PEM pass phrase:

With MariaDB Connector/C 3.0 entering the passphrase manually it’s not required anymore if the passphrase
was specified before establishing the connection:

mysql_options(mysql, MARIADB_OPT_SSL_PASSPHRASE, "4_l0ng3r_P4ssphr4s3_is_much_b3tt3r_th4n_4_sh0rter_0ne");

Note:

MariaDB Connector/C 3.0 is an alpha release. In general this means that there are no known serious bugs, except for those marked as feature requests, but we feel it needs further testing and development before we call it stable.