Refactor proposed changes from PR #3896
diff --git a/application/config/database.php b/application/config/database.php
index 429b4d4..656f0c3 100644
--- a/application/config/database.php
+++ b/application/config/database.php
@@ -40,6 +40,16 @@
 | 				 Sites using Latin-1 or UTF-8 database character set and collation are unaffected.
 |	['swap_pre'] A default table prefix that should be swapped with the dbprefix
 |	['encrypt']  Whether or not to use an encrypted connection.
+|
+|			'mysql' (deprecated), 'sqlsrv' and 'pdo/sqlsrv' drivers accept TRUE/FALSE
+|			'mysqli' driver accepts an array with the following options:
+|
+|				'ssl_key'    - Path to the private key file
+|				'ssl_cert'   - Path to the public key certificate file
+|				'ssl_ca'     - Path to the certificate authority file
+|				'ssl_capath' - Path to a directory containing trusted CA certificats in PEM format
+|				'ssl_cipher' - List of *allowed* ciphers to be used for the encryption
+|
 |	['compress'] Whether or not to use client compression (MySQL only)
 |	['stricton'] TRUE/FALSE - forces 'Strict Mode' connections
 |							- good for ensuring strict SQL while developing
@@ -80,7 +90,6 @@
 	'encrypt' => FALSE,
 	'compress' => FALSE,
 	'stricton' => FALSE,
-	'ssl_options' => array(),
 	'failover' => array(),
 	'save_queries' => TRUE
 );
diff --git a/system/database/drivers/mysqli/mysqli_driver.php b/system/database/drivers/mysqli/mysqli_driver.php
index 61a37bd..82abf4e 100644
--- a/system/database/drivers/mysqli/mysqli_driver.php
+++ b/system/database/drivers/mysqli/mysqli_driver.php
@@ -86,21 +86,6 @@
 	 */
 	public $stricton = FALSE;
 
-	/**
-	 * Used to set various SSL options that can be used when making SSL connections.
-	 *
-	 * @see http://php.net/manual/en/mysqli.ssl-set.php		Documentation for MySQLi
-	 *
-	 * @var array
-	 */
-	public $ssl_options = array(
-			"ssl_key"    => '', // The path name to the key file.
-			"ssl_cert"   => '', // The path name to the certificate file.
-			"ssl_ca"     => '', // The path name to the certificate authority file.
-			"ssl_capath" => '', // The pathname to a directory that contains trusted SSL CA certificates in PEM format.
-			"ssl_cipher" => '' // A list of allowable ciphers to use for SSL encryption.
-	);
-
 	// --------------------------------------------------------------------
 
 	/**
@@ -117,7 +102,6 @@
 	 *
 	 * @param	bool	$persistent
 	 * @return	object
-	 * @todo	SSL support
 	 */
 	public function db_connect($persistent = FALSE)
 	{
@@ -147,45 +131,45 @@
 			$mysqli->options(MYSQLI_INIT_COMMAND, 'SET SESSION sql_mode="STRICT_ALL_TABLES"');
 		}
 
-		if ($this->encrypt === TRUE)
+		if (is_array($this->encrypt))
 		{
-			$ssl_key    = array_key_exists('ssl_key', $this->ssl_options) ? $this->ssl_options['ssl_key'] : '';
-			$ssl_cert   = array_key_exists('ssl_cert', $this->ssl_options) ? $this->ssl_options['ssl_cert'] : '';
-			$ssl_ca     = array_key_exists('ssl_ca', $this->ssl_options) ? $this->ssl_options['ssl_ca'] : '';
-			$ssl_capath = array_key_exists('ssl_capath', $this->ssl_options) ? $this->ssl_options['ssl_capath'] : '';
-			$ssl_cipher = array_key_exists('ssl_cipher', $this->ssl_options) ? $this->ssl_options['ssl_cipher'] : '';
+			$ssl = array();
+			empty($this->encrypt['ssl_key'])    OR $ssl['key']    = $this->encrypt['ssl_key'];
+			empty($this->encrypt['ssl_cert'])   OR $ssl['cert']   = $this->encrypt['ssl_cert'];
+			empty($this->encrypt['ssl_ca'])     OR $ssl['ca']     = $this->encrypt['ssl_ca'];
+			empty($this->encrypt['ssl_capath']) OR $ssl['capath'] = $this->encrypt['ssl_capath'];
+			empty($this->encrypt['ssl_cipher']) OR $ssl['cipher'] = $this->encrypt['ssl_cipher'];
 
-			$mysqli->ssl_set($ssl_key, $ssl_cert, $ssl_ca, $ssl_capath, $ssl_cipher);
-			$client_flags |= MYSQLI_CLIENT_SSL;
+			if ( ! empty($ssl))
+			{
+				$client_flags |= MYSQLI_CLIENT_SSL;
+				$mysqli->ssl_set(
+					isset($ssl['key'])    ? $ssl['key']    : NULL,
+					isset($ssl['cert'])   ? $ssl['cert']   : NULL,
+					isset($ssl['ca'])     ? $ssl['ca']     : NULL,
+					isset($ssl['capath']) ? $ssl['capath'] : NULL,
+					isset($ssl['cipher']) ? $ssl['cipher'] : NULL
+				);
+			}
 		}
 
-		$connected = @$mysqli->real_connect($hostname, $this->username, $this->password, $this->database, $port, $socket, $client_flags);
-
-		if ($connected)
+		if ($mysqli->real_connect($hostname, $this->username, $this->password, $this->database, $port, $socket, $client_flags))
 		{
-			// If SSL was requested we want to do some checking and log an error if an SSL connection wasn't established.
-			if ($this->encrypt === TRUE)
+			// Prior to version 5.7.3, MySQL silently downgrades to an unencrypted connection if SSL setup fails
+			if (($client_flags & MYSQLI_CLIENT_SSL) && version_compare($mysqli->client_info, '5.7.3', '<='))
 			{
-				$res        = $mysqli->query("SHOW STATUS LIKE 'ssl_cipher';");
-				$ssl_status = $res->fetch_row();
-
-				if ($ssl_status[1] == '')
+				$ssl = $mysqli->query("SHOW STATUS LIKE 'ssl_cipher'")->fetch_row();
+				if (empty($ssl[1]))
 				{
-					log_message('error',
-							"Problem With MySQLi SSL: An SSL connection was requested but the resulting connection is not using SSL!");
+					$mysqli->close();
+					$message = 'MySQLi was configured for an SSL connection, but got an unencrypted connection instead!';
+					log_message('error', $message);
+					return ($this->db->db_debug) ? $this->db->display_error($message, '', TRUE) : FALSE;
 				}
 			}
 
 			return $mysqli;
 		}
-		else
-		{
-			if ($mysqli->connect_errno)
-			{
-				log_message('error',
-						'msqli connect failed, error: ' . mysqli_connect_error() . " | " . $mysqli->connect_error . " | " . $mysqli->connect_errno);
-			}
-		}
 
 		return FALSE;
 	}
diff --git a/user_guide_src/source/changelog.rst b/user_guide_src/source/changelog.rst
index d175f4b..da4d8ff 100644
--- a/user_guide_src/source/changelog.rst
+++ b/user_guide_src/source/changelog.rst
@@ -14,6 +14,7 @@
 -  Database
 
    -  Added ``list_fields()`` support for SQLite ('sqlite3' and 'pdo_sqlite' drivers).
+   -  Added support for setting SSL options for the 'mysqli' driver.
 
 -  Libraries