[BACK]Return to verify.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / openssl

Annotation of src/usr.bin/openssl/verify.c, Revision 1.2

1.2     ! jsing       1: /* $OpenBSD: verify.c,v 1.1 2014/08/26 17:47:25 jsing Exp $ */
1.1       jsing       2: /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
                      3:  * All rights reserved.
                      4:  *
                      5:  * This package is an SSL implementation written
                      6:  * by Eric Young (eay@cryptsoft.com).
                      7:  * The implementation was written so as to conform with Netscapes SSL.
                      8:  *
                      9:  * This library is free for commercial and non-commercial use as long as
                     10:  * the following conditions are aheared to.  The following conditions
                     11:  * apply to all code found in this distribution, be it the RC4, RSA,
                     12:  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
                     13:  * included with this distribution is covered by the same copyright terms
                     14:  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
                     15:  *
                     16:  * Copyright remains Eric Young's, and as such any Copyright notices in
                     17:  * the code are not to be removed.
                     18:  * If this package is used in a product, Eric Young should be given attribution
                     19:  * as the author of the parts of the library used.
                     20:  * This can be in the form of a textual message at program startup or
                     21:  * in documentation (online or textual) provided with the package.
                     22:  *
                     23:  * Redistribution and use in source and binary forms, with or without
                     24:  * modification, are permitted provided that the following conditions
                     25:  * are met:
                     26:  * 1. Redistributions of source code must retain the copyright
                     27:  *    notice, this list of conditions and the following disclaimer.
                     28:  * 2. Redistributions in binary form must reproduce the above copyright
                     29:  *    notice, this list of conditions and the following disclaimer in the
                     30:  *    documentation and/or other materials provided with the distribution.
                     31:  * 3. All advertising materials mentioning features or use of this software
                     32:  *    must display the following acknowledgement:
                     33:  *    "This product includes cryptographic software written by
                     34:  *     Eric Young (eay@cryptsoft.com)"
                     35:  *    The word 'cryptographic' can be left out if the rouines from the library
                     36:  *    being used are not cryptographic related :-).
                     37:  * 4. If you include any Windows specific code (or a derivative thereof) from
                     38:  *    the apps directory (application code) you must include an acknowledgement:
                     39:  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
                     40:  *
                     41:  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
                     42:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     43:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     44:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                     45:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     46:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     47:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     48:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     49:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     50:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     51:  * SUCH DAMAGE.
                     52:  *
                     53:  * The licence and distribution terms for any publically available version or
                     54:  * derivative of this code cannot be changed.  i.e. this code cannot simply be
                     55:  * copied and put under another distribution licence
                     56:  * [including the GNU Public Licence.]
                     57:  */
                     58:
                     59: #include <stdio.h>
                     60: #include <stdlib.h>
                     61: #include <string.h>
                     62:
                     63: #include "apps.h"
                     64:
                     65: #include <openssl/bio.h>
                     66: #include <openssl/err.h>
                     67: #include <openssl/pem.h>
                     68: #include <openssl/x509.h>
                     69: #include <openssl/x509v3.h>
                     70:
                     71: static int cb(int ok, X509_STORE_CTX * ctx);
                     72: static int check(X509_STORE * ctx, char *file, STACK_OF(X509) * uchain,
                     73:     STACK_OF(X509) * tchain, STACK_OF(X509_CRL) * crls, ENGINE * e);
                     74: static int v_verbose = 0, vflags = 0;
                     75:
                     76: int verify_main(int, char **);
                     77:
                     78: int
                     79: verify_main(int argc, char **argv)
                     80: {
                     81:        ENGINE *e = NULL;
                     82:        int i, ret = 1, badarg = 0;
                     83:        char *CApath = NULL, *CAfile = NULL;
                     84:        char *untfile = NULL, *trustfile = NULL, *crlfile = NULL;
                     85:        STACK_OF(X509) * untrusted = NULL, *trusted = NULL;
                     86:        STACK_OF(X509_CRL) * crls = NULL;
                     87:        X509_STORE *cert_ctx = NULL;
                     88:        X509_LOOKUP *lookup = NULL;
                     89:        X509_VERIFY_PARAM *vpm = NULL;
                     90: #ifndef OPENSSL_NO_ENGINE
                     91:        char *engine = NULL;
                     92: #endif
                     93:
                     94:        cert_ctx = X509_STORE_new();
                     95:        if (cert_ctx == NULL)
                     96:                goto end;
                     97:        X509_STORE_set_verify_cb(cert_ctx, cb);
                     98:
                     99:        argc--;
                    100:        argv++;
                    101:        for (;;) {
                    102:                if (argc >= 1) {
                    103:                        if (strcmp(*argv, "-CApath") == 0) {
                    104:                                if (argc-- < 1)
                    105:                                        goto end;
                    106:                                CApath = *(++argv);
                    107:                        } else if (strcmp(*argv, "-CAfile") == 0) {
                    108:                                if (argc-- < 1)
                    109:                                        goto end;
                    110:                                CAfile = *(++argv);
                    111:                        } else if (args_verify(&argv, &argc, &badarg, bio_err,
                    112:                            &vpm)) {
                    113:                                if (badarg)
                    114:                                        goto end;
                    115:                                continue;
                    116:                        } else if (strcmp(*argv, "-untrusted") == 0) {
                    117:                                if (argc-- < 1)
                    118:                                        goto end;
                    119:                                untfile = *(++argv);
                    120:                        } else if (strcmp(*argv, "-trusted") == 0) {
                    121:                                if (argc-- < 1)
                    122:                                        goto end;
                    123:                                trustfile = *(++argv);
                    124:                        } else if (strcmp(*argv, "-CRLfile") == 0) {
                    125:                                if (argc-- < 1)
                    126:                                        goto end;
                    127:                                crlfile = *(++argv);
                    128:                        }
                    129: #ifndef OPENSSL_NO_ENGINE
                    130:                        else if (strcmp(*argv, "-engine") == 0) {
                    131:                                if (--argc < 1)
                    132:                                        goto end;
                    133:                                engine = *(++argv);
                    134:                        }
                    135: #endif
                    136:                        else if (strcmp(*argv, "-help") == 0)
                    137:                                goto end;
                    138:                        else if (strcmp(*argv, "-verbose") == 0)
                    139:                                v_verbose = 1;
                    140:                        else if (argv[0][0] == '-')
                    141:                                goto end;
                    142:                        else
                    143:                                break;
                    144:                        argc--;
                    145:                        argv++;
                    146:                } else
                    147:                        break;
                    148:        }
                    149:
                    150: #ifndef OPENSSL_NO_ENGINE
                    151:        e = setup_engine(bio_err, engine, 0);
                    152: #endif
                    153:
                    154:        if (vpm)
                    155:                X509_STORE_set1_param(cert_ctx, vpm);
                    156:
                    157:        lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
                    158:        if (lookup == NULL)
                    159:                abort();
                    160:        if (CAfile) {
                    161:                i = X509_LOOKUP_load_file(lookup, CAfile, X509_FILETYPE_PEM);
                    162:                if (!i) {
                    163:                        BIO_printf(bio_err, "Error loading file %s\n", CAfile);
                    164:                        ERR_print_errors(bio_err);
                    165:                        goto end;
                    166:                }
                    167:        } else
                    168:                X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT);
                    169:
                    170:        lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_hash_dir());
                    171:        if (lookup == NULL)
                    172:                abort();
                    173:        if (CApath) {
                    174:                i = X509_LOOKUP_add_dir(lookup, CApath, X509_FILETYPE_PEM);
                    175:                if (!i) {
                    176:                        BIO_printf(bio_err, "Error loading directory %s\n", CApath);
                    177:                        ERR_print_errors(bio_err);
                    178:                        goto end;
                    179:                }
                    180:        } else
                    181:                X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT);
                    182:
                    183:        ERR_clear_error();
                    184:
                    185:        if (untfile) {
                    186:                untrusted = load_certs(bio_err, untfile, FORMAT_PEM,
                    187:                    NULL, e, "untrusted certificates");
                    188:                if (!untrusted)
                    189:                        goto end;
                    190:        }
                    191:        if (trustfile) {
                    192:                trusted = load_certs(bio_err, trustfile, FORMAT_PEM,
                    193:                    NULL, e, "trusted certificates");
                    194:                if (!trusted)
                    195:                        goto end;
                    196:        }
                    197:        if (crlfile) {
                    198:                crls = load_crls(bio_err, crlfile, FORMAT_PEM,
                    199:                    NULL, e, "other CRLs");
                    200:                if (!crls)
                    201:                        goto end;
                    202:        }
                    203:        ret = 0;
                    204:        if (argc < 1) {
                    205:                if (1 != check(cert_ctx, NULL, untrusted, trusted, crls, e))
                    206:                        ret = -1;
                    207:        } else {
                    208:                for (i = 0; i < argc; i++)
                    209:                        if (1 != check(cert_ctx, argv[i], untrusted, trusted,
                    210:                            crls, e))
                    211:                                ret = -1;
                    212:        }
                    213:
                    214: end:
                    215:        if (ret == 1) {
                    216:                BIO_printf(bio_err, "usage: verify [-verbose] [-CApath path] [-CAfile file] [-purpose purpose] [-crl_check]");
                    217:                BIO_printf(bio_err, " [-attime timestamp]");
                    218: #ifndef OPENSSL_NO_ENGINE
                    219:                BIO_printf(bio_err, " [-engine e]");
                    220: #endif
                    221:                BIO_printf(bio_err, " cert1 cert2 ...\n");
                    222:
                    223:                BIO_printf(bio_err, "recognized usages:\n");
                    224:                for (i = 0; i < X509_PURPOSE_get_count(); i++) {
                    225:                        X509_PURPOSE *ptmp;
                    226:                        ptmp = X509_PURPOSE_get0(i);
                    227:                        BIO_printf(bio_err, "\t%-10s\t%s\n",
                    228:                            X509_PURPOSE_get0_sname(ptmp),
                    229:                            X509_PURPOSE_get0_name(ptmp));
                    230:                }
                    231:        }
                    232:        if (vpm)
                    233:                X509_VERIFY_PARAM_free(vpm);
                    234:        if (cert_ctx != NULL)
                    235:                X509_STORE_free(cert_ctx);
                    236:        sk_X509_pop_free(untrusted, X509_free);
                    237:        sk_X509_pop_free(trusted, X509_free);
                    238:        sk_X509_CRL_pop_free(crls, X509_CRL_free);
                    239:
                    240:        return (ret < 0 ? 2 : ret);
                    241: }
                    242:
                    243: static int
                    244: check(X509_STORE * ctx, char *file, STACK_OF(X509) * uchain,
                    245:     STACK_OF(X509) * tchain, STACK_OF(X509_CRL) * crls, ENGINE * e)
                    246: {
                    247:        X509 *x = NULL;
                    248:        int i = 0, ret = 0;
                    249:        X509_STORE_CTX *csc;
                    250:
                    251:        x = load_cert(bio_err, file, FORMAT_PEM, NULL, e, "certificate file");
                    252:        if (x == NULL)
                    253:                goto end;
                    254:        fprintf(stdout, "%s: ", (file == NULL) ? "stdin" : file);
                    255:
                    256:        csc = X509_STORE_CTX_new();
                    257:        if (csc == NULL) {
                    258:                ERR_print_errors(bio_err);
                    259:                goto end;
                    260:        }
                    261:        X509_STORE_set_flags(ctx, vflags);
                    262:        if (!X509_STORE_CTX_init(csc, ctx, x, uchain)) {
                    263:                ERR_print_errors(bio_err);
                    264:                goto end;
                    265:        }
                    266:        if (tchain)
                    267:                X509_STORE_CTX_trusted_stack(csc, tchain);
                    268:        if (crls)
                    269:                X509_STORE_CTX_set0_crls(csc, crls);
                    270:        i = X509_verify_cert(csc);
                    271:        X509_STORE_CTX_free(csc);
                    272:
                    273:        ret = 0;
                    274:
                    275: end:
                    276:        if (i > 0) {
                    277:                fprintf(stdout, "OK\n");
                    278:                ret = 1;
                    279:        } else
                    280:                ERR_print_errors(bio_err);
                    281:        if (x != NULL)
                    282:                X509_free(x);
                    283:
                    284:        return (ret);
                    285: }
                    286:
                    287: static int
                    288: cb(int ok, X509_STORE_CTX * ctx)
                    289: {
                    290:        int cert_error = X509_STORE_CTX_get_error(ctx);
                    291:        X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);
                    292:
                    293:        if (!ok) {
                    294:                if (current_cert) {
                    295:                        X509_NAME_print_ex_fp(stdout,
                    296:                            X509_get_subject_name(current_cert),
                    297:                            0, XN_FLAG_ONELINE);
                    298:                        printf("\n");
                    299:                }
                    300:                printf("%serror %d at %d depth lookup:%s\n",
                    301:                    X509_STORE_CTX_get0_parent_ctx(ctx) ? "[CRL path]" : "",
                    302:                    cert_error,
                    303:                    X509_STORE_CTX_get_error_depth(ctx),
                    304:                    X509_verify_cert_error_string(cert_error));
                    305:                switch (cert_error) {
                    306:                case X509_V_ERR_NO_EXPLICIT_POLICY:
                    307:                        policies_print(NULL, ctx);
                    308:                case X509_V_ERR_CERT_HAS_EXPIRED:
                    309:
                    310:                        /*
                    311:                         * since we are just checking the certificates, it is
                    312:                         * ok if they are self signed. But we should still
                    313:                         * warn the user.
                    314:                         */
                    315:
                    316:                case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
                    317:                        /* Continue after extension errors too */
                    318:                case X509_V_ERR_INVALID_CA:
                    319:                case X509_V_ERR_INVALID_NON_CA:
                    320:                case X509_V_ERR_PATH_LENGTH_EXCEEDED:
                    321:                case X509_V_ERR_INVALID_PURPOSE:
                    322:                case X509_V_ERR_CRL_HAS_EXPIRED:
                    323:                case X509_V_ERR_CRL_NOT_YET_VALID:
                    324:                case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
                    325:                        ok = 1;
                    326:
                    327:                }
                    328:
                    329:                return ok;
                    330:
                    331:        }
                    332:        if (cert_error == X509_V_OK && ok == 2)
                    333:                policies_print(NULL, ctx);
                    334:        if (!v_verbose)
                    335:                ERR_clear_error();
                    336:        return (ok);
                    337: }