Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New mtls connection #51

Merged
merged 4 commits into from
Jan 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 27 additions & 2 deletions include/crypto.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,33 @@
extern int32_t Crypto_Config_CryptoLib(uint8_t sadb_type, uint8_t cryptography_type, uint8_t crypto_create_fecf, uint8_t process_sdls_pdus,
uint8_t has_pus_hdr, uint8_t ignore_sa_state, uint8_t ignore_anti_replay,
uint8_t unique_sa_per_mapid, uint8_t crypto_check_fecf, uint8_t vcid_bitmask);
extern int32_t Crypto_Config_MariaDB(char *mysql_username, char *mysql_password, char *mysql_hostname,
char *mysql_database, uint16_t mysql_port);
/*===========================================================================
Function: Crypto_Config_MariaDB
Description: sets the fields the struct SadbMariaDBConfig_t for required
* parameters to create MySQL connection.
* 1) char* mysql_username - mariadb username
* 2) char* mysql_password - password associated with the username
* 3) char* mysql_hostname - hostname of the server that hosts the mariadb database
* 4) char* mysql_hostname - database schema name - OPTIONAL.
5) char* mysql_hostname - port associated with mariadb. By default port 3306.
6) uint8_t encrypted_connection - attempting an encrypted connection.
* Set encrypted_connection = 1 if you are attempting an encrypted connection.
Optional parameters that are only required for an encrypted connection:
uint8_t encrypted_connection
7) char* ssl_cert - The path name of the server public key certificate file with .pem extension.
8) char* ssl_key - The path name of the server private key file with .pem extension.
9) char* ssl_ca - The path name of the Certificate Authority (CA) certificate file.
10) char* ssl_capath - Certificate Authority (CA) directory.
Outputs: status - int32
References: 1) https://dev.mysql.com/doc/c-api/8.0/en/c-api-encrypted-
* connections.html#c-api-enforcing-encrypted-connection
* 2) https://dev.mysql.com/doc/c-api/8.0/en/mysql-ssl-set.html
* 3) https://www.xuchao.org/docs/mysql/connectors-apis.html#c-api-encrypted-connections
Example call:
Note: MySQL server MUST be configured for encrypted connections:
* https://dev.mysql.com/doc/refman/5.7/en/using-encrypted-connections.html
==========================================================*/
extern int32_t Crypto_Config_MariaDB(char* mysql_username, char* mysql_password, char* mysql_hostname, char* mysql_database, uint16_t mysql_port, uint8_t encrypted_connection, char* ssl_cert, char* ssl_key, char* ssl_ca, char* ssl_capath);
extern int32_t Crypto_Config_Kmc_Crypto_Service(char *kmc_crypto_hostname, uint16_t kmc_crypto_port, char *mtls_cert_path,
char *mtls_key_path, uint8_t ignore_ssl_hostname_validation);
extern int32_t Crypto_Config_Add_Gvcid_Managed_Parameter(uint8_t tfvn, uint16_t scid, uint8_t vcid, uint8_t has_fecf,
Expand Down
7 changes: 7 additions & 0 deletions include/crypto_config_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,13 @@ typedef struct
char *mysql_hostname;
char *mysql_database;
uint16_t mysql_port;
/*attributes ssl_cert,ssl_key,ssl_ca,bind_address are related to a TLS
connection*/
uint8_t encrypted_connection;
char* ssl_cert;
char* ssl_key;
char* ssl_ca;
char* ssl_capath;
} SadbMariaDBConfig_t;
#define SADB_MARIADB_CONFIG_SIZE (sizeof(SadbMariaDBConfig_t))

Expand Down
62 changes: 36 additions & 26 deletions src/src_main/crypto_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,19 +146,27 @@ int32_t Crypto_Init(void)

// Init Security Associations
status = sadb_routine->sadb_init();
status = sadb_routine->sadb_config();
if (status==CRYPTO_LIB_SUCCESS)
{
status = sadb_routine->sadb_config();

Crypto_Local_Init();
Crypto_Local_Config();
Crypto_Local_Init();
Crypto_Local_Config();

// TODO - Add error checking
// TODO - Add error checking

// Init table for CRC calculations
Crypto_Calc_CRC_Init_Table();
// Init table for CRC calculations
Crypto_Calc_CRC_Init_Table();

// cFS Standard Initialized Message
printf(KBLU "Crypto Lib Intialized. Version %d.%d.%d.%d\n" RESET, CRYPTO_LIB_MAJOR_VERSION,
CRYPTO_LIB_MINOR_VERSION, CRYPTO_LIB_REVISION, CRYPTO_LIB_MISSION_REV);
// cFS Standard Initialized Message
printf(KBLU "Crypto Lib Intialized. Version %d.%d.%d.%d\n" RESET, CRYPTO_LIB_MAJOR_VERSION,
CRYPTO_LIB_MINOR_VERSION, CRYPTO_LIB_REVISION, CRYPTO_LIB_MISSION_REV);
}
else
{
printf(KBLU "Error, Crypto Lib NOT Intialized, sadb_init() returned error:%d. Version .%d.%d.%d\n" RESET, CRYPTO_LIB_MAJOR_VERSION,
CRYPTO_LIB_MINOR_VERSION, CRYPTO_LIB_REVISION, CRYPTO_LIB_MISSION_REV);
}

return status;
}
Expand Down Expand Up @@ -238,27 +246,29 @@ int32_t Crypto_Config_CryptoLib(uint8_t sadb_type, uint8_t cryptography_type, ui
* @param mysql_hostname: char*
* @param mysql_database: char*
* @param mysql_port: uint16
* @return int32: Success/Failure
* @return int32: Success/Failure
**/
int32_t Crypto_Config_MariaDB(char *mysql_username, char *mysql_password, char *mysql_hostname,
char *mysql_database, uint16_t mysql_port)
/*set parameters for an encrypted TLS connection*/
int32_t Crypto_Config_MariaDB(char* mysql_username, char* mysql_password, char* mysql_hostname, char* mysql_database, uint16_t mysql_port, uint8_t encrypted_connection, char* ssl_cert, char* ssl_key, char* ssl_ca, char* ssl_capath)
{
int32_t status = CRYPTO_LIB_SUCCESS;
sadb_mariadb_config = (SadbMariaDBConfig_t *)calloc(1, SADB_MARIADB_CONFIG_SIZE);
if(sadb_mariadb_config != NULL)
int32_t status = CRYPTO_LIB_ERROR;
sadb_mariadb_config = (SadbMariaDBConfig_t*)calloc(1, SADB_MARIADB_CONFIG_SIZE);
if (NULL!=sadb_mariadb_config)
{
sadb_mariadb_config->mysql_username = mysql_username;
sadb_mariadb_config->mysql_password = mysql_password;
sadb_mariadb_config->mysql_hostname = mysql_hostname;
sadb_mariadb_config->mysql_database = mysql_database;
sadb_mariadb_config->mysql_port = mysql_port;
sadb_mariadb_config->mysql_username=mysql_username;
sadb_mariadb_config->mysql_password=mysql_password;
sadb_mariadb_config->mysql_hostname=mysql_hostname;
sadb_mariadb_config->mysql_database=mysql_database;
sadb_mariadb_config->mysql_port=mysql_port;
/*start - encrypted connection related parameters*/
sadb_mariadb_config->encrypted_connection = encrypted_connection;
sadb_mariadb_config->ssl_cert = ssl_cert;
sadb_mariadb_config->ssl_key = ssl_key;
sadb_mariadb_config->ssl_ca = ssl_ca;
sadb_mariadb_config->ssl_capath = ssl_capath;
/*end - encrypted connection related parameters*/
status = CRYPTO_LIB_SUCCESS;
}
else
{
// null returned, throw error and return
status = CRYPTO_LIB_ERR_NULL_BUFFER;
}

return status;
}

Expand Down
61 changes: 48 additions & 13 deletions src/src_mysql/sadb_routine_mariadb.template.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,20 +96,55 @@ static int32_t sadb_config(void)
return CRYPTO_LIB_SUCCESS;
}

static int32_t sadb_init(void)
{
int32_t status = CRYPTO_LIB_SUCCESS;
con = mysql_init(NULL);

// TODO - add mysql_options/mysql_get_ssl_cipher logic for mTLS connections.

if (mysql_real_connect(con, sadb_mariadb_config->mysql_hostname, sadb_mariadb_config->mysql_username,
sadb_mariadb_config->mysql_password, sadb_mariadb_config->mysql_database,
sadb_mariadb_config->mysql_port, NULL, 0) == NULL)
{ // 0,NULL,0 are port number, unix socket, client flag
status = finish_with_error(con, SADB_MARIADB_CONNECTION_FAILED);
static int32_t sadb_init(void) {
int32_t status = CRYPTO_LIB_ERROR;
if (NULL != sadb_mariadb_config) {
con = mysql_init(NULL);
//if encrypted connection (TLS) connection
if (sadb_mariadb_config->encrypted_connection == 1 ||
sadb_mariadb_config->encrypted_connection == 2) {
/*Note:MySQL server MUST be configured for encrypted connections:
* https://dev.mysql.com/doc/refman/5.7/en/using-encrypted-connections.html*/
mysql_ssl_set(con,
sadb_mariadb_config->ssl_key,
sadb_mariadb_config->ssl_cert,
sadb_mariadb_config->ssl_ca,
sadb_mariadb_config->ssl_capath, NULL);
/*Based documentation mysql_ssl_set() always returns 0.
Therefore successful connections can only be checked
via subsequent call to mysql_real_connect()*/
//if NULL is returned then there is an error, else success
if (mysql_real_connect(con, sadb_mariadb_config->mysql_hostname,
sadb_mariadb_config->mysql_username,
sadb_mariadb_config->mysql_password,
sadb_mariadb_config->mysql_database,
sadb_mariadb_config->mysql_port, NULL, 0) == NULL) {
//0,NULL,0 are port number, unix socket, client flag
finish_with_error(con, SADB_MARIADB_CONNECTION_FAILED);
status = CRYPTO_LIB_ERROR;
} else {
status = CRYPTO_LIB_SUCCESS;
if (status) {
printf("sadb_initUsing an encrypted connection \n");
}
}
}//end if TLS connection
//else regular username & password connection
else {
//if NULL is returned then there is an error, else success
if (mysql_real_connect(con, sadb_mariadb_config->mysql_hostname,
sadb_mariadb_config->mysql_username,
sadb_mariadb_config->mysql_password,
sadb_mariadb_config->mysql_database,
sadb_mariadb_config->mysql_port, NULL, 0) == NULL) {
//0,NULL,0 are port number, unix socket, client flag
finish_with_error(con, SADB_MARIADB_CONNECTION_FAILED);
status = CRYPTO_LIB_ERROR;
} else {
status = CRYPTO_LIB_SUCCESS;
}
}//end regular password
}

return status;
}

Expand Down
135 changes: 135 additions & 0 deletions util/src_util/ut_mysql_m_tls_connection.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/* Copyright (C) 2009 - 2022 National Aeronautics and Space Administration. All Foreign Rights are Reserved to the U.S. Government.
This software is provided "as is" without any warranty of any kind, either expressed, implied, or statutory, including, but not
limited to, any warranty that the software will conform to specifications, any implied warranties of merchantability, fitness
for a particular purpose, and freedom from infringement, and any warranty that the documentation will conform to the program, or
any warranty that the software will be error free.
In no event shall NASA be liable for any damages, including, but not limited to direct, indirect, special or consequential damages,
arising out of, resulting from, or in any way connected with the software or its documentation, whether or not based upon warranty,
contract, tort or otherwise, and whether or not loss was sustained from, or arose out of the results of, or use of, the software,
documentation or services provided hereunder.
ITC Team
NASA IV&V
[email protected]
*/

/**
* @brief Unit Test: Test
*
* Test mTLS (mutual trust) connection
*1) Required development packages: sudo yum install mariadb-connector-c-devel.x86_64
*
2)IMPORTANT:The .pem files & MySQL MUST be configured and on the host before running this test
* using this test refer to the guide:https://dev.mysql.com/doc/refman/8.0/en/encrypted-connections.html
*
The program requires these files to establish a TLS connection:
i) ssl_cert=/etc/pki/tls/certs/local-test-cert.pem
ii) ssl_key=/etc/pki/tls/private/local-test-key.pem
iii) ssl_ca=/etc/pki/tls/certs/ammos-ca-bundle.crt
3)IMPORTANT:Build with "cmake -DMYSQL=ON ."
*
IMPORTANT:The database must have similar configuration for this test to succeed:
MariaDB server to use the standard host-based <your_server_hots_name>.
In our case host was asec-cmdenc-dev2.jpl.nasa.gov
This was done by editing the server configuration file -- /etc/my.cnf.d/mariadb.server -- and adding the following options:

* For example:
ssl_cert=/etc/pki/tls/certs/local-test-cert.pem
ssl_key=/etc/pki/tls/private/local-test-key.pem
ssl_ca=/etc/pki/tls/certs/ammos-ca-bundle.crt

This user is setup to allow normal password access.
This user is allowed to access MariaDB on both the localhost and asec-cmdenc-dev2.jpl.nasa.gov hostnames,
and *can* use TLS to connect, but is NOT REQUIRED to. TLS access requires the use of the full hostname, since the server certificate will not validate for 'localhost'.

To connect using 2-way TLS, with any certificate:

To connect as testuser2 with 2-way TLS, using the local-test-cert.pem certificate:
mysql -u testuser2 -h asec-cmdenc-dev2.jpl.nasa.gov --ssl-ca=/etc/pki/tls/certs/ammos-ca-bundle.crt --ssl-verify-server-cert --ssl-cert=/etc/pki/tls/certs/local-test-cert.pem --ssl-key=/etc/pki/tls/private/local-test-key.pem
Password: mTLS does not require a password.
**/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ut_tc_apply.h"
#include "utest.h"
#include "crypto_error.h"
#include "crypto.h"
#include "crypto_error.h"
#include "sadb_routine.h"
#include "crypto_config_structs.h"
#include <mysql/mysql.h>


int32_t Crypto_Init_Unit_Test_For_DB(void);
/*Attempting to test a connection similar to command line authentication:
To connect as testuser2 with 2-way TLS, using the local-test-cert.pem certificate:
mysql -u testuser2 -h asec-cmdenc-dev2.jpl.nasa.gov --ssl-ca=/etc/pki/tls/certs/ammos-ca-bundle.crt --ssl-verify-server-cert --ssl-cert=/etc/pki/tls/certs/local-test-cert.pem --ssl-key=/etc/pki/tls/private/local-test-key.pem
Password: 2 way TLS or mTLS does not require a password.
However using the MySQL's C API*/
UTEST(MARIA_DB_CONNECTION_TESTS, TLS_TEST) {

printf("START mariadb connection, TLS test() \n");
int status = 0;
/*connection input parameters.
Note: username, pass, and paths may differ on your system*/
char* mysql_username = "testuser1";
char* password = "<PASSWORD>"; //replace with actual password or test will fail.
char* mysql_hostname = "asec-cmdenc-dev2.jpl.nasa.gov";
char* mysql_database = NULL;
uint16_t mysql_port = 3306;
/*encrypted_connection = 1 means we want to attempt a TLS encrypted connection.*/
uint8_t encrypted_connection = 1;
char* ssl_cert = "/etc/pki/tls/certs/ammos-server-cert.pem";
char* ssl_key = "/etc/pki/tls/private/ammos-server-key.pem";
char* ssl_ca = "/etc/pki/tls/certs/ammos-ca-bundle.crt";
char* ssl_capath = "/etc/pki/tls/certs/";
/*set configuration params*/
status = Crypto_Config_MariaDB(mysql_username, password, mysql_hostname, mysql_database, mysql_port, encrypted_connection, ssl_cert, ssl_key, ssl_ca, ssl_capath);
ASSERT_EQ(CRYPTO_LIB_SUCCESS, status);
/*Prepare SADB type from config*/
status = Crypto_Init_Unit_Test_For_DB();
ASSERT_EQ(CRYPTO_LIB_SUCCESS, status);
printf("END mariadb connection, TLS test() status:%d \n", status);
printf("START mariadb connection, mTLS test() \n");
status = 0;
/*connection input parameters.
Note: username, pass, and paths may differ on your system*/
mysql_username = "testuser2";
password = NULL; //mTLS does not require a password.
mysql_hostname = "asec-cmdenc-dev2.jpl.nasa.gov";
mysql_database = NULL;
mysql_port = 3306;
/*encrypted_connection = 2 means we want to attempt a mTLS encrypted connection.*/
encrypted_connection = 2;
ssl_cert = "/etc/pki/tls/certs/local-test-cert.pem";
ssl_key = "/etc/pki/tls/private/local-test-key.pem";
ssl_ca = "/etc/pki/tls/certs/ammos-ca-bundle.crt";
ssl_capath = "/etc/pki/tls/certs/";
/*set configuration params*/
status = Crypto_Config_MariaDB(mysql_username, password, mysql_hostname, mysql_database, mysql_port, encrypted_connection, ssl_cert, ssl_key, ssl_ca, ssl_capath);
ASSERT_EQ(CRYPTO_LIB_SUCCESS, status);
/*Prepare SADB type from config*/
status = Crypto_Init_Unit_Test_For_DB();
ASSERT_EQ(CRYPTO_LIB_SUCCESS, status);
printf("END mariadb connection, mTLS test() status:%d \n", status);

}

/*Helper Functions:*/

/*
* Note: SADB_TYPE_INMEMORY was change to SADB_TYPE_MARIADB for this test only.
*/
int32_t Crypto_Init_Unit_Test_For_DB(void) {
int32_t status = CRYPTO_LIB_SUCCESS;

Crypto_Config_CryptoLib(SADB_TYPE_MARIADB, CRYPTOGRAPHY_TYPE_LIBGCRYPT, CRYPTO_TC_CREATE_FECF_TRUE, TC_PROCESS_SDLS_PDUS_TRUE, TC_HAS_PUS_HDR,
TC_IGNORE_SA_STATE_FALSE, TC_IGNORE_ANTI_REPLAY_FALSE, TC_UNIQUE_SA_PER_MAP_ID_TRUE,
TC_CHECK_FECF_TRUE, 0x3F);
Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 0, TC_HAS_FECF, TC_HAS_SEGMENT_HDRS);
Crypto_Config_Add_Gvcid_Managed_Parameter(0, 0x0003, 1, TC_HAS_FECF, TC_HAS_SEGMENT_HDRS);
status = Crypto_Init();
return status;
}
UTEST_MAIN();
Loading