Skip to content

Commit 1e754d3

Browse files
committed
wolfsshd: unit test for CheckAuthKeysLine
- Expose CheckAuthKeysLine under WOLFSSHD_UNIT_TEST so tests can link it. - Add test_CheckAuthKeysLine covering match, different key, and same-length key differing only in the last byte. - Route the test Log() to stderr instead of an unused local buffer. Issue: F-4107
1 parent 902517a commit 1e754d3

3 files changed

Lines changed: 111 additions & 2 deletions

File tree

apps/wolfsshd/auth.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,13 @@ USER_NODE* AddNewUser(USER_NODE* list, byte type, const byte* username,
152152
#endif
153153

154154
/* TODO: Can use wolfSSH_ReadKey_buffer? */
155+
#ifdef WOLFSSHD_UNIT_TEST
156+
int CheckAuthKeysLine(char* line, word32 lineSz, const byte* key,
157+
word32 keySz)
158+
#else
155159
static int CheckAuthKeysLine(char* line, word32 lineSz, const byte* key,
156160
word32 keySz)
161+
#endif
157162
{
158163
int ret = WSSHD_AUTH_SUCCESS;
159164
char* type = NULL;

apps/wolfsshd/auth.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,5 +83,7 @@ int wolfSSHD_GetHomeDirectory(WOLFSSHD_AUTH* auth, WOLFSSH* ssh, WCHAR* out, int
8383
#if defined(WOLFSSH_HAVE_LIBCRYPT) || defined(WOLFSSH_HAVE_LIBLOGIN)
8484
int CheckPasswordHashUnix(const char* input, char* stored);
8585
#endif
86+
int CheckAuthKeysLine(char* line, word32 lineSz, const byte* key,
87+
word32 keySz);
8688
#endif
8789
#endif /* WOLFAUTH_H */

apps/wolfsshd/test/test_configuration.c

Lines changed: 104 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#endif
2020

2121
#include <wolfssh/ssh.h>
22+
#include <wolfssl/wolfcrypt/coding.h>
2223
#include <configuration.h>
2324
#include <auth.h>
2425

@@ -38,10 +39,9 @@ void Log(const char *const, ...) FMTCHECK;
3839
void Log(const char *const fmt, ...)
3940
{
4041
va_list vlist;
41-
char msgStr[WOLFSSH_DEFAULT_LOG_WIDTH];
4242

4343
va_start(vlist, fmt);
44-
WVSNPRINTF(msgStr, sizeof(msgStr), fmt, vlist);
44+
vfprintf(stderr, fmt, vlist);
4545
va_end(vlist);
4646
}
4747

@@ -494,11 +494,113 @@ static int test_CheckPasswordHashUnix(void)
494494
}
495495
#endif /* WOLFSSH_HAVE_LIBCRYPT || WOLFSSH_HAVE_LIBLOGIN */
496496

497+
#ifdef WOLFSSL_BASE64_ENCODE
498+
/* Build a mutable "ssh-rsa <base64(key)>" line; WSTRTOK mutates in place. */
499+
static int BuildAuthKeysLine(const byte* key, word32 keySz,
500+
char* lineOut, word32 lineOutSz)
501+
{
502+
static const char prefix[] = "ssh-rsa ";
503+
word32 prefixLen = (word32)(sizeof(prefix) - 1);
504+
word32 b64Sz;
505+
506+
if (lineOutSz <= prefixLen) {
507+
return WS_BUFFER_E;
508+
}
509+
WMEMCPY(lineOut, prefix, prefixLen);
510+
b64Sz = lineOutSz - prefixLen;
511+
if (Base64_Encode_NoNl(key, keySz, (byte*)lineOut + prefixLen, &b64Sz)
512+
!= 0) {
513+
return WS_FATAL_ERROR;
514+
}
515+
/* Base64_Encode_NoNl does not null-terminate; do it ourselves. */
516+
if (prefixLen + b64Sz >= lineOutSz) {
517+
return WS_BUFFER_E;
518+
}
519+
lineOut[prefixLen + b64Sz] = '\0';
520+
return WS_SUCCESS;
521+
}
522+
523+
/* Negative-path coverage for CheckAuthKeysLine so mutation of the
524+
* ConstantCompare clause (the only substantive bytewise check after the
525+
* length comparison) does not survive the test suite. */
526+
static int test_CheckAuthKeysLine(void)
527+
{
528+
int ret = WS_SUCCESS;
529+
/* Three equal-length payloads. keyB differs from keyA throughout;
530+
* keyALastByte differs from keyA only in the final byte -- this is the
531+
* case that kills a "delete the ConstantCompare" mutation, since the
532+
* length comparison alone would accept it. */
533+
static const char keyAStr[] = "wolfssh-auth-key-test-A-AAAAAAA";
534+
static const char keyBStr[] = "wolfssh-auth-key-test-B-BBBBBBB";
535+
const byte* keyA = (const byte*)keyAStr;
536+
const byte* keyB = (const byte*)keyBStr;
537+
const word32 keySz = (word32)(sizeof(keyAStr) - 1);
538+
byte keyALastByte[sizeof(keyAStr) - 1];
539+
char line[256];
540+
char lineCopy[256];
541+
int rc;
542+
543+
WMEMCPY(keyALastByte, keyA, keySz);
544+
keyALastByte[keySz - 1] ^= 0x01;
545+
546+
ret = BuildAuthKeysLine(keyA, keySz, line, sizeof(line));
547+
if (ret != WS_SUCCESS) {
548+
return ret;
549+
}
550+
551+
Log(" Testing scenario: matching key authenticates.");
552+
WMEMCPY(lineCopy, line, WSTRLEN(line) + 1);
553+
rc = CheckAuthKeysLine(lineCopy, (word32)WSTRLEN(lineCopy),
554+
keyA, keySz);
555+
if (rc == WSSHD_AUTH_SUCCESS) {
556+
Log(" PASSED.\n");
557+
}
558+
else {
559+
Log(" FAILED (rc=%d).\n", rc);
560+
ret = WS_FATAL_ERROR;
561+
}
562+
563+
if (ret == WS_SUCCESS) {
564+
Log(" Testing scenario: different same-length key is rejected.");
565+
WMEMCPY(lineCopy, line, WSTRLEN(line) + 1);
566+
rc = CheckAuthKeysLine(lineCopy, (word32)WSTRLEN(lineCopy),
567+
keyB, keySz);
568+
if (rc == WSSHD_AUTH_FAILURE) {
569+
Log(" PASSED.\n");
570+
}
571+
else {
572+
Log(" FAILED (rc=%d).\n", rc);
573+
ret = WS_FATAL_ERROR;
574+
}
575+
}
576+
577+
if (ret == WS_SUCCESS) {
578+
Log(" Testing scenario: same-length key differing in last byte is "
579+
"rejected.");
580+
WMEMCPY(lineCopy, line, WSTRLEN(line) + 1);
581+
rc = CheckAuthKeysLine(lineCopy, (word32)WSTRLEN(lineCopy),
582+
keyALastByte, keySz);
583+
if (rc == WSSHD_AUTH_FAILURE) {
584+
Log(" PASSED.\n");
585+
}
586+
else {
587+
Log(" FAILED (rc=%d).\n", rc);
588+
ret = WS_FATAL_ERROR;
589+
}
590+
}
591+
592+
return ret;
593+
}
594+
#endif /* WOLFSSL_BASE64_ENCODE */
595+
497596
const TEST_CASE testCases[] = {
498597
TEST_DECL(test_ConfigDefaults),
499598
TEST_DECL(test_ParseConfigLine),
500599
TEST_DECL(test_ConfigCopy),
501600
TEST_DECL(test_ConfigFree),
601+
#ifdef WOLFSSL_BASE64_ENCODE
602+
TEST_DECL(test_CheckAuthKeysLine),
603+
#endif
502604
#if defined(WOLFSSH_HAVE_LIBCRYPT) || defined(WOLFSSH_HAVE_LIBLOGIN)
503605
TEST_DECL(test_CheckPasswordHashUnix),
504606
#endif

0 commit comments

Comments
 (0)