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

Add cipher customization support #666

Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ All notable changes to the ZSS package will be documented in this file.

## `2.13.0`
- Enhancement: Added support for using "zowe.network" and "components.app-server.zowe.network" to set listener IP and TLS version properties. (#659)
- Enhancement: Added support for using "zowe.network" and "components.app-server.zowe.network" to set cipher suites. (#666)
- Enhancement: Change pattern matching for keyrings to allow more types of keyrings in the future (#581)
- Bugfix: Corrected build environment file's use of IP address to github.com (#660)

Expand Down
42 changes: 38 additions & 4 deletions c/zss.c
Original file line number Diff line number Diff line change
Expand Up @@ -1147,6 +1147,8 @@ static char* generateCookieName(JsonObject *envConfig, int port) {
#define AGENT_HTTPS_PREFIX "ZWED_agent_https_"
#define ENV_AGENT_HTTPS_KEY(key) AGENT_HTTPS_PREFIX key

TLS_IANA_CIPHER_MAP(ianaCipherMap)

static bool readAgentHttpsSettingsV2(ShortLivedHeap *slh,
ConfigManager *configmgr,
char **outAddress,
Expand All @@ -1162,13 +1164,45 @@ static bool readAgentHttpsSettingsV2(ShortLivedHeap *slh,
TlsSettings *settings = (TlsSettings*)SLHAlloc(slh, sizeof(*settings));
settings->maxTls = jsonObjectGetString(httpsConfigObject, "maxTls");
settings->minTls = jsonObjectGetString(httpsConfigObject, "minTls");
char *ciphers = jsonObjectGetString(httpsConfigObject, "ciphers");

Json *cipherJson = jsonObjectGetPropertyValue(httpsConfigObject, "ciphers");
char *ciphers = NULL;
if (jsonIsString(cipherJson)) {
/*
* Takes a string of ciphers. This isn't ideal, but any other methods are
* going to be fairly complicated.
*
* Takes a string of ciphers.
* ciphers: 13021303003500380039002F00320033
*/
ciphers = jsonObjectGetString(httpsConfigObject, "ciphers");
zowelog(NULL, LOG_COMP_ID_MVD_SERVER, ZOWE_LOG_DEBUG, "Cipher string override to %s\n", ciphers);
} else {
JsonArray *cipherArray = jsonObjectGetArray(httpsConfigObject, "ciphers");
int count = jsonArrayGetCount(cipherArray);

int cipherCharLength = 4;
ciphers = (char *)safeMalloc((sizeof(char) * cipherCharLength * count)+1, "cipher list");

for (int i = 0; i < count; i++) {
char *ianaName = jsonArrayGetString(cipherArray, i);
zowelog(NULL, LOG_COMP_ID_MVD_SERVER, ZOWE_LOG_DEBUG, "Cipher request=%s\n", ianaName);
CipherMap *cipher = (CipherMap *)ianaCipherMap;
bool found = false;
while (cipher->suiteId != NULL) {
1000TurquoisePogs marked this conversation as resolved.
Show resolved Hide resolved
if (!strcmp(ianaName, cipher->name)) {
1000TurquoisePogs marked this conversation as resolved.
Show resolved Hide resolved
strcat(ciphers, cipher->suiteId);
zowelog(NULL, LOG_COMP_ID_MVD_SERVER, ZOWE_LOG_DEBUG, "Cipher match=%s\n", cipher->suiteId);
found = true;
break;
}
++cipher;
}
if (!found) {
zowelog(NULL, LOG_COMP_ID_MVD_SERVER, ZOWE_LOG_WARNING, ZSS_LOG_CIPHER_INVALID_MSG, ianaName);
}
}
zowelog(NULL, LOG_COMP_ID_MVD_SERVER, ZOWE_LOG_DEBUG, "Cipher array override to %s\n", ciphers);

}

ECVT *ecvt = getECVT();
/*
2.3 (1020300) no tls 1.3
Expand Down
5 changes: 3 additions & 2 deletions defaults.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ components:
label: ${{ ()=> { if (components.zss.tls) { return zowe.certificate.keystore.alias } else { return null } }() }}
port: ${{ ()=> { if (components.zss.tls) { return components.zss.port } else { return null } }() }}
ipAddresses: "${{ ()=> { if (components.zss.tls){ if (zowe.environments?.ZWED_agent_https_ipAddresses){ return zowe.environments.ZWED_agent_https_ipAddresses.split(',') } else if (components.zss.zowe?.network?.server?.listenAddresses) { return components.zss.zowe.network.server.listenAddresses } else if (zowe.network?.server?.listenAddresses) { return zowe.network.server.listenAddresses } else { return [ '0.0.0.0' ] } } else { return null } }() }}"
maxTls: "${{ ()=> { if (components.zss.zowe?.network?.server?.tls?.maxTls) { return components.zss.zowe.network.server.tls.maxTls } else if (zowe.network?.server?.tls?.maxTls) { return zowe.network.server.tls.maxTls } else { return 'TLSv1.3' } }() }}"
minTls: "${{ ()=> { if (components.zss.zowe?.network?.server?.tls?.minTls) { return components.zss.zowe.network.server.tls.minTls } else if (zowe.network?.server?.tls?.minTls) { return zowe.network.server.tls.minTls } else { return 'TLSv1.2' } }() }}"
maxTls: "${{ ()=> { let maxTls = components.zss.zowe?.network?.server?.tls?.maxTls || zowe.network?.server?.tls?.maxTls; return maxTls ? maxTls : 'TLSv1.3'; }() }}"
minTls: "${{ ()=> { let minTls = components.zss.zowe?.network?.server?.tls?.minTls || zowe.network?.server?.tls?.minTls; return minTls ? minTls : 'TLSv1.2'; }() }}"
ciphers: "${{ ()=> { let ciphers = components.zss.zowe?.network?.server?.tls?.ciphers || zowe.network?.server?.tls?.ciphers; if (typeof ciphers == 'string') { return ciphers; } else if (Array.isArray(ciphers)) { return ciphers.map(cipher => cipher.toUpperCase()); } else { return [ 'TLS_AES_256_GCM_SHA384', 'TLS_AES_128_GCM_SHA256', 'TLS_CHACHA20_POLY1305_SHA256', 'TLS_DHE_RSA_WITH_AES_128_GCM_SHA256', 'TLS_DHE_RSA_WITH_AES_256_GCM_SHA384', 'TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256', 'TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384', 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256', 'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384' ]; } }() }}"
http:
port: ${{ ()=> { if (components.zss.tls) { return null } else { return components.zss.port } }() }}
ipAddresses: "${{ () => { if (components.zss.tls) { return null } else { if (zowe.environments?.ZWED_agent_http_ipAddresses) { return zowe.environments.ZWED_agent_http_ipAddresses.split(',') } else if (components.zss.zowe?.network?.server?.listenAddresses) { return components.zss.zowe.network.server.listenAddresses } else if (zowe.network?.server?.listenAddresses) { return zowe.network.server.listenAddresses } else { return [ '127.0.0.1' ] } } }() }}"
Expand Down
2 changes: 1 addition & 1 deletion deps/zowe-common-c
Submodule zowe-common-c updated 2 files
+1 −0 c/tls.c
+97 −0 h/tls.h
7 changes: 7 additions & 0 deletions h/zssLogging.h
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,13 @@ bool isLogLevelValid(int level);
#define ZSS_LOG_HTTPS_INVALID_MSG_TEXT "Failed to configure https server, check agent https settings\n"
#define ZSS_LOG_HTTPS_INVALID_MSG ZSS_LOG_HTTPS_INVALID_MSG_ID" "ZSS_LOG_HTTPS_INVALID_MSG_TEXT

#ifndef ZSS_LOG_CIPHER_INVALID_MSG_ID
#define ZSS_LOG_CIPHER_INVALID_MSG_ID ZSS_LOG_MSG_PRFX"1066W"
#endif
#define ZSS_LOG_CIPHER_INVALID_MSG_TEXT "Requested cipher '%s' not available.\n"
#define ZSS_LOG_CIPHER_INVALID_MSG ZSS_LOG_CIPHER_INVALID_MSG_ID" "ZSS_LOG_CIPHER_INVALID_MSG_TEXT


/* registerProduct */

#ifndef ZSS_LOG_PROD_REG_ENABLED_MSG_ID
Expand Down
13 changes: 11 additions & 2 deletions schemas/zss-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,17 @@
"description": "The password to the keyring"
},
"ciphers": {
"type": [ "string", "null" ],
"description": "The list of ciphers in order of priority"
"oneOf": [
{ "type": "string",
"description": "A set of cipher suite IDs as a number string without separators. The numbers are in order of priority."
},
{ "type": "array",
"description": "A set of IANA names for cipher suites, in order of priority",
"items": {
"type": "string"
}
}
]
},
"keyshares": {
"type": [ "string", "null" ],
Expand Down
Loading