summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmilien Mantel <emilien.mantel@businessdecision.com>2010-06-17 21:38:59 +0200
committerDavid Sommerseth <dazo@users.sourceforge.net>2010-06-17 21:46:09 +0200
commit935c62be9c0c8a256112df818bfb8470586a23b6 (patch)
treefc18cc3b6330bd0de8c536c60b905fb034ae2e6a
parentc5b7923a2b0a94d702e1dad59438f7ee75971d3b (diff)
downloadopenvpn-935c62be9c0c8a256112df818bfb8470586a23b6.tar.gz
openvpn-935c62be9c0c8a256112df818bfb8470586a23b6.tar.xz
openvpn-935c62be9c0c8a256112df818bfb8470586a23b6.zip
Choose a different field in X509 to be username
For my company, we use a PKI (linked to a LDAP) with OpenVPN. We can't use "CN" to be username (few people can have the same "CN"). In our case, we only use the UID. With my patch, you can choose another field to be username with a new option called --x509-username-field, the default value is "CN". Signed-off-by: Emilien Mantel <emilien.mantel@businessdecision.com> Acked-by: David Sommerseth <dazo@users.sourceforge.net> Signed-off-by: David Sommerseth <dazo@users.sourceforge.net>
-rw-r--r--options.c11
-rw-r--r--options.h3
-rw-r--r--ssl.c29
-rw-r--r--ssl.h7
4 files changed, 36 insertions, 14 deletions
diff --git a/options.c b/options.c
index 86279e4..ea2dcbe 100644
--- a/options.c
+++ b/options.c
@@ -46,6 +46,7 @@
#include "helper.h"
#include "manage.h"
#include "configure.h"
+#include <ctype.h>
#include "memdbg.h"
@@ -500,6 +501,8 @@ static const char usage_message[] =
"--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"
+ "--x509-username-field : Field used in x509 certificat to be username.\n"
+ " Default is CN.\n"
#ifdef WIN32
"--cryptoapicert select-string : Load the certificate and private key from the\n"
" Windows Certificate System Store.\n"
@@ -753,6 +756,7 @@ init_options (struct options *o, const bool init_gc)
o->renegotiate_seconds = 3600;
o->handshake_window = 60;
o->transition_window = 3600;
+ o->x509_username_field = X509_USERNAME_FIELD_DEFAULT;
#endif
#endif
#ifdef ENABLE_PKCS11
@@ -5667,6 +5671,13 @@ add_option (struct options *options,
}
options->key_method = key_method;
}
+ else if (streq (p[0], "x509-username-field") && p[1])
+ {
+ char *s = p[1];
+ VERIFY_PERMISSION (OPT_P_GENERAL);
+ while ((*s = toupper(*s)) != '\0') s++; /* Uppercase if necessary */
+ options->x509_username_field = p[1];
+ }
#endif /* USE_SSL */
#endif /* USE_CRYPTO */
#ifdef ENABLE_PKCS11
diff --git a/options.h b/options.h
index a3114e2..10109e7 100644
--- a/options.h
+++ b/options.h
@@ -484,6 +484,9 @@ struct options
within n seconds of handshake initiation. */
int handshake_window;
+ /* Field used to be the username in X509 cert. */
+ char *x509_username_field;
+
/* Old key allowed to live n seconds after new key goes active */
int transition_window;
diff --git a/ssl.c b/ssl.c
index 276322f..970270b 100644
--- a/ssl.c
+++ b/ssl.c
@@ -730,6 +730,8 @@ get_peer_cert(X509_STORE_CTX *ctx, const char *tmp_dir, struct gc_arena *gc)
return peercert_filename;
}
+char * x509_username_field; /* GLOBAL */
+
/*
* Our verify callback function -- check
* that an incoming peer certificate is good.
@@ -740,7 +742,7 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx)
{
char *subject = NULL;
char envname[64];
- char common_name[TLS_CN_LEN];
+ char common_name[TLS_USERNAME_LEN];
SSL *ssl;
struct tls_session *session;
const struct tls_options *opt;
@@ -772,18 +774,20 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx)
string_mod_sslname (subject, X509_NAME_CHAR_CLASS, opt->ssl_flags);
string_replace_leading (subject, '-', '_');
- /* extract the common name */
- if (!extract_x509_field_ssl (X509_get_subject_name (ctx->current_cert), "CN", common_name, TLS_CN_LEN))
+ /* extract the username (default is CN) */
+ if (!extract_x509_field_ssl (X509_get_subject_name (ctx->current_cert), x509_username_field, common_name, TLS_USERNAME_LEN))
{
if (!ctx->error_depth)
- {
- msg (D_TLS_ERRORS, "VERIFY ERROR: could not extract Common Name from X509 subject string ('%s') -- note that the Common Name length is limited to %d characters",
- subject,
- TLS_CN_LEN);
- goto err;
- }
+ {
+ msg (D_TLS_ERRORS, "VERIFY ERROR: could not extract %s from X509 subject string ('%s') -- note that the username length is limited to %d characters",
+ x509_username_field,
+ subject,
+ TLS_USERNAME_LEN);
+ goto err;
+ }
}
+
string_mod_sslname (common_name, COMMON_NAME_CHAR_CLASS, opt->ssl_flags);
cert_hash_remember (session, ctx->error_depth, ctx->current_cert->sha1_hash);
@@ -1786,7 +1790,8 @@ init_ssl (const struct options *options)
}
else
#endif
- SSL_CTX_set_verify (ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
+ x509_username_field = (char *) options->x509_username_field;
+ SSL_CTX_set_verify (ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
verify_callback);
/* Connection information callback */
@@ -3594,9 +3599,9 @@ key_method_2_read (struct buffer *buf, struct tls_multi *multi, struct tls_sessi
s2 = verify_user_pass_script (session, up);
/* check sizing of username if it will become our common name */
- if ((session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) && strlen (up->username) >= TLS_CN_LEN)
+ if ((session->opt->ssl_flags & SSLF_USERNAME_AS_COMMON_NAME) && strlen (up->username) >= TLS_USERNAME_LEN)
{
- msg (D_TLS_ERRORS, "TLS Auth Error: --username-as-common name specified and username is longer than the maximum permitted Common Name length of %d characters", TLS_CN_LEN);
+ msg (D_TLS_ERRORS, "TLS Auth Error: --username-as-common name specified and username is longer than the maximum permitted Common Name length of %d characters", TLS_USERNAME_LEN);
s1 = OPENVPN_PLUGIN_FUNC_ERROR;
}
diff --git a/ssl.h b/ssl.h
index a22c854..93aac78 100644
--- a/ssl.h
+++ b/ssl.h
@@ -278,8 +278,8 @@
* Buffer sizes (also see mtu.h).
*/
-/* Maximum length of common name */
-#define TLS_CN_LEN 64
+/* Maximum length of the username in cert */
+#define TLS_USERNAME_LEN 64
/* Legal characters in an X509 or common name */
#define X509_NAME_CHAR_CLASS (CC_ALNUM|CC_UNDERBAR|CC_DASH|CC_DOT|CC_AT|CC_COLON|CC_SLASH|CC_EQUAL)
@@ -288,6 +288,9 @@
/* Maximum length of OCC options string passed as part of auth handshake */
#define TLS_OPTIONS_LEN 512
+/* Default field in X509 to be username */
+#define X509_USERNAME_FIELD_DEFAULT "CN"
+
/*
* Range of key exchange methods
*/