MySQL 5.6 C API Developer Guide

Chapter 15 C API Support for Encrypted Connections

For applications that require control over how encrypted connections are established, the C API provides these capabilities:

C API Options for Encrypted Connections

mysql_options() provides the following options for control over use of encrypted connections. For option details, see Section 7.49, “mysql_options()”.

  • MYSQL_OPT_SSL_CA: The path name of the Certificate Authority (CA) certificate file. This option, if used, must specify the same certificate used by the server.

  • MYSQL_OPT_SSL_CAPATH: The path name of the directory that contains trusted SSL CA certificate files.

  • MYSQL_OPT_SSL_CERT: The path name of the client public key certificate file.

  • MYSQL_OPT_SSL_CIPHER: The list of permissible ciphers for SSL encryption.

  • MYSQL_OPT_SSL_CRL: The path name of the file containing certificate revocation lists.

  • MYSQL_OPT_SSL_CRLPATH: The path name of the directory that contains certificate revocation list files.

  • MYSQL_OPT_SSL_KEY: The path name of the client private key file.

  • MYSQL_OPT_SSL_MODE: The connection security state.

  • MYSQL_OPT_SSL_VERIFY_SERVER_CERT: Whether to perform host name identity verification of the server certificate Common Name value.

mysql_ssl_set() can be used as a convenience routine that is equivalent to a set of mysql_options() calls that specify certificate and key files, encryption ciphers, and so forth. See Section 7.68, “mysql_ssl_set()”.

Enforcing an Encrypted Connection

mysql_options() options for information such as SSL certificate and key files are used to establish an encrypted connection if such connections are available, but do not enforce any requirement that the connection obtained be encrypted. To require an encrypted connection, use the following technique:

  1. Call mysql_options() as necessary supply the appropriate SSL parameters (certificate and key files, encryption ciphers, and so forth).

  2. For MySQL 5.6.36 and higher, MYSQL_OPT_SSL_MODE is available, so call mysql_options() to pass the MYSQL_OPT_SSL_MODE option with a value of SSL_MODE_REQUIRED.

    Important

    In MySQL 5.6, the minor C API version number was not incremented for the addition of MYSQL_OPT_SSL_MODE in MySQL 5.6.36. Application programs compiled for MySQL 5.6 that require MYSQL_OPT_SSL_MODE may fail to operate properly if the dynamic loader provides an older client library that does not include MYSQL_OPT_SSL_MODE. Such applications must be written to handle this possibility by checking whether the mysql_options() call succeeds or fails.

  3. Call mysql_real_connect() to connect to the server. As of MySQL 5.6.36, the call fails if an encrypted connection cannot be obtained; exit with an error. Prior to 5.6.36 (before MYSQL_OPT_SSL_MODE is available), clients are required to check for themselves, after calling mysql_real_connect(), whether the connection is encrypted. To do this if mysql_real_connect() succeeds, call mysql_get_ssl_cipher() to check whether the resulting connection is encrypted. If not, exit with an error.

MySQL clients implement this technique using a wrapper function named mysql_connect_ssl_check() to establish and check the connection, rather than calling mysql_real_connect() directly. To see how this works, look in the client directory of a MySQL source distribution at the source for any of the standard MySQL clients, as well as the client_priv.h file that contains the mysql_connect_ssl_check() wrapper function implementation. A call to mysql_connect_ssl_check() takes arguments like the arguments to mysql_real_connect(), plus an extra argument indicating whether to require an encrypted connection:

if (!mysql_connect_ssl_check(&mysql, host, user, pass, db,
                             port, sock, flags,
                             opt_ssl_required))
{
  /* failure: connection not obtained, or not encrypted if required to be */
}
else
{
  /* success: connection obtained, encrypted if required to be */
}

Version notes:

  • In MySQL 5.6.30, the --ssl-mode=REQUIRED command-line option was backported from MySQL 5.7 to MySQL 5.6. Clients can check for this option and use it to determine whether to require an encrypted connection. If so, clients must check for themselves, after calling mysql_real_connect(), whether the connection is encrypted, and fail if not. To do this, call mysql_get_ssl_cipher() and check the return value.

  • In MySQL 5.6.36, the MYSQL_OPT_SSL_MODE option for mysql_options() was backported from MySQL 5.7 to MySQL 5.6. A call to mysql_options() to set the MYSQL_OPT_SSL_MODE option to value of SSL_MODE_REQUIRED suffices to cause mysql_real_connect() to fail if the connection is not encrypted. mysql_get_ssl_cipher() can still be called after connecting, although it is not necessary to do so.

Improving Security of Encrypted Connections

For additional security relative to that provided by the default encryption, clients can supply a CA certificate matching the one used by the server and enable host name identity verification. In this way, the server and client place their trust in the same CA certificate and the client verifies that the host to which it connected is the one intended:

  • To specify the CA certificate, call mysql_options() to pass the MYSQL_OPT_SSL_CA (or MYSQL_OPT_SSL_CAPATH) option.

  • To enable host name identity verification, call mysql_options() to enable the MYSQL_OPT_SSL_VERIFY_SERVER_CERT option.

  • To require an encrypted connection, call mysql_options() to pass the MYSQL_OPT_SSL_MODE option with a value of SSL_MODE_REQUIRED. (For details about SSL_MODE_REQUIRED, see Enforcing an Encrypted Connection.)