diff --git a/include/mysqli.php b/include/mysqli.php
new file mode 100644
index 0000000000000000000000000000000000000000..43b15067f444b49b0b4411fcb609ef7c6b8851c0
--- /dev/null
+++ b/include/mysqli.php
@@ -0,0 +1,227 @@
+<?php
+/*********************************************************************
+    mysqli.php
+
+    Collection of MySQL helper interface functions.
+
+    Mostly wrappers with error/resource checking.
+
+    Peter Rotich <peter@osticket.com>
+    Jared Hancock <jared@osticket.com>
+    Copyright (c)  2006-2013 osTicket
+    http://www.osticket.com
+
+    Released under the GNU General Public License WITHOUT ANY WARRANTY.
+    See LICENSE.TXT for details.
+
+    vim: expandtab sw=4 ts=4 sts=4:
+**********************************************************************/
+$__db = null;
+
+function db_connect($host, $user, $passwd, $options) {
+    global $__db;
+
+    //Assert
+    if(!strlen($user) || !strlen($passwd) || !strlen($host))
+        return NULL;
+
+    if (!($__db = mysqli_init()))
+        return NULL;
+
+    // Setup SSL if enabled
+    if (isset($options['certs']))
+        $__db->set_ssl(
+                $options['certs']['key'],
+                $options['certs']['cert'],
+                $options['certs']['ca'],
+                null, null);
+
+    //Connectr
+    if(!$__db->real_connect($host, $user, $passwd))
+        return NULL;
+
+    //Select the database, if any.
+    if(isset($options['db'])) $__db->select_db($options['db']);
+
+    //set desired encoding just in case mysql charset is not UTF-8 - Thanks to FreshMedia
+    @$__db->query('SET NAMES "utf8"');
+    @$__db->query('SET CHARACTER SET "utf8"');
+    @$__db->query('SET COLLATION_CONNECTION=utf8_general_ci');
+
+    @db_set_variable('sql_mode', '');
+
+    return $__db;
+}
+
+function db_close() {
+    global $__db;
+    return @$__db->close();
+}
+
+function db_version() {
+
+    $version=0;
+    if(preg_match('/(\d{1,2}\.\d{1,2}\.\d{1,2})/',
+            db_result(db_query('SELECT VERSION()')),
+            $matches))                                      # nolint
+        $version=$matches[1];                               # nolint
+
+    return $version;
+}
+
+function db_timezone() {
+    return db_get_variable('time_zone');
+}
+
+function db_get_variable($variable, $type='session') {
+    $sql =sprintf('SELECT @@%s.%s', $type, $variable);
+    return db_result(db_query($sql));
+}
+
+function db_set_variable($variable, $value, $type='session') {
+    $sql =sprintf('SET %s %s=%s',strtoupper($type), $variable, db_input($value));
+    return db_query($sql);
+}
+
+
+function db_select_database($database) {
+    global $__db;
+    return ($database && @$__db->select_db($database));
+}
+
+function db_create_database($database, $charset='utf8',
+        $collate='utf8_general_ci') {
+    global $__db;
+    return @$__db->query(sprintf('CREATE DATABASE %s DEFAULT CHARACTER SET %s COLLATE %s', $database, $charset, $collate));
+}
+
+// execute sql query
+function db_query($query, $conn=null) {
+    global $ost, $__db;
+
+    if (!$conn) $conn = $__db;
+
+    $res = $conn->query($query);
+
+    if(!$res && $ost) { //error reporting
+        $msg='['.$query.']'."\n\n".db_error();
+        $ost->logDBError('DB Error #'.db_errno(), $msg);
+        //echo $msg; #uncomment during debuging or dev.
+    }
+
+    return $res;
+}
+
+function db_squery($query) { //smart db query...utilizing args and sprintf
+
+    $args  = func_get_args();
+    $query = array_shift($args);
+    $query = str_replace("?", "%s", $query);
+    $args  = array_map('db_real_escape', $args);
+    array_unshift($args, $query);
+    $query = call_user_func_array('sprintf', $args);
+    return db_query($query);
+}
+
+function db_count($query) {
+    return db_result(db_query($query));
+}
+
+function db_result($res, $row=0) {
+    if (!$res)
+        return NULL;
+
+    $res->data_seek($row);
+    list($value) = db_output($res->fetch_row());
+    return $value;
+}
+
+function db_fetch_array($res, $mode=MYSQL_ASSOC) {
+    return ($res) ? db_output($res->fetch_array($mode)) : NULL;
+}
+
+function db_fetch_row($res) {
+    return ($res) ? db_output($res->fetch_row()) : NULL;
+}
+
+function db_fetch_field($res) {
+    return ($res) ? $res->fetch_field() : NULL;
+}
+
+function db_assoc_array($res, $mode=false) {
+    if($res && db_num_rows($res)) {
+        while ($row=db_fetch_array($res, $mode))
+            $result[]=$row;
+    }
+    return $result;
+}
+
+function db_num_rows($res) {
+    return ($res) ? $res->num_rows : 0;
+}
+
+function db_affected_rows() {
+    global $__db;
+    return $__db->affected_rows;
+}
+
+function db_data_seek($res, $row_number) {
+    return ($res && $res->data_seek($row_number));
+}
+
+function db_data_reset($res) {
+    return db_data_seek($res, 0);
+}
+
+function db_insert_id() {
+    global $__db;
+    return $__db->insert_id;
+}
+
+function db_free_result($res) {
+    return ($res && $res->free());
+}
+
+function db_output($var) {
+
+    if(!function_exists('get_magic_quotes_runtime') || !get_magic_quotes_runtime()) //Sucker is NOT on - thanks.
+        return $var;
+
+    if (is_array($var))
+        return array_map('db_output', $var);
+
+    return (!is_numeric($var))?stripslashes($var):$var;
+
+}
+
+//Do not call this function directly...use db_input
+function db_real_escape($val, $quote=false) {
+    global $__db;
+
+    //Magic quotes crap is taken care of in main.inc.php
+    $val=$__db->real_escape_string($val);
+
+    return ($quote)?"'$val'":$val;
+}
+
+function db_input($var, $quote=true) {
+
+    if(is_array($var))
+        return array_map('db_input', $var, array_fill(0, count($var), $quote));
+    elseif($var && preg_match("/^\d+(\.\d+)?$/", $var))
+        return $var;
+
+    return db_real_escape($var, $quote);
+}
+
+function db_error() {
+    global $__db;
+    return $__db->error;
+}
+
+function db_errno() {
+    global $__db;
+    return $__db->errno;
+}
+?>
+
diff --git a/include/ost-sampleconfig.php b/include/ost-sampleconfig.php
index 8a1f3b98eed8b51f6cbd535a8c181bebb5b7f312..d3cbb517a3b2922444a6ccdbd9fcb936439cf5a1 100644
--- a/include/ost-sampleconfig.php
+++ b/include/ost-sampleconfig.php
@@ -4,7 +4,7 @@
 
     Static osTicket configuration file. Mainly useful for mysql login info.
     Created during installation process and shouldn't change even on upgrades.
-   
+
     Peter Rotich <peter@osticket.com>
     Copyright (c)  2006-2010 osTicket
     http://www.osticket.com
@@ -36,11 +36,31 @@ define('ADMIN_EMAIL','%ADMIN-EMAIL');
 
 #Mysql Login info
 define('DBTYPE','mysql');
-define('DBHOST','%CONFIG-DBHOST'); 
+define('DBHOST','%CONFIG-DBHOST');
 define('DBNAME','%CONFIG-DBNAME');
 define('DBUSER','%CONFIG-DBUSER');
 define('DBPASS','%CONFIG-DBPASS');
 
+# SSL Options
+# ---------------------------------------------------
+# SSL options for MySQL can be enabled by adding a certificate allowed by
+# the database server here. To use SSL, you must have a client certificate
+# signed by a CA (certificate authority). You can easily create this
+# yourself with the EasyRSA suite. Give the public CA certificate, and both
+# the public and private parts of your client certificate below.
+#
+# Once configured, you can ask MySQL to require the certificate for
+# connections:
+#
+# > create user osticket;
+# > grant all on osticket.* to osticket require subject '<subject>';
+#
+# More information (to-be) available in doc/security/hardening.md
+
+# define('DBSSLCA','/path/to/ca.crt');
+# define('DBSSLCERT','/path/to/client.crt');
+# define('DBSSLKEY','/path/to/client.key');
+
 #Table prefix
 define('TABLE_PREFIX','%CONFIG-PREFIX');
 
diff --git a/main.inc.php b/main.inc.php
index a8aac57df7a8e7995d80b54bcd37d70bfd6555f6..4b5ddd99034455e06ff0ea6a9dc8e06b6242ba70 100644
--- a/main.inc.php
+++ b/main.inc.php
@@ -122,7 +122,10 @@
     require(INCLUDE_DIR.'class.format.php'); //format helpers
     require(INCLUDE_DIR.'class.validator.php'); //Class to help with basic form input validation...please help improve it.
     require(INCLUDE_DIR.'class.mailer.php');
-    require(INCLUDE_DIR.'mysql.php');
+    if (extension_loaded('mysqli'))
+        require_once INCLUDE_DIR.'mysqli.php';
+    else
+        require(INCLUDE_DIR.'mysql.php');
 
     #CURRENT EXECUTING SCRIPT.
     define('THISPAGE', Misc::currentURL());
@@ -190,7 +193,15 @@
 
     #Connect to the DB && get configuration from database
     $ferror=null;
-    if (!db_connect(DBHOST,DBUSER,DBPASS) || !db_select_database(DBNAME)) {
+    $options = array();
+    if (defined('DBSSLCA'))
+        $options['certs'] = array(
+            'ca' => DBSSLCA,
+            'cert' => DBSSLCERT,
+            'key' => DBSSLKEY
+        );
+    if (!db_connect(DBHOST,DBUSER,DBPASS, $options)
+            || !db_select_database(DBNAME)) {
         $ferror='Unable to connect to the database';
     } elseif(!($ost=osTicket::start(1)) || !($cfg = $ost->getConfig())) {
         $ferror='Unable to load config info from DB. Get tech support.';