Skip to content
Draft
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
13 changes: 13 additions & 0 deletions .ci/coverage_more.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@ pdiv "Sizes"
pdiv "Constants"
./constants

echo "" > x509_verify.log

for n in tests/x509/*.pem; do
pdiv "X.509 verify $n"
./x509_verify $n >>x509_verify.log 2>&1
done

pdiv "X.509 verify of all certs packaged"
find tests/x509 -name '*.pem' -exec './x509_verify' {} \+ >>x509_verify.log 2>&1

pdiv "X.509 verify of all certs packaged via STDIN"
for f in $(find tests/x509 -maxdepth 2 -name '*.pem'); do echo "- - - - - - -"; echo $f; cat $f | ./x509_verify; done >>x509_verify.log 2>&1

pdiv "Generate hashsum_tv.txt"
for i in $(for j in $(echo $(./hashsum -h | awk '/Algorithms/,EOF' | tail -n +2)); do echo $j; done | sort); do
echo -n "$i: " && ./hashsum -a $i tests/test.key
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ tv_gen
tv_gen.exe
timing
timing.exe
x509_verify
x509_verify.exe

# Visual Studio special files
# ignore user specific settings
Expand Down
3 changes: 2 additions & 1 deletion demos/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,13 @@ endif()
# Demos that are usable but only rarely make sense to be installed
#
# -----------------------------------------------------------------------------
set(USABLE_DEMOS aesgcm constants crypt der_print_flexi latex-tables openssh-privkey openssl-enc sizes timing)
set(USABLE_DEMOS aesgcm constants crypt der_print_flexi latex-tables openssh-privkey openssl-enc sizes timing x509_verify)
list(JOIN USABLE_DEMOS " " USABLE_DEMOS_STR)
option(BUILD_USABLE_DEMOS "Build usable demos (${USABLE_DEMOS_STR})" FALSE)

if(BUILD_USABLE_DEMOS)
list(APPEND USABLE_DEMOS_TARGETS ${USABLE_DEMOS})
x509_verify
endif()

# -----------------------------------------------------------------------------
Expand Down
79 changes: 71 additions & 8 deletions demos/timing.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@ static ulong64 t_read(void)

static void init_timer(void)
{
#if defined(LTC_NO_ASM)
skew = 0;
fprintf(stderr, "LTC_NO_ASM\nClock Skew: %lu\n", (unsigned long)skew);
#else
ulong64 c1, c2, t1, t2;
unsigned long y1;

Expand All @@ -137,6 +141,7 @@ static void init_timer(void)
}
skew = c2 - c1;
fprintf(stderr, "Clock Skew: %lu\n", (unsigned long)skew);
#endif
}

static void time_keysched(void)
Expand Down Expand Up @@ -702,11 +707,21 @@ static void time_rsa(void)
unsigned char buf[2][2048] = { 0 };
unsigned long x, y, z, zzz;
int err, zz, stat;
ltc_rsa_op_parameters rsa_params = {
.u.crypt.lparam = (const unsigned char *)"testprog",
.u.crypt.lparamlen = 8,
.prng = &yarrow_prng,
.wprng = find_prng("yarrow"),
.params.hash_alg = "sha1",
.params.mgf1_hash_alg = "sha1",
.params.saltlen = 8,
};

if (ltc_mp.name == NULL) return;

for (x = 2048; x <= 8192; x <<= 1) {
t2 = 0;
rsa_params.padding = LTC_PKCS_1_OAEP;
for (y = 0; y < 4; y++) {
t_start();
t1 = t_read();
Expand Down Expand Up @@ -734,9 +749,7 @@ static void time_rsa(void)
t_start();
t1 = t_read();
z = sizeof(buf[1]);
if ((err = rsa_encrypt_key(buf[0], 32, buf[1], &z, (const unsigned char *)"testprog", 8, &yarrow_prng,
find_prng("yarrow"), find_hash("sha1"),
&key)) != CRYPT_OK) {
if ((err = rsa_encrypt_key_v2(buf[0], 32, buf[1], &z, &rsa_params, &key)) != CRYPT_OK) {
fprintf(stderr, "\n\nrsa_encrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
exit(EXIT_FAILURE);
}
Expand All @@ -755,8 +768,7 @@ static void time_rsa(void)
t_start();
t1 = t_read();
zzz = sizeof(buf[0]);
if ((err = rsa_decrypt_key(buf[1], z, buf[0], &zzz, (const unsigned char *)"testprog", 8, find_hash("sha1"),
&zz, &key)) != CRYPT_OK) {
if ((err = rsa_decrypt_key_v2(buf[1], z, buf[0], &zzz, &rsa_params, &zz, &key)) != CRYPT_OK) {
fprintf(stderr, "\n\nrsa_decrypt_key says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
exit(EXIT_FAILURE);
}
Expand All @@ -771,12 +783,12 @@ static void time_rsa(void)
fprintf(stderr, "RSA-%lu decrypt_key took %15"PRI64"u cycles\n", x, t2);

t2 = 0;
rsa_params.padding = LTC_PKCS_1_PSS;
for (y = 0; y < 256; y++) {
t_start();
t1 = t_read();
z = sizeof(buf[1]);
if ((err = rsa_sign_hash(buf[0], 20, buf[1], &z, &yarrow_prng,
find_prng("yarrow"), find_hash("sha1"), 8, &key)) != CRYPT_OK) {
if ((err = rsa_sign_hash_v2(buf[0], 20, buf[1], &z, &rsa_params, &key)) != CRYPT_OK) {
fprintf(stderr, "\n\nrsa_sign_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
exit(EXIT_FAILURE);
}
Expand All @@ -794,7 +806,7 @@ static void time_rsa(void)
for (y = 0; y < 2048; y++) {
t_start();
t1 = t_read();
if ((err = rsa_verify_hash(buf[1], z, buf[0], 20, find_hash("sha1"), 8, &stat, &key)) != CRYPT_OK) {
if ((err = rsa_verify_hash_v2(buf[1], z, buf[0], 20, &rsa_params, &stat, &key)) != CRYPT_OK) {
fprintf(stderr, "\n\nrsa_verify_hash says %s, wait...no it should say %s...damn you!\n", error_to_string(err), error_to_string(CRYPT_OK));
exit(EXIT_FAILURE);
}
Expand Down Expand Up @@ -1364,6 +1376,56 @@ static void time_encmacs(void)
time_encmacs_(32);
}

static void time_x509_import_spki(const char *pem)
{
const ltc_x509_certificate *cert;
FILE *f;
int err, y, n;
ltc_pka_key k[8] = {0};
ulong64 t1, t2;
f = fopen(pem, "r");
if ((err = x509_import_pem_filehandle(f, &cert)) != CRYPT_OK) {
fprintf(stderr, "\nx509_import_pem_filehandle() error... %s\n", error_to_string(err));
exit(EXIT_FAILURE);
}
if ((err = x509_import_spki(cert->asn1->data, cert->asn1->size, k, NULL)) != CRYPT_OK) {
fprintf(stderr, "\nx509_import_spki() error... %s\n", error_to_string(err));
exit(EXIT_FAILURE);
}
pka_key_free(k);
#define DO1 x509_import_spki(cert->asn1->data, cert->asn1->size, &k[n++], NULL);
#define DO2 DO1 DO1
#define DO4 DO2 DO2
#define DO8 DO4 DO4
t2 = -1;
for (y = 0; y < 1000; y++) {
n = 0;
t_start();
t1 = t_read();
DO8;
t1 = (t_read() - t1)>>1;
if (t1 < t2) t2 = t1;
for (n = LTC_ARRAY_SIZE(k); n --> 0;) {
pka_key_free(&k[n]);
}
}
fprintf(stderr, "x509 %-20s: %9"PRI64"u cycles\n", strrchr(pem, '/') + 1, t2/LTC_ARRAY_SIZE(k));
x509_free(&cert);
fclose(f);
}

static void time_x509(void)
{
time_x509_import_spki("tests/x509/gnutls/cert-rsa-pss.pem");
time_x509_import_spki("tests/x509/LTC_CA.pem");
time_x509_import_spki("tests/x509/LTC_S0.pem");
time_x509_import_spki("tests/x509/LTC_SS0.pem");
time_x509_import_spki("tests/x509/secp384r1.pem");
time_x509_import_spki("tests/x509/secp521r1.pem");
time_x509_import_spki("tests/x509/invalid/LTC_SSS0.pem");
time_x509_import_spki("tests/x509/invalid/secp224r1.pem");
}

static void LTC_NORETURN die(int status)
{
FILE* o = status == EXIT_SUCCESS ? stdout : stderr;
Expand Down Expand Up @@ -1403,6 +1465,7 @@ const struct
LTC_TEST_FN(dsa),
LTC_TEST_FN(ecc),
LTC_TEST_FN(dh),
LTC_TEST_FN(x509),
};
char *single_test = NULL;
unsigned int i;
Expand Down
166 changes: 166 additions & 0 deletions demos/x509_verify.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/* load a X.509 certificate chain and verify its validity */
#include <tomcrypt.h>
#include <stdarg.h>

#ifdef LTC_QUIET
static void print_err(const char *fmt, ...)
{
LTC_UNUSED_PARAM(fmt);
}

#define print_stderr(...)
#else
static void print_err(const char *fmt, ...)
{
va_list args;

va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
}

#define print_stderr(...) fprintf(stderr, ##__VA_ARGS__)
#endif

#if defined(LTC_TEST_DBG) && LTC_TEST_DBG > 1
#define LTC_DER_PRINT_FLEXI_NO_MAIN
#include "der_print_flexi.c"

static void s_der_print_flexi(const ltc_asn1_list* l)
{
print_stderr("\n\n");
s_der_print_flexi_i(l, 0);
print_stderr("\n\n");
}
#else
static void s_der_print_flexi(const ltc_asn1_list* l)
{
LTC_UNUSED_PARAM(l);
}
#endif

static unsigned long num_certs;
static const ltc_x509_certificate *cert[256] = {0};
static FILE *f;

static void die_(int err, int line)
{
unsigned long n;
print_err("%3d: LTC sez %s\n", line, error_to_string(err));
for (n = num_certs; n --> 0;) {
x509_free(&cert[n]);
}
if (f) fclose(f);
exit(EXIT_FAILURE);
}

#define die(i) do { die_(i, __LINE__); } while(0)
#define DIE(s, ...) do { print_err("%3d: " s "\n", __LINE__, ##__VA_ARGS__); exit(EXIT_FAILURE); } while(0)
#ifndef LTC_ARRAY_SIZE
#define LTC_ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
#endif

int main(int argc, char **argv)
{
const unsigned char zero_cert_buf[sizeof(cert)] = {0};
int err, argn = 1;
unsigned long len, processed, n;
long tell, tot_data = 0;

if ((err = register_all_hashes()) != CRYPT_OK) {
die(err);
}
if ((err = crypt_mp_init("ltm")) != CRYPT_OK) {
die(err);
}

next:
tot_data = processed = num_certs = n = 0;
if (argc > argn) f = fopen(argv[argn], "r");
else f = stdin;
if (f == NULL) DIE("fopen sez no");
if (f != stdin) {
fseek(f, 0, SEEK_END);
tot_data = ftell(f);
fseek(f, 0, SEEK_SET);
tell = 0;
} else {
tell = -1;
}

print_stderr("-=-=-=-=-=-=-\nDecode %s\n=-=-=-=-=-=-=\n", argv[argn]);

while (tell != tot_data) {
err = x509_import_pem_filehandle(f, &cert[n]);
if (err == CRYPT_PK_ASN1_ERROR || err == CRYPT_UNKNOWN_PEM)
continue;
else if (err != CRYPT_OK)
break;
if (cert[n] && cert[n]->asn1)
s_der_print_flexi(cert[n]->asn1);
if (f != stdin) {
tell = ftell(f);
print_stderr("%2lu len: %ld - tot: %ld - processed: %lu (%s)\n", n, tell, tot_data, processed, error_to_string(err));
len = tell - processed;
processed += len;
}
n++;
if (n == LTC_ARRAY_SIZE(cert))
break;
}
num_certs = n;
print_stderr("len: %ld - tot: %ld - processed: %lu (%s)\n", tell, tot_data, processed, error_to_string(err));
if (err && argc > argn) goto check_next;
if (err && err != CRYPT_NOP) die(err);
for (n = 0; n < num_certs; ++n) {
unsigned long m = n + 1 == num_certs ? n : n + 1;
int stat;
if ((err = x509_cert_is_signed_by(cert[n], &cert[m]->tbs_certificate.subject_public_key_info, &stat)) != CRYPT_OK) {
print_err("%3d: LTC sez %s\n", __LINE__, error_to_string(err));
if (m == n) {
print_stderr("Cert is last in chain, but not self-signed.\n");
} else {
break;
}
}
{
const ltc_x509_string *subjects[4];
const ltc_x509_name *subject, *issuer;
int issuer_matches_next_subject = x509_cmp_name(&cert[n]->tbs_certificate.issuer, &cert[m]->tbs_certificate.subject);
subject = &cert[n]->tbs_certificate.subject;
if (n != m) {
issuer = &cert[m]->tbs_certificate.subject;
} else {
issuer = &cert[m]->tbs_certificate.issuer;
}
x509_name_detail_get(subject, LTC_X509_CN, &subjects[0]);
x509_name_detail_get(subject, LTC_X509_O, &subjects[2]);
x509_name_detail_get(issuer, LTC_X509_CN, &subjects[1]);
x509_name_detail_get(issuer, LTC_X509_O, &subjects[3]);
#define X509_STRING_STR(s) (s) ? (s)->str : "NULL"
print_stderr("Cert: %s - %s\nCA: %s - %s\nIssuer matches next subject: %s\nVerify: %s\n",
X509_STRING_STR(subjects[0]), X509_STRING_STR(subjects[2]),
X509_STRING_STR(subjects[1]), X509_STRING_STR(subjects[3]),
issuer_matches_next_subject ? "True" : "False", stat ? "Success" : "Failed");
/* In case of LTC_QUIET this would show up as unused. */
LTC_UNUSED_PARAM(issuer_matches_next_subject);
}
}
check_next:
for (n = num_certs; n --> 0;) {
x509_free(&cert[n]);
}
if (XMEMCMP(cert, zero_cert_buf, sizeof(zero_cert_buf))) {
DIE("cert buf not completely cleaned");
}
if (f != stdin) {
fclose(f);
argn++;
if (argc > argn) {
goto next;
}
}
return 0;
}
Loading