Skip to content

Commit 681eac7

Browse files
committed
Add demos/x509_verify.c
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
1 parent 9522c7c commit 681eac7

File tree

7 files changed

+157
-2
lines changed

7 files changed

+157
-2
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ tv_gen
5252
tv_gen.exe
5353
timing
5454
timing.exe
55+
x509_verify
56+
x509_verify.exe
5557

5658
# Visual Studio special files
5759
# ignore user specific settings

demos/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ endif()
2828
#
2929
# Demos that are usable but only rarely make sense to be installed
3030
#
31-
# USEABLE_DEMOS = aesgcm constants crypt openssh-privkey openssl-enc pem-info sizes timing
31+
# USEABLE_DEMOS = aesgcm constants crypt openssh-privkey openssl-enc pem-info sizes timing x509_verify
3232
# -----------------------------------------------------------------------------
3333

3434
if(BUILD_USABLE_DEMOS)
@@ -43,6 +43,7 @@ if(BUILD_USABLE_DEMOS)
4343
pem-info
4444
sizes
4545
timing
46+
x509_verify
4647
)
4748
endif()
4849

demos/x509_verify.c

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2+
/* SPDX-License-Identifier: Unlicense */
3+
/* load a X.509 certificate chain and verify its validity */
4+
#include <tomcrypt.h>
5+
#include <stdarg.h>
6+
7+
#ifdef LTC_QUIET
8+
static void print_err(const char *fmt, ...)
9+
{
10+
LTC_UNUSED_PARAM(fmt);
11+
}
12+
13+
#define print_stderr(...)
14+
#else
15+
static void print_err(const char *fmt, ...)
16+
{
17+
va_list args;
18+
19+
va_start(args, fmt);
20+
vfprintf(stderr, fmt, args);
21+
va_end(args);
22+
}
23+
24+
#define print_stderr(...) fprintf(stderr, ##__VA_ARGS__)
25+
#endif
26+
27+
28+
static unsigned long num_certs;
29+
static const ltc_x509_certificate *cert[256] = {0};
30+
static FILE *f;
31+
32+
static void die_(int err, int line)
33+
{
34+
unsigned long n;
35+
print_err("%3d: LTC sez %s\n", line, error_to_string(err));
36+
for (n = num_certs; n --> 0;) {
37+
x509_free(&cert[n]);
38+
}
39+
if (f) fclose(f);
40+
exit(EXIT_FAILURE);
41+
}
42+
43+
#define die(i) do { die_(i, __LINE__); } while(0)
44+
#define DIE(s, ...) do { print_err("%3d: " s "\n", __LINE__, ##__VA_ARGS__); exit(EXIT_FAILURE); } while(0)
45+
#ifndef LTC_ARRAY_SIZE
46+
#define LTC_ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
47+
#endif
48+
49+
int main(int argc, char **argv)
50+
{
51+
const unsigned char zero_cert_buf[sizeof(cert)] = {0};
52+
int err, argn = 1;
53+
unsigned long len, processed, n;
54+
long tell, tot_data = 0;
55+
56+
if ((err = register_all_hashes()) != CRYPT_OK) {
57+
die(err);
58+
}
59+
if ((err = crypt_mp_init("ltm")) != CRYPT_OK) {
60+
die(err);
61+
}
62+
63+
next:
64+
tot_data = processed = num_certs = n = 0;
65+
if (argc > argn) f = fopen(argv[argn], "r");
66+
else f = stdin;
67+
if (f == NULL) DIE("fopen sez no");
68+
if (f != stdin) {
69+
fseek(f, 0, SEEK_END);
70+
tot_data = ftell(f);
71+
rewind(f);
72+
tell = 0;
73+
} else {
74+
tell = -1;
75+
}
76+
77+
print_stderr("-=-=-=-=-=-=-\nDecode %s\n=-=-=-=-=-=-=\n", argv[argn]);
78+
79+
while (tell != tot_data) {
80+
err = x509_import_pem_filehandle(f, &cert[n]);
81+
if (err == CRYPT_PK_ASN1_ERROR || err == CRYPT_UNKNOWN_PEM)
82+
continue;
83+
else if (err != CRYPT_OK)
84+
break;
85+
if (f != stdin) {
86+
tell = ftell(f);
87+
print_stderr("%2lu len: %ld - tot: %ld - processed: %lu (%s)\n", n, tell, tot_data, processed, error_to_string(err));
88+
len = tell - processed;
89+
processed += len;
90+
}
91+
n++;
92+
if (n == LTC_ARRAY_SIZE(cert))
93+
break;
94+
}
95+
num_certs = n;
96+
print_stderr("len: %ld - tot: %ld - processed: %lu (%s)\n", tell, tot_data, processed, error_to_string(err));
97+
if (err && argc > argn) goto check_next;
98+
if (err && err != CRYPT_NOP) die(err);
99+
for (n = 0; n < num_certs; ++n) {
100+
unsigned long m = n + 1 == num_certs ? n : n + 1;
101+
int stat;
102+
if ((err = x509_cert_is_signed_by(cert[n], &cert[m]->tbs_certificate.subject_public_key_info, &stat)) != CRYPT_OK) {
103+
print_err("%3d: LTC sez %s\n", __LINE__, error_to_string(err));
104+
if (m == n) {
105+
print_stderr("Cert is last in chain, but not self-signed.\n");
106+
} else {
107+
break;
108+
}
109+
}
110+
{
111+
const ltc_x509_string *subjects[4];
112+
int issuer_matches_subject = x509_cmp_name(&cert[n]->tbs_certificate.issuer, &cert[m]->tbs_certificate.subject);
113+
x509_name_detail_get(&cert[n]->tbs_certificate.subject, LTC_X509_CN, &subjects[0]);
114+
x509_name_detail_get(&cert[n]->tbs_certificate.subject, LTC_X509_O, &subjects[2]);
115+
if (n != m) {
116+
x509_name_detail_get(&cert[m]->tbs_certificate.subject, LTC_X509_CN, &subjects[1]);
117+
x509_name_detail_get(&cert[m]->tbs_certificate.subject, LTC_X509_O, &subjects[3]);
118+
} else {
119+
x509_name_detail_get(&cert[m]->tbs_certificate.issuer, LTC_X509_CN, &subjects[1]);
120+
x509_name_detail_get(&cert[m]->tbs_certificate.issuer, LTC_X509_O, &subjects[3]);
121+
}
122+
#define X509_STRING_STR(s) (s) ? (s)->str : "NULL"
123+
print_stderr("Cert: %s - %s\nCA: %s - %s\nIssuer matches subject: %s\nVerify: %s\n",
124+
X509_STRING_STR(subjects[0]), X509_STRING_STR(subjects[2]),
125+
X509_STRING_STR(subjects[1]), X509_STRING_STR(subjects[3]),
126+
issuer_matches_subject ? "True" : "False", stat ? "Success" : "Failed");
127+
/* In case of LTC_QUIET this would show up as unused. */
128+
LTC_UNUSED_PARAM(issuer_matches_subject);
129+
}
130+
}
131+
check_next:
132+
for (n = num_certs; n --> 0;) {
133+
x509_free(&cert[n]);
134+
}
135+
if (XMEMCMP(cert, zero_cert_buf, sizeof(zero_cert_buf))) {
136+
DIE("cert buf not completely cleaned");
137+
}
138+
if (f != stdin) {
139+
fclose(f);
140+
argn++;
141+
if (argc > argn) {
142+
goto next;
143+
}
144+
}
145+
return 0;
146+
}

makefile.mingw

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,8 @@ constants.exe: demos/constants.o $(LIBMAIN_S)
301301
$(CC) demos/constants.o $(LIBMAIN_S) $(LTC_LDFLAGS) -o $@
302302
timing.exe: demos/timing.o $(LIBMAIN_S)
303303
$(CC) demos/timing.o $(LIBMAIN_S) $(LTC_LDFLAGS) -o $@
304+
x509_verify.exe: demos/x509_verify.o $(LIBMAIN_S)
305+
$(CC) demos/x509_verify.o $(LIBMAIN_S) $(LTC_LDFLAGS) -o $@
304306

305307
#Tests
306308
test.exe: $(TOBJECTS) $(LIBMAIN_S)

makefile.msvc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ constants.exe: demos/constants.c $(LIBMAIN_S)
288288
cl $(LTC_CFLAGS) demos/constants.c tests/common.c $(LIBMAIN_S) $(LTC_LDFLAGS) /Fe$@
289289
timing.exe: demos/timing.c $(LIBMAIN_S)
290290
cl $(LTC_CFLAGS) demos/timing.c tests/common.c $(LIBMAIN_S) $(LTC_LDFLAGS) /Fe$@
291+
x509_verify.exe: demos/x509_verify.c $(LIBMAIN_S)
292+
cl $(LTC_CFLAGS) demos/x509_verify.c tests/common.c $(LIBMAIN_S) $(LTC_LDFLAGS) /Fe$@
291293

292294
#Tests
293295
test.exe: $(LIBMAIN_S) $(TOBJECTS)

makefile.unix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,8 @@ constants: demos/constants.o $(LIBMAIN_S)
312312
$(CC) demos/constants.o $(LIBMAIN_S) $(LTC_LDFLAGS) -o $@
313313
timing: demos/timing.o $(LIBMAIN_S)
314314
$(CC) demos/timing.o $(LIBMAIN_S) $(LTC_LDFLAGS) -o $@
315+
x509_verify: demos/x509_verify.o $(LIBMAIN_S)
316+
$(CC) demos/x509_verify.o $(LIBMAIN_S) $(LTC_LDFLAGS) -o $@
315317

316318
#Tests
317319
test: $(TOBJECTS) $(LIBMAIN_S)

makefile_include.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ TEST=test
174174
USEFUL_DEMOS = hashsum
175175

176176
# Demos that are usable but only rarely make sense to be installed
177-
USEABLE_DEMOS = aesgcm constants crypt openssh-privkey openssl-enc pem-info sizes timing
177+
USEABLE_DEMOS = aesgcm constants crypt openssh-privkey openssl-enc pem-info sizes timing x509_verify
178178

179179
# Demos that are used for testing or measuring
180180
TEST_DEMOS = small tv_gen

0 commit comments

Comments
 (0)