diff --git a/apps/wolfsshd/configuration.c b/apps/wolfsshd/configuration.c index 473b0e280..1ddb5ccba 100644 --- a/apps/wolfsshd/configuration.c +++ b/apps/wolfsshd/configuration.c @@ -80,6 +80,9 @@ struct WOLFSSHD_CONFIG { char* authKeysFile; char* forceCmd; char* pidFile; + char* winUserStores; + char* winUserDwFlags; + char* winUserPvPara; WOLFSSHD_CONFIG* next; /* next config in list */ long loginTimer; word16 port; @@ -89,6 +92,8 @@ struct WOLFSSHD_CONFIG { byte permitRootLogin:1; byte permitEmptyPasswords:1; byte authKeysFileSet:1; /* if not set then no explicit authorized keys */ + byte useSystemCA:1; + byte useUserCAStore:1; }; int CountWhitespace(const char* in, int inSz, byte inv); @@ -312,6 +317,9 @@ void wolfSSHD_ConfigFree(WOLFSSHD_CONFIG* conf) FreeString(¤t->hostKeyFile, heap); FreeString(¤t->hostCertFile, heap); FreeString(¤t->pidFile, heap); + FreeString(¤t->winUserStores, heap); + FreeString(¤t->winUserDwFlags, heap); + FreeString(¤t->winUserPvPara, heap); WFREE(current, heap, DYNTYPE_SSHD); current = next; @@ -350,9 +358,14 @@ enum { OPT_TRUSTED_USER_CA_KEYS = 21, OPT_PIDFILE = 22, OPT_BANNER = 23, + OPT_TRUSTED_SYSTEM_CA_KEYS = 24, + OPT_TRUSTED_USER_CA_STORE = 25, + OPT_WIN_USER_STORES = 26, + OPT_WIN_USER_DW_FLAGS = 27, + OPT_WIN_USER_PV_PARA = 28 }; enum { - NUM_OPTIONS = 24 + NUM_OPTIONS = 29 }; static const CONFIG_OPTION options[NUM_OPTIONS] = { @@ -380,6 +393,11 @@ static const CONFIG_OPTION options[NUM_OPTIONS] = { {OPT_TRUSTED_USER_CA_KEYS, "TrustedUserCAKeys"}, {OPT_PIDFILE, "PidFile"}, {OPT_BANNER, "Banner"}, + {OPT_TRUSTED_SYSTEM_CA_KEYS, "wolfSSH_TrustedSystemCAKeys"}, + {OPT_TRUSTED_USER_CA_STORE, "wolfSSH_TrustedUserCaStore"}, + {OPT_WIN_USER_STORES, "wolfSSH_WinUserStores"}, + {OPT_WIN_USER_DW_FLAGS, "wolfSSH_WinUserDwFlags"}, + {OPT_WIN_USER_PV_PARA, "wolfSSH_WinUserPvPara"}, }; /* returns WS_SUCCESS on success */ @@ -1021,12 +1039,27 @@ 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; case OPT_BANNER: ret = SetFileString(&(*conf)->banner, value, (*conf)->heap); break; + case OPT_TRUSTED_USER_CA_STORE: + ret = wolfSSHD_ConfigSetUserCAStore(*conf, value); + break; + case OPT_WIN_USER_STORES: + ret = wolfSSHD_ConfigSetWinUserStores(*conf, value); + break; + case OPT_WIN_USER_DW_FLAGS: + ret = wolfSSHD_ConfigSetWinUserDwFlags(*conf, value); + break; + case OPT_WIN_USER_PV_PARA: + ret = wolfSSHD_ConfigSetWinUserPvPara(*conf, value); + break; default: break; } @@ -1309,6 +1342,157 @@ 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; +} + +/* getter function for if using user CA store + * return 1 if true and 0 if false */ +int wolfSSHD_ConfigGetUserCAStore(const WOLFSSHD_CONFIG* conf) +{ + if (conf != NULL) { + return conf->useUserCAStore; + } + return 0; +} + + +/* setter function for if using user CA store + * 'yes' if true and 'no' if false + * returns WS_SUCCESS on success */ +int wolfSSHD_ConfigSetUserCAStore(WOLFSSHD_CONFIG* conf, const char* value) +{ + int ret = WS_SUCCESS; + + if (conf != NULL) { + if (WSTRCMP(value, "yes") == 0) { + wolfSSH_Log(WS_LOG_INFO, "[SSHD] User CA store enabled. Note this " + "is currently only supported on Windows."); + conf->useUserCAStore = 1; + } + else if (WSTRCMP(value, "no") == 0) { + wolfSSH_Log(WS_LOG_INFO, "[SSHD] User CA store disabled"); + conf->useUserCAStore = 0; + } + else { + wolfSSH_Log(WS_LOG_INFO, "[SSHD] User CA store unexpected flag"); + ret = WS_FATAL_ERROR; + } + } + + return ret; +} + +char* wolfSSHD_ConfigGetWinUserStores(WOLFSSHD_CONFIG* conf) { + if (conf != NULL) { + if (conf->winUserStores == NULL) { + /* If no value was specified, default to CERT_STORE_PROV_SYSTEM */ + CreateString(&conf->winUserStores, "CERT_STORE_PROV_SYSTEM", + (int)WSTRLEN("CERT_STORE_PROV_SYSTEM"), conf->heap); + } + + return conf->winUserStores; + } + + return NULL; +} + +int wolfSSHD_ConfigSetWinUserStores(WOLFSSHD_CONFIG* conf, const char* value) { + int ret = WS_SUCCESS; + + if (conf == NULL) { + ret = WS_BAD_ARGUMENT; + } + + ret = CreateString(&conf->winUserStores, value, (int)WSTRLEN(value), conf->heap); + + return ret; +} + +char* wolfSSHD_ConfigGetWinUserDwFlags(WOLFSSHD_CONFIG* conf) { + if (conf != NULL) { + if (conf->winUserDwFlags == NULL) { + /* If no value was specified, default to CERT_SYSTEM_STORE_CURRENT_USER */ + CreateString(&conf->winUserDwFlags, "CERT_SYSTEM_STORE_CURRENT_USER", + (int)WSTRLEN("CERT_SYSTEM_STORE_CURRENT_USER"), conf->heap); + } + + return conf->winUserDwFlags; + } + + return NULL; +} + +int wolfSSHD_ConfigSetWinUserDwFlags(WOLFSSHD_CONFIG* conf, const char* value) { + int ret = WS_SUCCESS; + + if (conf == NULL) { + ret = WS_BAD_ARGUMENT; + } + + ret = CreateString(&conf->winUserDwFlags, value, (int)WSTRLEN(value), conf->heap); + + return ret; +} + +char* wolfSSHD_ConfigGetWinUserPvPara(WOLFSSHD_CONFIG* conf) { + if (conf != NULL) { + if (conf->winUserPvPara == NULL) { + /* If no value was specified, default to MY */ + CreateString(&conf->winUserPvPara, "MY", (int)WSTRLEN("MY"), conf->heap); + } + + return conf->winUserPvPara; + } + + return NULL; +} + +int wolfSSHD_ConfigSetWinUserPvPara(WOLFSSHD_CONFIG* conf, const char* value) { + int ret = WS_SUCCESS; + + if (conf == NULL) { + ret = WS_BAD_ARGUMENT; + } + + ret = CreateString(&conf->winUserPvPara, value, (int)WSTRLEN(value), conf->heap); + + return ret; +} + char* wolfSSHD_ConfigGetUserCAKeysFile(const WOLFSSHD_CONFIG* conf) { char* ret = NULL; diff --git a/apps/wolfsshd/configuration.h b/apps/wolfsshd/configuration.h index e39d9fa20..5551a69bd 100644 --- a/apps/wolfsshd/configuration.h +++ b/apps/wolfsshd/configuration.h @@ -42,6 +42,16 @@ char* wolfSSHD_ConfigGetHostCertFile(const WOLFSSHD_CONFIG* conf); char* wolfSSHD_ConfigGetUserCAKeysFile(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_ConfigSetUserCAStore(WOLFSSHD_CONFIG* conf, const char* value); +int wolfSSHD_ConfigGetUserCAStore(const WOLFSSHD_CONFIG* conf); +char* wolfSSHD_ConfigGetWinUserStores(WOLFSSHD_CONFIG* conf); +int wolfSSHD_ConfigSetWinUserStores(WOLFSSHD_CONFIG* conf, const char* value); +char* wolfSSHD_ConfigGetWinUserDwFlags(WOLFSSHD_CONFIG* conf); +int wolfSSHD_ConfigSetWinUserDwFlags(WOLFSSHD_CONFIG* conf, const char* value); +char* wolfSSHD_ConfigGetWinUserPvPara(WOLFSSHD_CONFIG* conf); +int wolfSSHD_ConfigSetWinUserPvPara(WOLFSSHD_CONFIG* conf, const char* value); int wolfSSHD_ConfigSetUserCAKeysFile(WOLFSSHD_CONFIG* conf, const char* file); word16 wolfSSHD_ConfigGetPort(const WOLFSSHD_CONFIG* conf); char* wolfSSHD_ConfigGetAuthKeysFile(const WOLFSSHD_CONFIG* conf); diff --git a/apps/wolfsshd/wolfsshd.c b/apps/wolfsshd/wolfsshd.c index 9ea7ed77e..372b16667 100644 --- a/apps/wolfsshd/wolfsshd.c +++ b/apps/wolfsshd/wolfsshd.c @@ -423,6 +423,56 @@ static int SetupCTX(WOLFSSHD_CONFIG* conf, WOLFSSH_CTX** ctx, #endif /* WOLFSSH_OSSH_CERTS || WOLFSSH_CERTS */ #ifdef WOLFSSH_CERTS + /* check if loading in system and/or user CA certs */ + #ifdef WOLFSSL_SYS_CA_CERTS + if (ret == WS_SUCCESS && (wolfSSHD_ConfigGetSystemCA(conf) + || wolfSSHD_ConfigGetUserCAStore(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 (wolfSSHD_ConfigGetSystemCA(conf)) { + 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 (wolfSSHD_ConfigGetUserCAStore(conf)) { + if (wolfSSL_CTX_load_windows_user_CA_certs(sslCtx, + wolfSSHD_ConfigGetWinUserStores(conf), + wolfSSHD_ConfigGetWinUserDwFlags(conf), + wolfSSHD_ConfigGetWinUserPvPara(conf)) != WOLFSSL_SUCCESS) { + wolfSSH_Log(WS_LOG_INFO, "[SSHD] Issue loading user 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); + } + } + #endif + + /* load in CA certs from file set */ if (ret == WS_SUCCESS) { char* caCert = wolfSSHD_ConfigGetUserCAKeysFile(conf); if (caCert != NULL) { diff --git a/examples/echoserver/echoserver.c b/examples/echoserver/echoserver.c index 97d3accfa..48eca62b3 100644 --- a/examples/echoserver/echoserver.c +++ b/examples/echoserver/echoserver.c @@ -2855,8 +2855,6 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args) #endif /* NO_WOLFSSH_SERVER */ -void wolfSSL_Debugging_ON(void); - int wolfSSH_Echoserver(int argc, char** argv) { func_args args; diff --git a/src/certman.c b/src/certman.c index 40b8eba7a..41fd327a9 100644 --- a/src/certman.c +++ b/src/certman.c @@ -36,7 +36,6 @@ #endif -#include #include #include #include @@ -84,6 +83,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; diff --git a/wolfssh/certman.h b/wolfssh/certman.h index 63e4542de..7431a72de 100644 --- a/wolfssh/certman.h +++ b/wolfssh/certman.h @@ -30,6 +30,7 @@ #include #include +#include /* 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); diff --git a/wolfssh/test.h b/wolfssh/test.h index 0d1e129b6..9cf524b01 100644 --- a/wolfssh/test.h +++ b/wolfssh/test.h @@ -1117,6 +1117,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, @@ -1186,7 +1187,9 @@ static int Base16_Decode(const byte* in, word32 inLen, *outLen = outIdx; return 0; } - +#else + #include +#endif /* !WOLFSSL_BASE16 */ static void FreeBins(byte* b1, byte* b2, byte* b3, byte* b4) {