Annotation of embedaddon/strongswan/src/pki/commands/verify.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:  * Copyright (C) 2016-2018 Tobias Brunner
                      3:  * Copyright (C) 2009 Martin Willi
                      4:  * HSR Hochschule fuer Technik Rapperswil
                      5:  *
                      6:  * This program is free software; you can redistribute it and/or modify it
                      7:  * under the terms of the GNU General Public License as published by the
                      8:  * Free Software Foundation; either version 2 of the License, or (at your
                      9:  * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
                     10:  *
                     11:  * This program is distributed in the hope that it will be useful, but
                     12:  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     13:  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
                     14:  * for more details.
                     15:  */
                     16: 
                     17: #include <sys/types.h>
                     18: #include <sys/stat.h>
                     19: #include <unistd.h>
                     20: #include <errno.h>
                     21: 
                     22: #include "pki.h"
                     23: 
                     24: #include <credentials/certificates/certificate.h>
                     25: #include <credentials/certificates/x509.h>
                     26: #include <credentials/sets/mem_cred.h>
                     27: 
                     28: /**
                     29:  * Load a CA or CRL and add it to the credential set
                     30:  */
                     31: static bool load_cert(mem_cred_t *creds, char *path, certificate_type_t subtype)
                     32: {
                     33:        certificate_t *cert;
                     34:        char *credname;
                     35: 
                     36:        switch (subtype)
                     37:        {
                     38:                case CERT_X509:
                     39:                        credname = "CA certificate";
                     40:                        break;
                     41:                case CERT_X509_CRL:
                     42:                        credname = "CRL";
                     43:                        break;
                     44:                default:
                     45:                        return FALSE;
                     46:        }
                     47:        cert = lib->creds->create(lib->creds,
                     48:                                                          CRED_CERTIFICATE, subtype,
                     49:                                                          BUILD_FROM_FILE, path, BUILD_END);
                     50:        if (!cert)
                     51:        {
                     52:                fprintf(stderr, "parsing %s from '%s' failed\n", credname, path);
                     53:                return FALSE;
                     54:        }
                     55:        if (subtype == CERT_X509_CRL)
                     56:        {
                     57:                creds->add_crl(creds, (crl_t*)cert);
                     58:        }
                     59:        else
                     60:        {
                     61:                creds->add_cert(creds, TRUE, cert);
                     62:        }
                     63:        return TRUE;
                     64: }
                     65: 
                     66: /**
                     67:  * Load CA cert or CRL either from a file or a path
                     68:  */
                     69: static bool load_certs(mem_cred_t *creds, char *path,
                     70:                                           certificate_type_t subtype)
                     71: {
                     72:        enumerator_t *enumerator;
                     73:        struct stat st;
                     74:        bool loaded = FALSE;
                     75: 
                     76:        if (stat(path, &st))
                     77:        {
                     78:                fprintf(stderr, "failed to access '%s': %s\n", path, strerror(errno));
                     79:                return FALSE;
                     80:        }
                     81:        if (S_ISDIR(st.st_mode))
                     82:        {
                     83:                enumerator = enumerator_create_directory(path);
                     84:                if (!enumerator)
                     85:                {
                     86:                        fprintf(stderr, "directory '%s' can not be opened: %s",
                     87:                                        path, strerror(errno));
                     88:                        return FALSE;
                     89:                }
                     90:                while (enumerator->enumerate(enumerator, NULL, &path, &st))
                     91:                {
                     92:                        if (S_ISREG(st.st_mode) && load_cert(creds, path, subtype))
                     93:                        {
                     94:                                loaded = TRUE;
                     95:                        }
                     96:                }
                     97:                enumerator->destroy(enumerator);
                     98:        }
                     99:        else
                    100:        {
                    101:                loaded = load_cert(creds, path, subtype);
                    102:        }
                    103:        return loaded;
                    104: }
                    105: 
                    106: /**
                    107:  * Verify a certificate signature
                    108:  */
                    109: static int verify()
                    110: {
                    111:        bool trusted = FALSE, valid = FALSE, revoked = FALSE;
                    112:        bool has_ca = FALSE, online = FALSE;
                    113:        certificate_t *cert;
                    114:        enumerator_t *enumerator;
                    115:        auth_cfg_t *auth;
                    116:        mem_cred_t *creds;
                    117:        char *arg, *file = NULL;
                    118: 
                    119:        creds = mem_cred_create();
                    120:        lib->credmgr->add_set(lib->credmgr, &creds->set);
                    121: 
                    122:        while (TRUE)
                    123:        {
                    124:                switch (command_getopt(&arg))
                    125:                {
                    126:                        case 'h':
                    127:                                creds->destroy(creds);
                    128:                                return command_usage(NULL);
                    129:                        case 'i':
                    130:                                file = arg;
                    131:                                continue;
                    132:                        case 'c':
                    133:                                if (load_certs(creds, arg, CERT_X509))
                    134:                                {
                    135:                                        has_ca = TRUE;
                    136:                                }
                    137:                                continue;
                    138:                        case 'l':
                    139:                                if (load_certs(creds, arg, CERT_X509_CRL))
                    140:                                {
                    141:                                        online = TRUE;
                    142:                                }
                    143:                                continue;
                    144:                        case 'o':
                    145:                                online = TRUE;
                    146:                                continue;
                    147:                        case EOF:
                    148:                                break;
                    149:                        default:
                    150:                                creds->destroy(creds);
                    151:                                return command_usage("invalid --verify option");
                    152:                }
                    153:                break;
                    154:        }
                    155: 
                    156:        if (file)
                    157:        {
                    158:                cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
                    159:                                                                  BUILD_FROM_FILE, file, BUILD_END);
                    160:        }
                    161:        else
                    162:        {
                    163:                chunk_t chunk;
                    164: 
                    165:                set_file_mode(stdin, CERT_ASN1_DER);
                    166:                if (!chunk_from_fd(0, &chunk))
                    167:                {
                    168:                        fprintf(stderr, "reading certificate failed: %s\n", strerror(errno));
                    169:                        goto end;
                    170:                }
                    171:                cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509,
                    172:                                                                  BUILD_BLOB, chunk, BUILD_END);
                    173:                free(chunk.ptr);
                    174:        }
                    175:        if (!cert)
                    176:        {
                    177:                fprintf(stderr, "parsing certificate failed\n");
                    178:                goto end;
                    179:        }
                    180:        cert = creds->add_cert_ref(creds, !has_ca, cert);
                    181: 
                    182:        enumerator = lib->credmgr->create_trusted_enumerator(lib->credmgr,
                    183:                                                                        KEY_ANY, cert->get_subject(cert), online);
                    184:        if (enumerator->enumerate(enumerator, &cert, &auth))
                    185:        {
                    186:                trusted = TRUE;
                    187:                if (cert->get_validity(cert, NULL, NULL, NULL))
                    188:                {
                    189:                        printf("certificate trusted, lifetimes valid");
                    190:                        valid = TRUE;
                    191:                }
                    192:                else
                    193:                {
                    194:                        printf("certificate trusted, but no valid lifetime");
                    195:                }
                    196:                if (online)
                    197:                {
                    198:                        switch ((uintptr_t)auth->get(auth, AUTH_RULE_CRL_VALIDATION))
                    199:                        {
                    200:                                case VALIDATION_GOOD:
                    201:                                        printf(", certificate not revoked");
                    202:                                        break;
                    203:                                case VALIDATION_SKIPPED:
                    204:                                        printf(", no revocation information");
                    205:                                        break;
                    206:                                case VALIDATION_STALE:
                    207:                                        printf(", revocation information stale");
                    208:                                        break;
                    209:                                case VALIDATION_FAILED:
                    210:                                        printf(", revocation checking failed");
                    211:                                        break;
                    212:                                case VALIDATION_ON_HOLD:
                    213:                                        printf(", certificate revocation on hold");
                    214:                                        revoked = TRUE;
                    215:                                        break;
                    216:                                case VALIDATION_REVOKED:
                    217:                                        printf(", certificate revoked");
                    218:                                        revoked = TRUE;
                    219:                                        break;
                    220:                        }
                    221:                }
                    222:                printf("\n");
                    223:        }
                    224:        enumerator->destroy(enumerator);
                    225:        cert->destroy(cert);
                    226: 
                    227:        if (!trusted)
                    228:        {
                    229:                printf("certificate untrusted\n");
                    230:        }
                    231: 
                    232: end:
                    233:        lib->credmgr->remove_set(lib->credmgr, &creds->set);
                    234:        creds->destroy(creds);
                    235: 
                    236:        if (!trusted)
                    237:        {
                    238:                return 1;
                    239:        }
                    240:        if (!valid)
                    241:        {
                    242:                return 2;
                    243:        }
                    244:        if (revoked)
                    245:        {
                    246:                return 3;
                    247:        }
                    248:        return 0;
                    249: }
                    250: 
                    251: /**
                    252:  * Register the command.
                    253:  */
                    254: static void __attribute__ ((constructor))reg()
                    255: {
                    256:        command_register((command_t) {
                    257:                verify, 'v', "verify",
                    258:                "verify a certificate using the CA certificate",
                    259:                {"[--in file] [--cacert file] [--crl file]"},
                    260:                {
                    261:                        {"help",        'h', 0, "show usage information"},
                    262:                        {"in",          'i', 1, "X.509 certificate to verify, default: stdin"},
                    263:                        {"cacert",      'c', 1, "CA certificate for trustchain verification"},
                    264:                        {"crl",         'l', 1, "CRL for trustchain verification"},
                    265:                        {"online",      'o', 0, "enable online CRL/OCSP revocation checking"},
                    266:                }
                    267:        });
                    268: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>