diff --git a/CHANGELOG.md b/CHANGELOG.md index 4019d60ef..f272d1147 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) diff --git a/c/tls.c b/c/tls.c index 557034675..70af67fbe 100644 --- a/c/tls.c +++ b/c/tls.c @@ -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) { @@ -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"); @@ -78,12 +124,25 @@ int tlsInit(TlsEnvironment **outEnv, TlsSettings *settings) { 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_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); @@ -173,14 +232,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. diff --git a/h/tls.h b/h/tls.h index cf951cea4..e70c90091 100644 --- a/h/tls.h +++ b/h/tls.h @@ -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 { @@ -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);