From e9c5e1708139d62865db1c468b2a9fc8339b2f26 Mon Sep 17 00:00:00 2001 From: james Date: Sat, 15 Oct 2005 07:21:39 +0000 Subject: Merged --capath patch (Thomas Noel). svn merge -r 616:617 $SO/patches/2.0.x-r599-capath/openvpn Pre-2.1_beta3 git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@621 e7ae566f-a301-0410-adde-c780ea21d3b5 --- ChangeLog | 1 + options.c | 23 +++++++++++++++++++++-- options.h | 1 + ssl.c | 28 ++++++++++++++++++++++++---- 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index aa03feb..5bbdca1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -10,6 +10,7 @@ $Id$ used at the same time as --pkcs12, the CA certificate is loaded from the file specified by --ca regardless if the pkcs12 file contains a CA cert or not (Mathias Sundman). +* Merged --capath patch (Thomas Noel). * NOTE TO PACKAGE MAINTAINERS: Moved "plugin" directory to "plugins". This is to work around a strange problem with the diff --git a/options.c b/options.c index fa911b6..0895674 100644 --- a/options.c +++ b/options.c @@ -398,6 +398,13 @@ static const char usage_message[] = " number, such as 1 (default), 2, etc.\n" "--ca file : Certificate authority file in .pem format containing\n" " root certificate.\n" + "--capath dir : A directory of trusted certificates (CAs" +#if OPENSSL_VERSION_NUMBER >= 0x00907000L + " and CRLs).\n" +#else + ").\n" + " WARNING: no support of CRL available with this version.\n" +#endif "--dh file : File containing Diffie Hellman parameters\n" " in .pem format (for --tls-server only).\n" " Use \"openssl dhparam -out dh1024.pem 1024\" to generate.\n" @@ -1139,6 +1146,7 @@ show_settings (const struct options *o) SHOW_BOOL (tls_client); SHOW_INT (key_method); SHOW_STR (ca_file); + SHOW_STR (ca_path); SHOW_STR (dh_file); SHOW_STR (cert_file); SHOW_STR (priv_key_file); @@ -1671,7 +1679,8 @@ options_postprocess (struct options *options, bool first_time) #ifdef WIN32 if (options->cryptoapi_cert) { - notnull (options->ca_file, "CA file (--ca)"); + if ((!(options->ca_file)) && (!(options->ca_path))) + msg(M_USAGE, "You must define CA file (--ca) or CA path (--capath)"); if (options->cert_file) msg(M_USAGE, "Parameter --cert cannot be used when --cryptoapicert is also specified."); if (options->priv_key_file) @@ -1683,6 +1692,8 @@ options_postprocess (struct options *options, bool first_time) #endif if (options->pkcs12_file) { + if (options->ca_path) + msg(M_USAGE, "Parameter --capath cannot be used when --pkcs12 is also specified."); if (options->cert_file) msg(M_USAGE, "Parameter --cert cannot be used when --pkcs12 is also specified."); if (options->priv_key_file) @@ -1690,7 +1701,8 @@ options_postprocess (struct options *options, bool first_time) } else { - notnull (options->ca_file, "CA file (--ca) or PKCS#12 file (--pkcs12)"); + if ((!(options->ca_file)) && (!(options->ca_path))) + msg(M_USAGE, "You must define CA file (--ca) or CA path (--capath)"); if (pull) { const int sum = (options->cert_file != NULL) + (options->priv_key_file != NULL); @@ -1727,6 +1739,7 @@ options_postprocess (struct options *options, bool first_time) const char err[] = "Parameter %s can only be specified in TLS-mode, i.e. where --tls-server or --tls-client is also specified."; MUST_BE_UNDEF (ca_file); + MUST_BE_UNDEF (ca_path); MUST_BE_UNDEF (dh_file); MUST_BE_UNDEF (cert_file); MUST_BE_UNDEF (priv_key_file); @@ -4646,6 +4659,12 @@ add_option (struct options *options, VERIFY_PERMISSION (OPT_P_GENERAL); options->ca_file = p[1]; } + else if (streq (p[0], "capath") && p[1]) + { + ++i; + VERIFY_PERMISSION (OPT_P_GENERAL); + options->ca_path = p[1]; + } else if (streq (p[0], "dh") && p[1]) { ++i; diff --git a/options.h b/options.h index 3df6ecb..bb41759 100644 --- a/options.h +++ b/options.h @@ -368,6 +368,7 @@ struct options bool tls_server; bool tls_client; const char *ca_file; + const char *ca_path; const char *dh_file; const char *cert_file; const char *priv_key_file; diff --git a/ssl.c b/ssl.c index 17b418b..60516a8 100644 --- a/ssl.c +++ b/ssl.c @@ -914,12 +914,32 @@ init_ssl (const struct options *options) if (options->ca_file) { /* Load CA file for verifying peer supplied certificate */ - ASSERT (options->ca_file); - if (!SSL_CTX_load_verify_locations (ctx, options->ca_file, NULL)) - msg (M_SSLERR, "Cannot load CA certificate file %s (SSL_CTX_load_verify_locations)", options->ca_file); + ASSERT (options->ca_file || options->ca_path); + if (!SSL_CTX_load_verify_locations (ctx, options->ca_file, options->ca_path)) + msg (M_SSLERR, "Cannot load CA certificate file %s path %s (SSL_CTX_load_verify_locations)", options->ca_file, options->ca_path); + + /* Set a store for certs (CA & CRL) with a lookup on the "capath" hash directory */ + if (options->ca_path) { + X509_STORE *store = SSL_CTX_get_cert_store(ctx); + + if (store) { + X509_LOOKUP *lookup = X509_STORE_add_lookup(store, X509_LOOKUP_hash_dir()); + if (!X509_LOOKUP_add_dir(lookup, options->ca_path, X509_FILETYPE_PEM)) + X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); + else + msg(M_WARN, "WARNING: experimental option --capath %s", options->ca_path); +#if OPENSSL_VERSION_NUMBER >= 0x00907000L + X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); +#else +#warn This version of OpenSSL cannot handle CRL files in capath + msg(M_WARN, "WARNING: this version of OpenSSL cannot handle CRL files in capath"); +#endif + } else + msg(M_SSLERR, "Cannot get certificate store (SSL_CTX_get_cert_store)"); + } /* Load names of CAs from file and use it as a client CA list */ - { + if (options->ca_file) { STACK_OF(X509_NAME) *cert_names; cert_names = SSL_load_client_CA_file (options->ca_file); if (!cert_names) -- cgit