add TrustedSystemCAKeys sshd option for system CA load

pull/1242/head
JacobBarthelmeh 2023-09-12 14:15:23 -07:00 committed by John Safranek
parent fb15a05ed0
commit 37e75d4aa0
6 changed files with 105 additions and 4 deletions

View File

@ -109,6 +109,7 @@ struct WOLFSSHD_CONFIG {
byte permitEmptyPasswords:1;
byte authKeysFileSet:1; /* if not set then no explicit authorized keys */
byte strictModes:1; /* enforce file permission/ownership checks */
byte useSystemCA:1;
};
/* Maximum depth of nested Include directives. Bounds the recursion
@ -434,9 +435,10 @@ enum {
OPT_PUBKEY_AUTH = 24,
OPT_STRICT_MODES = 25,
OPT_AUTHORIZED_UPN_DOMAINS = 26,
OPT_TRUSTED_SYSTEM_CA_KEYS = 27,
};
enum {
NUM_OPTIONS = 27
NUM_OPTIONS = 28
};
/* bit in WOLFSSHD_CONFIG.setMask recording that option 'o' was set on a node.
@ -474,6 +476,7 @@ static const CONFIG_OPTION options[NUM_OPTIONS] = {
{OPT_FORCE_CMD, "ForceCommand"},
{OPT_HOST_CERT, "HostCertificate"},
{OPT_TRUSTED_USER_CA_KEYS, "TrustedUserCAKeys"},
{OPT_TRUSTED_SYSTEM_CA_KEYS, "TrustedSystemCAKeys"},
{OPT_PIDFILE, "PidFile"},
{OPT_BANNER, "Banner"},
{OPT_STRICT_MODES, "StrictModes"},
@ -1342,6 +1345,9 @@ static int HandleConfigOption(WOLFSSHD_CONFIG** conf, int opt,
/* TODO: Add logic to check if file exists? */
ret = wolfSSHD_ConfigSetUserCAKeysFile(*conf, value);
break;
case OPT_TRUSTED_SYSTEM_CA_KEYS:
ret = wolfSSHD_ConfigSetSystemCA(*conf, value);
break;
case OPT_PIDFILE:
ret = SetFileString(&(*conf)->pidFile, value, (*conf)->heap);
break;
@ -1818,6 +1824,44 @@ char* wolfSSHD_ConfigGetHostCertFile(const WOLFSSHD_CONFIG* conf)
return ret;
}
/* getter function for if using system CAs
* return 1 if true and 0 if false */
int wolfSSHD_ConfigGetSystemCA(const WOLFSSHD_CONFIG* conf)
{
if (conf != NULL) {
return conf->useSystemCA;
}
return 0;
}
/* setter function for if using system CAs
* 'yes' if true and 'no' if false
* returns WS_SUCCESS on success */
int wolfSSHD_ConfigSetSystemCA(WOLFSSHD_CONFIG* conf, const char* value)
{
int ret = WS_SUCCESS;
if (conf != NULL) {
if (WSTRCMP(value, "yes") == 0) {
wolfSSH_Log(WS_LOG_INFO, "[SSHD] System CAs enabled");
conf->useSystemCA = 1;
}
else if (WSTRCMP(value, "no") == 0) {
wolfSSH_Log(WS_LOG_INFO, "[SSHD] System CAs disabled");
conf->useSystemCA = 0;
}
else {
wolfSSH_Log(WS_LOG_INFO, "[SSHD] System CAs unexpected flag");
ret = WS_FATAL_ERROR;
}
}
return ret;
}
char* wolfSSHD_ConfigGetUserCAKeysFile(const WOLFSSHD_CONFIG* conf)
{
char* ret = NULL;

View File

@ -64,6 +64,8 @@ char* wolfSSHD_ConfigGetUserCAKeysFile(const WOLFSSHD_CONFIG* conf);
char* wolfSSHD_ConfigGetAuthorizedUPNDomains(const WOLFSSHD_CONFIG* conf);
int wolfSSHD_ConfigSetHostKeyFile(WOLFSSHD_CONFIG* conf, const char* file);
int wolfSSHD_ConfigSetHostCertFile(WOLFSSHD_CONFIG* conf, const char* file);
int wolfSSHD_ConfigSetSystemCA(WOLFSSHD_CONFIG* conf, const char* value);
int wolfSSHD_ConfigGetSystemCA(const WOLFSSHD_CONFIG* conf);
int wolfSSHD_ConfigSetUserCAKeysFile(WOLFSSHD_CONFIG* conf, const char* file);
word16 wolfSSHD_ConfigGetPort(const WOLFSSHD_CONFIG* conf);
char* wolfSSHD_ConfigGetAuthKeysFile(const WOLFSSHD_CONFIG* conf);

View File

@ -570,6 +570,39 @@ static int SetupCTX(WOLFSSHD_CONFIG* conf, WOLFSSH_CTX** ctx,
#endif /* WOLFSSH_OSSH_CERTS || WOLFSSH_CERTS */
#ifdef WOLFSSH_CERTS
/* check if loading in system CA certs */
if (ret == WS_SUCCESS && wolfSSHD_ConfigGetSystemCA(conf)) {
WOLFSSL_CTX* sslCtx;
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Using system CAs");
sslCtx = wolfSSL_CTX_new(wolfSSLv23_method());
if (sslCtx == NULL) {
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Unable to create temporary CTX");
ret = WS_FATAL_ERROR;
}
if (ret == WS_SUCCESS) {
if (wolfSSL_CTX_load_system_CA_certs(sslCtx) != WOLFSSL_SUCCESS) {
wolfSSH_Log(WS_LOG_INFO, "[SSHD] Issue loading system CAs");
ret = WS_FATAL_ERROR;
}
}
if (ret == WS_SUCCESS) {
if (wolfSSH_SetCertManager(*ctx,
wolfSSL_CTX_GetCertManager(sslCtx)) != WS_SUCCESS) {
wolfSSH_Log(WS_LOG_INFO,
"[SSHD] Issue copying over system CAs");
ret = WS_FATAL_ERROR;
}
}
if (sslCtx != NULL) {
wolfSSL_CTX_free(sslCtx);
}
}
/* load in CA certs from file set */
if (ret == WS_SUCCESS) {
char* caCert = wolfSSHD_ConfigGetUserCAKeysFile(conf);
if (caCert != NULL) {

View File

@ -36,7 +36,6 @@
#endif
#include <wolfssl/ssl.h>
#include <wolfssl/ocsp.h>
#include <wolfssl/wolfcrypt/asn.h>
#include <wolfssl/wolfcrypt/error-crypt.h>
@ -85,6 +84,26 @@ struct WOLFSSH_CERTMAN {
};
/* used to import an external cert manager, frees and replaces existing manager
* returns WS_SUCCESS on success
*/
int wolfSSH_SetCertManager(WOLFSSH_CTX* ctx, WOLFSSL_CERT_MANAGER* cm)
{
if (ctx == NULL || cm == NULL) {
return WS_BAD_ARGUMENT;
}
/* free up existing cm if present */
if (ctx->certMan != NULL && ctx->certMan->cm != NULL) {
wolfSSL_CertManagerFree(ctx->certMan->cm);
}
wolfSSL_CertManager_up_ref(cm);
ctx->certMan->cm = cm;
return WS_SUCCESS;
}
static WOLFSSH_CERTMAN* _CertMan_init(WOLFSSH_CERTMAN* cm, void* heap)
{
WOLFSSH_CERTMAN* ret = NULL;

View File

@ -30,6 +30,7 @@
#include <wolfssh/settings.h>
#include <wolfssh/port.h>
#include <wolfssl/ssl.h> /* included for WOLFSSL_CERT_MANAGER struct */
#ifdef __cplusplus
extern "C" {
@ -40,6 +41,9 @@ struct WOLFSSH_CERTMAN;
typedef struct WOLFSSH_CERTMAN WOLFSSH_CERTMAN;
WOLFSSH_API
int wolfSSH_SetCertManager(WOLFSSH_CTX* ctx, WOLFSSL_CERT_MANAGER* cm);
WOLFSSH_API
WOLFSSH_CERTMAN* wolfSSH_CERTMAN_new(void* heap);

View File

@ -1167,6 +1167,7 @@ static INLINE void build_addr_ipv6(struct sockaddr_in6* addr, const char* peer,
#define BAD 0xFF
#ifndef WOLFSSL_BASE16
static const byte hexDecode[] =
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
@ -1236,10 +1237,8 @@ static int Base16_Decode(const byte* in, word32 inLen,
*outLen = outIdx;
return 0;
}
#endif /* !WOLFSSL_BASE16 */
static void FreeBins(byte* b1, byte* b2, byte* b3, byte* b4)
{
if (b1 != NULL) free(b1);