Optional RSA

1. If RSA is disabled in the wolfCrypt build, the RSA related code
   in wolfSSH shall be disabled.
2. Examples will force themselves to use ECC if RSA is disabled.
pull/282/head
John Safranek 2020-09-04 15:28:25 -07:00
parent 45048426e0
commit 39f30e25a4
No known key found for this signature in database
GPG Key ID: 8CE817DE0D3CCB4A
9 changed files with 102 additions and 11 deletions

View File

@ -869,6 +869,10 @@ THREAD_RETURN WOLFSSH_THREAD client_test(void* args)
if (username == NULL)
err_sys("client requires a username parameter.");
#ifdef NO_RSA
userEcc = 1;
#endif
#ifdef SINGLE_THREADED
if (keepOpen)
err_sys("Threading needed for terminal session\n");

View File

@ -1602,6 +1602,12 @@ THREAD_RETURN WOLFSSH_THREAD echoserver_test(void* args)
}
#endif
#ifdef NO_RSA
/* If wolfCrypt isn't built with RSA, force ECC on. */
userEcc = 1;
peerEcc = 1;
#endif
if (wolfSSH_Init() != WS_SUCCESS) {
fprintf(stderr, "Couldn't initialize wolfSSH.\n");
exit(EXIT_FAILURE);

View File

@ -660,6 +660,11 @@ THREAD_RETURN WOLFSSH_THREAD server_test(void* args)
}
myoptind = 0; /* reset for test cases */
#ifdef NO_RSA
/* If wolfCrypt isn't built with RSA, force ECC on. */
useEcc = 1;
#endif
if (wolfSSH_Init() != WS_SUCCESS) {
fprintf(stderr, "Couldn't initialize wolfSSH.\n");
exit(EXIT_FAILURE);

View File

@ -1329,6 +1329,11 @@ THREAD_RETURN WOLFSSH_THREAD sftpclient_test(void* args)
if (username == NULL)
err_sys("client requires a username parameter.");
#ifdef NO_RSA
userEcc = 1;
/* peerEcc = 1; */
#endif
if (autopilot != AUTOPILOT_OFF) {
if (apLocal == NULL || apRemote == NULL) {
err_sys("Options -G and -g require both -l and -r.");

View File

@ -379,6 +379,7 @@ static int PostUnlock(WOLFSSH_AGENT_CTX* agent,
}
#ifndef NO_RSA
static int PostAddRsaId(WOLFSSH_AGENT_CTX* agent,
byte keyType, byte* key, word32 keySz,
word32 nSz, word32 eSz, word32 dSz,
@ -457,6 +458,7 @@ static int PostAddRsaId(WOLFSSH_AGENT_CTX* agent,
WLOG_LEAVE(ret);
return ret;
}
#endif
static int PostAddEcdsaId(WOLFSSH_AGENT_CTX* agent,
@ -667,6 +669,7 @@ static int PostSignRequest(WOLFSSH_AGENT_CTX* agent,
int sigSz = sizeof(sig);
if (cur->keyType == ID_SSH_RSA) {
#ifndef NO_RSA
WOLFSSH_AGENT_KEY_RSA* key;
RsaKey rsa;
byte encSig[MAX_ENCODED_SIG_SZ];
@ -708,6 +711,7 @@ static int PostSignRequest(WOLFSSH_AGENT_CTX* agent,
wc_FreeRsaKey(&rsa);
if (ret != 0)
ret = WS_RSA_E;
#endif
}
else if (cur->keyType == ID_ECDSA_SHA2_NISTP256) {
WOLFSSH_AGENT_KEY_ECDSA* key;
@ -942,6 +946,7 @@ static int DoAddIdentity(WOLFSSH_AGENT_CTX* agent,
begin += sz;
if (keyType == ID_SSH_RSA) {
#ifndef NO_RSA
byte* key;
byte* scratch;
word32 keySz, nSz, eSz, dSz, iqmpSz, pSz, qSz, commentSz;
@ -983,6 +988,7 @@ static int DoAddIdentity(WOLFSSH_AGENT_CTX* agent,
ret = PostAddRsaId(agent, keyType, key, keySz,
nSz, eSz, dSz, iqmpSz, pSz, qSz, commentSz);
}
#endif
}
else if (keyType == ID_ECDSA_SHA2_NISTP256 ||
keyType == ID_ECDSA_SHA2_NISTP384 ||

View File

@ -679,12 +679,15 @@ int wolfSSH_ProcessBuffer(WOLFSSH_CTX* ctx,
if (type == BUFTYPE_PRIVKEY && format != WOLFSSH_FORMAT_RAW) {
/* Check RSA key */
union {
#ifndef NO_RSA
RsaKey rsa;
#endif
ecc_key ecc;
} key;
word32 scratch = 0;
int ret;
#ifndef NO_RSA
if (wc_InitRsaKey(&key.rsa, NULL) < 0)
return WS_RSA_E;
@ -692,6 +695,7 @@ int wolfSSH_ProcessBuffer(WOLFSSH_CTX* ctx,
wc_FreeRsaKey(&key.rsa);
if (ret < 0) {
#endif
/* Couldn't decode as RSA key. Try decoding as ECC key. */
scratch = 0;
if (wc_ecc_init_ex(&key.ecc, ctx->heap, INVALID_DEVID) != 0)
@ -714,7 +718,9 @@ int wolfSSH_ProcessBuffer(WOLFSSH_CTX* ctx,
if (ret != 0)
return WS_BAD_FILE_E;
#ifndef NO_RSA
}
#endif
}
return WS_SUCCESS;
@ -2534,9 +2540,11 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
byte useRsa;
word32 keySz;
union {
#ifndef NO_RSA
struct {
RsaKey key;
} rsa;
#endif
struct {
ecc_key key;
} ecc;
@ -2733,6 +2741,7 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
sigKeyBlock.useRsa = ssh->handshake->pubKeyId == ID_SSH_RSA;
if (sigKeyBlock.useRsa) {
#ifndef NO_RSA
byte* e;
word32 eSz;
byte* n;
@ -2767,6 +2776,9 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
sigKeyBlock.keySz = sizeof(sigKeyBlock.sk.rsa.key);
else
ret = WS_RSA_E;
#else
(void)tmpIdx;
#endif
}
else {
byte* q;
@ -2901,6 +2913,7 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
}
if (ret == WS_SUCCESS) {
if (sigKeyBlock.useRsa) {
#ifndef NO_RSA
sig = sig + begin;
/* In the fuzz, sigSz ends up 1 and it has issues. */
sigSz = scratch;
@ -2929,6 +2942,7 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
ret = WS_RSA_E;
}
}
#endif
}
else {
byte* r;
@ -2966,8 +2980,11 @@ static int DoKexDhReply(WOLFSSH* ssh, byte* buf, word32 len, word32* idx)
}
}
if (sigKeyBlock.useRsa)
if (sigKeyBlock.useRsa) {
#ifndef NO_RSA
wc_FreeRsaKey(&sigKeyBlock.sk.rsa.key);
#endif
}
else
wc_ecc_free(&sigKeyBlock.sk.ecc.key);
}
@ -3558,7 +3575,7 @@ static int DoUserAuthRequestPassword(WOLFSSH* ssh, WS_UserAuthData* authData,
return ret;
}
#ifndef NO_RSA
/* Utility for DoUserAuthRequestPublicKey() */
/* returns negative for error, positive is size of digest. */
static int DoUserAuthRequestRsa(WOLFSSH* ssh, WS_UserAuthData_PublicKey* pk,
@ -3678,6 +3695,7 @@ static int DoUserAuthRequestRsa(WOLFSSH* ssh, WS_UserAuthData_PublicKey* pk,
WLOG(WS_LOG_DEBUG, "Leaving DoUserAuthRequestRsa(), ret = %d", ret);
return ret;
}
#endif
/* Utility for DoUserAuthRequestPublicKey() */
@ -3962,9 +3980,12 @@ static int DoUserAuthRequestPublicKey(WOLFSSH* ssh, WS_UserAuthData* authData,
}
if (ret == WS_SUCCESS) {
if (pkTypeId == ID_SSH_RSA)
if (pkTypeId == ID_SSH_RSA) {
#ifndef NO_RSA
ret = DoUserAuthRequestRsa(ssh, pk,
hashId, digest, digestSz);
#endif
}
else if (pkTypeId == ID_ECDSA_SHA2_NISTP256 ||
pkTypeId == ID_ECDSA_SHA2_NISTP384 ||
pkTypeId == ID_ECDSA_SHA2_NISTP521)
@ -6056,6 +6077,7 @@ int SendKexDhReply(WOLFSSH* ssh)
const char *name;
word32 nameSz;
union {
#ifndef NO_RSA
struct {
RsaKey key;
byte e[257];
@ -6065,6 +6087,7 @@ int SendKexDhReply(WOLFSSH* ssh)
word32 nSz;
byte nPad;
} rsa;
#endif
struct {
ecc_key key;
word32 keyBlobSz;
@ -6134,6 +6157,7 @@ int SendKexDhReply(WOLFSSH* ssh)
* either be RSA or ECDSA public key blob. */
if (ret == WS_SUCCESS) {
if (sigKeyBlock.useRsa) {
#ifndef NO_RSA
/* Decode the user-configured RSA private key. */
sigKeyBlock.sk.rsa.eSz = sizeof(sigKeyBlock.sk.rsa.e);
sigKeyBlock.sk.rsa.nSz = sizeof(sigKeyBlock.sk.rsa.n);
@ -6223,6 +6247,7 @@ int SendKexDhReply(WOLFSSH* ssh)
enmhashId,
sigKeyBlock.sk.rsa.n,
sigKeyBlock.sk.rsa.nSz);
#endif
}
else {
sigKeyBlock.sk.ecc.primeName =
@ -6511,6 +6536,7 @@ int SendKexDhReply(WOLFSSH* ssh)
if (ret == WS_SUCCESS) {
if (sigKeyBlock.useRsa) {
#ifndef NO_RSA
byte encSig[MAX_ENCODED_SIG_SZ];
word32 encSigSz;
@ -6530,6 +6556,7 @@ int SendKexDhReply(WOLFSSH* ssh)
ret = WS_RSA_E;
}
}
#endif
}
else {
WLOG(WS_LOG_INFO, "Signing hash with ECDSA.");
@ -6573,10 +6600,14 @@ int SendKexDhReply(WOLFSSH* ssh)
}
}
if (sigKeyBlock.useRsa)
if (sigKeyBlock.useRsa) {
#ifndef NO_RSA
wc_FreeRsaKey(&sigKeyBlock.sk.rsa.key);
else
#endif
}
else {
wc_ecc_free(&sigKeyBlock.sk.ecc.key);
}
sigBlockSz = (LENGTH_SZ * 2) + sigKeyBlock.nameSz + sigSz;
@ -6605,6 +6636,7 @@ int SendKexDhReply(WOLFSSH* ssh)
WMEMCPY(output + idx, sigKeyBlock.name, sigKeyBlock.nameSz);
idx += sigKeyBlock.nameSz;
if (sigKeyBlock.useRsa) {
#ifndef NO_RSA
c32toa(sigKeyBlock.sk.rsa.eSz + sigKeyBlock.sk.rsa.ePad,
output + idx);
idx += LENGTH_SZ;
@ -6617,6 +6649,7 @@ int SendKexDhReply(WOLFSSH* ssh)
if (sigKeyBlock.sk.rsa.nPad) output[idx++] = 0;
WMEMCPY(output + idx, sigKeyBlock.sk.rsa.n, sigKeyBlock.sk.rsa.nSz);
idx += sigKeyBlock.sk.rsa.nSz;
#endif
}
else {
c32toa(sigKeyBlock.sk.ecc.primeNameSz, output + idx);
@ -7282,6 +7315,7 @@ typedef struct WS_KeySignature {
const char *name;
word32 nameSz;
union {
#ifndef NO_RSA
struct {
RsaKey key;
byte e[256];
@ -7291,6 +7325,7 @@ typedef struct WS_KeySignature {
word32 nSz;
byte nPad;
} rsa;
#endif
struct {
ecc_key key;
word32 keyBlobSz;
@ -7352,6 +7387,7 @@ static int BuildUserAuthRequestPassword(WOLFSSH* ssh,
}
#ifndef NO_RSA
static int PrepareUserAuthRequestRsa(WOLFSSH* ssh, word32* payloadSz,
const WS_UserAuthData* authData, WS_KeySignature* keySig)
{
@ -7504,6 +7540,7 @@ static int BuildUserAuthRequestRsa(WOLFSSH* ssh,
return ret;
}
#endif
static int PrepareUserAuthRequestEcc(WOLFSSH* ssh, word32* payloadSz,
@ -7725,8 +7762,11 @@ static int PrepareUserAuthRequestPublicKey(WOLFSSH* ssh, word32* payloadSz,
authData->sf.publicKey.publicKeySz;
}
if (keySig->keySigId == ID_SSH_RSA)
if (keySig->keySigId == ID_SSH_RSA) {
#ifndef NO_RSA
ret = PrepareUserAuthRequestRsa(ssh, payloadSz, authData, keySig);
#endif
}
else if (keySig->keySigId == ID_ECDSA_SHA2_NISTP256 ||
keySig->keySigId == ID_ECDSA_SHA2_NISTP384 ||
keySig->keySigId == ID_ECDSA_SHA2_NISTP521)
@ -7766,9 +7806,12 @@ static int BuildUserAuthRequestPublicKey(WOLFSSH* ssh,
begin += pk->publicKeySz;
if (pk->hasSignature) {
if (keySig->keySigId == ID_SSH_RSA)
if (keySig->keySigId == ID_SSH_RSA) {
#ifndef NO_RSA
ret = BuildUserAuthRequestRsa(ssh, output, &begin,
authData, sigStart, sigStartIdx, keySig);
#endif
}
else if (keySig->keySigId == ID_ECDSA_SHA2_NISTP256 ||
keySig->keySigId == ID_ECDSA_SHA2_NISTP384 ||
keySig->keySigId == ID_ECDSA_SHA2_NISTP521)
@ -7789,8 +7832,11 @@ static int BuildUserAuthRequestPublicKey(WOLFSSH* ssh,
static void CleanupUserAuthRequestPublicKey(WS_KeySignature* keySig)
{
if (keySig != NULL) {
if (keySig->keySigId == ID_SSH_RSA)
if (keySig->keySigId == ID_SSH_RSA) {
#ifndef NO_RSA
wc_FreeRsaKey(&keySig->ks.rsa.key);
#endif
}
else
wc_ecc_free(&keySig->ks.ecc.key);
}

View File

@ -57,6 +57,8 @@
int wolfSSH_MakeRsaKey(byte* out, word32 outSz,
word32 size, word32 e)
{
#ifndef NO_RSA
int ret = WS_SUCCESS;
WC_RNG rng;
@ -105,6 +107,13 @@ int wolfSSH_MakeRsaKey(byte* out, word32 outSz,
WLOG(WS_LOG_DEBUG, "Leaving wolfSSH_MakeRsaKey(), ret = %d", ret);
return ret;
#else
(void)out;
(void)outSz;
(void)size;
(void)e;
return WS_NOT_COMPILED;
#endif
}

View File

@ -1441,7 +1441,9 @@ int wolfSSH_ReadKey_buffer(const byte* in, word32 inSz, int format,
else if (format == WOLFSSH_FORMAT_ASN1) {
byte* newKey;
union {
RsaKey rsa;
#ifndef NO_RSA
RsaKey rsa;
#endif
ecc_key ecc;
} testKey;
word32 scratch = 0;
@ -1459,7 +1461,7 @@ int wolfSSH_ReadKey_buffer(const byte* in, word32 inSz, int format,
}
*outSz = inSz;
WMEMCPY(newKey, in, inSz);
#ifndef NO_RSA
/* TODO: This is copied and modified from a function in src/internal.c.
This and that code should be combined into a single function. */
if (wc_InitRsaKey(&testKey.rsa, heap) < 0)
@ -1474,6 +1476,7 @@ int wolfSSH_ReadKey_buffer(const byte* in, word32 inSz, int format,
*outTypeSz = (word32)WSTRLEN((const char*)*outType);
}
else {
#endif
/* Couldn't decode as RSA testKey. Try decoding as ECC testKey. */
scratch = 0;
if (wc_ecc_init_ex(&testKey.ecc, heap, INVALID_DEVID) != 0)
@ -1489,7 +1492,9 @@ int wolfSSH_ReadKey_buffer(const byte* in, word32 inSz, int format,
}
else
return WS_BAD_FILE_E;
#ifndef NO_RSA
}
#endif
}
else
ret = WS_ERROR;

View File

@ -570,9 +570,10 @@ static void test_wolfSSH_CTX_UsePrivateKey_buffer(void)
AssertNotNull(ctx->privateKey);
AssertIntNE(0, ctx->privateKeySz);
AssertIntEQ(ECC_SECP256R1, ctx->useEcc);
#ifndef NO_RSA
lastKey = ctx->privateKey;
lastKeySz = ctx->privateKeySz;
AssertIntEQ(WS_SUCCESS,
wolfSSH_CTX_UsePrivateKey_buffer(ctx, rsaKey, rsaKeySz,
TEST_GOOD_FORMAT_ASN1));
@ -581,6 +582,10 @@ static void test_wolfSSH_CTX_UsePrivateKey_buffer(void)
AssertIntEQ(0, ctx->useEcc);
AssertIntEQ(0, (lastKey == ctx->privateKey));
AssertIntNE(lastKeySz, ctx->privateKeySz);
#else
(void)lastKey;
(void)lastKeySz;
#endif
wolfSSH_CTX_free(ctx);
FreeBins(eccKey, rsaKey, NULL, NULL);