Skip to content

Commit 65624f3

Browse files
authored
Merge pull request #186 from padelsbach/wp_kmod_tests
Add tests modeled after kmod usage
2 parents febb147 + 8f7bbc9 commit 65624f3

File tree

4 files changed

+290
-0
lines changed

4 files changed

+290
-0
lines changed

test/include.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ test_unit_test_SOURCES = \
2525
test/test_logging.c \
2626
test/test_pbe.c \
2727
test/test_pkey.c \
28+
test/test_pkcs7_x509.c \
2829
test/test_rand.c \
2930
test/test_rsa.c \
3031
test/test_tls1_prf.c \

test/test_pkcs7_x509.c

Lines changed: 283 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,283 @@
1+
/* test_pkcs7_x509.c
2+
*
3+
* Copyright (C) 2006-2025 wolfSSL Inc.
4+
*
5+
* This file is part of wolfProvider.
6+
*
7+
* wolfProvider is free software; you can redistribute it and/or modify
8+
* it under the terms of the GNU General Public License as published by
9+
* the Free Software Foundation; either version 3 of the License, or
10+
* (at your option) any later version.
11+
*
12+
* wolfProvider is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with wolfProvider. If not, see <http://www.gnu.org/licenses/>.
19+
*/
20+
21+
#include "unit.h"
22+
23+
/* Test key generated with the following commands:
24+
* openssl req -x509 -newkey rsa:2048 -outform der -out cert.der -days 365 -nodes -subj "/CN=Test User/O=Example Corp/C=US"
25+
* xxd -i cert.der */
26+
27+
static const unsigned char cert_der[] = {
28+
0x30, 0x82, 0x03, 0x1f, 0x30, 0x82, 0x02, 0x07, 0xa0, 0x03, 0x02, 0x01,
29+
0x02, 0x02, 0x14, 0x53, 0x95, 0x98, 0x04, 0xf5, 0x99, 0x2d, 0x64, 0x6b,
30+
0xb9, 0x7e, 0xac, 0x3d, 0x80, 0x9d, 0xa4, 0xa4, 0x93, 0x59, 0x58, 0x30,
31+
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
32+
0x05, 0x00, 0x30, 0x38, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
33+
0x03, 0x0c, 0x09, 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x65, 0x72,
34+
0x31, 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0c, 0x45,
35+
0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x6f, 0x72, 0x70, 0x31,
36+
0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
37+
0x30, 0x1e, 0x17, 0x0d, 0x32, 0x35, 0x30, 0x36, 0x32, 0x31, 0x30, 0x31,
38+
0x31, 0x36, 0x34, 0x38, 0x5a, 0x17, 0x0d, 0x32, 0x36, 0x30, 0x36, 0x32,
39+
0x31, 0x30, 0x31, 0x31, 0x36, 0x34, 0x38, 0x5a, 0x30, 0x38, 0x31, 0x12,
40+
0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x54, 0x65, 0x73,
41+
0x74, 0x20, 0x55, 0x73, 0x65, 0x72, 0x31, 0x15, 0x30, 0x13, 0x06, 0x03,
42+
0x55, 0x04, 0x0a, 0x0c, 0x0c, 0x45, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65,
43+
0x20, 0x43, 0x6f, 0x72, 0x70, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
44+
0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
45+
0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
46+
0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82,
47+
0x01, 0x01, 0x00, 0xce, 0xf0, 0x99, 0x44, 0x0a, 0xa9, 0xd2, 0x98, 0x07,
48+
0xd5, 0xfb, 0x6b, 0x39, 0xe3, 0xf2, 0x2e, 0x14, 0x10, 0x1f, 0x95, 0x9c,
49+
0xb8, 0x62, 0x52, 0x40, 0x6e, 0x69, 0x6e, 0x23, 0x8f, 0xb2, 0xcb, 0xfa,
50+
0x74, 0xaf, 0xe3, 0xfd, 0x1a, 0x35, 0x86, 0x46, 0xb7, 0xc8, 0xf4, 0xf4,
51+
0xec, 0x78, 0x38, 0x6b, 0xa4, 0x0b, 0xbb, 0x55, 0x61, 0x9e, 0xdc, 0xdb,
52+
0x21, 0xdf, 0x30, 0x7d, 0x79, 0xfa, 0xba, 0xdd, 0x08, 0x5d, 0xd2, 0xed,
53+
0xd0, 0x6e, 0xfb, 0x60, 0xfa, 0x32, 0x86, 0x4c, 0x87, 0xed, 0x7c, 0x39,
54+
0xc5, 0x81, 0x3a, 0xad, 0xef, 0xd6, 0x8a, 0x16, 0x00, 0xd0, 0x0e, 0x8a,
55+
0x61, 0x35, 0x6b, 0x90, 0x45, 0xa3, 0x62, 0x8a, 0xec, 0x4f, 0x95, 0xff,
56+
0x91, 0x97, 0x43, 0x62, 0x5e, 0x79, 0x59, 0x1f, 0x13, 0x60, 0x98, 0x9d,
57+
0x30, 0x23, 0x18, 0xd8, 0x06, 0xed, 0x9c, 0xbd, 0xb5, 0x3a, 0xac, 0xe5,
58+
0x5a, 0x97, 0xdd, 0x29, 0x81, 0xde, 0x62, 0x88, 0x82, 0x1a, 0x00, 0x9c,
59+
0xa4, 0x7d, 0x91, 0xe8, 0xe9, 0xd1, 0xae, 0x07, 0x94, 0xd3, 0x1d, 0x61,
60+
0xfb, 0x87, 0xcc, 0xc7, 0x56, 0x9e, 0xac, 0xd5, 0x9d, 0x36, 0xeb, 0x2d,
61+
0x62, 0x1f, 0xe0, 0xc8, 0x86, 0x79, 0xea, 0x21, 0x4d, 0xc9, 0xd2, 0xcb,
62+
0xfb, 0x62, 0x2f, 0xc2, 0xc0, 0xa2, 0x3d, 0x2e, 0xad, 0xf2, 0xaf, 0xab,
63+
0xac, 0x1e, 0x45, 0x39, 0x10, 0x55, 0x7b, 0x32, 0xf7, 0x95, 0x76, 0x11,
64+
0xc7, 0xce, 0xc1, 0xba, 0x43, 0x39, 0x58, 0xc0, 0xc0, 0xb2, 0x9b, 0xd8,
65+
0xec, 0x88, 0x3b, 0x48, 0x39, 0x82, 0xba, 0xcd, 0x92, 0x6f, 0x64, 0xcd,
66+
0xd3, 0xbc, 0xff, 0x40, 0x0d, 0xef, 0xf5, 0x1e, 0xd7, 0x60, 0x4b, 0x23,
67+
0x26, 0x86, 0x61, 0xfe, 0xd1, 0x85, 0x79, 0x00, 0x96, 0x84, 0x71, 0xba,
68+
0xb2, 0x05, 0x8d, 0x0f, 0x75, 0x25, 0x0b, 0x02, 0x03, 0x01, 0x00, 0x01,
69+
0xa3, 0x21, 0x30, 0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
70+
0x16, 0x04, 0x14, 0x78, 0x92, 0x53, 0x9c, 0x8b, 0x59, 0x13, 0x88, 0x7d,
71+
0x5c, 0x8e, 0x12, 0x66, 0x4a, 0x9e, 0x07, 0x0b, 0x61, 0x77, 0xa1, 0x30,
72+
0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
73+
0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xba, 0xb6, 0x44, 0xf8, 0x72,
74+
0xda, 0x34, 0x93, 0xf0, 0x61, 0x0d, 0x8d, 0xfa, 0x33, 0xd3, 0x08, 0x58,
75+
0x1b, 0x87, 0xb5, 0xef, 0x7c, 0x46, 0x6e, 0x89, 0xfb, 0xa3, 0x05, 0x09,
76+
0x96, 0x01, 0x4d, 0xc7, 0xe5, 0x9b, 0xee, 0xc9, 0x11, 0x3b, 0x51, 0x93,
77+
0x16, 0x89, 0x8c, 0x09, 0xd2, 0xc4, 0x6c, 0xb2, 0xdc, 0xea, 0x3a, 0xee,
78+
0x6c, 0x13, 0x7f, 0x0e, 0x2b, 0xde, 0xff, 0x88, 0xfa, 0xec, 0xc7, 0x69,
79+
0xab, 0xd3, 0xbb, 0x80, 0x8e, 0x38, 0x73, 0x9b, 0xe1, 0x5a, 0x3b, 0xfc,
80+
0xbd, 0xa5, 0x11, 0x76, 0x51, 0xb5, 0xb8, 0x45, 0x80, 0xa4, 0xf0, 0xd9,
81+
0xcd, 0x55, 0xc9, 0x71, 0x9e, 0x00, 0x5e, 0x1f, 0xa6, 0x68, 0x62, 0x30,
82+
0x2b, 0xbb, 0x76, 0x9e, 0x7b, 0x6d, 0x6e, 0x18, 0x0b, 0x62, 0x98, 0x58,
83+
0x4a, 0x03, 0x9c, 0x10, 0x6d, 0x75, 0xe9, 0xc4, 0xad, 0x0f, 0x28, 0x56,
84+
0xc6, 0xa4, 0xb1, 0x12, 0xd5, 0x20, 0x96, 0x14, 0xe5, 0xa0, 0x75, 0x45,
85+
0x53, 0x50, 0x1f, 0x3c, 0x50, 0x17, 0x48, 0x0d, 0x3f, 0xde, 0x91, 0xa2,
86+
0x0f, 0x68, 0xdf, 0x5b, 0x4c, 0x08, 0x09, 0xc3, 0x46, 0x78, 0x5a, 0xcd,
87+
0x4d, 0xbb, 0xf2, 0x39, 0xf1, 0x08, 0x8f, 0xde, 0xf8, 0x84, 0xc6, 0xa5,
88+
0x50, 0x5a, 0xa7, 0x0b, 0x53, 0x4d, 0x9b, 0xe7, 0xd8, 0x0c, 0x77, 0x2b,
89+
0x26, 0xa6, 0x46, 0x86, 0xac, 0xfa, 0x68, 0x38, 0x6d, 0x4f, 0x7c, 0xb1,
90+
0xba, 0x95, 0x1c, 0xf2, 0xb3, 0x57, 0xdb, 0x5c, 0x3d, 0xcc, 0x82, 0x55,
91+
0xd1, 0xed, 0xf8, 0x25, 0x3e, 0x81, 0xbf, 0xe6, 0x1b, 0xf2, 0x3d, 0x58,
92+
0x77, 0x7c, 0x0e, 0xf8, 0xfa, 0xd4, 0x1c, 0xff, 0xcb, 0xc4, 0x7f, 0x93,
93+
0xff, 0x9a, 0x89, 0xe9, 0x35, 0x5d, 0xbc, 0x1e, 0x69, 0xc7, 0xca, 0x1c,
94+
0xef, 0x75, 0x01, 0xed, 0x2c, 0x28, 0x7f, 0x2d, 0x57, 0x1b, 0x77
95+
};
96+
unsigned int cert_der_len = sizeof(cert_der); /* 803 */
97+
98+
/*
99+
* The following test case adds tests which are modeled after the OSSL usage
100+
* by libkmod. https://github.com/kmod-project/kmod
101+
*
102+
* The make check in kmod source code does not test crypto operations.
103+
* These tests don't add a lot of new coverage beyond what we already have.
104+
*/
105+
int test_pkcs7_x509_sign_verify(void* data)
106+
{
107+
(void)data; /* Unused parameter */
108+
/* === Step 1: Generate keypair === */
109+
EVP_PKEY *pkey = EVP_RSA_gen(2048);
110+
if (!pkey) {
111+
PRINT_MSG("Key generation failed");
112+
return -1;
113+
}
114+
115+
PRINT_MSG("Keypair generated successfully");
116+
117+
/* === Step 2: Create self-signed cert === */
118+
X509 *cert = X509_new();
119+
ASN1_INTEGER_set(X509_get_serialNumber(cert), 1);
120+
X509_gmtime_adj(X509_get_notBefore(cert), 0);
121+
X509_gmtime_adj(X509_get_notAfter(cert), 31536000L);
122+
X509_set_pubkey(cert, pkey);
123+
124+
X509_NAME *name = X509_get_subject_name(cert);
125+
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC, (unsigned char *)"Test Signer", -1, -1, 0);
126+
X509_set_issuer_name(cert, name);
127+
X509_sign(cert, pkey, EVP_sha256());
128+
129+
/* === Step 3: Create the data to be signed === */
130+
const char *msg = "this is a signed message";
131+
BIO *data_bio = BIO_new_mem_buf(msg, (int)strlen(msg));
132+
133+
/* === Step 4: Sign the message === */
134+
PKCS7 *p7 = PKCS7_sign(cert, pkey, NULL, data_bio, PKCS7_BINARY | PKCS7_DETACHED);
135+
if (!p7) {
136+
PRINT_MSG("PKCS7_sign failed");
137+
return -1;
138+
}
139+
140+
/* === Step 5: Write and read back the DER (simulate disk round trip) === */
141+
BIO *p7_mem = BIO_new(BIO_s_mem());
142+
i2d_PKCS7_bio(p7_mem, p7);
143+
144+
char *p7_buf = NULL;
145+
long p7_len = BIO_get_mem_data(p7_mem, &p7_buf);
146+
BIO *p7_in = BIO_new_mem_buf(p7_buf, (int)p7_len);
147+
PKCS7 *p7_read = d2i_PKCS7_bio(p7_in, NULL);
148+
149+
/* === Step 6: Set up trust store with our self-signed cert === */
150+
X509_STORE *store = X509_STORE_new();
151+
X509_STORE_add_cert(store, cert);
152+
153+
BIO *out = BIO_new_fp(stdout, BIO_NOCLOSE);
154+
(void)BIO_reset(data_bio); /* rewind input message */
155+
156+
int ok = PKCS7_verify(p7_read, NULL, store, data_bio, out, 0);
157+
if (!ok) {
158+
PRINT_MSG("PKCS7 verification failed");
159+
return -1;
160+
}
161+
162+
PRINT_MSG("PKCS7 verification succeeded");
163+
164+
/* === Step 7: Examine signer info === */
165+
STACK_OF(PKCS7_SIGNER_INFO) *signers = PKCS7_get_signer_info(p7_read);
166+
if (!signers || sk_PKCS7_SIGNER_INFO_num(signers) <= 0) {
167+
PRINT_MSG("No signers found");
168+
return -1;
169+
}
170+
171+
for (int i = 0; i < sk_PKCS7_SIGNER_INFO_num(signers); i++) {
172+
PKCS7_SIGNER_INFO *si = sk_PKCS7_SIGNER_INFO_value(signers, i);
173+
EVP_PKEY *pkey_tmp;
174+
X509_ALGOR *digest_alg, *sig_alg;
175+
176+
PKCS7_SIGNER_INFO_get0_algs(si, &pkey_tmp, &digest_alg, &sig_alg);
177+
178+
PRINT_MSG("Signer %d:", i);
179+
PRINT_MSG(" Digest Algorithm: ");
180+
i2a_ASN1_OBJECT(out, digest_alg->algorithm);
181+
PRINT_MSG(" Signature Algorithm: ");
182+
i2a_ASN1_OBJECT(out, sig_alg->algorithm);
183+
PRINT_MSG("");
184+
}
185+
186+
/* === Cleanup === */
187+
EVP_PKEY_free(pkey);
188+
X509_free(cert);
189+
PKCS7_free(p7);
190+
PKCS7_free(p7_read);
191+
X509_STORE_free(store);
192+
BIO_free(data_bio);
193+
BIO_free(p7_mem);
194+
BIO_free(p7_in);
195+
BIO_free(out);
196+
197+
return 0; /* Success */
198+
}
199+
200+
static int test_x509_name(X509_NAME *name) {
201+
int count = X509_NAME_entry_count(name);
202+
PRINT_MSG("X509_NAME has %d entries", count);
203+
if (count < 0) {
204+
PRINT_MSG("Error counting X509_NAME entries");
205+
return -1;
206+
}
207+
208+
for (int i = 0; i < count; i++) {
209+
X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, i);
210+
if (!entry) continue;
211+
212+
ASN1_OBJECT *obj = X509_NAME_ENTRY_get_object(entry);
213+
ASN1_STRING *data = X509_NAME_ENTRY_get_data(entry);
214+
215+
char obj_buf[80];
216+
OBJ_obj2txt(obj_buf, sizeof(obj_buf), obj, 1);
217+
PRINT_MSG(" OID: %s", obj_buf);
218+
219+
const unsigned char *data_ptr = ASN1_STRING_get0_data(data);
220+
int data_len = ASN1_STRING_length(data);
221+
PRINT_MSG(" Value: %.*s", data_len, data_ptr);
222+
}
223+
224+
return 0;
225+
}
226+
227+
static int test_x509_algor(X509 *cert) {
228+
X509_ALGOR *alg = NULL;
229+
X509_PUBKEY *pubkey = X509_get_X509_PUBKEY(cert);
230+
if (!pubkey) {
231+
PRINT_MSG("No public key found");
232+
return -1;
233+
}
234+
235+
PRINT_MSG("Public key algorithm:");
236+
237+
if (!X509_PUBKEY_get0_param(NULL, NULL, NULL, &alg, pubkey)) {
238+
PRINT_MSG("Failed to get algorithm info");
239+
return -1;
240+
}
241+
242+
PRINT_MSG("Algorithm OID: %i", OBJ_obj2nid(alg->algorithm));
243+
244+
const ASN1_OBJECT *obj = NULL;
245+
X509_ALGOR_get0(&obj, NULL, NULL, alg);
246+
247+
char alg_buf[80];
248+
OBJ_obj2txt(alg_buf, sizeof(alg_buf), obj, 1);
249+
PRINT_MSG("Public key algorithm OID: %s", alg_buf);
250+
251+
return 0; /* Success */
252+
}
253+
254+
int test_x509_cert(void* data) {
255+
(void)data; /* Unused parameter */
256+
int err = 0;
257+
const unsigned char *p = cert_der;
258+
X509 *cert = d2i_X509(NULL, &p, cert_der_len);
259+
if (!cert) {
260+
PRINT_MSG("Failed to parse DER certificate");
261+
err = -1;
262+
}
263+
264+
if (err == 0) {
265+
PRINT_MSG("Subject:");
266+
X509_NAME *subject = X509_get_subject_name(cert);
267+
err = test_x509_name(subject);
268+
if (err) {
269+
PRINT_MSG("Failed to test subject name");
270+
}
271+
}
272+
273+
if (err == 0) {
274+
PRINT_MSG("Testing algorithm info:");
275+
err = test_x509_algor(cert);
276+
if (err) {
277+
PRINT_MSG("Failed to test algorithm info");
278+
}
279+
}
280+
281+
X509_free(cert);
282+
return err;
283+
}

test/unit.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,9 @@ TEST_CASE test_case[] = {
300300
TEST_DECL(test_ecx_misc, NULL),
301301
TEST_DECL(test_ecx_null_init, NULL),
302302
#endif
303+
304+
TEST_DECL(test_pkcs7_x509_sign_verify, NULL),
305+
TEST_DECL(test_x509_cert, NULL),
303306
};
304307
#define TEST_CASE_CNT (int)(sizeof(test_case) / sizeof(*test_case))
305308

test/unit.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,4 +402,7 @@ int test_ecx_misc(void *data);
402402
int test_ecx_null_init(void *data);
403403
#endif
404404

405+
int test_pkcs7_x509_sign_verify(void *data);
406+
int test_x509_cert(void *data);
407+
405408
#endif /* UNIT_H */

0 commit comments

Comments
 (0)