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

Check for min and max tls #411

Merged
merged 11 commits into from
Nov 22, 2023
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# Zowe Common C Changelog

## `2.13.0`
- Added support for using "zowe.network" and "components.zss.zowe.network" to set TLS version properties. (#411)

## `2.11.0`

- WTO printing methods have been moved to zos.c to be more available as utilities (for ex: for the Launcher)
Expand Down
102 changes: 90 additions & 12 deletions c/tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "fdpoll.h"
#include "tls.h"
#include "zos.h"
#include "logging.h"

int getClientCertificate(gsk_handle soc_handle, char *clientCertificate, unsigned int clientCertificateBufferSize, unsigned int *clientCertificateLength) {

Expand Down Expand Up @@ -55,17 +56,62 @@ int getClientCertificate(gsk_handle soc_handle, char *clientCertificate, unsigne
return rc;
}

static int isTLSV13Enabled(TlsSettings *settings) {
static int isTLSV13Available(TlsSettings *settings) {
ECVT *ecvt = getECVT();
if ((ecvt->ecvtpseq > 0x1020300) && (settings->maxTls == NULL || !strcmp(settings->maxTls, "TLSv1.3"))) {
if (ecvt->ecvtpseq > 0x1020300) {
return true;
}
/*
Default to false for versions lower than 2.3 and when set to anything other than TLSV1.3.
zOS 2.3 and below do not support tls v1.3 in gsk
*/
return false;
}

#define TLS_INVALID 0
#define TLS_V1_0 1
#define TLS_V1_1 2
#define TLS_V1_2 3
#define TLS_V1_3 4

#define TLS_MIN_DEFAULT TLS_V1_2
#define TLS_MAX_DEFAULT TLS_V1_3

static char *TLS_NAMES[5] = {
"invalid",
"TLSv1.0",
"TLSv1.1",
"TLSv1.2",
"TLSv1.3"
};

#define TLS_NAMES_LENGTH 5

static int getTlsMax(TlsSettings *settings) {
if (settings->maxTls != NULL) {
for (int i = 0; i < TLS_NAMES_LENGTH; i++) {
if (!strcmp(settings->maxTls, TLS_NAMES[i])) {
zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "Min TLS requested=%d\n",i);
return i;
}
}
}
zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "Min TLS defaulting\n");
return TLS_MAX_DEFAULT;
}

static int getTlsMin(TlsSettings *settings) {
if (settings->minTls != NULL) {
for (int i = 0; i < TLS_NAMES_LENGTH; i++) {
if (!strcmp(settings->minTls, TLS_NAMES[i])) {
zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "Max TLS requested=%d\n",i);
return i;
}
}
}
zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "Max TLS defaulting\n");
return TLS_MIN_DEFAULT;
}

int tlsInit(TlsEnvironment **outEnv, TlsSettings *settings) {
int rc = 0;
TlsEnvironment *env = (TlsEnvironment *)safeMalloc(sizeof(*env), "Tls Environment");
Expand All @@ -76,14 +122,38 @@ int tlsInit(TlsEnvironment **outEnv, TlsSettings *settings) {
rc = rc || gsk_environment_open(&env->envHandle);
rc = rc || gsk_attribute_set_enum(env->envHandle, GSK_PROTOCOL_SSLV2, GSK_PROTOCOL_SSLV2_OFF);
rc = rc || gsk_attribute_set_enum(env->envHandle, GSK_PROTOCOL_SSLV3, GSK_PROTOCOL_SSLV3_OFF);
rc = rc || gsk_attribute_set_enum(env->envHandle, GSK_PROTOCOL_TLSV1, GSK_PROTOCOL_TLSV1_OFF);
rc = rc || gsk_attribute_set_enum(env->envHandle, GSK_PROTOCOL_TLSV1_1, GSK_PROTOCOL_TLSV1_1_OFF);
rc = rc || gsk_attribute_set_enum(env->envHandle, GSK_PROTOCOL_TLSV1_2, GSK_PROTOCOL_TLSV1_2_ON);
/*
We will treat not set as allowing TLSv1.3.
*/
if (isTLSV13Enabled(settings)) {

int tlsMin = getTlsMin(settings);
int tlsMax = getTlsMax(settings);
if (tlsMax < tlsMin) {
tlsMin = tlsMax;
}
if (tlsMin <= TLS_V1_0 && tlsMax >= TLS_V1_0) {
zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "TLS 1.0 on\n");
rc = rc || gsk_attribute_set_enum(env->envHandle, GSK_PROTOCOL_TLSV1, GSK_PROTOCOL_TLSV1_ON);
} else {
zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "TLS 1.0 off\n");
rc = rc || gsk_attribute_set_enum(env->envHandle, GSK_PROTOCOL_TLSV1, GSK_PROTOCOL_TLSV1_OFF);
}
if (tlsMin <= TLS_V1_1 && tlsMax >= TLS_V1_1) {
Copy link
Member Author

@1000TurquoisePogs 1000TurquoisePogs Nov 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

leave out tls 1.1 and tls 1.0

zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "TLS 1.1 on\n");
rc = rc || gsk_attribute_set_enum(env->envHandle, GSK_PROTOCOL_TLSV1_1, GSK_PROTOCOL_TLSV1_1_ON);
} else {
zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "TLS 1.1 off\n");
rc = rc || gsk_attribute_set_enum(env->envHandle, GSK_PROTOCOL_TLSV1_1, GSK_PROTOCOL_TLSV1_1_OFF);
}
if (tlsMin <= TLS_V1_2 && tlsMax >= TLS_V1_2) {
zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "TLS 1.2 on\n");
rc = rc || gsk_attribute_set_enum(env->envHandle, GSK_PROTOCOL_TLSV1_2, GSK_PROTOCOL_TLSV1_2_ON);
} else {
zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "TLS 1.2 off\n");
rc = rc || gsk_attribute_set_enum(env->envHandle, GSK_PROTOCOL_TLSV1_2, GSK_PROTOCOL_TLSV1_2_OFF);
}
if (isTLSV13Available(settings) && tlsMin <= TLS_V1_3 && tlsMax >= TLS_V1_3) {
zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "TLS 1.3 on\n");
rc = rc || gsk_attribute_set_enum(env->envHandle, GSK_PROTOCOL_TLSV1_3, GSK_PROTOCOL_TLSV1_3_ON);
} else {
zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "TLS 1.3 off\n");
}
rc = rc || gsk_attribute_set_enum(env->envHandle, GSK_SERVER_EPHEMERAL_DH_GROUP_SIZE, GSK_SERVER_EPHEMERAL_DH_GROUP_SIZE_2048);

Expand Down Expand Up @@ -173,14 +243,22 @@ int tlsSocketInit(TlsEnvironment *env, TlsSocket **outSocket, int fd, bool isSer
rc = rc || gsk_attribute_set_buffer(socket->socketHandle, GSK_KEYRING_LABEL, label, 0);
}
if (ciphers) {
zowelog(NULL, LOG_COMP_HTTPSERVER, ZOWE_LOG_DEBUG, "Ciphers set to %s\n", ciphers);
rc = rc || gsk_attribute_set_buffer(socket->socketHandle, GSK_V3_CIPHER_SPECS_EXPANDED, ciphers, 0);
rc = rc || gsk_attribute_set_enum(socket->socketHandle, GSK_V3_CIPHERS, GSK_V3_CIPHERS_CHAR4);
}
rc = rc || gsk_attribute_set_enum(socket->socketHandle, GSK_SESSION_TYPE, isServer ? GSK_SERVER_SESSION_WITH_CL_AUTH : GSK_CLIENT_SESSION);

int tlsMin = getTlsMin(env->settings);
int tlsMax = getTlsMax(env->settings);
if (tlsMax < tlsMin) {
tlsMin = tlsMax;
}

/*
To be safe,
To be safe, only enable tls 1.3 content when it is being used
*/
if (isTLSV13Enabled(env->settings)) {
if (isTLSV13Available(env->settings) && tlsMin <= TLS_V1_3 && tlsMax >= TLS_V1_3) {
if (keyshares) {
/*
Only TLS 1.3 needs this.
Expand Down
98 changes: 98 additions & 0 deletions h/tls.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ typedef struct TlsSettings_tag {
TODO: Find out why it isn't negotiating 1.2.
*/
char *maxTls;
char *minTls;
} TlsSettings;

typedef struct TlsEnvironment_tag {
Expand All @@ -146,6 +147,103 @@ typedef struct TlsSocket_tag {
gsk_handle socketHandle;
} TlsSocket;

typedef struct CipherMap_tag {
const char* name;
const char* suiteId; //number string
} CipherMap;

#define TLS_IANA_CIPHER_MAP(ianaCipherMap)\
static const CipherMap ianaCipherMap[] = {\
{"TLS_NULL_WITH_NULL_NULL", TLS_NULL_WITH_NULL_NULL},\
{"TLS_RSA_WITH_NULL_MD5", TLS_RSA_WITH_NULL_MD5},\
{"TLS_RSA_WITH_NULL_SHA", TLS_RSA_WITH_NULL_SHA},\
{"TLS_RSA_EXPORT_WITH_RC4_40_MD5", TLS_RSA_EXPORT_WITH_RC4_40_MD5},\
{"TLS_RSA_WITH_RC4_128_MD5", TLS_RSA_WITH_RC4_128_MD5},\
{"TLS_RSA_WITH_RC4_128_SHA", TLS_RSA_WITH_RC4_128_SHA},\
{"TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5", TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5},\
{"TLS_RSA_WITH_DES_CBC_SHA", TLS_RSA_WITH_DES_CBC_SHA},\
{"TLS_RSA_WITH_3DES_EDE_CBC_SHA", TLS_RSA_WITH_3DES_EDE_CBC_SHA},\
{"TLS_DH_DSS_WITH_DES_CBC_SHA", TLS_DH_DSS_WITH_DES_CBC_SHA},\
{"TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA", TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA},\
{"TLS_DH_RSA_WITH_DES_CBC_SHA", TLS_DH_RSA_WITH_DES_CBC_SHA},\
{"TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA", TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA},\
{"TLS_DHE_DSS_WITH_DES_CBC_SHA", TLS_DHE_DSS_WITH_DES_CBC_SHA},\
{"TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA", TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA},\
{"TLS_DHE_RSA_WITH_DES_CBC_SHA", TLS_DHE_RSA_WITH_DES_CBC_SHA},\
{"TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA", TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA},\
{"TLS_RSA_WITH_AES_128_CBC_SHA", TLS_RSA_WITH_AES_128_CBC_SHA},\
{"TLS_DH_DSS_WITH_AES_128_CBC_SHA", TLS_DH_DSS_WITH_AES_128_CBC_SHA},\
{"TLS_DH_RSA_WITH_AES_128_CBC_SHA", TLS_DH_RSA_WITH_AES_128_CBC_SHA},\
{"TLS_DHE_DSS_WITH_AES_128_CBC_SHA", TLS_DHE_DSS_WITH_AES_128_CBC_SHA},\
{"TLS_DHE_RSA_WITH_AES_128_CBC_SHA", TLS_DHE_RSA_WITH_AES_128_CBC_SHA},\
{"TLS_RSA_WITH_AES_256_CBC_SHA", TLS_RSA_WITH_AES_256_CBC_SHA},\
{"TLS_DH_DSS_WITH_AES_256_CBC_SHA", TLS_DH_DSS_WITH_AES_256_CBC_SHA},\
{"TLS_DH_RSA_WITH_AES_256_CBC_SHA", TLS_DH_RSA_WITH_AES_256_CBC_SHA},\
{"TLS_DHE_DSS_WITH_AES_256_CBC_SHA", TLS_DHE_DSS_WITH_AES_256_CBC_SHA},\
{"TLS_DHE_RSA_WITH_AES_256_CBC_SHA", TLS_DHE_RSA_WITH_AES_256_CBC_SHA},\
{"TLS_RSA_WITH_NULL_SHA256", TLS_RSA_WITH_NULL_SHA256},\
{"TLS_RSA_WITH_AES_128_CBC_SHA256", TLS_RSA_WITH_AES_128_CBC_SHA256},\
{"TLS_RSA_WITH_AES_256_CBC_SHA256", TLS_RSA_WITH_AES_256_CBC_SHA256},\
{"TLS_DH_DSS_WITH_AES_128_CBC_SHA256", TLS_DH_DSS_WITH_AES_128_CBC_SHA256},\
{"TLS_DH_RSA_WITH_AES_128_CBC_SHA256", TLS_DH_RSA_WITH_AES_128_CBC_SHA256},\
{"TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", TLS_DHE_DSS_WITH_AES_128_CBC_SHA256},\
{"TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", TLS_DHE_RSA_WITH_AES_128_CBC_SHA256},\
{"TLS_DH_DSS_WITH_AES_256_CBC_SHA256", TLS_DH_DSS_WITH_AES_256_CBC_SHA256},\
{"TLS_DH_RSA_WITH_AES_256_CBC_SHA256", TLS_DH_RSA_WITH_AES_256_CBC_SHA256},\
{"TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", TLS_DHE_DSS_WITH_AES_256_CBC_SHA256},\
{"TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", TLS_DHE_RSA_WITH_AES_256_CBC_SHA256},\
{"TLS_RSA_WITH_AES_128_GCM_SHA256", TLS_RSA_WITH_AES_128_GCM_SHA256},\
{"TLS_RSA_WITH_AES_256_GCM_SHA384", TLS_RSA_WITH_AES_256_GCM_SHA384},\
{"TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},\
{"TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", TLS_DHE_RSA_WITH_AES_256_GCM_SHA384},\
{"TLS_DH_RSA_WITH_AES_128_GCM_SHA256", TLS_DH_RSA_WITH_AES_128_GCM_SHA256},\
{"TLS_DH_RSA_WITH_AES_256_GCM_SHA384", TLS_DH_RSA_WITH_AES_256_GCM_SHA384},\
{"TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", TLS_DHE_DSS_WITH_AES_128_GCM_SHA256},\
{"TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", TLS_DHE_DSS_WITH_AES_256_GCM_SHA384},\
{"TLS_DH_DSS_WITH_AES_128_GCM_SHA256", TLS_DH_DSS_WITH_AES_128_GCM_SHA256},\
{"TLS_DH_DSS_WITH_AES_256_GCM_SHA384", TLS_DH_DSS_WITH_AES_256_GCM_SHA384},\
{"TLS_ECDH_ECDSA_WITH_NULL_SHA", TLS_ECDH_ECDSA_WITH_NULL_SHA},\
{"TLS_ECDH_ECDSA_WITH_RC4_128_SHA", TLS_ECDH_ECDSA_WITH_RC4_128_SHA},\
{"TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA},\
{"TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA},\
{"TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA},\
{"TLS_ECDHE_ECDSA_WITH_NULL_SHA", TLS_ECDHE_ECDSA_WITH_NULL_SHA},\
{"TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", TLS_ECDHE_ECDSA_WITH_RC4_128_SHA},\
{"TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA},\
{"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA},\
{"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA},\
{"TLS_ECDH_RSA_WITH_NULL_SHA", TLS_ECDH_RSA_WITH_NULL_SHA},\
{"TLS_ECDH_RSA_WITH_RC4_128_SHA", TLS_ECDH_RSA_WITH_RC4_128_SHA},\
{"TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA},\
{"TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", TLS_ECDH_RSA_WITH_AES_128_CBC_SHA},\
{"TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", TLS_ECDH_RSA_WITH_AES_256_CBC_SHA},\
{"TLS_ECDHE_RSA_WITH_NULL_SHA", TLS_ECDHE_RSA_WITH_NULL_SHA},\
{"TLS_ECDHE_RSA_WITH_RC4_128_SHA", TLS_ECDHE_RSA_WITH_RC4_128_SHA},\
{"TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA},\
{"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},\
{"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},\
{"TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},\
{"TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384},\
{"TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256},\
{"TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384},\
{"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256},\
{"TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384},\
{"TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256},\
{"TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384},\
{"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},\
{"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384},\
{"TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256},\
{"TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384},\
{"TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},\
{"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384},\
{"TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256},\
{"TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384},\
{"TLS_AES_128_GCM_SHA256", TLS_AES_128_GCM_SHA256},\
{"TLS_AES_256_GCM_SHA384", TLS_AES_256_GCM_SHA384},\
{"TLS_CHACHA20_POLY1305_SHA256", TLS_CHACHA20_POLY1305_SHA256},\
{0, NULL}\
};

int tlsInit(TlsEnvironment **outEnv, TlsSettings *settings);
int tlsDestroy(TlsEnvironment *env);
int tlsSocketInit(TlsEnvironment *env, TlsSocket **outSocket, int fd, bool isServer);
Expand Down
Loading