Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -2377,7 +2377,11 @@ static int SetHostCertificate(WOLFSSH_CTX* ctx,
}
}

/* Replace the matching slot if the search found one, else append. */
destIdx = HINTISSET(certIdx) ? certIdx : ctx->privateKeyCount;

Comment thread
yosuke-wolfssl marked this conversation as resolved.
if (destIdx >= WOLFSSH_MAX_PVT_KEYS) {
WFREE(der, ctx->heap, dynamicType);
ret = WS_CTX_KEY_COUNT_E;
}
else {
Expand Down
56 changes: 55 additions & 1 deletion tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,12 @@ static void test_wolfSSH_CTX_UseCert_buffer(void)
WOLFSSH_CTX* ctx = NULL;
byte* cert = NULL;
word32 certSz = 0;
#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256
byte* key = NULL;
word32 keySz = 0;
word32 count = 0;
byte lastFmt = ID_NONE;
#endif

ctx = wolfSSH_CTX_new(WOLFSSH_ENDPOINT_SERVER, NULL);
AssertNotNull(ctx);
Expand All @@ -695,6 +701,8 @@ static void test_wolfSSH_CTX_UseCert_buffer(void)
#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256
AssertIntEQ(WS_SUCCESS,
wolfSSH_CTX_UseCert_buffer(ctx, cert, certSz, WOLFSSH_FORMAT_PEM));
AssertIntEQ(1, ctx->privateKeyCount);
AssertNotNull(ctx->privateKey[0].cert);
#endif

AssertIntEQ(WS_BAD_FILETYPE_E,
Expand All @@ -707,17 +715,63 @@ static void test_wolfSSH_CTX_UseCert_buffer(void)
free(cert);
cert = NULL;

AssertIntEQ(0, load_file("./keys/server-cert.der", &cert, &certSz));
#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256
/* A matching private key seeds a key copy in the cert slot. */
AssertIntEQ(0, load_file("./keys/server-key-ecc.der", &key, &keySz));
AssertIntEQ(WS_SUCCESS,
wolfSSH_CTX_UsePrivateKey_buffer(ctx, key, keySz,
WOLFSSH_FORMAT_ASN1));
count = ctx->privateKeyCount;
AssertIntEQ(2, count);
#endif

/* A different certificate, so the reload shows in the stored DER. */
AssertIntEQ(0, load_file("./keys/fred-cert.der", &cert, &certSz));
AssertNotNull(cert);
AssertIntNE(0, certSz);

#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256
AssertIntEQ(WS_SUCCESS,
wolfSSH_CTX_UseCert_buffer(ctx, cert, certSz, WOLFSSH_FORMAT_ASN1));
Comment thread
yosuke-wolfssl marked this conversation as resolved.
/* Reloading replaces the slot instead of appending a duplicate. */
AssertIntEQ(count, ctx->privateKeyCount);
AssertIntEQ(certSz, ctx->privateKey[0].certSz);
AssertIntEQ(0, XMEMCMP(ctx->privateKey[0].cert, cert, certSz));
AssertIntEQ(2, ctx->publicKeyAlgoCount);
/* The replaced slot keeps a fresh copy of the matching key. */
AssertIntEQ(ctx->privateKey[1].keySz, ctx->privateKey[0].keySz);
AssertIntEQ(0, XMEMCMP(ctx->privateKey[0].key, ctx->privateKey[1].key,
ctx->privateKey[0].keySz));

/* A full table still replaces the matching slot rather than rejecting;
* a third certificate keeps the stored-DER checks honest. */
free(cert);
cert = NULL;
AssertIntEQ(0, load_file("./keys/server-cert.der", &cert, &certSz));
ctx->privateKeyCount = WOLFSSH_MAX_PVT_KEYS;
AssertIntEQ(WS_SUCCESS,
wolfSSH_CTX_UseCert_buffer(ctx, cert, certSz, WOLFSSH_FORMAT_ASN1));
AssertIntEQ(certSz, ctx->privateKey[0].certSz);
Comment thread
yosuke-wolfssl marked this conversation as resolved.
AssertIntEQ(0, XMEMCMP(ctx->privateKey[0].cert, cert, certSz));
/* publicKeyAlgo stays stale from the fabricated count; ctx freed below. */
ctx->privateKeyCount = count;
Comment thread
yosuke-wolfssl marked this conversation as resolved.

/* No matching slot and no room: rejected, and the DER is freed. */
lastFmt = ctx->privateKey[0].publicKeyFmt;
ctx->privateKey[0].publicKeyFmt = ID_NONE;
Comment thread
yosuke-wolfssl marked this conversation as resolved.
ctx->privateKeyCount = WOLFSSH_MAX_PVT_KEYS;
AssertIntEQ(WS_CTX_KEY_COUNT_E,
wolfSSH_CTX_UseCert_buffer(ctx, cert, certSz, WOLFSSH_FORMAT_ASN1));
AssertIntEQ(WOLFSSH_MAX_PVT_KEYS, ctx->privateKeyCount);
ctx->privateKeyCount = count;
ctx->privateKey[0].publicKeyFmt = lastFmt;
#endif

wolfSSH_CTX_free(ctx);
free(cert);
#ifndef WOLFSSH_NO_ECDSA_SHA2_NISTP256
free(key);
#endif
#endif /* WOLFSSH_CERTS */
}

Expand Down
Loading