mirror of https://github.com/wolfSSL/wolfssh.git
ossh: check the key-type parse before the ID lookup
- GetOpenSshPublicKey() calls NameToId() and enters the key-type switch only when GetStringRef() returns WS_SUCCESS, and returns that result otherwise. - publicKeyType starts NULL and keyId starts ID_UNKNOWN. - tests/api.c adds test_GetOpenSshPublicKey_type(), gated on WOLFSSH_TPM and WOLFSSH_TEST_INTERNAL, covering a truncated type string, a truncated length prefix, an empty type, an unsupported type and a well-formed ssh-rsa blob. - Each case asserts idx alongside the return code: UINT32_SZ for a truncated type string, 0 for a truncated length prefix, and the full blob size for the empty type, the unsupported type and the ssh-rsa key. Issue: F-11650pull/1171/head
parent
faca3bc265
commit
f60b00cbf8
83
src/ossh.c
83
src/ossh.c
|
|
@ -471,50 +471,55 @@ static int GetOpenSshPublicKeyRsa(RsaKey* key, const byte* buf, word32 len,
|
|||
int GetOpenSshPublicKey(WS_KeySignature *key,
|
||||
const byte* buf, word32 len, word32* idx)
|
||||
{
|
||||
int ret = WS_SUCCESS;
|
||||
const byte* publicKeyType;
|
||||
int ret;
|
||||
const byte* publicKeyType = NULL;
|
||||
word32 publicKeyTypeSz = 0;
|
||||
byte keyId;
|
||||
byte keyId = ID_UNKNOWN;
|
||||
|
||||
ret = GetStringRef(&publicKeyTypeSz, &publicKeyType, buf, len, idx);
|
||||
keyId = NameToId((const char*)publicKeyType, publicKeyTypeSz);
|
||||
|
||||
switch (keyId) {
|
||||
#ifndef WOLFSSH_NO_RSA
|
||||
case ID_SSH_RSA:
|
||||
ret = GetOpenSshPublicKeyRsa(&key->ks.rsa.key, buf, len, idx);
|
||||
break;
|
||||
#endif
|
||||
#ifndef WOLFSSH_NO_ECDSA
|
||||
case ID_ECDSA_SHA2_NISTP256:
|
||||
case ID_ECDSA_SHA2_NISTP384:
|
||||
case ID_ECDSA_SHA2_NISTP521:
|
||||
ret = GetOpenSshPublicKeyEcc(&key->ks.ecc.key, buf, len, idx);
|
||||
break;
|
||||
#endif
|
||||
#ifndef WOLFSSH_NO_ED25519
|
||||
case ID_ED25519:
|
||||
ret = GetOpenSshKeyPublicEd25519(&key->ks.ed25519.key, buf, len, idx);
|
||||
break;
|
||||
#endif
|
||||
#ifndef WOLFSSH_NO_MLDSA
|
||||
case ID_MLDSA44:
|
||||
ret = GetOpenSshKeyPublicMlDsa(&key->ks.mldsa.key, buf, len,
|
||||
idx, WC_ML_DSA_44);
|
||||
break;
|
||||
case ID_MLDSA65:
|
||||
ret = GetOpenSshKeyPublicMlDsa(&key->ks.mldsa.key, buf, len,
|
||||
idx, WC_ML_DSA_65);
|
||||
break;
|
||||
case ID_MLDSA87:
|
||||
ret = GetOpenSshKeyPublicMlDsa(&key->ks.mldsa.key, buf, len,
|
||||
idx, WC_ML_DSA_87);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ret = WS_UNIMPLEMENTED_E;
|
||||
break;
|
||||
if (ret == WS_SUCCESS) {
|
||||
keyId = NameToId((const char*)publicKeyType, publicKeyTypeSz);
|
||||
|
||||
switch (keyId) {
|
||||
#ifndef WOLFSSH_NO_RSA
|
||||
case ID_SSH_RSA:
|
||||
ret = GetOpenSshPublicKeyRsa(&key->ks.rsa.key, buf, len, idx);
|
||||
break;
|
||||
#endif
|
||||
#ifndef WOLFSSH_NO_ECDSA
|
||||
case ID_ECDSA_SHA2_NISTP256:
|
||||
case ID_ECDSA_SHA2_NISTP384:
|
||||
case ID_ECDSA_SHA2_NISTP521:
|
||||
ret = GetOpenSshPublicKeyEcc(&key->ks.ecc.key, buf, len, idx);
|
||||
break;
|
||||
#endif
|
||||
#ifndef WOLFSSH_NO_ED25519
|
||||
case ID_ED25519:
|
||||
ret = GetOpenSshKeyPublicEd25519(&key->ks.ed25519.key, buf, len,
|
||||
idx);
|
||||
break;
|
||||
#endif
|
||||
#ifndef WOLFSSH_NO_MLDSA
|
||||
case ID_MLDSA44:
|
||||
ret = GetOpenSshKeyPublicMlDsa(&key->ks.mldsa.key, buf, len,
|
||||
idx, WC_ML_DSA_44);
|
||||
break;
|
||||
case ID_MLDSA65:
|
||||
ret = GetOpenSshKeyPublicMlDsa(&key->ks.mldsa.key, buf, len,
|
||||
idx, WC_ML_DSA_65);
|
||||
break;
|
||||
case ID_MLDSA87:
|
||||
ret = GetOpenSshKeyPublicMlDsa(&key->ks.mldsa.key, buf, len,
|
||||
idx, WC_ML_DSA_87);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ret = WS_UNIMPLEMENTED_E;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
68
tests/api.c
68
tests/api.c
|
|
@ -2270,6 +2270,71 @@ static void test_LoadTpmSshKey_NoTrailingNewline(void)
|
|||
|
||||
#endif /* WOLFSSH_TPM && FILESYSTEM && !USER_FILESYSTEM */
|
||||
|
||||
#if defined(WOLFSSH_TPM) && defined(WOLFSSH_TEST_INTERNAL)
|
||||
|
||||
/* The key type is read with GetStringRef(), which sets the length from the
|
||||
* wire but leaves the pointer alone when the name runs past the buffer. */
|
||||
static void test_GetOpenSshPublicKey_type(void)
|
||||
{
|
||||
/* "ssh" carrying a length of 7. */
|
||||
static const byte truncType[] = {
|
||||
0x00, 0x00, 0x00, 0x07, 's', 's', 'h'
|
||||
};
|
||||
/* Too short to hold the length prefix. */
|
||||
static const byte truncLen[] = { 0x00, 0x00 };
|
||||
/* Parses, but names no key. */
|
||||
static const byte emptyType[] = { 0x00, 0x00, 0x00, 0x00 };
|
||||
/* A known SSH key type that wolfSSH's NameIdMap does not carry. */
|
||||
static const byte unsupportedType[] = {
|
||||
0x00, 0x00, 0x00, 0x07, 's', 's', 'h', '-', 'd', 's', 's'
|
||||
};
|
||||
#ifndef WOLFSSH_NO_RSA
|
||||
/* string "ssh-rsa", mpint e, mpint n. */
|
||||
static const byte rsaKey[] = {
|
||||
0x00, 0x00, 0x00, 0x07, 's', 's', 'h', '-', 'r', 's', 'a',
|
||||
0x00, 0x00, 0x00, 0x03, 0x01, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x09,
|
||||
0x00, 0xC5, 0x1A, 0x37, 0x8B, 0x42, 0x9D, 0xE0, 0x6F
|
||||
};
|
||||
#endif
|
||||
WS_KeySignature keySig;
|
||||
word32 idx;
|
||||
|
||||
WMEMSET(&keySig, 0, sizeof(keySig));
|
||||
|
||||
/* On failure idx keeps whatever was consumed, as elsewhere in the tree. */
|
||||
idx = 0;
|
||||
AssertIntEQ(GetOpenSshPublicKey(&keySig, truncType,
|
||||
(word32)sizeof(truncType), &idx), WS_BUFFER_E);
|
||||
AssertIntEQ(idx, UINT32_SZ);
|
||||
|
||||
idx = 0;
|
||||
AssertIntEQ(GetOpenSshPublicKey(&keySig, truncLen,
|
||||
(word32)sizeof(truncLen), &idx), WS_BUFFER_E);
|
||||
AssertIntEQ(idx, 0);
|
||||
|
||||
idx = 0;
|
||||
AssertIntEQ(GetOpenSshPublicKey(&keySig, emptyType,
|
||||
(word32)sizeof(emptyType), &idx), WS_UNIMPLEMENTED_E);
|
||||
AssertIntEQ(idx, (word32)sizeof(emptyType));
|
||||
|
||||
idx = 0;
|
||||
AssertIntEQ(GetOpenSshPublicKey(&keySig, unsupportedType,
|
||||
(word32)sizeof(unsupportedType), &idx), WS_UNIMPLEMENTED_E);
|
||||
AssertIntEQ(idx, (word32)sizeof(unsupportedType));
|
||||
|
||||
#ifndef WOLFSSH_NO_RSA
|
||||
idx = 0;
|
||||
AssertIntEQ(wc_InitRsaKey(&keySig.ks.rsa.key, NULL), 0);
|
||||
AssertIntEQ(GetOpenSshPublicKey(&keySig, rsaKey,
|
||||
(word32)sizeof(rsaKey), &idx), WS_SUCCESS);
|
||||
AssertIntEQ(idx, (word32)sizeof(rsaKey));
|
||||
AssertIntEQ(wc_FreeRsaKey(&keySig.ks.rsa.key), 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* WOLFSSH_TPM && WOLFSSH_TEST_INTERNAL */
|
||||
|
||||
|
||||
static void test_wolfSSH_ReadKey_badPad(void)
|
||||
{
|
||||
|
|
@ -7749,6 +7814,9 @@ int wolfSSH_ApiTest(int argc, char** argv)
|
|||
#if defined(WOLFSSH_TPM) && !defined(NO_FILESYSTEM) && \
|
||||
!defined(NO_WRITE_TEMP_FILES) && !defined(WOLFSSH_USER_FILESYSTEM)
|
||||
test_LoadTpmSshKey_NoTrailingNewline();
|
||||
#endif
|
||||
#if defined(WOLFSSH_TPM) && defined(WOLFSSH_TEST_INTERNAL)
|
||||
test_GetOpenSshPublicKey_type();
|
||||
#endif
|
||||
test_wolfSSH_ReadKey_shortBuffer();
|
||||
test_wolfSSH_ReadKey_noTrailingNewline();
|
||||
|
|
|
|||
Loading…
Reference in New Issue