ca.c revision 1.3
1/* $OpenBSD: ca.c,v 1.3 2013/11/21 08:36:51 eric Exp $ */ 2 3/* 4 * Copyright (c) 2012 Gilles Chehade <gilles@poolp.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19#include <sys/types.h> 20 21#include <openssl/err.h> 22#include <openssl/ssl.h> 23 24#include "log.h" 25 26int ca_X509_verify(X509 *, STACK_OF(X509) *, const char *, const char *, const char **); 27 28static int 29verify_cb(int ok, X509_STORE_CTX *ctx) 30{ 31 switch (X509_STORE_CTX_get_error(ctx)) { 32 case X509_V_OK: 33 break; 34 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: 35 log_warnx("warn: unable to get issuer cert"); 36 break; 37 case X509_V_ERR_CERT_NOT_YET_VALID: 38 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: 39 log_warnx("warn: certificate not yet valid"); 40 break; 41 case X509_V_ERR_CERT_HAS_EXPIRED: 42 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: 43 log_warnx("warn: certificate has expired"); 44 break; 45 case X509_V_ERR_NO_EXPLICIT_POLICY: 46 log_warnx("warn: no explicit policy"); 47 break; 48 } 49 return ok; 50} 51 52int 53ca_X509_verify(X509 *certificate, STACK_OF(X509) *chain, const char *CAfile, 54 const char *CRLfile, const char **errstr) 55{ 56 X509_STORE *store = NULL; 57 X509_STORE_CTX *xsc = NULL; 58 int ret = 0; 59 60 if ((store = X509_STORE_new()) == NULL) 61 goto end; 62 63 if (! X509_STORE_load_locations(store, CAfile, NULL)) { 64 log_warn("warn: unable to load CA file %s", CAfile); 65 goto end; 66 } 67 X509_STORE_set_default_paths(store); 68 69 if ((xsc = X509_STORE_CTX_new()) == NULL) 70 goto end; 71 72 if (X509_STORE_CTX_init(xsc, store, certificate, chain) != 1) 73 goto end; 74 75 X509_STORE_CTX_set_verify_cb(xsc, verify_cb); 76 77 ret = X509_verify_cert(xsc); 78 79end: 80 *errstr = NULL; 81 if (ret != 1) { 82 if (xsc) 83 *errstr = X509_verify_cert_error_string(xsc->error); 84 else if (ERR_peek_last_error()) 85 *errstr = ERR_error_string(ERR_peek_last_error(), NULL); 86 } 87 88 if (xsc) 89 X509_STORE_CTX_free(xsc); 90 if (store) 91 X509_STORE_free(store); 92 93 return ret > 0 ? 1 : 0; 94} 95