mirror of
https://github.com/OpenVPN/openvpn.git
synced 2024-09-20 12:02:28 +02:00
Added 'dir' flag to "crl-verify" (see man page for info).
Don't call SSL_CTX_set_client_CA_list or SSL_CTX_set_client_CA_list if not running in server mode (these functions are only useful for TLS/SSL servers). Modified openvpn_snprintf to return false on overflow, and true otherwise. When AUTH_FAILED,... is received, log the full string. git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@7213 e7ae566f-a301-0410-adde-c780ea21d3b5
This commit is contained in:
parent
d3269d070c
commit
893f4f9328
9
buffer.c
9
buffer.c
@ -218,20 +218,21 @@ buf_printf (struct buffer *buf, const char *format, ...)
|
||||
/*
|
||||
* This is necessary due to certain buggy implementations of snprintf,
|
||||
* that don't guarantee null termination for size > 0.
|
||||
* Return false on overflow.
|
||||
*/
|
||||
|
||||
int openvpn_snprintf(char *str, size_t size, const char *format, ...)
|
||||
bool openvpn_snprintf(char *str, size_t size, const char *format, ...)
|
||||
{
|
||||
va_list arglist;
|
||||
int ret = 0;
|
||||
int len = -1;
|
||||
if (size > 0)
|
||||
{
|
||||
va_start (arglist, format);
|
||||
ret = vsnprintf (str, size, format, arglist);
|
||||
len = vsnprintf (str, size, format, arglist);
|
||||
va_end (arglist);
|
||||
str[size - 1] = 0;
|
||||
}
|
||||
return ret;
|
||||
return (len >= 0 && len < size);
|
||||
}
|
||||
|
||||
/*
|
||||
|
2
buffer.h
2
buffer.h
@ -280,7 +280,7 @@ bool buf_printf (struct buffer *buf, const char *format, ...)
|
||||
/*
|
||||
* Like snprintf but guarantees null termination for size > 0
|
||||
*/
|
||||
int openvpn_snprintf(char *str, size_t size, const char *format, ...)
|
||||
bool openvpn_snprintf(char *str, size_t size, const char *format, ...)
|
||||
#ifdef __GNUC__
|
||||
__attribute__ ((format (printf, 3, 4)))
|
||||
#endif
|
||||
|
12
openvpn.8
12
openvpn.8
@ -4457,7 +4457,7 @@ or
|
||||
.B --tls-verify.
|
||||
.\"*********************************************************
|
||||
.TP
|
||||
.B --crl-verify crl
|
||||
.B --crl-verify crl ['dir']
|
||||
Check peer certificate against the file
|
||||
.B crl
|
||||
in PEM format.
|
||||
@ -4473,6 +4473,16 @@ overall integrity of the PKI.
|
||||
|
||||
The only time when it would be necessary to rebuild the entire PKI from scratch would be
|
||||
if the root certificate key itself was compromised.
|
||||
|
||||
If the optional
|
||||
.B dir
|
||||
flag is specified, enable a different mode where
|
||||
.B crl
|
||||
is a directory containing files named as revoked serial numbers
|
||||
(the files may be empty, the contents are never read). If a client
|
||||
requests a connection, where the client certificate serial number
|
||||
(decimal string) is the name of a file present in the directory,
|
||||
it will be rejected.
|
||||
.\"*********************************************************
|
||||
.SS SSL Library information:
|
||||
.\"*********************************************************
|
||||
|
@ -534,7 +534,7 @@ static const char usage_message[] =
|
||||
" see --secret option for more info.\n"
|
||||
"--askpass [file]: Get PEM password from controlling tty before we daemonize.\n"
|
||||
"--auth-nocache : Don't cache --askpass or --auth-user-pass passwords.\n"
|
||||
"--crl-verify crl: Check peer certificate against a CRL.\n"
|
||||
"--crl-verify crl ['dir']: Check peer certificate against a CRL.\n"
|
||||
"--tls-verify cmd: Execute shell command cmd to verify the X509 name of a\n"
|
||||
" pending TLS connection that has otherwise passed all other\n"
|
||||
" tests of certification. cmd should return 0 to allow\n"
|
||||
@ -5836,6 +5836,8 @@ add_option (struct options *options,
|
||||
else if (streq (p[0], "crl-verify") && p[1])
|
||||
{
|
||||
VERIFY_PERMISSION (OPT_P_GENERAL);
|
||||
if (p[2] && streq(p[2], "dir"))
|
||||
options->ssl_flags |= SSLF_CRL_VERIFY_DIR;
|
||||
options->crl_file = p[1];
|
||||
}
|
||||
else if (streq (p[0], "tls-verify") && p[1])
|
||||
|
2
push.c
2
push.c
@ -42,7 +42,7 @@
|
||||
void
|
||||
receive_auth_failed (struct context *c, const struct buffer *buffer)
|
||||
{
|
||||
msg (M_VERB0, "AUTH: Received AUTH_FAILED control message");
|
||||
msg (M_VERB0, "AUTH: Received control message: %s", BSTR(buffer));
|
||||
connection_list_set_no_advance(&c->options);
|
||||
if (c->options.pull)
|
||||
{
|
||||
|
47
ssl.c
47
ssl.c
@ -836,6 +836,7 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx)
|
||||
const struct tls_options *opt;
|
||||
const int max_depth = MAX_CERT_DEPTH;
|
||||
struct argv argv = argv_new ();
|
||||
char *serial = NULL;
|
||||
|
||||
/* get the tls_session pointer */
|
||||
ssl = X509_STORE_CTX_get_ex_data (ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
|
||||
@ -929,14 +930,12 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx)
|
||||
{
|
||||
ASN1_INTEGER *asn1_i;
|
||||
BIGNUM *bignum;
|
||||
char *dec;
|
||||
asn1_i = X509_get_serialNumber(ctx->current_cert);
|
||||
bignum = ASN1_INTEGER_to_BN(asn1_i, NULL);
|
||||
dec = BN_bn2dec(bignum);
|
||||
serial = BN_bn2dec(bignum);
|
||||
openvpn_snprintf (envname, sizeof(envname), "tls_serial_%d", ctx->error_depth);
|
||||
setenv_str (opt->es, envname, dec);
|
||||
setenv_str (opt->es, envname, serial);
|
||||
BN_free(bignum);
|
||||
OPENSSL_free(dec);
|
||||
}
|
||||
|
||||
/* export current untrusted IP */
|
||||
@ -1059,6 +1058,25 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx)
|
||||
|
||||
/* check peer cert against CRL */
|
||||
if (opt->crl_file)
|
||||
{
|
||||
if (opt->ssl_flags & SSLF_CRL_VERIFY_DIR)
|
||||
{
|
||||
char fn[256];
|
||||
int fd;
|
||||
if (!openvpn_snprintf(fn, sizeof(fn), "%s%c%s", opt->crl_file, OS_SPECIFIC_DIRSEP, serial))
|
||||
{
|
||||
msg (D_HANDSHAKE, "VERIFY CRL: filename overflow");
|
||||
goto err;
|
||||
}
|
||||
fd = open (fn, O_RDONLY);
|
||||
if (fd >= 0)
|
||||
{
|
||||
msg (D_HANDSHAKE, "VERIFY CRL: certificate serial number %s is revoked", serial);
|
||||
close(fd);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
X509_CRL *crl=NULL;
|
||||
X509_REVOKED *revoked;
|
||||
@ -1108,19 +1126,22 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx)
|
||||
if (!retval)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
msg (D_HANDSHAKE, "VERIFY OK: depth=%d, %s", ctx->error_depth, subject);
|
||||
|
||||
session->verified = true;
|
||||
|
||||
done:
|
||||
OPENSSL_free (subject);
|
||||
if (serial)
|
||||
OPENSSL_free(serial);
|
||||
argv_reset (&argv);
|
||||
return 1; /* Accept connection */
|
||||
return (session->verified == true) ? 1 : 0;
|
||||
|
||||
err:
|
||||
ERR_clear_error ();
|
||||
OPENSSL_free (subject);
|
||||
argv_reset (&argv);
|
||||
return 0; /* Reject connection */
|
||||
session->verified = false;
|
||||
goto done;
|
||||
}
|
||||
|
||||
void
|
||||
@ -1954,7 +1975,7 @@ init_ssl (const struct options *options)
|
||||
{
|
||||
if (!X509_STORE_add_cert(ctx->cert_store,sk_X509_value(ca, i)))
|
||||
msg (M_SSLERR, "Cannot add certificate to certificate chain (X509_STORE_add_cert)");
|
||||
if (!SSL_CTX_add_client_CA(ctx, sk_X509_value(ca, i)))
|
||||
if (options->tls_server && !SSL_CTX_add_client_CA(ctx, sk_X509_value(ca, i)))
|
||||
msg (M_SSLERR, "Cannot add certificate to client CA list (SSL_CTX_add_client_CA)");
|
||||
}
|
||||
}
|
||||
@ -2066,11 +2087,11 @@ init_ssl (const struct options *options)
|
||||
#endif
|
||||
{
|
||||
/* Load CA file for verifying peer supplied certificate */
|
||||
status = SSL_CTX_load_verify_locations (ctx, options->ca_file, options->ca_path);
|
||||
status = SSL_CTX_load_verify_locations (ctx, options->ca_file, NULL);
|
||||
}
|
||||
|
||||
if (!status)
|
||||
msg (M_SSLERR, "Cannot load CA certificate file %s path %s (SSL_CTX_load_verify_locations)", options->ca_file, options->ca_path);
|
||||
msg (M_SSLERR, "Cannot load CA certificate file %s path %s (SSL_CTX_load_verify_locations)", np(options->ca_file), np(options->ca_path));
|
||||
|
||||
/* Set a store for certs (CA & CRL) with a lookup on the "capath" hash directory */
|
||||
if (options->ca_path) {
|
||||
@ -2094,7 +2115,7 @@ init_ssl (const struct options *options)
|
||||
}
|
||||
|
||||
/* Load names of CAs from file and use it as a client CA list */
|
||||
if (options->ca_file) {
|
||||
if (options->ca_file && options->tls_server) {
|
||||
STACK_OF(X509_NAME) *cert_names = NULL;
|
||||
#if ENABLE_INLINE_FILES
|
||||
if (!strcmp (options->ca_file, INLINE_FILE_TAG) && options->ca_file_inline)
|
||||
|
Loading…
Reference in New Issue
Block a user