Skip to content
Merged
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: 2 additions & 2 deletions src/sign-verify/clu_verify.c
Original file line number Diff line number Diff line change
Expand Up @@ -998,7 +998,7 @@ int wolfCLU_verify_signature_xmss(byte* sig, int sigSz,
}

if (ret == 0) {
for (int i = 0; i < XMSS_OID_LEN; i++) {
for (unsigned int i = 0; i < XMSS_OID_LEN; i++) {
oid = (oid << 8) | keyBuf[i];
}

Expand Down Expand Up @@ -1153,7 +1153,7 @@ int wolfCLU_verify_signature_xmssmt(byte* sig, int sigSz,
}

if (ret == 0) {
for (int i = 0; i < XMSS_OID_LEN; i++) {
for (unsigned int i = 0; i < XMSS_OID_LEN; i++) {
oid = (oid << 8) | keyBuf[i];
}

Expand Down
26 changes: 21 additions & 5 deletions src/x509/clu_ca_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
#include <wolfclu/x509/clu_cert.h>
#include <wolfclu/x509/clu_x509_sign.h>
#include <wolfclu/certgen/clu_certgen.h>
#include <wolfssl/openssl/evp.h>
#include <wolfssl/ssl.h>
#include <wolfssl/wolfcrypt/error-crypt.h>

#ifndef WOLFCLU_NO_FILESYSTEM

Expand Down Expand Up @@ -169,7 +172,7 @@ int wolfCLU_CASetup(int argc, char** argv)
ca = wolfSSL_X509_load_certificate_file(optarg,
WOLFSSL_FILETYPE_ASN1);
}

if (ca == NULL) {
wolfCLU_LogError("Unable to open CA file %s", optarg);
ret = WOLFCLU_FATAL_ERROR;
Expand Down Expand Up @@ -246,7 +249,7 @@ int wolfCLU_CASetup(int argc, char** argv)
wolfCLU_CertSignSetHash(signer, hashType);
}

if (ret == WOLFCLU_SUCCESS && keyIn != NULL) {
if (ret == WOLFCLU_SUCCESS && keyIn != NULL && altSign == 0) {
pkey = wolfSSL_PEM_read_bio_PrivateKey(keyIn, NULL, NULL, NULL);
if (pkey == NULL) {
wolfCLU_LogError("Error reading key from file");
Expand Down Expand Up @@ -285,9 +288,16 @@ int wolfCLU_CASetup(int argc, char** argv)
wolfCLU_GetTypeFromPKEY(pkey));
}
else if (altSign) {
ret = wolfCLU_GenChimeraCertSign(keyIn, altKey, altKeyPub, subjKey, ca,
wolfSSL_X509_NAME_oneline(wolfSSL_X509_get_subject_name(x509), 0, 0),
out, outForm);
char* subjName = wolfSSL_X509_NAME_oneline(
wolfSSL_X509_get_subject_name(x509), 0, 0);
if (subjName != NULL) {
ret = wolfCLU_GenChimeraCertSign(keyIn, altKey, altKeyPub, subjKey,
ca, subjName, out, outForm);
XFREE(subjName, 0, DYNAMIC_TYPE_OPENSSL);
}
else {
ret = MEMORY_E;
}
}
else {
wolfCLU_CertSignSetCA(signer, ca, pkey,
Expand Down Expand Up @@ -319,9 +329,15 @@ int wolfCLU_CASetup(int argc, char** argv)
if (altKeyPub != NULL) {
wolfSSL_BIO_free(altKeyPub);
}
if (subjKey != NULL) {
wolfSSL_BIO_free(subjKey);
}
if (!selfSigned) {
wolfSSL_X509_free(x509);
}
if ((selfSigned || altSign) && ca != NULL) {
wolfSSL_X509_free(ca);
}

/* check for success on signer free since random data is output */
if (wolfCLU_CertSignFree(signer) != WOLFCLU_SUCCESS) {
Expand Down
9 changes: 4 additions & 5 deletions src/x509/clu_request_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -981,19 +981,18 @@ int wolfCLU_requestSetup(int argc, char** argv)
}

if (ret == WOLFCLU_SUCCESS && doVerify) {
WOLFSSL_EVP_PKEY* pubKey = pkey;

/* get public key from req if not passed in */
if (pubKey == NULL) {
pubKey = wolfSSL_X509_get_pubkey(x509);
if (pkey == NULL) {
pkey = wolfSSL_X509_get_pubkey(x509);
}

if (pubKey == NULL) {
if (pkey == NULL) {
wolfCLU_LogError("Error getting the public key to verify");
ret = WOLFCLU_FATAL_ERROR;
}
else {
if (wolfSSL_X509_REQ_verify(x509, pubKey) == 1) {
if (wolfSSL_X509_REQ_verify(x509, pkey) == 1) {
WOLFCLU_LOG(WOLFCLU_L0, "verify OK");
}
else {
Expand Down
11 changes: 11 additions & 0 deletions tests/base64/base64-test.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,17 @@ def test_stdin_input(self):
self.assertEqual(result.returncode, 0,
"Couldn't parse input from stdin")

def test_help(self):
""" Test help flag """
result = subprocess.run(
[WOLFSSL_BIN, "base64", "-h"],
capture_output=True,
timeout=60,
)
self.assertEqual(result.returncode, 0, result.stderr + result.stdout)
self.assertGreater(len(result.stderr), 0, "output was not completed")



if __name__ == "__main__":
test_main()
6 changes: 6 additions & 0 deletions tests/client/client-test.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ def test_s_client_x509(self):
self.assertIn("-----BEGIN CERTIFICATE-----", result.stdout,
"Expected x509 PEM output not found")

def test_client_help(self):
""" run help command for client """
r = run_wolfssl("s_client", "-help")
self.assertEqual(r.returncode, 0, r.stderr)
self.assertIn("s_client" , r.stderr, "help menu was not printed")

class ShellInjectionTest(unittest.TestCase):
"""Regression tests for shell command injection via hostname.

Expand Down
32 changes: 32 additions & 0 deletions tests/dgst/dgst-test.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,38 @@ def test_fail_wrong_digest(self):
os.path.join(CERTS_DIR, "server-key.der"))
self.assertNotEqual(r.returncode, 0)

def test_help(self):
for flag in ("-help", "-h"):
r = run_wolfssl("dgst", flag)
self.assertEqual(r.returncode, 0, r.stderr)
self.assertIn("dgst", r.stdout + r.stderr)

def test_sign_verify_all_hash_algs(self):
"""Sign/verify round-trip for each supported hash algorithm.

Covers the per-algorithm digest-selection branches in
clu_dgst_setup.c. -md5 is skipped under FIPS.
"""
algs = ["sha", "sha224", "sha256", "sha384", "sha512"]
if not is_fips():
algs.append("md5")
input_file = os.path.join(CERTS_DIR, "server-key.der")

for alg in algs:
with self.subTest(alg=alg):
sig_file = "dgst-{}.sig".format(alg)
self.addCleanup(lambda p=sig_file: os.remove(p)
if os.path.exists(p) else None)
r = run_wolfssl("dgst", "-" + alg, "-sign",
os.path.join(CERTS_DIR, "server-key.pem"),
"-out", sig_file, input_file)
self.assertEqual(r.returncode, 0, r.stderr)

r = run_wolfssl("dgst", "-" + alg, "-verify",
os.path.join(CERTS_DIR, "server-keyPub.pem"),
"-signature", sig_file, input_file)
self.assertEqual(r.returncode, 0, r.stderr)

def test_dgst_out_roundtrip(self):
"""dgst -out creates the signature file; -signature round-trips."""
sig_file = "dgst-out-test.sig"
Expand Down
96 changes: 92 additions & 4 deletions tests/genkey_sign_ver/genkey-sign-ver-test.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import unittest

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

# Files that tests may create; cleaned up by tearDownClass
_TEMP_FILES = []
Expand Down Expand Up @@ -385,12 +385,100 @@ def test_xmss_missing_height_value(self):
self._track("xmss-bad.priv", "xmss-bad.pub")
r = run_wolfssl("-genkey", "xmss", "-out", "xmss-bad",
"-outform", "raw", "-output", "KEYPAIR", "-height")
self.assertNotEqual(r.returncode, 0,
"expected failure for missing -height value")
self.assertEqual(r.returncode, 0,
"expected default value of 20 set for -height (no "
"crash)")

def test_xmss_missing_height_arg(self):
self._track("xmss-bad.priv", "xmss-bad.pub")
r = run_wolfssl("-genkey", "xmss", "-out", "xmss-bad",
"-outform", "raw", "-output", "KEYPAIR")
self.assertEqual(r.returncode, 0,
"expected default value for -height (no "
"crash)")

@unittest.skipUnless(_has_algorithm("xmss"), "xmss not available")
class XmssmtTest(_GenkeySignVerifyBase):

def test_xmssmt_raw(self):
# The XMSS^MT signer derives the parameter set from the key file name,
# so the keybase must be a valid param string with '-' in place of '/'
# (e.g. "XMSSMT-SHA2_20/2_256" -> "XMSSMT-SHA2_20-2_256"). -height 20
# defaults to layer 2, matching this name.
keybase = "XMSSMT-SHA2_20-2_256"
self._track(keybase + ".priv", keybase + ".pub")
self._gen_sign_verify(
"xmssmt", keybase, "xmss-signed.sig", "raw",
extra_genkey_args=["-height", "20"],
skip_priv_verify=True, use_output_flag=True)

def test_xmssmt_missing_height_value(self):
"""-height with no value must fail gracefully (no crash)."""
self._track("xmss-bad.priv", "xmss-bad.pub")
r = run_wolfssl("-genkey", "xmssmt", "-out", "xmss-bad",
"-outform", "raw", "-output", "KEYPAIR", "-height")
self.assertEqual(r.returncode, 0,
"expected default value of 20 set for -height (no "
"crash)")

def test_xmssmt_missing_height_arg(self):
self._track("xmss-bad.priv", "xmss-bad.pub")
r = run_wolfssl("-genkey", "xmssmt", "-out", "xmss-bad",
"-outform", "raw", "-output", "KEYPAIR")
self.assertEqual(r.returncode, 0,
"expected default value for -height (no "
"crash)")


class SignVerifySetupArgsTest(unittest.TestCase):
"""Argument-parsing branches in clu_sign_verify_setup.c.

These exercise the legacy `-rsa`/`-ecc`/... sign & verify entry point
(note the leading dash, which selects the legacy code path).
"""

SIGN_FILE = "svsetup-sign-this.txt"
RSA_KEY = os.path.join(CERTS_DIR, "server-key.pem")
ECC_KEY = os.path.join(CERTS_DIR, "ecc-key.pem")
ECC_PUB = os.path.join(CERTS_DIR, "ecc-keyPub.pem")

@classmethod
def setUpClass(cls):
config_log = os.path.join(".", "config.log")
if os.path.isfile(config_log):
with open(config_log, "r") as f:
if "disable-filesystem" in f.read():
raise unittest.SkipTest("filesystem support disabled")
with open(cls.SIGN_FILE, "w") as f:
f.write("Sign this test data\n")

@classmethod
def tearDownClass(cls):
_cleanup_files([cls.SIGN_FILE])

def test_sign_help(self):
r = run_wolfssl("-rsa", "-sign", "-help")
self.assertGreaterEqual(r.returncode, 0,
"-height without value crashed with signal "
"sign help crashed with signal "
"{}".format(r.returncode))
self.assertIn("RSA Sign", r.stdout + r.stderr)

def test_verify_help(self):
r = run_wolfssl("-rsa", "-verify", "-help")
self.assertGreaterEqual(r.returncode, 0,
"verify help crashed with signal "
"{}".format(r.returncode))
self.assertIn("RSA Verify", r.stdout + r.stderr)

def test_generic_help(self):
"""No -sign/-verify prints both the sign and verify help blocks."""
r = run_wolfssl("-ecc", "-help")
self.assertGreaterEqual(r.returncode, 0,
"generic help crashed with signal "
"{}".format(r.returncode))
combined = r.stdout + r.stderr
self.assertIn("ECC Sign", combined)
self.assertIn("ECC Verify", combined)

class GenkeyArgvTest(unittest.TestCase):
"""Argument-bounds checks for the genkey subcommand entry point."""
Expand Down
35 changes: 35 additions & 0 deletions tests/ocsp/ocsp-test.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,24 +321,59 @@ class TestWolfsslClientWolfsslResponder(_OCSPInteropBase):
CLIENT_BIN = WOLFSSL_BIN
RESPONDER_BIN = WOLFSSL_BIN

def test_01_client_start_up(self):
""" successful round trip from client to server """
resp = self._start_responder(INDEX_VALID, nrequest=1)
rc, out = _run_client(self.CLIENT_BIN, self.PORT,
["-cert", os.path.join(CERTS_DIR, "server-cert.pem")])

resp.stop()
self.assertEqual(rc, 0, out)
self.assertIn("good", out.lower(), out)


@unittest.skipUnless(HAS_OPENSSL, "openssl not available")
class TestWolfsslClientOpensslResponder(_OCSPInteropBase):
CLIENT_BIN = WOLFSSL_BIN
RESPONDER_BIN = "openssl"

def test_01_client_start_up(self):
resp = self._start_responder(INDEX_VALID, nrequest=1)
rc, out = _run_client(self.CLIENT_BIN, self.PORT,
["-cert", os.path.join(CERTS_DIR, "server-cert.pem")])

resp.stop()
self.assertEqual(rc, 0, out)
self.assertIn("good", out.lower(), out)


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

def test_01_client_start_up(self):
resp = self._start_responder(INDEX_VALID, nrequest=1)
rc, out = _run_client(self.CLIENT_BIN, self.PORT,
["-cert", os.path.join(CERTS_DIR, "server-cert.pem")])

resp.stop()
self.assertEqual(rc, 0, out)
self.assertIn("good", out.lower(), out)

@unittest.skipUnless(HAS_OPENSSL, "openssl not available")
class TestOpensslClientOpensslResponder(_OCSPInteropBase):
CLIENT_BIN = "openssl"
RESPONDER_BIN = "openssl"

def test_01_client_start_up(self):
resp = self._start_responder(INDEX_VALID, nrequest=1)
rc, out = _run_client(self.CLIENT_BIN, self.PORT,
["-cert", os.path.join(CERTS_DIR, "server-cert.pem")])

resp.stop()
self.assertEqual(rc, 0, out)
self.assertIn("good", out.lower(), out)

def load_tests(loader, tests, pattern):
"""Exclude the abstract _OCSPInteropBase from test discovery."""
Expand Down
26 changes: 26 additions & 0 deletions tests/pkcs/pkcs12-test.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,32 @@ def test_pass_on_cmdline(self):
"-passout", "pass:", "-in", P12_FILE)
self.assertEqual(r.returncode, 0, r.stderr)

def test_help(self):
for flag in ("-help", "-h"):
r = run_wolfssl("pkcs12", flag)
self.assertEqual(r.returncode, 0, r.stderr)
self.assertIn("wolfssl pkcs12", r.stdout + r.stderr)

def test_bad_argument_fails(self):
r = run_wolfssl("pkcs12", "-not-a-real-option", "-in", P12_FILE)
self.assertNotEqual(r.returncode, 0)

def test_out_to_file(self):
out = "pkcs12-out.pem"
self.addCleanup(lambda: os.remove(out) if os.path.exists(out) else None)
r = run_wolfssl("pkcs12", "-nodes", "-passin", 'pass:wolfSSL test',
"-passout", "pass:", "-in", P12_FILE, "-out", out)
self.assertEqual(r.returncode, 0, r.stderr)
self.assertTrue(os.path.isfile(out), "pkcs12 -out did not create file")
with open(out, "r") as f:
self.assertIn("BEGIN ", f.read())

def test_out_bad_path_fails(self):
r = run_wolfssl("pkcs12", "-nodes", "-passin", 'pass:wolfSSL test',
"-passout", "pass:", "-in", P12_FILE,
"-out", os.path.join("no-such-dir", "out.pem"))
self.assertNotEqual(r.returncode, 0)

def test_nocerts_with_passout(self):
r = subprocess.run(
[WOLFSSL_BIN, "pkcs12", "-passin", "stdin", "-passout", "pass:",
Expand Down
Loading
Loading