diff --git a/src/wh_client_cert.c b/src/wh_client_cert.c index 26b2f3cae..5e872bfd6 100644 --- a/src/wh_client_cert.c +++ b/src/wh_client_cert.c @@ -332,6 +332,12 @@ int wh_Client_CertReadTrustedResponse(whClientContext* c, uint8_t* cert, memcpy(cert, payload, resp->cert_len); *cert_len = resp->cert_len; } + else { + *cert_len = resp->cert_len; + if (out_rc != NULL) { + *out_rc = WH_ERROR_BUFFER_SIZE; + } + } } } } diff --git a/test-refactor/README.md b/test-refactor/README.md index 8d1a0a52a..bdf1397e6 100644 --- a/test-refactor/README.md +++ b/test-refactor/README.md @@ -48,9 +48,15 @@ For running the more substantial client tests only, no server modifications are 4. Optionally call `whTestGroup_Misc()` ## Adding a multi-port test -1. Create a new function which returns `int` (0 for success) with a context argument (`whClientContext*` for client tests, `whServerContext*` for server tests, or none for misc tests). -2. In wh_test_list.c, add a line with `WH_TEST_DECL()` -3. In wh_test_list.c, add the function to the appropriate `whTestCase` array. +Tests are organized as a single registered parent function per source file, which dispatches to one or more `static` sub-tests within that file. + +If adding a new test file and/or a new group of tests: +1. Create a function which returns `int` (0 for success) with a context argument (`whClientContext*` for client tests, `whServerContext*` for server tests, or none for misc tests). Inside it, call each sub-test with `WH_TEST_RETURN_ON_FAIL`. +2. In `wh_test_list.c`, add a `WH_TEST_DECL()` line. +3. In `wh_test_list.c`, add the entry-point to the appropriate `whTestCase` array. + +To add an individual test to an existing group: +1. Add sub-tests as `static` functions in the same file. Name them with a leading underscore (e.g. `_whTest_`). **Note**: if the test is specific to a platform, do not add it to the common list as shown above. Port-specific tests live within the port (not this directory), and are called from the port-specific code. diff --git a/test-refactor/client-server/wh_test_client_certs.c b/test-refactor/client-server/wh_test_client_certs.c new file mode 100644 index 000000000..ea29c1789 --- /dev/null +++ b/test-refactor/client-server/wh_test_client_certs.c @@ -0,0 +1,93 @@ +/* + * Copyright (C) 2026 wolfSSL Inc. + * + * This file is part of wolfHSM. + * + * wolfHSM is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * wolfHSM is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with wolfHSM. If not, see . + */ +/* + * test-refactor/wh_test_client_certs.c + * + * Client-side certificate test suite. Exercises the cert + * manager through the client request/response API. + */ + +#include "wolfhsm/wh_settings.h" + +#if defined(WOLFHSM_CFG_CERTIFICATE_MANAGER) \ + && !defined(WOLFHSM_CFG_NO_CRYPTO) + +#include + +#include "wolfhsm/wh_error.h" +#include "wolfhsm/wh_client.h" + +#include "wh_test_common.h" +#include "wh_test_list.h" + +extern const unsigned char ROOT_A_CERT[]; +extern const size_t ROOT_A_CERT_len; + + +/* + * Verify that wh_Client_CertReadTrusted reports WH_ERROR_BUFFER_SIZE + * and updates the cert_len out-param when the caller buffer is too + * small to hold the returned certificate. + */ +static int _whTest_CertReadTrustedSmallBuffer(whClientContext* ctx) +{ + int32_t out_rc = 0; + const whNvmId cert_id = 103; + uint8_t small_buf[16] = {0}; + uint8_t full_buf[2048] = {0}; + uint32_t cert_len = 0; + + /* Sanity: the test cert must actually exceed the small buffer. */ + WH_TEST_ASSERT_RETURN(ROOT_A_CERT_len > sizeof(small_buf)); + WH_TEST_ASSERT_RETURN(ROOT_A_CERT_len <= sizeof(full_buf)); + + WH_TEST_RETURN_ON_FAIL(wh_Client_CertAddTrusted( + ctx, cert_id, WH_NVM_ACCESS_ANY, WH_NVM_FLAGS_NONMODIFIABLE, + NULL, 0, ROOT_A_CERT, ROOT_A_CERT_len, &out_rc)); + WH_TEST_ASSERT_RETURN(out_rc == WH_ERROR_OK); + + /* Undersized buffer. */ + cert_len = sizeof(small_buf); + WH_TEST_RETURN_ON_FAIL(wh_Client_CertReadTrusted( + ctx, cert_id, small_buf, &cert_len, &out_rc)); + WH_TEST_ASSERT_RETURN(out_rc == WH_ERROR_BUFFER_SIZE); + WH_TEST_ASSERT_RETURN(cert_len == ROOT_A_CERT_len); + + /* Retry with a properly sized buffer using the reported length. */ + WH_TEST_RETURN_ON_FAIL(wh_Client_CertReadTrusted( + ctx, cert_id, full_buf, &cert_len, &out_rc)); + WH_TEST_ASSERT_RETURN(out_rc == WH_ERROR_OK); + WH_TEST_ASSERT_RETURN(cert_len == ROOT_A_CERT_len); + + WH_TEST_RETURN_ON_FAIL( + wh_Client_CertEraseTrusted(ctx, cert_id, &out_rc)); + WH_TEST_ASSERT_RETURN(out_rc == WH_ERROR_OK); + + return WH_ERROR_OK; +} + + +int whTest_ClientCerts(whClientContext* ctx) +{ + WH_TEST_RETURN_ON_FAIL(_whTest_CertReadTrustedSmallBuffer(ctx)); + + return WH_ERROR_OK; +} + +#endif /* WOLFHSM_CFG_CERTIFICATE_MANAGER && !WOLFHSM_CFG_NO_CRYPTO */ diff --git a/test-refactor/wh_test_list.c b/test-refactor/wh_test_list.c index 2867e82ef..0d9ed77d2 100644 --- a/test-refactor/wh_test_list.c +++ b/test-refactor/wh_test_list.c @@ -34,6 +34,7 @@ /* Test declarations and weak skip implementations. */ WH_TEST_DECL(whTest_Dma); WH_TEST_DECL(whTest_CertVerify); +WH_TEST_DECL(whTest_ClientCerts); WH_TEST_DECL(whTest_CryptoAes); WH_TEST_DECL(whTest_CryptoEcc256); WH_TEST_DECL(whTest_CryptoSha256); @@ -52,6 +53,7 @@ const whTestCase whTestsServer[] = { const size_t whTestsServerCount = sizeof(whTestsServer) / sizeof(whTestsServer[0]); const whTestCase whTestsClient[] = { + { "whTest_ClientCerts", whTest_ClientCerts }, { "whTest_CryptoAes", whTest_CryptoAes }, { "whTest_CryptoEcc256", whTest_CryptoEcc256 }, { "whTest_CryptoSha256", whTest_CryptoSha256 },