0
0
mirror of https://github.com/OpenVPN/openvpn.git synced 2024-09-20 12:02:28 +02:00

Added new "extra-certs" and "verify-hash" options (see man page for

details).

Increase the timeout after SIGUSR1 restart when restart is not
due to server_poll_timeout.

Version 2.1.3v


git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@7215 e7ae566f-a301-0410-adde-c780ea21d3b5
This commit is contained in:
James Yonan 2011-04-25 04:58:34 +00:00 committed by David Sommerseth
parent d5497262ae
commit 7966d75a9d
7 changed files with 128 additions and 1 deletions

3
init.c
View File

@ -1706,8 +1706,10 @@ socket_restart_pause (struct context *c)
if (auth_retry_get () == AR_NOINTERACT)
sec = 10;
#if 0 /* not really needed because of c->persist.restart_sleep_seconds */
if (c->options.server_poll_timeout && sec > 1)
sec = 1;
#endif
#endif
if (c->persist.restart_sleep_seconds > 0 && c->persist.restart_sleep_seconds > sec)
@ -2057,6 +2059,7 @@ do_init_crypto_tls (struct context *c, const unsigned int flags)
to.ns_cert_type = options->ns_cert_type;
memmove (to.remote_cert_ku, options->remote_cert_ku, sizeof (to.remote_cert_ku));
to.remote_cert_eku = options->remote_cert_eku;
to.verify_hash = options->verify_hash;
to.es = c->c2.es;
#ifdef ENABLE_DEBUG

View File

@ -3887,6 +3887,22 @@ that for certificate authority functions, you must set up the files
).
.\"*********************************************************
.TP
.B --extra-certs file
Specify a
.B file
containing one or more PEM certs (concatenated together)
that complete the
local certificate chain.
This option is useful for "split" CAs, where the CA for server
certs is different than the CA for client certs. Putting certs
in this file allows them to be used to complete the local
certificate chain without trusting them to verify the peer-submitted
certificate, as would be the case if the certs were placed in the
.B ca
file.
.\"*********************************************************
.TP
.B --key file
Local peer's private key in .pem format. Use the private key which was generated
when you built your peer's certificate (see
@ -3903,6 +3919,17 @@ and
.B --key.
.\"*********************************************************
.TP
.B --verify-hash hash
Specify SHA1 fingerprint for level-1 cert. The level-1 cert is the
CA (or intermediate cert) that signs the leaf certificate, and is
one removed from the leaf certificate in the direction of the root.
When accepting a connection from a peer, the level-1 cert
fingerprint must match
.B hash
or certificate verification will fail. Hash is specified
as XX:XX:... For example: AD:B0:95:D8:09:C8:36:45:12:A9:89:C8:90:09:CB:13:72:A6:AD:16
.\"*********************************************************
.TP
.B --pkcs11-cert-private [0|1]...
Set if access to certificate object should be performed after login.
Every provider has its own setting.

View File

@ -507,9 +507,11 @@ static const char usage_message[] =
" Use \"openssl dhparam -out dh1024.pem 1024\" to generate.\n"
"--cert file : Local certificate in .pem format -- must be signed\n"
" by a Certificate Authority in --ca file.\n"
"--extra-certs file : one or more PEM certs that complete the cert chain.\n"
"--key file : Local private key in .pem format.\n"
"--pkcs12 file : PKCS#12 file containing local private key, local certificate\n"
" and optionally the root CA certificate.\n"
"--verify-hash : Specify SHA1 fingerprint for level-1 cert.\n"
#ifdef WIN32
"--cryptoapicert select-string : Load the certificate and private key from the\n"
" Windows Certificate System Store.\n"
@ -894,6 +896,40 @@ is_stateful_restart (const struct options *o)
return is_persist_option (o) || connection_list_defined (o);
}
#ifdef USE_SSL
static uint8_t *
parse_hash_fingerprint(const char *str, int nbytes, int msglevel, struct gc_arena *gc)
{
int i;
const char *cp = str;
uint8_t *ret = (uint8_t *) gc_malloc (nbytes, true, gc);
char term = 1;
int byte;
char bs[3];
for (i = 0; i < nbytes; ++i)
{
if (strlen(cp) < 2)
msg (msglevel, "format error in hash fingerprint: %s", str);
bs[0] = *cp++;
bs[1] = *cp++;
bs[2] = 0;
byte = 0;
if (sscanf(bs, "%x", &byte) != 1)
msg (msglevel, "format error in hash fingerprint hex byte: %s", str);
ret[i] = (uint8_t)byte;
term = *cp++;
if (term != ':' && term != 0)
msg (msglevel, "format error in hash fingerprint delimiter: %s", str);
if (term == 0)
break;
}
if (term != 0 || i != nbytes-1)
msg (msglevel, "hash fingerprint is different length than expected (%d bytes): %s", nbytes, str);
return ret;
}
#endif
#ifdef WIN32
#ifdef ENABLE_DEBUG
@ -5758,6 +5794,22 @@ add_option (struct options *options,
}
#endif
}
else if (streq (p[0], "extra-certs") && p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->extra_certs_file = p[1];
#if ENABLE_INLINE_FILES
if (streq (p[1], INLINE_FILE_TAG) && p[2])
{
options->extra_certs_file_inline = p[2];
}
#endif
}
else if (streq (p[0], "verify-hash") && p[1])
{
VERIFY_PERMISSION (OPT_P_GENERAL);
options->verify_hash = parse_hash_fingerprint(p[1], SHA_DIGEST_LENGTH, msglevel, &options->gc);
}
#ifdef WIN32
else if (streq (p[0], "cryptoapicert") && p[1])
{

View File

@ -477,6 +477,7 @@ struct options
const char *ca_path;
const char *dh_file;
const char *cert_file;
const char *extra_certs_file;
const char *priv_key_file;
const char *pkcs12_file;
const char *cipher_list;
@ -487,6 +488,7 @@ struct options
#if ENABLE_INLINE_FILES
const char *ca_file_inline;
const char *cert_file_inline;
const char *extra_certs_file_inline;
char *priv_key_file_inline;
const char *dh_file_inline;
const char *pkcs12_file_inline; /* contains the base64 encoding of pkcs12 file */
@ -495,6 +497,7 @@ struct options
int ns_cert_type; /* set to 0, NS_SSL_SERVER, or NS_SSL_CLIENT */
unsigned remote_cert_ku[MAX_PARMS];
const char *remote_cert_eku;
uint8_t *verify_hash;
#ifdef ENABLE_PKCS11
const char *pkcs11_providers[MAX_PARMS];

41
ssl.c
View File

@ -910,6 +910,16 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx)
goto err; /* Reject connection */
}
/* verify level 1 cert, i.e. the CA that signed our leaf cert */
if (ctx->error_depth == 1 && opt->verify_hash)
{
if (memcmp (ctx->current_cert->sha1_hash, opt->verify_hash, SHA_DIGEST_LENGTH))
{
msg (D_TLS_ERRORS, "TLS Error: level-1 certificate hash verification failed");
goto err;
}
}
/* save common name in session object */
if (ctx->error_depth == 0)
set_common_name (session, common_name);
@ -2140,6 +2150,37 @@ init_ssl (const struct options *options)
msg (M_SSLERR, "Cannot load certificate chain file %s (SSL_use_certificate_chain_file)", options->cert_file);
}
/* Load extra certificates that are part of our own certificate
chain but shouldn't be included in the verify chain */
if (options->extra_certs_file || options->extra_certs_file_inline)
{
BIO *bio;
X509 *cert;
#if ENABLE_INLINE_FILES
if (!strcmp (options->extra_certs_file, INLINE_FILE_TAG) && options->extra_certs_file_inline)
{
bio = BIO_new_mem_buf ((char *)options->extra_certs_file_inline, -1);
}
else
#endif
{
bio = BIO_new(BIO_s_file());
if (BIO_read_filename(bio, options->extra_certs_file) <= 0)
msg (M_SSLERR, "Cannot load extra-certs file: %s", options->extra_certs_file);
}
for (;;)
{
cert = NULL;
if (!PEM_read_bio_X509 (bio, &cert, 0, NULL)) /* takes ownership of cert */
break;
if (!cert)
msg (M_SSLERR, "Error reading extra-certs certificate");
if (SSL_CTX_add_extra_chain_cert(ctx, cert) != 1)
msg (M_SSLERR, "Error adding extra-certs certificate");
}
BIO_free (bio);
}
/* Require peer certificate verification */
#if P2MP_SERVER
if (options->ssl_flags & SSLF_CLIENT_CERT_NOT_REQUIRED)

1
ssl.h
View File

@ -466,6 +466,7 @@ struct tls_options
int ns_cert_type;
unsigned remote_cert_ku[MAX_PARMS];
const char *remote_cert_eku;
uint8_t *verify_hash;
/* allow openvpn config info to be
passed over control channel */

View File

@ -1,5 +1,5 @@
dnl define the OpenVPN version
define(PRODUCT_VERSION,[2.1.3u])
define(PRODUCT_VERSION,[2.1.3v])
dnl define the TAP version
define(PRODUCT_TAP_ID,[tap0901])
define(PRODUCT_TAP_WIN32_MIN_MAJOR,[9])