From: Tobias Brunner Date: Mon, 12 Feb 2018 10:48:16 +0000 (+0100) Subject: pki: --verify command optionally takes directories for CAs and CRLs X-Git-Tag: 5.6.3dr2~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=943f3929f4cd5979a9ac94c59216389feb37b759;p=thirdparty%2Fstrongswan.git pki: --verify command optionally takes directories for CAs and CRLs --- diff --git a/src/pki/commands/verify.c b/src/pki/commands/verify.c index dd667fb34c..88ef448b52 100644 --- a/src/pki/commands/verify.c +++ b/src/pki/commands/verify.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Tobias Brunner + * Copyright (C) 2016-2018 Tobias Brunner * Copyright (C) 2009 Martin Willi * HSR Hochschule fuer Technik Rapperswil * @@ -14,6 +14,9 @@ * for more details. */ +#include +#include +#include #include #include "pki.h" @@ -22,6 +25,84 @@ #include #include +/** + * Load a CA or CRL and add it to the credential set + */ +static bool load_cert(mem_cred_t *creds, char *path, certificate_type_t subtype) +{ + certificate_t *cert; + char *credname; + + switch (subtype) + { + case CERT_X509: + credname = "CA certificate"; + break; + case CERT_X509_CRL: + credname = "CRL"; + break; + default: + return FALSE; + } + cert = lib->creds->create(lib->creds, + CRED_CERTIFICATE, subtype, + BUILD_FROM_FILE, path, BUILD_END); + if (!cert) + { + fprintf(stderr, "parsing %s from '%s' failed\n", credname, path); + return FALSE; + } + if (subtype == CERT_X509_CRL) + { + creds->add_crl(creds, (crl_t*)cert); + } + else + { + creds->add_cert(creds, TRUE, cert); + } + return TRUE; +} + +/** + * Load CA cert or CRL either from a file or a path + */ +static bool load_certs(mem_cred_t *creds, char *path, + certificate_type_t subtype) +{ + enumerator_t *enumerator; + struct stat st; + bool loaded = FALSE; + + if (stat(path, &st)) + { + fprintf(stderr, "failed to access '%s': %s\n", path, strerror(errno)); + return FALSE; + } + if (S_ISDIR(st.st_mode)) + { + enumerator = enumerator_create_directory(path); + if (!enumerator) + { + fprintf(stderr, "directory '%s' can not be opened: %s", + path, strerror(errno)); + return FALSE; + } + while (enumerator->enumerate(enumerator, NULL, &path, &st)) + { + if (S_ISREG(st.st_mode) && load_cert(creds, path, subtype)) + { + loaded = TRUE; + } + } + enumerator->destroy(enumerator); + } + else + { + loaded = load_cert(creds, path, subtype); + } + return loaded; +} + /** * Verify a certificate signature */ @@ -49,28 +130,16 @@ static int verify() file = arg; continue; case 'c': - cert = lib->creds->create(lib->creds, - CRED_CERTIFICATE, CERT_X509, - BUILD_FROM_FILE, arg, BUILD_END); - if (!cert) + if (load_certs(creds, arg, CERT_X509)) { - fprintf(stderr, "parsing CA certificate failed\n"); - goto end; + has_ca = TRUE; } - has_ca = TRUE; - creds->add_cert(creds, TRUE, cert); continue; case 'l': - cert = lib->creds->create(lib->creds, - CRED_CERTIFICATE, CERT_X509_CRL, - BUILD_FROM_FILE, arg, BUILD_END); - if (!cert) + if (load_certs(creds, arg, CERT_X509_CRL)) { - fprintf(stderr, "parsing CRL failed\n"); - goto end; + online = TRUE; } - online = TRUE; - creds->add_crl(creds, (crl_t*)cert); continue; case 'o': online = TRUE; @@ -108,7 +177,7 @@ static int verify() fprintf(stderr, "parsing certificate failed\n"); goto end; } - creds->add_cert(creds, !has_ca, cert); + cert = creds->add_cert_ref(creds, !has_ca, cert); enumerator = lib->credmgr->create_trusted_enumerator(lib->credmgr, KEY_ANY, cert->get_subject(cert), online); @@ -153,6 +222,7 @@ static int verify() printf("\n"); } enumerator->destroy(enumerator); + cert->destroy(cert); if (!trusted) { diff --git a/src/pki/man/pki---verify.1.in b/src/pki/man/pki---verify.1.in index 74adaf150e..a655858a1b 100644 --- a/src/pki/man/pki---verify.1.in +++ b/src/pki/man/pki---verify.1.in @@ -47,10 +47,13 @@ X.509 certificate to verify. If not given it is read from \fISTDIN\fR. .TP .BI "\-c, \-\-cacert " file CA certificate to use for trustchain verification. If not given the certificate -is assumed to be self\-signed. +is assumed to be self\-signed. May optionally be a path to a directory from +which CA certificates are loaded. Can be used multiple times. .TP .BI "\-l, \-\-crl " file -Local CRL to use for trustchain verification. Implies \fB-o\fR. +Local CRL to use for trustchain verification. May optionally be a path to a +directory from which CRLs are loaded. Can be used multiple times. +Implies \fB-o\fR. .TP .BI "\-o, \-\-online Enable online CRL/OCSP revocation checking.