Skip to content

Commit d35840f

Browse files
committed
Add demos/x509_verify.c
Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
1 parent 57effe5 commit d35840f

File tree

7 files changed

+177
-2
lines changed

7 files changed

+177
-2
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ tv_gen
5454
tv_gen.exe
5555
timing
5656
timing.exe
57+
x509_verify
58+
x509_verify.exe
5759

5860
# Visual Studio special files
5961
# ignore user specific settings

demos/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,13 @@ endif()
2424
# Demos that are usable but only rarely make sense to be installed
2525
#
2626
# -----------------------------------------------------------------------------
27-
set(USABLE_DEMOS aesgcm constants crypt der_print_flexi latex-tables openssh-privkey openssl-enc sizes timing)
27+
set(USABLE_DEMOS aesgcm constants crypt der_print_flexi latex-tables openssh-privkey openssl-enc sizes timing x509_verify)
2828
list(JOIN USABLE_DEMOS " " USABLE_DEMOS_STR)
2929
option(BUILD_USABLE_DEMOS "Build usable demos (${USABLE_DEMOS_STR})" FALSE)
3030

3131
if(BUILD_USABLE_DEMOS)
3232
list(APPEND USABLE_DEMOS_TARGETS ${USABLE_DEMOS})
33+
x509_verify
3334
endif()
3435

3536
# -----------------------------------------------------------------------------

demos/x509_verify.c

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
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+
#if defined(LTC_TEST_DBG) && LTC_TEST_DBG > 1
28+
#define LTC_DER_PRINT_FLEXI_NO_MAIN
29+
#include "der_print_flexi.c"
30+
31+
static void s_der_print_flexi(const ltc_asn1_list* l)
32+
{
33+
print_stderr("\n\n");
34+
s_der_print_flexi_i(l, 0);
35+
print_stderr("\n\n");
36+
}
37+
#else
38+
static void s_der_print_flexi(const ltc_asn1_list* l)
39+
{
40+
LTC_UNUSED_PARAM(l);
41+
}
42+
#endif
43+
44+
static unsigned long num_certs;
45+
static const ltc_x509_certificate *cert[256] = {0};
46+
static FILE *f;
47+
48+
static void die_(int err, int line)
49+
{
50+
unsigned long n;
51+
print_err("%3d: LTC sez %s\n", line, error_to_string(err));
52+
for (n = num_certs; n --> 0;) {
53+
x509_free(&cert[n]);
54+
}
55+
if (f) fclose(f);
56+
exit(EXIT_FAILURE);
57+
}
58+
59+
#define die(i) do { die_(i, __LINE__); } while(0)
60+
#define DIE(s, ...) do { print_err("%3d: " s "\n", __LINE__, ##__VA_ARGS__); exit(EXIT_FAILURE); } while(0)
61+
#ifndef LTC_ARRAY_SIZE
62+
#define LTC_ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
63+
#endif
64+
65+
int main(int argc, char **argv)
66+
{
67+
const unsigned char zero_cert_buf[sizeof(cert)] = {0};
68+
int err, argn = 1;
69+
unsigned long len, processed, n;
70+
long tell, tot_data = 0;
71+
72+
if ((err = register_all_hashes()) != CRYPT_OK) {
73+
die(err);
74+
}
75+
if ((err = crypt_mp_init("ltm")) != CRYPT_OK) {
76+
die(err);
77+
}
78+
79+
next:
80+
tot_data = processed = num_certs = n = 0;
81+
if (argc > argn) f = fopen(argv[argn], "r");
82+
else f = stdin;
83+
if (f == NULL) DIE("fopen sez no");
84+
if (f != stdin) {
85+
fseek(f, 0, SEEK_END);
86+
tot_data = ftell(f);
87+
fseek(f, 0, SEEK_SET);
88+
tell = 0;
89+
} else {
90+
tell = -1;
91+
}
92+
93+
print_stderr("-=-=-=-=-=-=-\nDecode %s\n=-=-=-=-=-=-=\n", argv[argn]);
94+
95+
while (tell != tot_data) {
96+
err = x509_import_pem_filehandle(f, &cert[n]);
97+
if (err == CRYPT_PK_ASN1_ERROR || err == CRYPT_UNKNOWN_PEM)
98+
continue;
99+
else if (err != CRYPT_OK)
100+
break;
101+
if (cert[n] && cert[n]->asn1)
102+
s_der_print_flexi(cert[n]->asn1);
103+
if (f != stdin) {
104+
tell = ftell(f);
105+
print_stderr("%2lu len: %ld - tot: %ld - processed: %lu (%s)\n", n, tell, tot_data, processed, error_to_string(err));
106+
len = tell - processed;
107+
processed += len;
108+
}
109+
n++;
110+
if (n == LTC_ARRAY_SIZE(cert))
111+
break;
112+
}
113+
num_certs = n;
114+
print_stderr("len: %ld - tot: %ld - processed: %lu (%s)\n", tell, tot_data, processed, error_to_string(err));
115+
if (err && argc > argn) goto check_next;
116+
if (err && err != CRYPT_NOP) die(err);
117+
for (n = 0; n < num_certs; ++n) {
118+
unsigned long m = n + 1 == num_certs ? n : n + 1;
119+
int stat;
120+
if ((err = x509_cert_is_signed_by(cert[n], &cert[m]->tbs_certificate.subject_public_key_info, &stat)) != CRYPT_OK) {
121+
print_err("%3d: LTC sez %s\n", __LINE__, error_to_string(err));
122+
if (m == n) {
123+
print_stderr("Cert is last in chain, but not self-signed.\n");
124+
} else {
125+
break;
126+
}
127+
}
128+
{
129+
const ltc_x509_string *subjects[4];
130+
const ltc_x509_name *subject, *issuer;
131+
int issuer_matches_next_subject = x509_cmp_name(&cert[n]->tbs_certificate.issuer, &cert[m]->tbs_certificate.subject);
132+
subject = &cert[n]->tbs_certificate.subject;
133+
if (n != m) {
134+
issuer = &cert[m]->tbs_certificate.subject;
135+
} else {
136+
issuer = &cert[m]->tbs_certificate.issuer;
137+
}
138+
x509_name_detail_get(subject, LTC_X509_CN, &subjects[0]);
139+
x509_name_detail_get(subject, LTC_X509_O, &subjects[2]);
140+
x509_name_detail_get(issuer, LTC_X509_CN, &subjects[1]);
141+
x509_name_detail_get(issuer, LTC_X509_O, &subjects[3]);
142+
#define X509_STRING_STR(s) (s) ? (s)->str : "NULL"
143+
print_stderr("Cert: %s - %s\nCA: %s - %s\nIssuer matches next subject: %s\nVerify: %s\n",
144+
X509_STRING_STR(subjects[0]), X509_STRING_STR(subjects[2]),
145+
X509_STRING_STR(subjects[1]), X509_STRING_STR(subjects[3]),
146+
issuer_matches_next_subject ? "True" : "False", stat ? "Success" : "Failed");
147+
/* In case of LTC_QUIET this would show up as unused. */
148+
LTC_UNUSED_PARAM(issuer_matches_next_subject);
149+
}
150+
}
151+
check_next:
152+
for (n = num_certs; n --> 0;) {
153+
x509_free(&cert[n]);
154+
}
155+
if (XMEMCMP(cert, zero_cert_buf, sizeof(zero_cert_buf))) {
156+
DIE("cert buf not completely cleaned");
157+
}
158+
if (f != stdin) {
159+
fclose(f);
160+
argn++;
161+
if (argc > argn) {
162+
goto next;
163+
}
164+
}
165+
return 0;
166+
}

makefile.mingw

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,8 @@ timing.exe: demos/timing.o $(LIBMAIN_S)
305305
$(CC) demos/timing.o $(LIBMAIN_S) $(LTC_LDFLAGS) -o $@
306306
der_print_flexi.exe: demos/der_print_flexi.o $(LIBMAIN_S)
307307
$(CC) demos/der_print_flexi.o $(LIBMAIN_S) $(LTC_LDFLAGS) -o $@
308+
x509_verify.exe: demos/x509_verify.o $(LIBMAIN_S)
309+
$(CC) demos/x509_verify.o $(LIBMAIN_S) $(LTC_LDFLAGS) -o $@
308310

309311
#Tests
310312
test.exe: $(TOBJECTS) $(LIBMAIN_S)

makefile.msvc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,8 @@ timing.exe: demos/timing.c $(LIBMAIN_S)
292292
cl $(LTC_CFLAGS) demos/timing.c tests/common.c $(LIBMAIN_S) $(LTC_LDFLAGS) /Fe$@
293293
der_print_flexi.exe: demos/der_print_flexi.c $(LIBMAIN_S)
294294
cl $(LTC_CFLAGS) demos/der_print_flexi.c tests/common.c $(LIBMAIN_S) $(LTC_LDFLAGS) /Fe$@
295+
x509_verify.exe: demos/x509_verify.c $(LIBMAIN_S)
296+
cl $(LTC_CFLAGS) demos/x509_verify.c tests/common.c $(LIBMAIN_S) $(LTC_LDFLAGS) /Fe$@
295297

296298
#Tests
297299
test.exe: $(LIBMAIN_S) $(TOBJECTS)

makefile.unix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,8 @@ timing: demos/timing.o $(LIBMAIN_S)
316316
$(CC) demos/timing.o $(LIBMAIN_S) $(LTC_LDFLAGS) -o $@
317317
der_print_flexi: demos/der_print_flexi.o $(LIBMAIN_S)
318318
$(CC) demos/der_print_flexi.o $(LIBMAIN_S) $(LTC_LDFLAGS) -o $@
319+
x509_verify: demos/x509_verify.o $(LIBMAIN_S)
320+
$(CC) demos/x509_verify.o $(LIBMAIN_S) $(LTC_LDFLAGS) -o $@
319321

320322
#Tests
321323
test: $(TOBJECTS) $(LIBMAIN_S)

makefile_include.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ TEST=test
180180
USEFUL_DEMOS = hashsum
181181

182182
# Demos that are usable but only rarely make sense to be installed
183-
USEABLE_DEMOS = aesgcm constants crypt der_print_flexi latex-tables openssh-privkey openssl-enc sizes timing
183+
USEABLE_DEMOS = aesgcm constants crypt der_print_flexi latex-tables openssh-privkey openssl-enc sizes timing x509_verify
184184

185185
# Demos that are used for testing or measuring
186186
TEST_DEMOS = small tv_gen

0 commit comments

Comments
 (0)