From e1184f1b350ce2ba9603530660cdc0d19d9174b6 Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Thu, 2 Apr 2026 16:49:27 -0700 Subject: [PATCH 1/4] Fix F-570, F-572, F-573, F-574, F-575, F-645, F-646, F-647, F-648, F-649, F-657, F-658, F-659, F-660, F-732, F-733, F-734, F-735, F-736, F-740, F-741, F-742, F-1108, F-1109, F-1484, F-1485, F-1486, F-1487, F-1488, F-1489 --- src/benchmark/clu_bench_setup.c | 2 +- src/certgen/clu_certgen_ed25519.c | 1 + src/certgen/clu_certgen_rsa.c | 73 +++++++---- src/crypto/clu_crypto_setup.c | 8 +- src/genkey/clu_genkey.c | 7 +- src/genkey/clu_genkey_setup.c | 6 +- src/hash/clu_alg_hash.c | 12 ++ src/hash/clu_hash_setup.c | 6 +- src/ocsp/clu_ocsp.c | 1 + src/pkcs/clu_pkcs12.c | 1 + src/pkcs/clu_pkcs8.c | 2 + src/pkey/clu_rsa.c | 2 +- src/sign-verify/clu_crl_verify.c | 2 +- src/sign-verify/clu_dgst_setup.c | 6 +- src/sign-verify/clu_sign.c | 15 +-- src/sign-verify/clu_sign_verify_setup.c | 10 +- src/sign-verify/clu_verify.c | 15 ++- src/tools/clu_rand.c | 18 +-- src/x509/clu_cert_setup.c | 6 +- src/x509/clu_config.c | 28 ++--- src/x509/clu_x509_sign.c | 117 ++++++++++++------ tests/bench/bench-test.sh | 12 ++ tests/dgst/dgst-test.sh | 9 ++ tests/encrypt/enc-test.sh | 10 ++ tests/genkey_sign_ver/genkey-sign-ver-test.sh | 71 +++++++++++ tests/hash/hash-test.sh | 12 ++ tests/pkey/rsa-test.sh | 8 ++ tests/x509/CRL-verify-test.sh | 8 ++ tests/x509/x509-process-test.sh | 7 ++ tests/x509/x509-req-test.sh | 62 +++++++++- 30 files changed, 423 insertions(+), 114 deletions(-) diff --git a/src/benchmark/clu_bench_setup.c b/src/benchmark/clu_bench_setup.c index 0c2d138e..aada45b3 100644 --- a/src/benchmark/clu_bench_setup.c +++ b/src/benchmark/clu_bench_setup.c @@ -74,7 +74,7 @@ int wolfCLU_benchSetup(int argc, char** argv) } ret = wolfCLU_checkForArg("-time", 5, argc, argv); - if (ret > 0) { + if (ret > 0 && ret + 1 < argc) { /* time for each test in seconds */ time = XATOI(argv[ret+1]); if (time < 1 || time > 10) { diff --git a/src/certgen/clu_certgen_ed25519.c b/src/certgen/clu_certgen_ed25519.c index 0d5709c4..32caaf8d 100644 --- a/src/certgen/clu_certgen_ed25519.c +++ b/src/certgen/clu_certgen_ed25519.c @@ -62,6 +62,7 @@ int make_self_signed_ed25519_certificate(char* keyPath, char* certOut) } if (XFSEEK(keyFile, 0, SEEK_SET) != 0 || (int)XFREAD(keyBuf, 1, keyFileSz, keyFile) != keyFileSz) { XFCLOSE(keyFile); + XFREE(keyBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return WOLFCLU_FAILURE; } XFCLOSE(keyFile); diff --git a/src/certgen/clu_certgen_rsa.c b/src/certgen/clu_certgen_rsa.c index b3c4a04c..70655d8e 100644 --- a/src/certgen/clu_certgen_rsa.c +++ b/src/certgen/clu_certgen_rsa.c @@ -32,6 +32,7 @@ int make_self_signed_rsa_certificate(char* keyPath, char* certOut, int oid) { int ret = 0; word32 index = 0; + int keyInit = 0, rngInit = 0; Cert newCert; RsaKey key; @@ -42,10 +43,10 @@ int make_self_signed_rsa_certificate(char* keyPath, char* certOut, int oid) XFILE file; XFILE pemFile; byte* keyBuf; - int certBufSz; - byte* certBuf; + int certBufSz = 0; + byte* certBuf = NULL; int pemBufSz; - byte* pemBuf; + byte* pemBuf = NULL; keyFile = XFOPEN(keyPath, "rb"); if (keyFile == NULL) { @@ -62,6 +63,7 @@ int make_self_signed_rsa_certificate(char* keyPath, char* certOut, int oid) } if (XFSEEK(keyFile, 0, SEEK_SET) != 0 || (int)XFREAD(keyBuf, 1, keyFileSz, keyFile) != keyFileSz) { XFCLOSE(keyFile); + XFREE(keyBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return WOLFCLU_FAILURE; } XFCLOSE(keyFile); @@ -72,19 +74,22 @@ int make_self_signed_rsa_certificate(char* keyPath, char* certOut, int oid) XFREE(keyBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return ret; } + keyInit = 1; ret = wc_InitRng(&rng); if (ret != 0) { wolfCLU_LogError("Failed to initialize rng.\nRET: %d", ret); XFREE(keyBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + wc_FreeRsaKey(&key); return ret; } + rngInit = 1; ret = wc_RsaPrivateKeyDecode(keyBuf, &index, &key, keyFileSz); XFREE(keyBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (ret != 0 ) { wolfCLU_LogError("Failed to decode private key.\nRET: %d", ret); - return ret; + goto cleanup; } wc_InitCert(&newCert); @@ -99,36 +104,44 @@ int make_self_signed_rsa_certificate(char* keyPath, char* certOut, int oid) WOLFCLU_LOG(WOLFCLU_L0, "Enter your countries 2 digit code (ex: United States -> US): "); if (XFGETS(country,CTC_NAME_SIZE, stdin) == NULL) { - return WOLFCLU_FAILURE; + ret = WOLFCLU_FAILURE; + goto cleanup; } country[CTC_NAME_SIZE-1] = '\0'; WOLFCLU_LOG(WOLFCLU_L0, "Enter the name of the province you are located at: "); if (XFGETS(province,CTC_NAME_SIZE, stdin) == NULL) { - return WOLFCLU_FAILURE; + ret = WOLFCLU_FAILURE; + goto cleanup; } WOLFCLU_LOG(WOLFCLU_L0, "Enter the name of the city you are located at: "); if (XFGETS(city,CTC_NAME_SIZE, stdin) == NULL) { - return WOLFCLU_FAILURE; + ret = WOLFCLU_FAILURE; + goto cleanup; } WOLFCLU_LOG(WOLFCLU_L0, "Enter the name of your orginization: "); if (XFGETS(org,CTC_NAME_SIZE, stdin) == NULL) { - return WOLFCLU_FAILURE; + ret = WOLFCLU_FAILURE; + goto cleanup; } WOLFCLU_LOG(WOLFCLU_L0, "Enter the name of your unit: "); if (XFGETS(unit,CTC_NAME_SIZE, stdin) == NULL) { - return WOLFCLU_FAILURE; + ret = WOLFCLU_FAILURE; + goto cleanup; } WOLFCLU_LOG(WOLFCLU_L0, "Enter the common name of your domain: "); if (XFGETS(commonName,CTC_NAME_SIZE, stdin) == NULL) { - return WOLFCLU_FAILURE; + ret = WOLFCLU_FAILURE; + goto cleanup; } WOLFCLU_LOG(WOLFCLU_L0, "Enter your email address: "); if (XFGETS(email,CTC_NAME_SIZE, stdin) == NULL) { - return WOLFCLU_FAILURE; + ret = WOLFCLU_FAILURE; + goto cleanup; } WOLFCLU_LOG(WOLFCLU_L0, "Enter the number of days this certificate should be valid: "); if (XFGETS(daysValid,CTC_NAME_SIZE, stdin) == NULL) { - return WOLFCLU_FAILURE; + ret = WOLFCLU_FAILURE; + goto cleanup; } XSTRNCPY(newCert.subject.country, country, CTC_NAME_SIZE); @@ -162,22 +175,23 @@ int make_self_signed_rsa_certificate(char* keyPath, char* certOut, int oid) certBuf = (byte*) XMALLOC(FOURK_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (certBuf == NULL) { wolfCLU_LogError("Failed to initialize buffer to stort certificate."); - return -1; + ret = -1; + goto cleanup; } XMEMSET(certBuf, 0, FOURK_SZ); ret = wc_MakeCert(&newCert, certBuf, FOURK_SZ, &key, NULL, &rng); if (ret < 0) { wolfCLU_LogError("Failed to make certificate."); - return ret; + goto cleanup; } WOLFCLU_LOG(WOLFCLU_L0, "MakeCert returned %d", ret); - ret = wc_SignCert(newCert.bodySz, newCert.sigType, certBuf, FOURK_SZ, &key, + ret = wc_SignCert(newCert.bodySz, newCert.sigType, certBuf, FOURK_SZ, &key, NULL, &rng); if (ret < 0) { wolfCLU_LogError("Failed to sign certificate."); - return ret; + goto cleanup; } WOLFCLU_LOG(WOLFCLU_L0, "SignCert returned %d", ret); @@ -189,7 +203,8 @@ int make_self_signed_rsa_certificate(char* keyPath, char* certOut, int oid) file = XFOPEN(certOut, "wb"); if (!file) { wolfCLU_LogError("failed to open file: %s", certOut); - return -1; + ret = -1; + goto cleanup; } ret = (int)XFWRITE(certBuf, 1, certBufSz, file); @@ -205,14 +220,16 @@ int make_self_signed_rsa_certificate(char* keyPath, char* certOut, int oid) pemBuf = (byte*)XMALLOC(FOURK_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (pemBuf == NULL) { wolfCLU_LogError("Failed to initialize pem buffer."); - return -1; + ret = -1; + goto cleanup; } XMEMSET(pemBuf, 0, FOURK_SZ); pemBufSz = wc_DerToPem(certBuf, certBufSz, pemBuf, FOURK_SZ, CERT_TYPE); if (pemBufSz < 0) { wolfCLU_LogError("Failed to convert from der to pem."); - return -1; + ret = -1; + goto cleanup; } WOLFCLU_LOG(WOLFCLU_L0, "Resulting pem buffer is %d bytes", pemBufSz); @@ -220,15 +237,27 @@ int make_self_signed_rsa_certificate(char* keyPath, char* certOut, int oid) pemFile = XFOPEN(certOut, "wb"); if (!pemFile) { wolfCLU_LogError("failed to open file: %s", certOut); - return -1; + ret = -1; + goto cleanup; } XFWRITE(pemBuf, 1, pemBufSz, pemFile); XFCLOSE(pemFile); WOLFCLU_LOG(WOLFCLU_L0, "Successfully converted the der to pem. Result is in: %s\n", certOut); - free_things_rsa(&pemBuf, &certBuf, NULL, &key, NULL, &rng); - return 1; + ret = 1; + +cleanup: + if (pemBuf != NULL) + XFREE(pemBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (certBuf != NULL) + XFREE(certBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (keyInit) + wc_FreeRsaKey(&key); + if (rngInit) + wc_FreeRng(&rng); + + return ret; } void free_things_rsa(byte** a, byte** b, byte** c, RsaKey* d, RsaKey* e, diff --git a/src/crypto/clu_crypto_setup.c b/src/crypto/clu_crypto_setup.c index 95cf8ac6..ee2960d9 100644 --- a/src/crypto/clu_crypto_setup.c +++ b/src/crypto/clu_crypto_setup.c @@ -186,14 +186,14 @@ int wolfCLU_setup(int argc, char** argv, char action) return WOLFCLU_FATAL_ERROR; } else { - ivString = (char*)XMALLOC(XSTRLEN(optarg), HEAP_HINT, + ivString = (char*)XMALLOC(XSTRLEN(optarg) + 1, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (ivString == NULL) { wolfCLU_freeBins(pwdKey, iv, key, NULL, NULL); return MEMORY_E; } - XSTRLCPY(ivString, optarg, XSTRLEN(optarg)); + XSTRLCPY(ivString, optarg, XSTRLEN(optarg) + 1); ret = wolfCLU_hexToBin(ivString, &iv, &ivSize, NULL, NULL, NULL, NULL, NULL, NULL, @@ -268,14 +268,14 @@ int wolfCLU_setup(int argc, char** argv, char action) else { char* keyString; - keyString = (char*)XMALLOC(XSTRLEN(optarg), HEAP_HINT, + keyString = (char*)XMALLOC(XSTRLEN(optarg) + 1, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (keyString == NULL) { wolfCLU_freeBins(pwdKey, iv, key, NULL, NULL); return MEMORY_E; } - XSTRLCPY(keyString, optarg, XSTRLEN(optarg)); + XSTRLCPY(keyString, optarg, XSTRLEN(optarg) + 1); ret = wolfCLU_hexToBin(keyString, &key, &numBits, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/src/genkey/clu_genkey.c b/src/genkey/clu_genkey.c index 6ed18f21..3f637c71 100644 --- a/src/genkey/clu_genkey.c +++ b/src/genkey/clu_genkey.c @@ -386,9 +386,10 @@ static int wolfCLU_ECC_write_priv_der(WOLFSSL_BIO* out, WOLFSSL_EC_KEY* key) } if (ret > 0) { - WOLFCLU_LOG(WOLFCLU_L0, "writing out %d bytes for private key", derSz); - ret = wolfSSL_BIO_write(out, der, derSz); - if (ret != derSz) { + int actualDerSz = ret; + WOLFCLU_LOG(WOLFCLU_L0, "writing out %d bytes for private key", actualDerSz); + ret = wolfSSL_BIO_write(out, der, actualDerSz); + if (ret != actualDerSz) { ret = WOLFCLU_FATAL_ERROR; } WOLFCLU_LOG(WOLFCLU_L0, "ret of write = %d", ret); diff --git a/src/genkey/clu_genkey_setup.c b/src/genkey/clu_genkey_setup.c index a104c05a..877de042 100644 --- a/src/genkey/clu_genkey_setup.c +++ b/src/genkey/clu_genkey_setup.c @@ -451,7 +451,7 @@ int wolfCLU_genKeySetup(int argc, char** argv) /* get the height argument */ ret = wolfCLU_checkForArg("-height", 7, argc, argv); - if (ret > 0 || argv[ret+1] != NULL) { + if (ret > 0 && argv[ret+1] != NULL) { WOLFCLU_LOG(WOLFCLU_L0, "Height: %s", argv[ret+1]); if (XSTRNCMP(argv[ret+1], "20", 2) == 0 @@ -473,7 +473,7 @@ int wolfCLU_genKeySetup(int argc, char** argv) /* get the layer argument */ ret = wolfCLU_checkForArg("-layer", 6, argc, argv); - if (ret > 0 || argv[ret+1] != NULL) { + if (ret > 0 && argv[ret+1] != NULL) { WOLFCLU_LOG(WOLFCLU_L0, "Layer: %s", argv[ret+1]); switch (height) { @@ -610,7 +610,7 @@ int wolfCLU_genKeySetup(int argc, char** argv) /* get the height argument */ ret = wolfCLU_checkForArg("-height", 7, argc, argv); - if (ret > 0 || argv[ret+1] != NULL) { + if (ret > 0 && argv[ret+1] != NULL) { WOLFCLU_LOG(WOLFCLU_L0, "Height: %s", argv[ret+1]); if (XSTRNCMP(argv[ret+1], "10", 2) == 0) { diff --git a/src/hash/clu_alg_hash.c b/src/hash/clu_alg_hash.c index b161d885..30b58317 100644 --- a/src/hash/clu_alg_hash.c +++ b/src/hash/clu_alg_hash.c @@ -40,6 +40,9 @@ int wolfCLU_algHashSetup(int argc, char** argv, int algorithm) alg = (char*)"md5"; size = WC_MD5_DIGEST_SIZE; break; + #else + wolfCLU_LogError("MD5 not compiled in"); + return NOT_COMPILED_IN; #endif case WOLFCLU_CERT_SHA256: @@ -47,6 +50,9 @@ int wolfCLU_algHashSetup(int argc, char** argv, int algorithm) alg = (char*)"sha256"; size = WC_SHA256_DIGEST_SIZE; break; + #else + wolfCLU_LogError("SHA-256 not compiled in"); + return NOT_COMPILED_IN; #endif case WOLFCLU_CERT_SHA384: @@ -54,6 +60,9 @@ int wolfCLU_algHashSetup(int argc, char** argv, int algorithm) alg = (char*)"sha384"; size = WC_SHA384_DIGEST_SIZE; break; + #else + wolfCLU_LogError("SHA-384 not compiled in"); + return NOT_COMPILED_IN; #endif case WOLFCLU_CERT_SHA512: @@ -61,6 +70,9 @@ int wolfCLU_algHashSetup(int argc, char** argv, int algorithm) alg = (char*)"sha512"; size = WC_SHA512_DIGEST_SIZE; break; + #else + wolfCLU_LogError("SHA-512 not compiled in"); + return NOT_COMPILED_IN; #endif default: diff --git a/src/hash/clu_hash_setup.c b/src/hash/clu_hash_setup.c index 86d904ae..2a950bad 100644 --- a/src/hash/clu_hash_setup.c +++ b/src/hash/clu_hash_setup.c @@ -94,7 +94,7 @@ int wolfCLU_hashSetup(int argc, char** argv) /* returns location of the arg in question if present */ ret = wolfCLU_checkForArg("-in", 3, argc, argv); - if (ret > 0) { + if (ret > 0 && ret + 1 < argc) { bioIn = wolfSSL_BIO_new_file(argv[ret+1], "rb"); if (bioIn == NULL) { wolfCLU_LogError("unable to open file %s", argv[ret+1]); @@ -104,7 +104,7 @@ int wolfCLU_hashSetup(int argc, char** argv) } ret = wolfCLU_checkForArg("-out", 4, argc, argv); - if (ret > 0) { + if (ret > 0 && ret + 1 < argc) { bioOut = wolfSSL_BIO_new_file(argv[ret+1], "wb"); if (bioOut == NULL) { wolfCLU_LogError("unable to open output file %s", @@ -114,7 +114,7 @@ int wolfCLU_hashSetup(int argc, char** argv) } ret = wolfCLU_checkForArg("-size", 5, argc, argv); - if (ret > 0) { + if (ret > 0 && ret + 1 < argc) { /* size of output */ #ifndef HAVE_BLAKE2 wolfCLU_LogError("%s: -size is only valid when blake2 is enabled.", diff --git a/src/ocsp/clu_ocsp.c b/src/ocsp/clu_ocsp.c index 4ca0dac9..c3ff2b57 100644 --- a/src/ocsp/clu_ocsp.c +++ b/src/ocsp/clu_ocsp.c @@ -884,6 +884,7 @@ static int ocspResponder(OcspResponderConfig* config) freeIndexEntries(indexEntries); XFREE(caCertDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(signerCertDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + wolfCLU_ForceZero(signerKeyDer, signerKeyDerSz); XFREE(signerKeyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(caSubject, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); diff --git a/src/pkcs/clu_pkcs12.c b/src/pkcs/clu_pkcs12.c index fc10da36..4bd09634 100644 --- a/src/pkcs/clu_pkcs12.c +++ b/src/pkcs/clu_pkcs12.c @@ -234,6 +234,7 @@ int wolfCLU_PKCS12(int argc, char** argv) } } + wolfCLU_ForceZero(password, MAX_PASSWORD_SIZE); wolfSSL_BIO_free(bioIn); wolfSSL_BIO_free(bioOut); wolfSSL_EVP_PKEY_free(pkey); diff --git a/src/pkcs/clu_pkcs8.c b/src/pkcs/clu_pkcs8.c index 0529aa55..c17393b9 100644 --- a/src/pkcs/clu_pkcs8.c +++ b/src/pkcs/clu_pkcs8.c @@ -187,6 +187,7 @@ int wolfCLU_PKCS8(int argc, char** argv) } } } + wolfCLU_ForceZero(keyBuffer, sizeof(keyBuffer)); } if (ret == WOLFCLU_SUCCESS && pass == NULL) { @@ -278,6 +279,7 @@ int wolfCLU_PKCS8(int argc, char** argv) } } + wolfCLU_ForceZero(password, MAX_PASSWORD_SIZE); wolfSSL_BIO_free(bioIn); wolfSSL_BIO_free(bioOut); wolfSSL_EVP_PKEY_free(pkey); diff --git a/src/pkey/clu_rsa.c b/src/pkey/clu_rsa.c index f25d30a9..abca3827 100644 --- a/src/pkey/clu_rsa.c +++ b/src/pkey/clu_rsa.c @@ -109,7 +109,7 @@ int wolfCLU_RSA(int argc, char** argv) break; case WOLFCLU_OUTFORM: - outForm = wolfCLU_checkInform(optarg); + outForm = wolfCLU_checkOutform(optarg); break; case WOLFCLU_PASSWORD: diff --git a/src/sign-verify/clu_crl_verify.c b/src/sign-verify/clu_crl_verify.c index b0220b71..974b0c8e 100644 --- a/src/sign-verify/clu_crl_verify.c +++ b/src/sign-verify/clu_crl_verify.c @@ -95,7 +95,7 @@ int wolfCLU_CRLVerify(int argc, char** argv) break; case WOLFCLU_OUTFORM: - outForm = wolfCLU_checkInform(optarg); + outForm = wolfCLU_checkOutform(optarg); break; case WOLFCLU_INFORM: diff --git a/src/sign-verify/clu_dgst_setup.c b/src/sign-verify/clu_dgst_setup.c index 1ea46bb5..40cfd21e 100644 --- a/src/sign-verify/clu_dgst_setup.c +++ b/src/sign-verify/clu_dgst_setup.c @@ -40,7 +40,7 @@ static const struct option dgst_options[] = { {"-sha512", no_argument, 0, WOLFCLU_CERT_SHA512}, {"-inform", required_argument, 0, WOLFCLU_INFORM }, - {"-out", required_argument, 0, WOLFCLU_INFILE }, + {"-out", required_argument, 0, WOLFCLU_OUTFILE }, {"-signature", required_argument, 0, WOLFCLU_INFILE }, {"-verify", required_argument, 0, WOLFCLU_VERIFY }, {"-sign", required_argument, 0, WOLFCLU_SIGN }, @@ -240,6 +240,10 @@ int wolfCLU_dgst_setup(int argc, char** argv) } break; + case WOLFCLU_OUTFILE: + sigFile = optarg; + break; + case WOLFCLU_INFILE: sigFile = optarg; break; diff --git a/src/sign-verify/clu_sign.c b/src/sign-verify/clu_sign.c index 622a161a..f31eba4b 100644 --- a/src/sign-verify/clu_sign.c +++ b/src/sign-verify/clu_sign.c @@ -108,6 +108,7 @@ int wolfCLU_sign_data(char* in, char* out, char* privKey, int keyType, } if (XFSEEK(f, 0, SEEK_SET) != 0 || (int)XFREAD(data, 1, fSz, f) != fSz) { + XFREE(data, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFCLOSE(f); return WOLFCLU_FATAL_ERROR; } @@ -234,9 +235,8 @@ int wolfCLU_sign_data_rsa(byte* data, char* out, word32 dataSz, char* privKey, /* retrieving private key and storing in the RsaKey */ if (ret == 0) { ret = wc_RsaPrivateKeyDecode(keyBuf, &index, &key, privFileSz); - if (privFileSz < 0) { + if (ret != 0) { wolfCLU_LogError("Failed to decode private key.\nRET: %d", ret); - ret = privFileSz; } } @@ -373,9 +373,8 @@ int wolfCLU_sign_data_ecc(byte* data, char* out, word32 fSz, char* privKey, /* retrieving private key and storing in the Ecc Key */ if (ret == 0) { ret = wc_EccPrivateKeyDecode(keyBuf, &index, &key, privFileSz); - if (privFileSz < 0) { + if (ret != 0) { wolfCLU_LogError("Failed to decode Ecc private key.\nRET: %d", ret); - ret = privFileSz; } } @@ -551,7 +550,7 @@ int wolfCLU_sign_data_ed25519 (byte* data, char* out, word32 fSz, char* privKey, ret = BAD_FUNC_ARG; } else { - XFWRITE(outBuf, 1, outBufSz, s); + XFWRITE(outBuf, 1, outLen, s); XFCLOSE(s); } } @@ -609,6 +608,9 @@ int wolfCLU_sign_data_dilithium (byte* data, char* out, word32 dataSz, char* pri dilithium_key key[1]; #endif + /* zero before init for defensive security */ + XMEMSET(key, 0, sizeof(dilithium_key)); + /* init the dilithium key */ if (wc_dilithium_init(key) != 0) { wolfCLU_LogError("Failed to initialize Dilithium Key.\nRET: %d", ret); @@ -617,7 +619,6 @@ int wolfCLU_sign_data_dilithium (byte* data, char* out, word32 dataSz, char* pri #endif return WOLFCLU_FAILURE; } - XMEMSET(key, 0, sizeof(dilithium_key)); if (wc_InitRng(&rng) != 0) { wolfCLU_LogError("Failed to initialize rng.\nRET: %d", ret); @@ -637,7 +638,7 @@ int wolfCLU_sign_data_dilithium (byte* data, char* out, word32 dataSz, char* pri #ifdef WOLFSSL_SMALL_STACK XFREE(key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); #endif - return ret; + return WOLFCLU_FATAL_ERROR; } XFSEEK(privKeyFile, 0, SEEK_END); diff --git a/src/sign-verify/clu_sign_verify_setup.c b/src/sign-verify/clu_sign_verify_setup.c index 16e6fe58..ce682bf5 100644 --- a/src/sign-verify/clu_sign_verify_setup.c +++ b/src/sign-verify/clu_sign_verify_setup.c @@ -95,7 +95,7 @@ int wolfCLU_sign_verify_setup(int argc, char** argv) } ret = wolfCLU_checkForArg("-inkey", 6, argc, argv); - if (ret > 0) { + if (ret > 0 && ret + 1 < argc) { priv = XMALLOC(XSTRLEN(argv[ret+1]) + 1, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (priv == NULL) { return MEMORY_E; @@ -119,7 +119,7 @@ int wolfCLU_sign_verify_setup(int argc, char** argv) } ret = wolfCLU_checkForArg("-inform", 7, argc, argv); - if (ret > 0) { + if (ret > 0 && ret + 1 < argc) { inForm = wolfCLU_checkInform(argv[ret+1]); if (inForm == USER_INPUT_ERROR) { ret = WOLFCLU_FATAL_ERROR; @@ -136,7 +136,7 @@ int wolfCLU_sign_verify_setup(int argc, char** argv) } ret = wolfCLU_checkForArg("-in", 3, argc, argv); - if (ret > 0) { + if (ret > 0 && ret + 1 < argc) { /* input file/text */ in = XMALLOC(XSTRLEN(argv[ret+1]) + 1, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); @@ -159,7 +159,7 @@ int wolfCLU_sign_verify_setup(int argc, char** argv) } ret = wolfCLU_checkForArg("-sigfile", 8, argc, argv); - if (ret > 0) { + if (ret > 0 && ret + 1 < argc) { sig = XMALLOC(XSTRLEN(argv[ret+1]) + 1, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (sig == NULL) { @@ -195,7 +195,7 @@ int wolfCLU_sign_verify_setup(int argc, char** argv) } ret = wolfCLU_checkForArg("-out", 4, argc, argv); - if (ret > 0) { + if (ret > 0 && ret + 1 < argc) { /* output file */ out = argv[ret+1]; } diff --git a/src/sign-verify/clu_verify.c b/src/sign-verify/clu_verify.c index 3c85020e..5047de3d 100644 --- a/src/sign-verify/clu_verify.c +++ b/src/sign-verify/clu_verify.c @@ -165,6 +165,7 @@ int wolfCLU_verify_signature(char* sig, char* hashFile, char* out, } if (XFSEEK(f, 0, SEEK_SET) != 0 || (int)XFREAD(data, 1, fSz, f) != fSz) { XFCLOSE(f); + XFREE(data, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return WOLFCLU_FATAL_ERROR; } XFCLOSE(f); @@ -194,6 +195,8 @@ int wolfCLU_verify_signature(char* sig, char* hashFile, char* out, if (XFSEEK(h, 0, SEEK_SET) != 0 || (int)XFREAD(hash, 1, hSz, h) != hSz) { XFCLOSE(h); + XFREE(hash, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(data, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return WOLFCLU_FATAL_ERROR; } XFCLOSE(h); @@ -222,6 +225,8 @@ int wolfCLU_verify_signature(char* sig, char* hashFile, char* out, if (XFSEEK(h, 0, SEEK_SET) != 0 || (int)XFREAD(hash, 1, hSz, h) != hSz) { XFCLOSE(h); + XFREE(hash, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(data, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return WOLFCLU_FATAL_ERROR; } XFCLOSE(h); @@ -254,6 +259,8 @@ int wolfCLU_verify_signature(char* sig, char* hashFile, char* out, if (XFSEEK(h, 0, SEEK_SET) != 0 || (int)XFREAD(hash, 1, hSz, h) != hSz) { XFCLOSE(h); + XFREE(hash, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(data, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return WOLFCLU_FATAL_ERROR; } XFCLOSE(h); @@ -286,6 +293,8 @@ int wolfCLU_verify_signature(char* sig, char* hashFile, char* out, if (XFSEEK(h, 0, SEEK_SET) != 0 || (int)XFREAD(hash, 1, hSz, h) != hSz) { XFCLOSE(h); + XFREE(hash, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(data, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return WOLFCLU_FATAL_ERROR; } XFCLOSE(h); @@ -316,6 +325,8 @@ int wolfCLU_verify_signature(char* sig, char* hashFile, char* out, if (XFSEEK(h, 0, SEEK_SET) != 0 || (int)XFREAD(hash, 1, hSz, h) != hSz) { XFCLOSE(h); + XFREE(hash, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(data, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return WOLFCLU_FATAL_ERROR; } XFCLOSE(h); @@ -758,6 +769,9 @@ int wolfCLU_verify_signature_dilithium(byte* sig, int sigSz, byte* msg, dilithium_key key[1]; #endif + /* zero before init for defensive security */ + XMEMSET(key, 0, sizeof(dilithium_key)); + /* init the dilithium key */ ret = wc_dilithium_init(key); if (ret != 0) { @@ -767,7 +781,6 @@ int wolfCLU_verify_signature_dilithium(byte* sig, int sigSz, byte* msg, #endif return ret; } - XMEMSET(key, 0, sizeof(dilithium_key)); /* open and read public key */ keyFile = XFOPEN(keyPath, "rb"); diff --git a/src/tools/clu_rand.c b/src/tools/clu_rand.c index 927fb2b1..cce46f1d 100644 --- a/src/tools/clu_rand.c +++ b/src/tools/clu_rand.c @@ -147,15 +147,19 @@ int wolfCLU_Rand(int argc, char** argv) ret = WOLFCLU_FATAL_ERROR; } - base64 = (byte*)XMALLOC(base64Sz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - if (base64 == NULL) { - wolfCLU_LogError("Error malloc'ing for base64"); - ret = WOLFCLU_FATAL_ERROR; + if (ret == WOLFCLU_SUCCESS) { + base64 = (byte*)XMALLOC(base64Sz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (base64 == NULL) { + wolfCLU_LogError("Error malloc'ing for base64"); + ret = WOLFCLU_FATAL_ERROR; + } } - if (Base64_Encode(buf, size, base64, &base64Sz) != 0) { - wolfCLU_LogError("Error base64 encoding"); - ret = WOLFCLU_FATAL_ERROR; + if (ret == WOLFCLU_SUCCESS) { + if (Base64_Encode(buf, size, base64, &base64Sz) != 0) { + wolfCLU_LogError("Error base64 encoding"); + ret = WOLFCLU_FATAL_ERROR; + } } if (ret == WOLFCLU_SUCCESS) { diff --git a/src/x509/clu_cert_setup.c b/src/x509/clu_cert_setup.c index 3ac36d97..4240e112 100644 --- a/src/x509/clu_cert_setup.c +++ b/src/x509/clu_cert_setup.c @@ -412,6 +412,7 @@ int wolfCLU_certSetup(int argc, char** argv) ret = USER_INPUT_ERROR; } wolfSSL_BIO_free(keyIn); + keyIn = NULL; } if (ret == WOLFCLU_SUCCESS && extFile != NULL) { @@ -774,7 +775,6 @@ int wolfCLU_certSetup(int argc, char** argv) wolfSSL_BIO_write(out, info, (int)XSTRLEN(info)); } - wolfSSL_EVP_PKEY_free(pkey); } } @@ -844,6 +844,10 @@ int wolfCLU_certSetup(int argc, char** argv) if (tmpOutBuf != NULL) { XFREE(tmpOutBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); } + if (keyIn != NULL) + wolfSSL_BIO_free(keyIn); + if (privkey != NULL) + wolfSSL_EVP_PKEY_free(privkey); wc_FreeDer(&derObj); wolfSSL_BIO_free(out); wolfSSL_X509_free(x509); diff --git a/src/x509/clu_config.c b/src/x509/clu_config.c index 5e73b336..03051aa2 100644 --- a/src/x509/clu_config.c +++ b/src/x509/clu_config.c @@ -48,7 +48,7 @@ static int wolfCLU_setAttributes(WOLFSSL_X509* x509, WOLFSSL_CONF* conf, MBSTRING_ASC, (const unsigned char*)current, currentSz); } - return WOLFCLU_FAILURE; + return WOLFCLU_SUCCESS; } @@ -117,7 +117,7 @@ static WOLFSSL_X509_EXTENSION* wolfCLU_parseBasicConstraint(char* in, int crit) for (word = XSTRTOK(str + idx, deli, &end); word != NULL; word = XSTRTOK(NULL, deli, &end)) { - if (word != NULL && XSTRNCMP(word, "CA", XSTRLEN(word)) == 0) { + if (word != NULL && XSTRCMP(word, "CA") == 0) { word = XSTRTOK(NULL, deli, &end); if (word != NULL) { int z, wordSz; @@ -125,13 +125,13 @@ static WOLFSSL_X509_EXTENSION* wolfCLU_parseBasicConstraint(char* in, int crit) wordSz = (int)XSTRLEN(word); for (z = 0; z < wordSz; z++) word[z] = toupper(word[z]); - if (XSTRNCMP(word, "TRUE", XSTRLEN(word)) == 0) { + if (XSTRCMP(word, "TRUE") == 0) { obj->ca = 1; } } } - if (word != NULL && XSTRNCMP(word, "pathlen", XSTRLEN(word)) == 0) { + if (word != NULL && XSTRCMP(word, "pathlen") == 0) { word = XSTRTOK(NULL, deli, &end); if (word != NULL) { if (obj->pathlen != NULL) @@ -237,40 +237,40 @@ static WOLFSSL_X509_EXTENSION* wolfCLU_parseKeyUsage(char* str, int crit, mxSz--; } - if (XSTRNCMP(word, "digitalSignature", XSTRLEN(word)) == 0) { + if (XSTRCMP(word, "digitalSignature") == 0) { keyUseFlag |= KEYUSE_DIGITAL_SIG; } - if (XSTRNCMP(word, "nonRepudiation", XSTRLEN(word)) == 0 || - XSTRNCMP(word, "contentCommitment", XSTRLEN(word)) == 0) { + if (XSTRCMP(word, "nonRepudiation") == 0 || + XSTRCMP(word, "contentCommitment") == 0) { keyUseFlag |= KEYUSE_CONTENT_COMMIT; } - if (XSTRNCMP(word, "keyEncipherment", XSTRLEN(word)) == 0) { + if (XSTRCMP(word, "keyEncipherment") == 0) { keyUseFlag |= KEYUSE_KEY_ENCIPHER; } - if (XSTRNCMP(word, "dataEncipherment", XSTRLEN(word)) == 0) { + if (XSTRCMP(word, "dataEncipherment") == 0) { keyUseFlag |= KEYUSE_DATA_ENCIPHER; } - if (XSTRNCMP(word, "keyAgreement", XSTRLEN(word)) == 0) { + if (XSTRCMP(word, "keyAgreement") == 0) { keyUseFlag |= KEYUSE_KEY_AGREE; } - if (XSTRNCMP(word, "keyCertSign", XSTRLEN(word)) == 0) { + if (XSTRCMP(word, "keyCertSign") == 0) { keyUseFlag |= KEYUSE_KEY_CERT_SIGN; } - if (XSTRNCMP(word, "cRLSign", XSTRLEN(word)) == 0) { + if (XSTRCMP(word, "cRLSign") == 0) { keyUseFlag |= KEYUSE_CRL_SIGN; } - if (XSTRNCMP(word, "encipherOnly", XSTRLEN(word)) == 0) { + if (XSTRCMP(word, "encipherOnly") == 0) { keyUseFlag |= KEYUSE_ENCIPHER_ONLY; } - if (XSTRNCMP(word, "decipherOnly", XSTRLEN(word)) == 0) { + if (XSTRCMP(word, "decipherOnly") == 0) { keyUseFlag |= KEYUSE_DECIPHER_ONLY; } } diff --git a/src/x509/clu_x509_sign.c b/src/x509/clu_x509_sign.c index 7d5625cd..f0b6083d 100644 --- a/src/x509/clu_x509_sign.c +++ b/src/x509/clu_x509_sign.c @@ -263,30 +263,30 @@ int wolfCLU_GenChimeraCertSign(WOLFSSL_BIO *bioCaKey, WOLFSSL_BIO *bioAltCaKey, * The value 11264 is enough for P-521 and ML-DSA-87 PEM certs. */ const int LARGE_TEMP_SZ = 11264; - byte caKeyBuf[LARGE_TEMP_SZ]; + byte* caKeyBuf = NULL; int caKeySz = LARGE_TEMP_SZ; - byte altCaKeyBuf[LARGE_TEMP_SZ]; + byte* altCaKeyBuf = NULL; int altCaKeySz = LARGE_TEMP_SZ; - byte sapkiBuf[LARGE_TEMP_SZ]; + byte* sapkiBuf = NULL; int sapkiSz = LARGE_TEMP_SZ; - byte altSigAlgBuf[LARGE_TEMP_SZ]; + byte* altSigAlgBuf = NULL; int altSigAlgSz = LARGE_TEMP_SZ; - byte scratchBuf[LARGE_TEMP_SZ]; + byte* scratchBuf = NULL; int scratchSz = LARGE_TEMP_SZ; - byte preTbsBuf[LARGE_TEMP_SZ]; + byte* preTbsBuf = NULL; int preTbsSz = LARGE_TEMP_SZ; - byte altSigValBuf[LARGE_TEMP_SZ]; + byte* altSigValBuf = NULL; int altSigValSz = LARGE_TEMP_SZ; - byte derBuf[LARGE_TEMP_SZ]; + byte* derBuf = NULL; int derSz = LARGE_TEMP_SZ; - byte outBuf[LARGE_TEMP_SZ]; + byte* outBuf = NULL; int outSz = LARGE_TEMP_SZ; DerBuffer *derObj = NULL; /* if generate server cert */ - byte caCertBuf[LARGE_TEMP_SZ]; + byte* caCertBuf = NULL; int caCertSz = LARGE_TEMP_SZ; - byte serverKeyBuf[LARGE_TEMP_SZ]; + byte* serverKeyBuf = NULL; int serverKeySz = LARGE_TEMP_SZ; if (bioCaKey == NULL || bioAltCaKey == NULL || bioAltSubjPubKey == NULL @@ -305,16 +305,39 @@ int wolfCLU_GenChimeraCertSign(WOLFSSL_BIO *bioCaKey, WOLFSSL_BIO *bioAltCaKey, ret = BAD_FUNC_ARG; } - XMEMSET(caKeyBuf, 0, caKeySz); - XMEMSET(altCaKeyBuf, 0, altCaKeySz); - XMEMSET(sapkiBuf, 0, sapkiSz); - XMEMSET(altSigAlgBuf, 0, altSigAlgSz); - XMEMSET(scratchBuf, 0, scratchSz); - XMEMSET(preTbsBuf, 0, preTbsSz); - XMEMSET(altSigValBuf, 0, altSigValSz); - XMEMSET(outBuf, 0, outSz); - XMEMSET(caCertBuf, 0, caCertSz); - XMEMSET(serverKeyBuf, 0, serverKeySz); + if (ret == WOLFCLU_SUCCESS) { + caKeyBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + altCaKeyBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + sapkiBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + altSigAlgBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + scratchBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + preTbsBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + altSigValBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + derBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + outBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + caCertBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + serverKeyBuf = (byte*)XMALLOC(LARGE_TEMP_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + + if (caKeyBuf == NULL || altCaKeyBuf == NULL || sapkiBuf == NULL || + altSigAlgBuf == NULL || scratchBuf == NULL || preTbsBuf == NULL || + altSigValBuf == NULL || derBuf == NULL || outBuf == NULL || + caCertBuf == NULL || serverKeyBuf == NULL) { + ret = MEMORY_E; + } + else { + XMEMSET(caKeyBuf, 0, LARGE_TEMP_SZ); + XMEMSET(altCaKeyBuf, 0, LARGE_TEMP_SZ); + XMEMSET(sapkiBuf, 0, LARGE_TEMP_SZ); + XMEMSET(altSigAlgBuf, 0, LARGE_TEMP_SZ); + XMEMSET(scratchBuf, 0, LARGE_TEMP_SZ); + XMEMSET(preTbsBuf, 0, LARGE_TEMP_SZ); + XMEMSET(altSigValBuf, 0, LARGE_TEMP_SZ); + XMEMSET(derBuf, 0, LARGE_TEMP_SZ); + XMEMSET(outBuf, 0, LARGE_TEMP_SZ); + XMEMSET(caCertBuf, 0, LARGE_TEMP_SZ); + XMEMSET(serverKeyBuf, 0, LARGE_TEMP_SZ); + } + } if (ret == WOLFCLU_SUCCESS) { ret = wc_InitRng(&rng); @@ -902,6 +925,18 @@ int wolfCLU_GenChimeraCertSign(WOLFSSL_BIO *bioCaKey, WOLFSSL_BIO *bioAltCaKey, wolfSSL_BIO_free(out); } + XFREE(caKeyBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(altCaKeyBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(sapkiBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(altSigAlgBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(scratchBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(preTbsBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(altSigValBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(derBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(outBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(caCertBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + XFREE(serverKeyBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (ret != WOLFCLU_SUCCESS) { wolfCLU_LogError("Error in wolfCLU_ChimeraCertSignSetCA: %d", ret); } @@ -942,24 +977,20 @@ enum wc_HashType wolfCLU_StringToHashType(char* in) ret = WC_HASH_TYPE_MD5; } - if (XSTRNCMP(in, "sha", 3) == 0) { - ret = WC_HASH_TYPE_SHA; + if (XSTRNCMP(in, "sha512", 6) == 0) { + ret = WC_HASH_TYPE_SHA512; } - - if (XSTRNCMP(in, "sha224", 6) == 0) { - ret = WC_HASH_TYPE_SHA256; + else if (XSTRNCMP(in, "sha384", 6) == 0) { + ret = WC_HASH_TYPE_SHA384; } - - if (XSTRNCMP(in, "sha256", 6) == 0) { + else if (XSTRNCMP(in, "sha256", 6) == 0) { ret = WC_HASH_TYPE_SHA256; } - - if (XSTRNCMP(in, "sha384", 6) == 0) { - ret = WC_HASH_TYPE_SHA384; + else if (XSTRNCMP(in, "sha224", 6) == 0) { + ret = WC_HASH_TYPE_SHA224; } - - if (XSTRNCMP(in, "sha512", 6) == 0) { - ret = WC_HASH_TYPE_SHA512; + else if (XSTRNCMP(in, "sha", 3) == 0) { + ret = WC_HASH_TYPE_SHA; } return ret; } @@ -1112,8 +1143,14 @@ static int wolfCLU_CertSignLog(WOLFCLU_CERT_SIGN* csign, WOLFSSL_X509* x509) subject = wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_subject_name(x509), NULL, 0); - if (wolfSSL_BIO_write(csign->dataBase, subject, (int)XSTRLEN(subject)) - <= 0) { + if (subject == NULL) { + wolfCLU_LogError("Unable to get subject name"); + ret = WOLFCLU_FATAL_ERROR; + } + + if (ret == WOLFCLU_SUCCESS && + wolfSSL_BIO_write(csign->dataBase, subject, + (int)XSTRLEN(subject)) <= 0) { wolfCLU_LogError("Unable to write to data base"); ret = WOLFCLU_FATAL_ERROR; } @@ -1296,7 +1333,7 @@ int wolfCLU_CertSign(WOLFCLU_CERT_SIGN* csign, WOLFSSL_X509* x509) /* set serial number of certificate */ if (ret == WOLFCLU_SUCCESS) { - WOLFSSL_ASN1_INTEGER* s; + WOLFSSL_ASN1_INTEGER* s = NULL; char buf[EXTERNAL_SERIAL_SIZE*2]; int size = EXTERNAL_SERIAL_SIZE*2; @@ -1319,6 +1356,8 @@ int wolfCLU_CertSign(WOLFCLU_CERT_SIGN* csign, WOLFSSL_X509* x509) != WOLFSSL_SUCCESS) { wolfCLU_LogError("Creating a random serial number fail"); ret = WOLFCLU_FATAL_ERROR; + wolfSSL_BN_free(bn); + break; } /* work around BN_to_ASN1_INTEGER check */ @@ -1329,7 +1368,9 @@ int wolfCLU_CertSign(WOLFCLU_CERT_SIGN* csign, WOLFSSL_X509* x509) wolfSSL_BN_free(bn); } while ((numBits % 8) == 7); } - wolfSSL_X509_set_serialNumber(x509, s); + if (ret == WOLFCLU_SUCCESS) { + wolfSSL_X509_set_serialNumber(x509, s); + } wolfSSL_ASN1_INTEGER_free(s); } diff --git a/tests/bench/bench-test.sh b/tests/bench/bench-test.sh index 7bc070f3..a15506c2 100755 --- a/tests/bench/bench-test.sh +++ b/tests/bench/bench-test.sh @@ -20,5 +20,17 @@ run_success "-bench aes-cbc -time 1" run_success "-bench sha -time 1" run_success "-bench md5 -time 1" +# Test missing argument value for -time (must fail gracefully, not segfault) +(./wolfssl -bench -time) 2>/dev/null +RET=$? +if [ $RET -eq 0 ]; then + echo "Expected failure for missing -time value" + exit 99 +fi +if [ $RET -ge 129 ] && [ $RET -le 192 ]; then + echo "Missing -time value caused signal $(($RET - 128)), expected graceful error" + exit 99 +fi + echo "Done" exit 0 diff --git a/tests/dgst/dgst-test.sh b/tests/dgst/dgst-test.sh index a03569d6..37b6415e 100755 --- a/tests/dgst/dgst-test.sh +++ b/tests/dgst/dgst-test.sh @@ -94,5 +94,14 @@ run_fail "dgst -sha256 -verify ./certs/server-keyPub.pem -signature configure.si run "dgst -sha256 -verify ./certs/ecc-keyPub.pem -signature configure.sig configure.ac" rm -f configure.sig +# Test that dgst -out creates output file and round-trips with -signature +run "dgst -sha256 -sign ./certs/server-key.pem -out dgst-out-test.sig ./configure.ac" +if [ ! -f dgst-out-test.sig ]; then + echo "dgst -out did not create output file" + exit 99 +fi +run "dgst -sha256 -verify ./certs/server-keyPub.pem -signature dgst-out-test.sig ./configure.ac" +rm -f dgst-out-test.sig + echo "Done" exit 0 diff --git a/tests/encrypt/enc-test.sh b/tests/encrypt/enc-test.sh index 31b7754f..66839c8a 100755 --- a/tests/encrypt/enc-test.sh +++ b/tests/encrypt/enc-test.sh @@ -185,5 +185,15 @@ fi rm -f test-dec.der rm -f test-enc.der +# Test encrypt with explicit hex IV and key (verifies XSTRLCPY size is correct) +echo "testing explicit hex IV and key" > enc_hex_test.txt +./wolfssl enc -aes-128-cbc -nosalt -in enc_hex_test.txt -out enc_hex_test.enc --key 00112233445566778899aabbccddeeff --iv 00112233445566778899aabb0011aab7 +if [ $? != 0 ]; then + echo "encrypt with explicit hex key/iv failed" + rm -f enc_hex_test.txt enc_hex_test.enc + exit 99 +fi +rm -f enc_hex_test.txt enc_hex_test.enc + echo "Done" exit 0 diff --git a/tests/genkey_sign_ver/genkey-sign-ver-test.sh b/tests/genkey_sign_ver/genkey-sign-ver-test.sh index 53239bd1..18977d58 100755 --- a/tests/genkey_sign_ver/genkey-sign-ver-test.sh +++ b/tests/genkey_sign_ver/genkey-sign-ver-test.sh @@ -317,4 +317,75 @@ if ./wolfssl xmss -help 2>&1 | grep -A6 "Available keys with current configure" fi +# Test ED25519 signature file is exactly 64 bytes +./wolfssl -genkey ed25519 -out edkey-sztest -outform der -output KEYPAIR +RESULT=$? +if [ $RESULT -eq 0 ]; then + printf '%s\n' "Sign this data" > sign-this.txt + ./wolfssl -ed25519 -sign -inkey edkey-sztest.priv -inform der -in sign-this.txt -out ed-sz-test.sig + RESULT=$? + if [ $RESULT -eq 0 ]; then + SIGSIZE=$(wc -c < ed-sz-test.sig) + if [ "$SIGSIZE" -ne 64 ]; then + printf '%s\n' "ED25519 signature size is $SIGSIZE, expected 64" && exit 99 + fi + fi + rm -f ed-sz-test.sig edkey-sztest.priv edkey-sztest.pub +fi + +# Test signing with invalid key file expects error +printf '%s\n' "Sign this data" > sign-this.txt +./wolfssl -ecc -sign -inkey /dev/null -inform der -in sign-this.txt -out bad-sign.sig 2>/dev/null +RESULT=$? +[ $RESULT -eq 0 ] && printf '%s\n' "Signing with /dev/null key should have failed" && exit 99 +rm -f bad-sign.sig + +./wolfssl -rsa -sign -inkey /dev/null -inform der -in sign-this.txt -out bad-sign.sig 2>/dev/null +RESULT=$? +[ $RESULT -eq 0 ] && printf '%s\n' "RSA signing with /dev/null key should have failed" && exit 99 +rm -f bad-sign.sig + +# Test missing argument value for -inkey (must fail gracefully, not segfault) +(./wolfssl -ecc -sign -inkey) 2>/dev/null +RET=$? +if [ $RET -eq 0 ]; then + printf '%s\n' "Expected failure for missing -inkey value" && exit 99 +fi +if [ $RET -ge 129 ] && [ $RET -le 192 ]; then + printf '%s\n' "Missing -inkey value caused signal $(($RET - 128)), expected graceful error" && exit 99 +fi + +# Test ECC DER key generation produces a reasonably sized file (not buffer-sized) +./wolfssl -genkey ecc -out ecc-rt-test -outform der -output KEYPAIR +RESULT=$? +if [ $RESULT -eq 0 ]; then + KEYSIZE=$(wc -c < ecc-rt-test.priv) + if [ "$KEYSIZE" -gt 256 ]; then + printf '%s\n' "ECC DER private key too large ($KEYSIZE bytes), may contain trailing garbage" && exit 99 + fi + rm -f ecc-rt-test.priv ecc-rt-test.pub +fi + +# Test dilithium sign with nonexistent key file expects failure +if ./wolfssl -genkey -h 2>&1 | grep -A6 "Available keys with current configure" | grep -q dilithium; then + printf '%s\n' "Sign this data" > sign-this.txt + ./wolfssl -dilithium -sign -inkey /nonexistent/key.priv -inform der -in sign-this.txt -out bad-dil.sig 2>/dev/null + RESULT=$? + [ $RESULT -eq 0 ] && printf '%s\n' "Dilithium sign with nonexistent key should have failed" && exit 99 + rm -f bad-dil.sig +fi + +# Test XMSS genkey with missing -height value (must fail gracefully, not crash) +if ./wolfssl xmss -help 2>&1 | grep -q xmss; then + (./wolfssl -genkey xmss -out xmss-bad -outform raw -output KEYPAIR -height) 2>/dev/null + RET=$? + if [ $RET -eq 0 ]; then + printf '%s\n' "Expected failure for missing -height value" && exit 99 + fi + if [ $RET -ge 129 ] && [ $RET -le 192 ]; then + printf '%s\n' "Missing -height value caused signal $(($RET - 128)), expected graceful error" && exit 99 + fi + rm -f xmss-bad.priv xmss-bad.pub +fi + exit 0 diff --git a/tests/hash/hash-test.sh b/tests/hash/hash-test.sh index 3756c0e5..74426cbd 100755 --- a/tests/hash/hash-test.sh +++ b/tests/hash/hash-test.sh @@ -94,5 +94,17 @@ then fi +# Test missing argument value for -in (must fail gracefully, not segfault) +(./wolfssl -hash sha256 -in) 2>/dev/null +RET=$? +if [ $RET -eq 0 ]; then + echo "Expected failure for missing -in value" + exit 99 +fi +if [ $RET -ge 129 ] && [ $RET -le 192 ]; then + echo "Missing -in value caused signal $(($RET - 128)), expected graceful error" + exit 99 +fi + echo "Done" exit 0 diff --git a/tests/pkey/rsa-test.sh b/tests/pkey/rsa-test.sh index 2bb0e6c9..e57ad4d4 100755 --- a/tests/pkey/rsa-test.sh +++ b/tests/pkey/rsa-test.sh @@ -138,5 +138,13 @@ if [ "$RESULT" != "$EXPECTED1" ]; then exit 99 fi +# Test -outform with invalid format gives outform-related error, not inform +RESULT=`./wolfssl rsa -in ./certs/server-key.pem -outform INVALID 2>&1` +echo "$RESULT" | grep -i "outform" +if [ $? != 0 ]; then + echo "Expected outform error message for -outform INVALID" + exit 99 +fi + echo "Done" exit 0 diff --git a/tests/x509/CRL-verify-test.sh b/tests/x509/CRL-verify-test.sh index 270e3c44..5b2e352c 100755 --- a/tests/x509/CRL-verify-test.sh +++ b/tests/x509/CRL-verify-test.sh @@ -87,6 +87,14 @@ if [ $? == 0 ]; then fi fi +# Test -outform with invalid format gives outform-related error +RESULT=`./wolfssl crl -in ./certs/crl.pem -outform INVALID 2>&1` +echo "$RESULT" | grep -i "outform" +if [ $? != 0 ]; then + echo "Expected outform error message for -outform INVALID" + exit 99 +fi + echo "Done" exit 0 diff --git a/tests/x509/x509-process-test.sh b/tests/x509/x509-process-test.sh index b20d3958..d9aaa7c1 100755 --- a/tests/x509/x509-process-test.sh +++ b/tests/x509/x509-process-test.sh @@ -358,6 +358,13 @@ run2 run3 run4 +# Test x509 -modulus -noout does not crash +(./wolfssl x509 -in ./certs/server-cert.pem -modulus -noout) 2>/dev/null +if [ $? -ne 0 ]; then + echo "x509 -modulus -noout crashed or failed" + exit 99 +fi + rm -f out.txt rm -f tmp.pem rm -f tmp.der diff --git a/tests/x509/x509-req-test.sh b/tests/x509/x509-req-test.sh index d0d8742f..606de164 100755 --- a/tests/x509/x509-req-test.sh +++ b/tests/x509/x509-req-test.sh @@ -181,6 +181,16 @@ rm -f tmp.cert run_success "x509 -req -in tmp.csr -days 3650 -sha1 -signkey ./certs/server-key.pem -out tmp.cert" rm -f tmp.cert run_success "x509 -req -in tmp.csr -days 3650 -sha224 -signkey ./certs/server-key.pem -out tmp.cert" +# Verify SHA-224 cert uses sha224 signature algorithm, not sha256 +SIGALG=`./wolfssl x509 -in tmp.cert -text -noout 2>&1` +echo "$SIGALG" | grep -i "sha224" +if [ $? -ne 0 ]; then + echo "$SIGALG" | grep -i "sha256" + if [ $? -eq 0 ]; then + echo "SHA-224 cert incorrectly uses SHA-256 signature algorithm" + exit 99 + fi +fi rm -f tmp.cert run_success "x509 -req -in tmp.csr -days 3650 -sha256 -signkey ./certs/server-key.pem -out tmp.cert" rm -f tmp.cert @@ -332,7 +342,55 @@ fi rm -f tmp.cert rm -f tmp.csr -echo "Done" -exit 0 +# Test that abbreviated keyUsage values are rejected (e.g. "d" should not match "digitalSignature") +cat << EOF > test-abbrev-ku.conf +[ req ] +distinguished_name = req_distinguished_name +prompt = no +x509_extensions = v3_req +req_extensions = v3_req +[ req_distinguished_name ] +countryName = US +stateOrProvinceName = Montana +localityName = Bozeman +organizationName = wolfSSL +commonName = testing +[ v3_req ] +basicConstraints = CA:FALSE +keyUsage = d +EOF +# This should either fail or produce a cert without digitalSignature keyUsage +RESULT=`./wolfssl req -new -key ./certs/server-key.pem -config ./test-abbrev-ku.conf -x509 -out tmp-ku.cert 2>&1` +if [ $? -eq 0 ] && [ -f tmp-ku.cert ]; then + KUTEXT=`./wolfssl x509 -in tmp-ku.cert -text -noout 2>&1` + echo "$KUTEXT" | grep -i "Digital Signature" + if [ $? -eq 0 ]; then + echo "Abbreviated keyUsage 'd' should not match digitalSignature" + rm -f tmp-ku.cert test-abbrev-ku.conf + exit 99 + fi +fi +rm -f tmp-ku.cert test-abbrev-ku.conf +# Test req with config containing challengePassword attribute +cat << EOF > test-attr.conf +[ req ] +distinguished_name = req_distinguished_name +attributes = req_attributes +prompt = no +[ req_distinguished_name ] +countryName = US +stateOrProvinceName = Montana +localityName = Bozeman +organizationName = wolfSSL +commonName = testing +[ req_attributes ] +challengePassword = testpass123 +EOF + +run_success "req -new -key ./certs/server-key.pem -config ./test-attr.conf -out tmp-attr.csr" +rm -f tmp-attr.csr test-attr.conf + +echo "Done" +exit 0 From 6590906c4ab459f1007c2e021ff7dcffe6be5026 Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Fri, 3 Apr 2026 09:58:29 -0700 Subject: [PATCH 2/4] =?UTF-8?q?address=20copilot,=20fenrir,=20and=20intern?= =?UTF-8?q?al=20review=20-=20Copilot:=20privkey=20double-free=20=E2=80=94?= =?UTF-8?q?=20Fixed:=20added=20privkey=20=3D=20NULL=20after=20mid-function?= =?UTF-8?q?=20free=20at=20line=20454=20-=20Copilot:=20ForceZero=20NULL=20g?= =?UTF-8?q?uard=20in=20OCSP=20=E2=80=94=20Fixed:=20added=20if=20(signerKey?= =?UTF-8?q?Der=20!=3D=20NULL=20&&=20signerKeyDerSz=20>=200)=20guard=20-=20?= =?UTF-8?q?Copilot:=20ForceZero=20on=20key=20buffers=20in=20GenChimeraCert?= =?UTF-8?q?Sign=20=E2=80=94=20Fixed:=20added=20ForceZero=20on=20caKeyBuf,?= =?UTF-8?q?=20altCaKeyBuf,=20serverKeyBuf=20before=20XFREE=20-=20Fenrir:?= =?UTF-8?q?=20pkey=20vs=20privkey=20=E2=80=94=20No=20change=20needed:=20pk?= =?UTF-8?q?ey=20is=20a=20borrowed=20ref=20from=20X509=5Fget0=5Fpubkey,=20n?= =?UTF-8?q?ot=20owned=20by=20caller.=20Removing=20the=20free=20was=20corre?= =?UTF-8?q?ct.=20-=20Fenrir:=20Missing=20ForceZero=20on=20heap=20key=20buf?= =?UTF-8?q?fers=20=E2=80=94=20Same=20as=20Copilot=20#3,=20addressed=20abov?= =?UTF-8?q?e=20-=20CI:=20switch-enum=20errors=20=E2=80=94=20Fixed:=20remov?= =?UTF-8?q?ed=20inner=20#ifdef=20guards=20on=20enum=20cases=20that=20alway?= =?UTF-8?q?s=20exist,=20added=20SM3=20under=20#ifdef=20WOLFSSL=5FSM3,=20re?= =?UTF-8?q?moved=20WC=5FHASH=5FTYPE=5FMAX=20(duplicate=20value)=20-=20CI:?= =?UTF-8?q?=20heap-buffer-overflow=20in=20strstr=20=E2=80=94=20Fixed:=20al?= =?UTF-8?q?locate=20inBufSz=20+=201=20and=20null-terminate=20for=20XSTRSTR?= =?UTF-8?q?=20safety=20-=20CI:=20heap-use-after-free=20=E2=80=94=20Fixed?= =?UTF-8?q?=20by=20the=20privkey=20NULL=20fix=20above?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ocsp/clu_ocsp.c | 3 +- src/x509/clu_cert_setup.c | 13 +++-- src/x509/clu_x509_sign.c | 88 ++++++++++++--------------------- tests/x509/x509-process-test.sh | 2 +- 4 files changed, 44 insertions(+), 62 deletions(-) diff --git a/src/ocsp/clu_ocsp.c b/src/ocsp/clu_ocsp.c index c3ff2b57..0e601d24 100644 --- a/src/ocsp/clu_ocsp.c +++ b/src/ocsp/clu_ocsp.c @@ -884,7 +884,8 @@ static int ocspResponder(OcspResponderConfig* config) freeIndexEntries(indexEntries); XFREE(caCertDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(signerCertDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - wolfCLU_ForceZero(signerKeyDer, signerKeyDerSz); + if (signerKeyDer != NULL && signerKeyDerSz > 0) + wolfCLU_ForceZero(signerKeyDer, signerKeyDerSz); XFREE(signerKeyDer, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(caSubject, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); diff --git a/src/x509/clu_cert_setup.c b/src/x509/clu_cert_setup.c index 4240e112..811fc554 100644 --- a/src/x509/clu_cert_setup.c +++ b/src/x509/clu_cert_setup.c @@ -326,12 +326,13 @@ int wolfCLU_certSetup(int argc, char** argv) ret = WOLFCLU_FATAL_ERROR; } else { - inBufRaw = (byte*)XMALLOC(inBufSz, HEAP_HINT, + inBufRaw = (byte*)XMALLOC(inBufSz + 1, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (inBufRaw == NULL) { ret = WOLFCLU_FATAL_ERROR; } else { + inBufRaw[inBufSz] = '\0'; if (wolfSSL_BIO_read(inMem, inBufRaw, inBufSz) != inBufSz) { wolfCLU_LogError("Failed to read input."); ret = WOLFCLU_FATAL_ERROR; @@ -452,6 +453,7 @@ int wolfCLU_certSetup(int argc, char** argv) } } wolfSSL_EVP_PKEY_free(privkey); + privkey = NULL; } /* try to open output file if set */ @@ -749,10 +751,14 @@ int wolfCLU_certSetup(int argc, char** argv) } else { if (wolfSSL_EVP_PKEY_id(pkey) == EVP_PKEY_RSA) { - const WOLFSSL_BIGNUM *num; + const WOLFSSL_BIGNUM *num = NULL; + WOLFSSL_RSA *rsa; char *hex; - wolfSSL_RSA_get0_key(EVP_PKEY_get0_RSA(pkey), &num, NULL, NULL); + rsa = EVP_PKEY_get0_RSA(pkey); + if (rsa != NULL) { + wolfSSL_RSA_get0_key(rsa, &num, NULL, NULL); + } hex = wolfSSL_BN_bn2hex(num); if (hex != NULL) { @@ -775,6 +781,7 @@ int wolfCLU_certSetup(int argc, char** argv) wolfSSL_BIO_write(out, info, (int)XSTRLEN(info)); } + wolfSSL_EVP_PKEY_free(pkey); } } diff --git a/src/x509/clu_x509_sign.c b/src/x509/clu_x509_sign.c index f0b6083d..3c3de345 100644 --- a/src/x509/clu_x509_sign.c +++ b/src/x509/clu_x509_sign.c @@ -925,6 +925,12 @@ int wolfCLU_GenChimeraCertSign(WOLFSSL_BIO *bioCaKey, WOLFSSL_BIO *bioAltCaKey, wolfSSL_BIO_free(out); } + if (caKeyBuf != NULL) + wolfCLU_ForceZero(caKeyBuf, LARGE_TEMP_SZ); + if (altCaKeyBuf != NULL) + wolfCLU_ForceZero(altCaKeyBuf, LARGE_TEMP_SZ); + if (serverKeyBuf != NULL) + wolfCLU_ForceZero(serverKeyBuf, LARGE_TEMP_SZ); XFREE(caKeyBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(altCaKeyBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); XFREE(sapkiBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); @@ -1270,64 +1276,32 @@ int wolfCLU_CertSign(WOLFCLU_CERT_SIGN* csign, WOLFSSL_X509* x509) /* set hash for signature */ if (ret == WOLFCLU_SUCCESS) { - switch (csign->hashType) { - case WC_HASH_TYPE_MD5: - #ifndef NO_MD5 - md = wolfSSL_EVP_md5(); - #else - wolfCLU_LogError("MD5 not compiled in"); - ret = WOLFCLU_FATAL_ERROR; - #endif - break; - - case WC_HASH_TYPE_SHA: - md = wolfSSL_EVP_sha1(); - break; - - case WC_HASH_TYPE_SHA224: - md = wolfSSL_EVP_sha224(); - break; - - case WC_HASH_TYPE_SHA256: - md = wolfSSL_EVP_sha256(); - break; - - case WC_HASH_TYPE_SHA384: - md = wolfSSL_EVP_sha384(); - break; - - case WC_HASH_TYPE_SHA512: - md = wolfSSL_EVP_sha512(); - break; - - case WC_HASH_TYPE_NONE: - case WC_HASH_TYPE_MD2: - case WC_HASH_TYPE_MD4: - case WC_HASH_TYPE_MD5_SHA: - case WC_HASH_TYPE_SHA3_224: - case WC_HASH_TYPE_SHA3_256: - case WC_HASH_TYPE_SHA3_384: - case WC_HASH_TYPE_SHA3_512: - case WC_HASH_TYPE_BLAKE2B: - case WC_HASH_TYPE_BLAKE2S: - - #if LIBWOLFSSL_VERSION_HEX > 0x05001000 - #ifndef WOLFSSL_NOSHA512_224 - case WC_HASH_TYPE_SHA512_224: - #endif - #ifndef WOLFSSL_NOSHA512_256 - case WC_HASH_TYPE_SHA512_256: - #endif - #ifdef WOLFSSL_SHAKE128 - case WC_HASH_TYPE_SHAKE128: - #endif - #ifdef WOLFSSL_SHAKE256 - case WC_HASH_TYPE_SHAKE256: + if (csign->hashType == WC_HASH_TYPE_MD5) { + #ifndef NO_MD5 + md = wolfSSL_EVP_md5(); + #else + wolfCLU_LogError("MD5 not compiled in"); + ret = WOLFCLU_FATAL_ERROR; #endif - #endif - default: - wolfCLU_LogError("Unsupported hash type"); - ret = WOLFCLU_FATAL_ERROR; + } + else if (csign->hashType == WC_HASH_TYPE_SHA) { + md = wolfSSL_EVP_sha1(); + } + else if (csign->hashType == WC_HASH_TYPE_SHA224) { + md = wolfSSL_EVP_sha224(); + } + else if (csign->hashType == WC_HASH_TYPE_SHA256) { + md = wolfSSL_EVP_sha256(); + } + else if (csign->hashType == WC_HASH_TYPE_SHA384) { + md = wolfSSL_EVP_sha384(); + } + else if (csign->hashType == WC_HASH_TYPE_SHA512) { + md = wolfSSL_EVP_sha512(); + } + else { + wolfCLU_LogError("Unsupported hash type"); + ret = WOLFCLU_FATAL_ERROR; } } diff --git a/tests/x509/x509-process-test.sh b/tests/x509/x509-process-test.sh index d9aaa7c1..43b5b07d 100755 --- a/tests/x509/x509-process-test.sh +++ b/tests/x509/x509-process-test.sh @@ -359,7 +359,7 @@ run3 run4 # Test x509 -modulus -noout does not crash -(./wolfssl x509 -in ./certs/server-cert.pem -modulus -noout) 2>/dev/null +./wolfssl x509 -in ./certs/server-cert.pem -modulus -noout if [ $? -ne 0 ]; then echo "x509 -modulus -noout crashed or failed" exit 99 From 5fc6fcd9ac4c2298e42a41adcbb48da31285464b Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Fri, 3 Apr 2026 11:44:43 -0700 Subject: [PATCH 3/4] =?UTF-8?q?Fix=20copilot,=20fenrir,=20internal=20revie?= =?UTF-8?q?w=20=20=20-=20Copilot:=20BN=5Fbn2hex=20NULL=20guard=20=E2=80=94?= =?UTF-8?q?=20Added=20NULL=20check=20on=20num=20before=20calling=20wolfSSL?= =?UTF-8?q?=5FBN=5Fbn2hex=20=20=20-=20Copilot:=20return=200=20on=20missing?= =?UTF-8?q?=20args=20=E2=80=94=20Changed=20return=20ret=20to=20return=20US?= =?UTF-8?q?ER=5FINPUT=5FERROR=20at=20lines=20118=20and=20194=20=20=20-=20C?= =?UTF-8?q?opilot:=20SHA-224=20test=20assertion=20=E2=80=94=20Test=20now?= =?UTF-8?q?=20fails=20if=20sha224=20is=20NOT=20found=20(not=20just=20if=20?= =?UTF-8?q?sha256=20is)=20=20=20-=20Copilot:=20dilithium=5Finit=20return?= =?UTF-8?q?=20value=20=E2=80=94=20Capture=20into=20ret=20for=20proper=20er?= =?UTF-8?q?ror=20logging=20=20=20-=20Security=20review:=20Missing=20ForceZ?= =?UTF-8?q?ero=20on=20keyBuf=20=E2=80=94=20Added=20ForceZero=20before=20XF?= =?UTF-8?q?REE=20on=20all=20keyBuf=20free=20paths=20in=20both=20certgen=20?= =?UTF-8?q?files?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/certgen/clu_certgen_ed25519.c | 2 ++ src/certgen/clu_certgen_rsa.c | 2 ++ src/sign-verify/clu_sign.c | 3 ++- src/sign-verify/clu_sign_verify_setup.c | 4 ++-- src/x509/clu_cert_setup.c | 7 ++++++- tests/x509/x509-req-test.sh | 9 +++------ 6 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/certgen/clu_certgen_ed25519.c b/src/certgen/clu_certgen_ed25519.c index 32caaf8d..d516d633 100644 --- a/src/certgen/clu_certgen_ed25519.c +++ b/src/certgen/clu_certgen_ed25519.c @@ -62,6 +62,7 @@ int make_self_signed_ed25519_certificate(char* keyPath, char* certOut) } if (XFSEEK(keyFile, 0, SEEK_SET) != 0 || (int)XFREAD(keyBuf, 1, keyFileSz, keyFile) != keyFileSz) { XFCLOSE(keyFile); + wolfCLU_ForceZero(keyBuf, keyFileSz); XFREE(keyBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return WOLFCLU_FAILURE; } @@ -85,6 +86,7 @@ int make_self_signed_ed25519_certificate(char* keyPath, char* certOut) ED25519_KEY_SIZE, keyBuf + ED25519_KEY_SIZE, ED25519_KEY_SIZE, &key); + wolfCLU_ForceZero(keyBuf, keyFileSz); XFREE(keyBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (ret != 0 ) { wolfCLU_LogError("Failed to decode private key.\nRET: %d", ret); diff --git a/src/certgen/clu_certgen_rsa.c b/src/certgen/clu_certgen_rsa.c index 70655d8e..e003f738 100644 --- a/src/certgen/clu_certgen_rsa.c +++ b/src/certgen/clu_certgen_rsa.c @@ -63,6 +63,7 @@ int make_self_signed_rsa_certificate(char* keyPath, char* certOut, int oid) } if (XFSEEK(keyFile, 0, SEEK_SET) != 0 || (int)XFREAD(keyBuf, 1, keyFileSz, keyFile) != keyFileSz) { XFCLOSE(keyFile); + wolfCLU_ForceZero(keyBuf, keyFileSz); XFREE(keyBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return WOLFCLU_FAILURE; } @@ -86,6 +87,7 @@ int make_self_signed_rsa_certificate(char* keyPath, char* certOut, int oid) rngInit = 1; ret = wc_RsaPrivateKeyDecode(keyBuf, &index, &key, keyFileSz); + wolfCLU_ForceZero(keyBuf, keyFileSz); XFREE(keyBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (ret != 0 ) { wolfCLU_LogError("Failed to decode private key.\nRET: %d", ret); diff --git a/src/sign-verify/clu_sign.c b/src/sign-verify/clu_sign.c index f31eba4b..559e0b99 100644 --- a/src/sign-verify/clu_sign.c +++ b/src/sign-verify/clu_sign.c @@ -612,7 +612,8 @@ int wolfCLU_sign_data_dilithium (byte* data, char* out, word32 dataSz, char* pri XMEMSET(key, 0, sizeof(dilithium_key)); /* init the dilithium key */ - if (wc_dilithium_init(key) != 0) { + ret = wc_dilithium_init(key); + if (ret != 0) { wolfCLU_LogError("Failed to initialize Dilithium Key.\nRET: %d", ret); #ifdef WOLFSSL_SMALL_STACK XFREE(key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); diff --git a/src/sign-verify/clu_sign_verify_setup.c b/src/sign-verify/clu_sign_verify_setup.c index ce682bf5..419e28bf 100644 --- a/src/sign-verify/clu_sign_verify_setup.c +++ b/src/sign-verify/clu_sign_verify_setup.c @@ -115,7 +115,7 @@ int wolfCLU_sign_verify_setup(int argc, char** argv) "signing or verifying."); wolfCLU_signHelp(algCheck); wolfCLU_verifyHelp(algCheck); - return ret; + return USER_INPUT_ERROR; } ret = wolfCLU_checkForArg("-inform", 7, argc, argv); @@ -191,7 +191,7 @@ int wolfCLU_sign_verify_setup(int argc, char** argv) XFREE(in, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (sig) XFREE(sig, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - return ret; + return USER_INPUT_ERROR; } ret = wolfCLU_checkForArg("-out", 4, argc, argv); diff --git a/src/x509/clu_cert_setup.c b/src/x509/clu_cert_setup.c index 811fc554..44190f21 100644 --- a/src/x509/clu_cert_setup.c +++ b/src/x509/clu_cert_setup.c @@ -759,7 +759,12 @@ int wolfCLU_certSetup(int argc, char** argv) if (rsa != NULL) { wolfSSL_RSA_get0_key(rsa, &num, NULL, NULL); } - hex = wolfSSL_BN_bn2hex(num); + if (num == NULL) { + wolfCLU_LogError("Modulus=unavailable"); + ret = WOLFCLU_FATAL_ERROR; + } + hex = (num != NULL) ? + wolfSSL_BN_bn2hex(num) : NULL; if (hex != NULL) { if (wolfSSL_BIO_write(out, "Modulus=", (int)XSTRLEN("Modulus=")) diff --git a/tests/x509/x509-req-test.sh b/tests/x509/x509-req-test.sh index 606de164..9322c104 100755 --- a/tests/x509/x509-req-test.sh +++ b/tests/x509/x509-req-test.sh @@ -181,15 +181,12 @@ rm -f tmp.cert run_success "x509 -req -in tmp.csr -days 3650 -sha1 -signkey ./certs/server-key.pem -out tmp.cert" rm -f tmp.cert run_success "x509 -req -in tmp.csr -days 3650 -sha224 -signkey ./certs/server-key.pem -out tmp.cert" -# Verify SHA-224 cert uses sha224 signature algorithm, not sha256 +# Verify SHA-224 cert uses sha224 signature algorithm SIGALG=`./wolfssl x509 -in tmp.cert -text -noout 2>&1` echo "$SIGALG" | grep -i "sha224" if [ $? -ne 0 ]; then - echo "$SIGALG" | grep -i "sha256" - if [ $? -eq 0 ]; then - echo "SHA-224 cert incorrectly uses SHA-256 signature algorithm" - exit 99 - fi + echo "SHA-224 cert does not report SHA-224 signature algorithm" + exit 99 fi rm -f tmp.cert run_success "x509 -req -in tmp.csr -days 3650 -sha256 -signkey ./certs/server-key.pem -out tmp.cert" From 4ea35116c21b250086230e73b621ece2f9772a1c Mon Sep 17 00:00:00 2001 From: Aidan Garske Date: Fri, 3 Apr 2026 15:24:13 -0700 Subject: [PATCH 4/4] Test and fix skoll finding --- src/certgen/clu_certgen_ed25519.c | 65 ++++++++++++++++++++++--------- src/certgen/clu_certgen_rsa.c | 2 + src/sign-verify/clu_sign.c | 2 +- 3 files changed, 50 insertions(+), 19 deletions(-) diff --git a/src/certgen/clu_certgen_ed25519.c b/src/certgen/clu_certgen_ed25519.c index d516d633..cf3e441d 100644 --- a/src/certgen/clu_certgen_ed25519.c +++ b/src/certgen/clu_certgen_ed25519.c @@ -68,19 +68,26 @@ int make_self_signed_ed25519_certificate(char* keyPath, char* certOut) } XFCLOSE(keyFile); + int keyInit = 0, rngInit = 0; + ret = wc_ed25519_init(&key); if (ret != 0) { wolfCLU_LogError("Failed to initialize ed25519 key\nRET: %d", ret); + wolfCLU_ForceZero(keyBuf, keyFileSz); XFREE(keyBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return ret; } + keyInit = 1; ret = wc_InitRng(&rng); if (ret != 0) { wolfCLU_LogError("Failed to initialize rng.\nRET: %d", ret); + wolfCLU_ForceZero(keyBuf, keyFileSz); XFREE(keyBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + wc_ed25519_free(&key); return ret; } + rngInit = 1; ret = wc_ed25519_import_private_key(keyBuf, ED25519_KEY_SIZE, @@ -90,7 +97,7 @@ int make_self_signed_ed25519_certificate(char* keyPath, char* certOut) XFREE(keyBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (ret != 0 ) { wolfCLU_LogError("Failed to decode private key.\nRET: %d", ret); - return ret; + goto cleanup; } wc_InitCert(&newCert); @@ -105,36 +112,44 @@ int make_self_signed_ed25519_certificate(char* keyPath, char* certOut) WOLFCLU_LOG(WOLFCLU_L0, "Enter your countries 2 digit code (ex: United States -> US): "); if (XFGETS(country,CTC_NAME_SIZE, stdin) == NULL) { - return WOLFCLU_FAILURE; + ret = WOLFCLU_FAILURE; + goto cleanup; } country[CTC_NAME_SIZE-1] = '\0'; WOLFCLU_LOG(WOLFCLU_L0, "Enter the name of the province you are located at: "); if (XFGETS(province,CTC_NAME_SIZE, stdin) == NULL) { - return WOLFCLU_FAILURE; + ret = WOLFCLU_FAILURE; + goto cleanup; } WOLFCLU_LOG(WOLFCLU_L0, "Enter the name of the city you are located at: "); if (XFGETS(city,CTC_NAME_SIZE, stdin) == NULL) { - return WOLFCLU_FAILURE; + ret = WOLFCLU_FAILURE; + goto cleanup; } WOLFCLU_LOG(WOLFCLU_L0, "Enter the name of your orginization: "); if (XFGETS(org,CTC_NAME_SIZE, stdin) == NULL) { - return WOLFCLU_FAILURE; + ret = WOLFCLU_FAILURE; + goto cleanup; } WOLFCLU_LOG(WOLFCLU_L0, "Enter the name of your unit: "); if (XFGETS(unit,CTC_NAME_SIZE, stdin) == NULL) { - return WOLFCLU_FAILURE; + ret = WOLFCLU_FAILURE; + goto cleanup; } WOLFCLU_LOG(WOLFCLU_L0, "Enter the common name of your domain: "); if (XFGETS(commonName,CTC_NAME_SIZE, stdin) == NULL) { - return WOLFCLU_FAILURE; + ret = WOLFCLU_FAILURE; + goto cleanup; } WOLFCLU_LOG(WOLFCLU_L0, "Enter your email address: "); if (XFGETS(email,CTC_NAME_SIZE, stdin) == NULL) { - return WOLFCLU_FAILURE; + ret = WOLFCLU_FAILURE; + goto cleanup; } WOLFCLU_LOG(WOLFCLU_L0, "Enter the number of days this certificate should be valid: "); if (XFGETS(daysValid,CTC_NAME_SIZE, stdin) == NULL) { - return WOLFCLU_FAILURE; + ret = WOLFCLU_FAILURE; + goto cleanup; } XSTRNCPY(newCert.subject.country, country, CTC_NAME_SIZE); @@ -151,14 +166,15 @@ int make_self_signed_ed25519_certificate(char* keyPath, char* certOut) certBuf = (byte*)XMALLOC(FOURK_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (certBuf == NULL) { wolfCLU_LogError("Failed to initialize buffer to stort certificate."); - return -1; + ret = MEMORY_E; + goto cleanup; } XMEMSET(certBuf, 0, FOURK_SZ); ret = wc_MakeCert_ex(&newCert, certBuf, FOURK_SZ, ED25519_TYPE, &key, &rng); if (ret < 0) { wolfCLU_LogError("Failed to make certificate."); - return ret; + goto cleanup; } WOLFCLU_LOG(WOLFCLU_L0, "MakeCert returned %d", ret); @@ -166,7 +182,7 @@ int make_self_signed_ed25519_certificate(char* keyPath, char* certOut) ED25519_TYPE, &key, &rng); if (ret < 0) { wolfCLU_LogError("Failed to sign certificate."); - return ret; + goto cleanup; } WOLFCLU_LOG(WOLFCLU_L0, "SignCert returned %d", ret); @@ -178,7 +194,8 @@ int make_self_signed_ed25519_certificate(char* keyPath, char* certOut) file = XFOPEN(certOut, "wb"); if (!file) { wolfCLU_LogError("failed to open file: %s", certOut); - return -1; + ret = WOLFCLU_FATAL_ERROR; + goto cleanup; } ret = (int)XFWRITE(certBuf, 1, certBufSz, file); @@ -194,14 +211,16 @@ int make_self_signed_ed25519_certificate(char* keyPath, char* certOut) pemBuf = (byte*)XMALLOC(FOURK_SZ, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (pemBuf == NULL) { wolfCLU_LogError("Failed to initialize pem buffer."); - return -1; + ret = MEMORY_E; + goto cleanup; } XMEMSET(pemBuf, 0, FOURK_SZ); pemBufSz = wc_DerToPem(certBuf, certBufSz, pemBuf, FOURK_SZ, CERT_TYPE); if (pemBufSz < 0) { wolfCLU_LogError("Failed to convert from der to pem."); - return -1; + ret = pemBufSz; + goto cleanup; } WOLFCLU_LOG(WOLFCLU_L0, "Resulting pem buffer is %d bytes", pemBufSz); @@ -209,15 +228,25 @@ int make_self_signed_ed25519_certificate(char* keyPath, char* certOut) pemFile = XFOPEN(certOut, "wb"); if (!pemFile) { wolfCLU_LogError("failed to open file: %s", certOut); - return -1; + ret = WOLFCLU_FATAL_ERROR; + goto cleanup; } XFWRITE(pemBuf, 1, pemBufSz, pemFile); XFCLOSE(pemFile); WOLFCLU_LOG(WOLFCLU_L0, "Successfully converted the der to pem. Result is in: %s\n", certOut); + ret = WOLFCLU_SUCCESS; - free_things_ed25519(&pemBuf, &certBuf, NULL, &key, NULL, &rng); - return 1; +cleanup: + if (pemBuf != NULL) + XFREE(pemBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (certBuf != NULL) + XFREE(certBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (keyInit) + wc_ed25519_free(&key); + if (rngInit) + wc_FreeRng(&rng); + return ret; } void free_things_ed25519(byte** a, byte** b, byte** c, ed25519_key* d, ed25519_key* e, diff --git a/src/certgen/clu_certgen_rsa.c b/src/certgen/clu_certgen_rsa.c index e003f738..7933c12c 100644 --- a/src/certgen/clu_certgen_rsa.c +++ b/src/certgen/clu_certgen_rsa.c @@ -72,6 +72,7 @@ int make_self_signed_rsa_certificate(char* keyPath, char* certOut, int oid) ret = wc_InitRsaKey(&key, NULL); if (ret != 0) { wolfCLU_LogError("Failed to initialize RsaKey\nRET: %d", ret); + wolfCLU_ForceZero(keyBuf, keyFileSz); XFREE(keyBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); return ret; } @@ -80,6 +81,7 @@ int make_self_signed_rsa_certificate(char* keyPath, char* certOut, int oid) ret = wc_InitRng(&rng); if (ret != 0) { wolfCLU_LogError("Failed to initialize rng.\nRET: %d", ret); + wolfCLU_ForceZero(keyBuf, keyFileSz); XFREE(keyBuf, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); wc_FreeRsaKey(&key); return ret; diff --git a/src/sign-verify/clu_sign.c b/src/sign-verify/clu_sign.c index 559e0b99..3c4e170b 100644 --- a/src/sign-verify/clu_sign.c +++ b/src/sign-verify/clu_sign.c @@ -666,7 +666,7 @@ int wolfCLU_sign_data_dilithium (byte* data, char* out, word32 dataSz, char* pri #ifdef WOLFSSL_SMALL_STACK XFREE(key, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); #endif - return ret; + return WOLFCLU_FATAL_ERROR; } XFCLOSE(privKeyFile);