Skip to content

Commit 6000e55

Browse files
added unit tests to ocsp that checks interop between responder and client for wolfssl and openssl
added more tests to cover help and sign/verify and fixing found memory leak fixed other memeory leak
1 parent e3d8ab6 commit 6000e55

17 files changed

Lines changed: 384 additions & 19 deletions

src/sign-verify/clu_verify.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -998,7 +998,7 @@ int wolfCLU_verify_signature_xmss(byte* sig, int sigSz,
998998
}
999999

10001000
if (ret == 0) {
1001-
for (int i = 0; i < XMSS_OID_LEN; i++) {
1001+
for (unsigned int i = 0; i < XMSS_OID_LEN; i++) {
10021002
oid = (oid << 8) | keyBuf[i];
10031003
}
10041004

@@ -1153,7 +1153,7 @@ int wolfCLU_verify_signature_xmssmt(byte* sig, int sigSz,
11531153
}
11541154

11551155
if (ret == 0) {
1156-
for (int i = 0; i < XMSS_OID_LEN; i++) {
1156+
for (unsigned int i = 0; i < XMSS_OID_LEN; i++) {
11571157
oid = (oid << 8) | keyBuf[i];
11581158
}
11591159

src/x509/clu_ca_setup.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include <wolfclu/x509/clu_cert.h>
2727
#include <wolfclu/x509/clu_x509_sign.h>
2828
#include <wolfclu/certgen/clu_certgen.h>
29+
#include <wolfssl/openssl/evp.h>
30+
#include <wolfssl/ssl.h>
2931

3032
#ifndef WOLFCLU_NO_FILESYSTEM
3133

@@ -169,7 +171,7 @@ int wolfCLU_CASetup(int argc, char** argv)
169171
ca = wolfSSL_X509_load_certificate_file(optarg,
170172
WOLFSSL_FILETYPE_ASN1);
171173
}
172-
174+
173175
if (ca == NULL) {
174176
wolfCLU_LogError("Unable to open CA file %s", optarg);
175177
ret = WOLFCLU_FATAL_ERROR;
@@ -246,7 +248,7 @@ int wolfCLU_CASetup(int argc, char** argv)
246248
wolfCLU_CertSignSetHash(signer, hashType);
247249
}
248250

249-
if (ret == WOLFCLU_SUCCESS && keyIn != NULL) {
251+
if (ret == WOLFCLU_SUCCESS && keyIn != NULL && altSign == 0) {
250252
pkey = wolfSSL_PEM_read_bio_PrivateKey(keyIn, NULL, NULL, NULL);
251253
if (pkey == NULL) {
252254
wolfCLU_LogError("Error reading key from file");
@@ -285,9 +287,11 @@ int wolfCLU_CASetup(int argc, char** argv)
285287
wolfCLU_GetTypeFromPKEY(pkey));
286288
}
287289
else if (altSign) {
288-
ret = wolfCLU_GenChimeraCertSign(keyIn, altKey, altKeyPub, subjKey, ca,
289-
wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_subject_name(x509), 0, 0),
290-
out, outForm);
290+
char* subjName = wolfSSL_X509_NAME_oneline(
291+
wolfSSL_X509_get_subject_name(x509), 0, 0);
292+
ret = wolfCLU_GenChimeraCertSign(keyIn, altKey, altKeyPub, subjKey,
293+
ca, subjName, out, outForm);
294+
XFREE(subjName, 0, DYNAMIC_TYPE_OPENSSL);
291295
}
292296
else {
293297
wolfCLU_CertSignSetCA(signer, ca, pkey,
@@ -319,9 +323,15 @@ int wolfCLU_CASetup(int argc, char** argv)
319323
if (altKeyPub != NULL) {
320324
wolfSSL_BIO_free(altKeyPub);
321325
}
326+
if (subjKey != NULL) {
327+
wolfSSL_BIO_free(subjKey);
328+
}
322329
if (!selfSigned) {
323330
wolfSSL_X509_free(x509);
324331
}
332+
if ((selfSigned || altSign) && ca != NULL) {
333+
wolfSSL_X509_free(ca);
334+
}
325335

326336
/* check for success on signer free since random data is output */
327337
if (wolfCLU_CertSignFree(signer) != WOLFCLU_SUCCESS) {

src/x509/clu_request_setup.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -981,19 +981,18 @@ int wolfCLU_requestSetup(int argc, char** argv)
981981
}
982982

983983
if (ret == WOLFCLU_SUCCESS && doVerify) {
984-
WOLFSSL_EVP_PKEY* pubKey = pkey;
985984

986985
/* get public key from req if not passed in */
987-
if (pubKey == NULL) {
988-
pubKey = wolfSSL_X509_get_pubkey(x509);
986+
if (pkey == NULL) {
987+
pkey = wolfSSL_X509_get_pubkey(x509);
989988
}
990989

991-
if (pubKey == NULL) {
990+
if (pkey == NULL) {
992991
wolfCLU_LogError("Error getting the public key to verify");
993992
ret = WOLFCLU_FATAL_ERROR;
994993
}
995994
else {
996-
if (wolfSSL_X509_REQ_verify(x509, pubKey) == 1) {
995+
if (wolfSSL_X509_REQ_verify(x509, pkey) == 1) {
997996
WOLFCLU_LOG(WOLFCLU_L0, "verify OK");
998997
}
999998
else {

tests/base64/base64-test.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,17 @@ def test_stdin_input(self):
103103
self.assertEqual(result.returncode, 0,
104104
"Couldn't parse input from stdin")
105105

106+
def test_help(self):
107+
""" Test help flag """
108+
result = subprocess.run(
109+
[WOLFSSL_BIN, "base64", "-h"],
110+
capture_output=True,
111+
timeout=60,
112+
)
113+
self.assertEqual(result.returncode, 0, result.stderr + result.stdout)
114+
self.assertGreater(len(result.stderr), 0, "out put was not completed")
115+
116+
106117

107118
if __name__ == "__main__":
108119
test_main()

tests/client/client-test.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ def test_s_client_x509(self):
6060
self.assertIn("-----BEGIN CERTIFICATE-----", result.stdout,
6161
"Expected x509 PEM output not found")
6262

63+
def test_client_help(self):
64+
""" run help command for client """
65+
r = run_wolfssl("s_client", "-help")
66+
self.assertEqual(r.returncode, 0, r.stderr)
67+
self.assertIn("s_client" , r.stderr, "help menu was not printed")
68+
6369
class ShellInjectionTest(unittest.TestCase):
6470
"""Regression tests for shell command injection via hostname.
6571

tests/dgst/dgst-test.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,38 @@ def test_fail_wrong_digest(self):
7777
os.path.join(CERTS_DIR, "server-key.der"))
7878
self.assertNotEqual(r.returncode, 0)
7979

80+
def test_help(self):
81+
for flag in ("-help", "-h"):
82+
r = run_wolfssl("dgst", flag)
83+
self.assertEqual(r.returncode, 0, r.stderr)
84+
self.assertIn("dgst", r.stdout + r.stderr)
85+
86+
def test_sign_verify_all_hash_algs(self):
87+
"""Sign/verify round-trip for each supported hash algorithm.
88+
89+
Covers the per-algorithm digest-selection branches in
90+
clu_dgst_setup.c. -md5 is skipped under FIPS.
91+
"""
92+
algs = ["sha", "sha224", "sha256", "sha384", "sha512"]
93+
if not is_fips():
94+
algs.append("md5")
95+
input_file = os.path.join(CERTS_DIR, "server-key.der")
96+
97+
for alg in algs:
98+
with self.subTest(alg=alg):
99+
sig_file = "dgst-{}.sig".format(alg)
100+
self.addCleanup(lambda p=sig_file: os.remove(p)
101+
if os.path.exists(p) else None)
102+
r = run_wolfssl("dgst", "-" + alg, "-sign",
103+
os.path.join(CERTS_DIR, "server-key.pem"),
104+
"-out", sig_file, input_file)
105+
self.assertEqual(r.returncode, 0, r.stderr)
106+
107+
r = run_wolfssl("dgst", "-" + alg, "-verify",
108+
os.path.join(CERTS_DIR, "server-keyPub.pem"),
109+
"-signature", sig_file, input_file)
110+
self.assertEqual(r.returncode, 0, r.stderr)
111+
80112
def test_dgst_out_roundtrip(self):
81113
"""dgst -out creates the signature file; -signature round-trips."""
82114
sig_file = "dgst-out-test.sig"

tests/genkey_sign_ver/genkey-sign-ver-test.py

Lines changed: 92 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import unittest
77

88
sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))
9-
from wolfclu_test import WOLFSSL_BIN, run_wolfssl, test_main
9+
from wolfclu_test import WOLFSSL_BIN, CERTS_DIR, run_wolfssl, test_main
1010

1111
# Files that tests may create; cleaned up by tearDownClass
1212
_TEMP_FILES = []
@@ -385,12 +385,100 @@ def test_xmss_missing_height_value(self):
385385
self._track("xmss-bad.priv", "xmss-bad.pub")
386386
r = run_wolfssl("-genkey", "xmss", "-out", "xmss-bad",
387387
"-outform", "raw", "-output", "KEYPAIR", "-height")
388-
self.assertNotEqual(r.returncode, 0,
389-
"expected failure for missing -height value")
388+
self.assertEqual(r.returncode, 0,
389+
"expected defalut value of 20 set for -hieght no "
390+
"crash")
391+
392+
def test_xmss_missing_height_arg(self):
393+
self._track("xmss-bad.priv", "xmss-bad.pub")
394+
r = run_wolfssl("-genkey", "xmss", "-out", "xmss-bad",
395+
"-outform", "raw", "-output", "KEYPAIR")
396+
self.assertEqual(r.returncode, 0,
397+
"expected defalut value for -hieght no "
398+
"crash")
399+
400+
@unittest.skipUnless(_has_algorithm("xmss"), "xmss not available")
401+
class XmssmtTest(_GenkeySignVerifyBase):
402+
403+
def test_xmssmt_raw(self):
404+
# The XMSS^MT signer derives the parameter set from the key file name,
405+
# so the keybase must be a valid param string with '-' in place of '/'
406+
# (e.g. "XMSSMT-SHA2_20/2_256" -> "XMSSMT-SHA2_20-2_256"). -height 20
407+
# defaults to layer 2, matching this name.
408+
keybase = "XMSSMT-SHA2_20-2_256"
409+
self._track(keybase + ".priv", keybase + ".pub")
410+
self._gen_sign_verify(
411+
"xmssmt", keybase, "xmss-signed.sig", "raw",
412+
extra_genkey_args=["-height", "20"],
413+
skip_priv_verify=True, use_output_flag=True)
414+
415+
def test_xmss_missing_height_value(self):
416+
"""-height with no value must fail gracefully (no crash)."""
417+
self._track("xmss-bad.priv", "xmss-bad.pub")
418+
r = run_wolfssl("-genkey", "xmssmt", "-out", "xmss-bad",
419+
"-outform", "raw", "-output", "KEYPAIR", "-height")
420+
self.assertEqual(r.returncode, 0,
421+
"expected defalut value of 20 set for -hieght no "
422+
"crash")
423+
424+
def test_xmss_missing_height_arg(self):
425+
self._track("xmss-bad.priv", "xmss-bad.pub")
426+
r = run_wolfssl("-genkey", "xmssmt", "-out", "xmss-bad",
427+
"-outform", "raw", "-output", "KEYPAIR")
428+
self.assertEqual(r.returncode, 0,
429+
"expected defalut value for -hieght no "
430+
"crash")
431+
432+
433+
class SignVerifySetupArgsTest(unittest.TestCase):
434+
"""Argument-parsing branches in clu_sign_verify_setup.c.
435+
436+
These exercise the legacy `-rsa`/`-ecc`/... sign & verify entry point
437+
(note the leading dash, which selects the legacy code path).
438+
"""
439+
440+
SIGN_FILE = "svsetup-sign-this.txt"
441+
RSA_KEY = os.path.join(CERTS_DIR, "server-key.pem")
442+
ECC_KEY = os.path.join(CERTS_DIR, "ecc-key.pem")
443+
ECC_PUB = os.path.join(CERTS_DIR, "ecc-keyPub.pem")
444+
445+
@classmethod
446+
def setUpClass(cls):
447+
config_log = os.path.join(".", "config.log")
448+
if os.path.isfile(config_log):
449+
with open(config_log, "r") as f:
450+
if "disable-filesystem" in f.read():
451+
raise unittest.SkipTest("filesystem support disabled")
452+
with open(cls.SIGN_FILE, "w") as f:
453+
f.write("Sign this test data\n")
454+
455+
@classmethod
456+
def tearDownClass(cls):
457+
_cleanup_files([cls.SIGN_FILE])
458+
459+
def test_sign_help(self):
460+
r = run_wolfssl("-rsa", "-sign", "-help")
390461
self.assertGreaterEqual(r.returncode, 0,
391-
"-height without value crashed with signal "
462+
"sign help crashed with signal "
392463
"{}".format(r.returncode))
464+
self.assertIn("RSA Sign", r.stdout + r.stderr)
393465

466+
def test_verify_help(self):
467+
r = run_wolfssl("-rsa", "-verify", "-help")
468+
self.assertGreaterEqual(r.returncode, 0,
469+
"verify help crashed with signal "
470+
"{}".format(r.returncode))
471+
self.assertIn("RSA Verify", r.stdout + r.stderr)
472+
473+
def test_generic_help(self):
474+
"""No -sign/-verify prints both the sign and verify help blocks."""
475+
r = run_wolfssl("-ecc", "-help")
476+
self.assertGreaterEqual(r.returncode, 0,
477+
"generic help crashed with signal "
478+
"{}".format(r.returncode))
479+
combined = r.stdout + r.stderr
480+
self.assertIn("ECC Sign", combined)
481+
self.assertIn("ECC Verify", combined)
394482

395483
class GenkeyArgvTest(unittest.TestCase):
396484
"""Argument-bounds checks for the genkey subcommand entry point."""

tests/ocsp/ocsp-test.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -320,25 +320,67 @@ def test_12_graceful_shutdown(self):
320320
class TestWolfsslClientWolfsslResponder(_OCSPInteropBase):
321321
CLIENT_BIN = WOLFSSL_BIN
322322
RESPONDER_BIN = WOLFSSL_BIN
323+
PORT = 3000
324+
325+
326+
def test_01_client_start_up(self):
327+
""" successful round trip from client to server """
328+
resp = self._start_responder(INDEX_VALID, nrequest=1)
329+
rc, out = _run_client(self.CLIENT_BIN, self.PORT,
330+
["-cert", os.path.join(CERTS_DIR, "server-cert.pem")])
331+
332+
resp.stop()
333+
self.assertEqual(rc, 0, out)
334+
self.assertIn("good", out.lower(), out)
323335

324336

325337
@unittest.skipUnless(HAS_OPENSSL, "openssl not available")
326338
class TestWolfsslClientOpensslResponder(_OCSPInteropBase):
327339
CLIENT_BIN = WOLFSSL_BIN
328340
RESPONDER_BIN = "openssl"
341+
PORT = 3000
342+
343+
def test_01_client_start_up(self):
344+
resp = self._start_responder(INDEX_VALID, nrequest=1)
345+
rc, out = _run_client(self.CLIENT_BIN, self.PORT,
346+
["-cert", os.path.join(CERTS_DIR, "server-cert.pem")])
347+
348+
resp.stop()
349+
self.assertEqual(rc, 0, out)
350+
self.assertIn("good", out.lower(), out)
329351

330352

331353
@unittest.skipUnless(HAS_OPENSSL, "openssl not available")
332354
class TestOpensslClientWolfsslResponder(_OCSPInteropBase):
333355
CLIENT_BIN = "openssl"
334356
RESPONDER_BIN = WOLFSSL_BIN
335357

358+
PORT = 3000
359+
360+
def test_01_client_start_up(self):
361+
resp = self._start_responder(INDEX_VALID, nrequest=1)
362+
rc, out = _run_client(self.CLIENT_BIN, self.PORT,
363+
["-cert", os.path.join(CERTS_DIR, "server-cert.pem")])
364+
365+
resp.stop()
366+
self.assertEqual(rc, 0, out)
367+
self.assertIn("good", out.lower(), out)
336368

337369
@unittest.skipUnless(HAS_OPENSSL, "openssl not available")
338370
class TestOpensslClientOpensslResponder(_OCSPInteropBase):
339371
CLIENT_BIN = "openssl"
340372
RESPONDER_BIN = "openssl"
341373

374+
PORT = 3000
375+
376+
def test_01_client_start_up(self):
377+
resp = self._start_responder(INDEX_VALID, nrequest=1)
378+
rc, out = _run_client(self.CLIENT_BIN, self.PORT,
379+
["-cert", os.path.join(CERTS_DIR, "server-cert.pem")])
380+
381+
resp.stop()
382+
self.assertEqual(rc, 0, out)
383+
self.assertIn("good", out.lower(), out)
342384

343385
def load_tests(loader, tests, pattern):
344386
"""Exclude the abstract _OCSPInteropBase from test discovery."""

tests/pkcs/pkcs12-test.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,32 @@ def test_pass_on_cmdline(self):
5959
"-passout", "pass:", "-in", P12_FILE)
6060
self.assertEqual(r.returncode, 0, r.stderr)
6161

62+
def test_help(self):
63+
for flag in ("-help", "-h"):
64+
r = run_wolfssl("pkcs12", flag)
65+
self.assertEqual(r.returncode, 0, r.stderr)
66+
self.assertIn("wolfssl pkcs12", r.stdout + r.stderr)
67+
68+
def test_bad_argument_fails(self):
69+
r = run_wolfssl("pkcs12", "-not-a-real-option", "-in", P12_FILE)
70+
self.assertNotEqual(r.returncode, 0)
71+
72+
def test_out_to_file(self):
73+
out = "pkcs12-out.pem"
74+
self.addCleanup(lambda: os.remove(out) if os.path.exists(out) else None)
75+
r = run_wolfssl("pkcs12", "-nodes", "-passin", 'pass:wolfSSL test',
76+
"-passout", "pass:", "-in", P12_FILE, "-out", out)
77+
self.assertEqual(r.returncode, 0, r.stderr)
78+
self.assertTrue(os.path.isfile(out), "pkcs12 -out did not create file")
79+
with open(out, "r") as f:
80+
self.assertIn("BEGIN ", f.read())
81+
82+
def test_out_bad_path_fails(self):
83+
r = run_wolfssl("pkcs12", "-nodes", "-passin", 'pass:wolfSSL test',
84+
"-passout", "pass:", "-in", P12_FILE,
85+
"-out", os.path.join("no-such-dir", "out.pem"))
86+
self.assertNotEqual(r.returncode, 0)
87+
6288
def test_nocerts_with_passout(self):
6389
r = subprocess.run(
6490
[WOLFSSL_BIN, "pkcs12", "-passin", "stdin", "-passout", "pass:",

0 commit comments

Comments
 (0)