Add Phase 9C security hardening
Generate exact-hash SDK source overrides without modifying dependencies. Harden SSH allocation and algorithm policy, tighten web authentication cleanup, and add focused host contract tests and documentation.
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "ssh_protocol_policy.h"
|
||||
|
||||
static const char *const expected[] = {
|
||||
"curve25519-sha256,ecdh-sha2-nistp256",
|
||||
"ecdsa-sha2-nistp256",
|
||||
"aes128-gcm@openssh.com,aes256-gcm@openssh.com",
|
||||
"hmac-sha2-256",
|
||||
"ssh-ed25519,ecdsa-sha2-nistp256",
|
||||
};
|
||||
static unsigned calls, fail_at;
|
||||
static int failure;
|
||||
static WOLFSSH_CTX *candidate;
|
||||
|
||||
static int set(WOLFSSH_CTX *ctx, const char *list, const char **field,
|
||||
unsigned step)
|
||||
{
|
||||
assert(ctx == candidate);
|
||||
assert(ctx->sentinel == 0x12345678U);
|
||||
assert(++calls == step);
|
||||
assert(strcmp(list, expected[step - 1]) == 0);
|
||||
if (step == fail_at) return failure;
|
||||
*field = list;
|
||||
return WS_SUCCESS;
|
||||
}
|
||||
#define SETTER(name, field, step) \
|
||||
int wolfSSH_CTX_SetAlgoList##name(WOLFSSH_CTX *c, const char *s) \
|
||||
{ return set(c, s, &c->field, step); }
|
||||
SETTER(Kex, algoListKex, 1)
|
||||
SETTER(Key, algoListKey, 2)
|
||||
SETTER(Cipher, algoListCipher, 3)
|
||||
SETTER(Mac, algoListMac, 4)
|
||||
SETTER(KeyAccepted, algoListKeyAccepted, 5)
|
||||
|
||||
static const char *get(const WOLFSSH_CTX *c, unsigned index)
|
||||
{
|
||||
switch (index) {
|
||||
case 0: return c->algoListKex;
|
||||
case 1: return c->algoListKey;
|
||||
case 2: return c->algoListCipher;
|
||||
case 3: return c->algoListMac;
|
||||
default: return c->algoListKeyAccepted;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
assert(ssh_protocol_policy_apply(NULL) == WS_SSH_CTX_NULL_E);
|
||||
assert(calls == 0);
|
||||
/* This is an unpublished stack-owned candidate. Any attempted vendor free
|
||||
* has no test definition and fails linking; transport publication is outside
|
||||
* this helper and is covered by the parent's integration tests. */
|
||||
static const char original[] = "old-default";
|
||||
for (unsigned step = 1; step <= 5; ++step) {
|
||||
for (unsigned sign = 0; sign < 2; ++sign) {
|
||||
WOLFSSH_CTX ctx = {
|
||||
.algoListKex = original, .algoListKey = original,
|
||||
.algoListCipher = original, .algoListMac = original,
|
||||
.algoListKeyAccepted = original, .sentinel = 0x12345678U,
|
||||
};
|
||||
candidate = &ctx;
|
||||
calls = 0;
|
||||
fail_at = step;
|
||||
failure = sign ? (int)(9000 + step) : -(int)(9000 + step);
|
||||
assert(ssh_protocol_policy_apply(&ctx) == failure);
|
||||
assert(calls == step);
|
||||
assert(ctx.sentinel == 0x12345678U);
|
||||
for (unsigned i = 0; i < 5; ++i) {
|
||||
if (i + 1 < step) assert(strcmp(get(&ctx, i), expected[i]) == 0);
|
||||
else assert(get(&ctx, i) == original);
|
||||
}
|
||||
}
|
||||
}
|
||||
const char *retained[5];
|
||||
for (unsigned pass = 0; pass < 2; ++pass) {
|
||||
WOLFSSH_CTX ctx = {.sentinel = 0x12345678U};
|
||||
candidate = &ctx;
|
||||
calls = fail_at = 0;
|
||||
assert(ssh_protocol_policy_apply(&ctx) == WS_SUCCESS);
|
||||
assert(calls == 5);
|
||||
for (unsigned i = 0; i < 5; ++i) {
|
||||
assert(strcmp(get(&ctx, i), expected[i]) == 0);
|
||||
if (pass == 0) retained[i] = get(&ctx, i);
|
||||
else assert(retained[i] == get(&ctx, i));
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < 5; ++i) assert(strcmp(retained[i], expected[i]) == 0);
|
||||
puts("PASS: apply NULL, five exact lists, every setter failure (+/-), stop/no fallback, retained strings");
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user