source: rtems-libbsd/freebsd/crypto/openssl/apps/verify.c @ 0a699e7

5-freebsd-126-freebsd-12
Last change on this file since 0a699e7 was 0a699e7, checked in by Christian Mauderer <christian.mauderer@…>, on 03/28/19 at 06:13:59

bin/openssl: Import from FreeBSD.

  • Property mode set to 100644
File size: 10.6 KB
Line 
1#include <machine/rtems-bsd-user-space.h>
2
3/*
4 * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
5 *
6 * Licensed under the OpenSSL license (the "License").  You may not use
7 * this file except in compliance with the License.  You can obtain a copy
8 * in the file LICENSE in the source distribution or at
9 * https://www.openssl.org/source/license.html
10 */
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include "apps.h"
16#include "progs.h"
17#include <openssl/bio.h>
18#include <openssl/err.h>
19#include <openssl/x509.h>
20#include <openssl/x509v3.h>
21#include <openssl/pem.h>
22
23static int cb(int ok, X509_STORE_CTX *ctx);
24static int check(X509_STORE *ctx, const char *file,
25                 STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
26                 STACK_OF(X509_CRL) *crls, int show_chain);
27static int v_verbose = 0, vflags = 0;
28
29typedef enum OPTION_choice {
30    OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
31    OPT_ENGINE, OPT_CAPATH, OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE,
32    OPT_UNTRUSTED, OPT_TRUSTED, OPT_CRLFILE, OPT_CRL_DOWNLOAD, OPT_SHOW_CHAIN,
33    OPT_V_ENUM, OPT_NAMEOPT,
34    OPT_VERBOSE
35} OPTION_CHOICE;
36
37const OPTIONS verify_options[] = {
38    {OPT_HELP_STR, 1, '-', "Usage: %s [options] cert.pem...\n"},
39    {OPT_HELP_STR, 1, '-', "Valid options are:\n"},
40    {"help", OPT_HELP, '-', "Display this summary"},
41    {"verbose", OPT_VERBOSE, '-',
42        "Print extra information about the operations being performed."},
43    {"CApath", OPT_CAPATH, '/', "A directory of trusted certificates"},
44    {"CAfile", OPT_CAFILE, '<', "A file of trusted certificates"},
45    {"no-CAfile", OPT_NOCAFILE, '-',
46     "Do not load the default certificates file"},
47    {"no-CApath", OPT_NOCAPATH, '-',
48     "Do not load certificates from the default certificates directory"},
49    {"untrusted", OPT_UNTRUSTED, '<', "A file of untrusted certificates"},
50    {"trusted", OPT_TRUSTED, '<', "A file of trusted certificates"},
51    {"CRLfile", OPT_CRLFILE, '<',
52        "File containing one or more CRL's (in PEM format) to load"},
53    {"crl_download", OPT_CRL_DOWNLOAD, '-',
54        "Attempt to download CRL information for this certificate"},
55    {"show_chain", OPT_SHOW_CHAIN, '-',
56        "Display information about the certificate chain"},
57    {"nameopt", OPT_NAMEOPT, 's', "Various certificate name options"},
58    OPT_V_OPTIONS,
59#ifndef OPENSSL_NO_ENGINE
60    {"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
61#endif
62    {NULL}
63};
64
65int verify_main(int argc, char **argv)
66{
67    ENGINE *e = NULL;
68    STACK_OF(X509) *untrusted = NULL, *trusted = NULL;
69    STACK_OF(X509_CRL) *crls = NULL;
70    X509_STORE *store = NULL;
71    X509_VERIFY_PARAM *vpm = NULL;
72    const char *prog, *CApath = NULL, *CAfile = NULL;
73    int noCApath = 0, noCAfile = 0;
74    int vpmtouched = 0, crl_download = 0, show_chain = 0, i = 0, ret = 1;
75    OPTION_CHOICE o;
76
77    if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
78        goto end;
79
80    prog = opt_init(argc, argv, verify_options);
81    while ((o = opt_next()) != OPT_EOF) {
82        switch (o) {
83        case OPT_EOF:
84        case OPT_ERR:
85            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
86            goto end;
87        case OPT_HELP:
88            opt_help(verify_options);
89            BIO_printf(bio_err, "Recognized usages:\n");
90            for (i = 0; i < X509_PURPOSE_get_count(); i++) {
91                X509_PURPOSE *ptmp;
92                ptmp = X509_PURPOSE_get0(i);
93                BIO_printf(bio_err, "\t%-10s\t%s\n",
94                        X509_PURPOSE_get0_sname(ptmp),
95                        X509_PURPOSE_get0_name(ptmp));
96            }
97
98            BIO_printf(bio_err, "Recognized verify names:\n");
99            for (i = 0; i < X509_VERIFY_PARAM_get_count(); i++) {
100                const X509_VERIFY_PARAM *vptmp;
101                vptmp = X509_VERIFY_PARAM_get0(i);
102                BIO_printf(bio_err, "\t%-10s\n",
103                        X509_VERIFY_PARAM_get0_name(vptmp));
104            }
105            ret = 0;
106            goto end;
107        case OPT_V_CASES:
108            if (!opt_verify(o, vpm))
109                goto end;
110            vpmtouched++;
111            break;
112        case OPT_CAPATH:
113            CApath = opt_arg();
114            break;
115        case OPT_CAFILE:
116            CAfile = opt_arg();
117            break;
118        case OPT_NOCAPATH:
119            noCApath = 1;
120            break;
121        case OPT_NOCAFILE:
122            noCAfile = 1;
123            break;
124        case OPT_UNTRUSTED:
125            /* Zero or more times */
126            if (!load_certs(opt_arg(), &untrusted, FORMAT_PEM, NULL,
127                            "untrusted certificates"))
128                goto end;
129            break;
130        case OPT_TRUSTED:
131            /* Zero or more times */
132            noCAfile = 1;
133            noCApath = 1;
134            if (!load_certs(opt_arg(), &trusted, FORMAT_PEM, NULL,
135                            "trusted certificates"))
136                goto end;
137            break;
138        case OPT_CRLFILE:
139            /* Zero or more times */
140            if (!load_crls(opt_arg(), &crls, FORMAT_PEM, NULL,
141                           "other CRLs"))
142                goto end;
143            break;
144        case OPT_CRL_DOWNLOAD:
145            crl_download = 1;
146            break;
147        case OPT_ENGINE:
148            if ((e = setup_engine(opt_arg(), 0)) == NULL) {
149                /* Failure message already displayed */
150                goto end;
151            }
152            break;
153        case OPT_SHOW_CHAIN:
154            show_chain = 1;
155            break;
156        case OPT_NAMEOPT:
157            if (!set_nameopt(opt_arg()))
158                goto end;
159            break;
160        case OPT_VERBOSE:
161            v_verbose = 1;
162            break;
163        }
164    }
165    argc = opt_num_rest();
166    argv = opt_rest();
167    if (trusted != NULL && (CAfile || CApath)) {
168        BIO_printf(bio_err,
169                   "%s: Cannot use -trusted with -CAfile or -CApath\n",
170                   prog);
171        goto end;
172    }
173
174    if ((store = setup_verify(CAfile, CApath, noCAfile, noCApath)) == NULL)
175        goto end;
176    X509_STORE_set_verify_cb(store, cb);
177
178    if (vpmtouched)
179        X509_STORE_set1_param(store, vpm);
180
181    ERR_clear_error();
182
183    if (crl_download)
184        store_setup_crl_download(store);
185
186    ret = 0;
187    if (argc < 1) {
188        if (check(store, NULL, untrusted, trusted, crls, show_chain) != 1)
189            ret = -1;
190    } else {
191        for (i = 0; i < argc; i++)
192            if (check(store, argv[i], untrusted, trusted, crls,
193                      show_chain) != 1)
194                ret = -1;
195    }
196
197 end:
198    X509_VERIFY_PARAM_free(vpm);
199    X509_STORE_free(store);
200    sk_X509_pop_free(untrusted, X509_free);
201    sk_X509_pop_free(trusted, X509_free);
202    sk_X509_CRL_pop_free(crls, X509_CRL_free);
203    release_engine(e);
204    return (ret < 0 ? 2 : ret);
205}
206
207static int check(X509_STORE *ctx, const char *file,
208                 STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
209                 STACK_OF(X509_CRL) *crls, int show_chain)
210{
211    X509 *x = NULL;
212    int i = 0, ret = 0;
213    X509_STORE_CTX *csc;
214    STACK_OF(X509) *chain = NULL;
215    int num_untrusted;
216
217    x = load_cert(file, FORMAT_PEM, "certificate file");
218    if (x == NULL)
219        goto end;
220
221    csc = X509_STORE_CTX_new();
222    if (csc == NULL) {
223        printf("error %s: X.509 store context allocation failed\n",
224               (file == NULL) ? "stdin" : file);
225        goto end;
226    }
227
228    X509_STORE_set_flags(ctx, vflags);
229    if (!X509_STORE_CTX_init(csc, ctx, x, uchain)) {
230        X509_STORE_CTX_free(csc);
231        printf("error %s: X.509 store context initialization failed\n",
232               (file == NULL) ? "stdin" : file);
233        goto end;
234    }
235    if (tchain != NULL)
236        X509_STORE_CTX_set0_trusted_stack(csc, tchain);
237    if (crls != NULL)
238        X509_STORE_CTX_set0_crls(csc, crls);
239    i = X509_verify_cert(csc);
240    if (i > 0 && X509_STORE_CTX_get_error(csc) == X509_V_OK) {
241        printf("%s: OK\n", (file == NULL) ? "stdin" : file);
242        ret = 1;
243        if (show_chain) {
244            int j;
245
246            chain = X509_STORE_CTX_get1_chain(csc);
247            num_untrusted = X509_STORE_CTX_get_num_untrusted(csc);
248            printf("Chain:\n");
249            for (j = 0; j < sk_X509_num(chain); j++) {
250                X509 *cert = sk_X509_value(chain, j);
251                printf("depth=%d: ", j);
252                X509_NAME_print_ex_fp(stdout,
253                                      X509_get_subject_name(cert),
254                                      0, get_nameopt());
255                if (j < num_untrusted)
256                    printf(" (untrusted)");
257                printf("\n");
258            }
259            sk_X509_pop_free(chain, X509_free);
260        }
261    } else {
262        printf("error %s: verification failed\n", (file == NULL) ? "stdin" : file);
263    }
264    X509_STORE_CTX_free(csc);
265
266 end:
267    if (i <= 0)
268        ERR_print_errors(bio_err);
269    X509_free(x);
270
271    return ret;
272}
273
274static int cb(int ok, X509_STORE_CTX *ctx)
275{
276    int cert_error = X509_STORE_CTX_get_error(ctx);
277    X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);
278
279    if (!ok) {
280        if (current_cert != NULL) {
281            X509_NAME_print_ex(bio_err,
282                            X509_get_subject_name(current_cert),
283                            0, get_nameopt());
284            BIO_printf(bio_err, "\n");
285        }
286        BIO_printf(bio_err, "%serror %d at %d depth lookup: %s\n",
287               X509_STORE_CTX_get0_parent_ctx(ctx) ? "[CRL path] " : "",
288               cert_error,
289               X509_STORE_CTX_get_error_depth(ctx),
290               X509_verify_cert_error_string(cert_error));
291
292        /*
293         * Pretend that some errors are ok, so they don't stop further
294         * processing of the certificate chain.  Setting ok = 1 does this.
295         * After X509_verify_cert() is done, we verify that there were
296         * no actual errors, even if the returned value was positive.
297         */
298        switch (cert_error) {
299        case X509_V_ERR_NO_EXPLICIT_POLICY:
300            policies_print(ctx);
301            /* fall thru */
302        case X509_V_ERR_CERT_HAS_EXPIRED:
303            /* Continue even if the leaf is a self signed cert */
304        case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
305            /* Continue after extension errors too */
306        case X509_V_ERR_INVALID_CA:
307        case X509_V_ERR_INVALID_NON_CA:
308        case X509_V_ERR_PATH_LENGTH_EXCEEDED:
309        case X509_V_ERR_INVALID_PURPOSE:
310        case X509_V_ERR_CRL_HAS_EXPIRED:
311        case X509_V_ERR_CRL_NOT_YET_VALID:
312        case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION:
313            ok = 1;
314        }
315
316        return ok;
317
318    }
319    if (cert_error == X509_V_OK && ok == 2)
320        policies_print(ctx);
321    if (!v_verbose)
322        ERR_clear_error();
323    return ok;
324}
Note: See TracBrowser for help on using the repository browser.