Add the option --verify-x509-name to provide the functionality
of the now deprecated --tls-remote.
The new option accepts RFC 2253 subject DNs only and compares
RDN or RDN prefix only if configured explicitly.
Signed-off-by: Heiko Hund <heiko.hund@sophos.com>
Acked-by: Arne Schwabe <arne@rfc2549.org>
Message-Id: 1362670601-18660-1-git-send-email-heiko.hund@sophos.com
URL: http://article.gmane.org/gmane.network.openvpn.devel/7376
Signed-off-by: Gert Doering <gert@greenie.muc.de>
... | ... |
@@ -3431,7 +3431,7 @@ the authenticated username as the common name, |
3431 | 3431 |
rather than the common name from the client cert. |
3432 | 3432 |
.\"********************************************************* |
3433 | 3433 |
.TP |
3434 |
-.B \-\-compat\-names [no\-remapping] |
|
3434 |
+.B \-\-compat\-names [no\-remapping] (DEPRECATED) |
|
3435 | 3435 |
Until OpenVPN v2.3 the format of the X.509 Subject fields was formatted |
3436 | 3436 |
like this: |
3437 | 3437 |
.IP |
... | ... |
@@ -3467,17 +3467,20 @@ The |
3467 | 3467 |
mode flag can be used with the |
3468 | 3468 |
.B |
3469 | 3469 |
\-\-compat\-names |
3470 |
-option to be compatible with the now deprecated \-\-no\-name\-remapping feature |
|
3471 |
-present in older OpenVPN versions. When this mode flag is used, the Common Name, |
|
3470 |
+option to be compatible with the now deprecated \-\-no\-name\-remapping option. |
|
3471 |
+It is only available at the server. When this mode flag is used, the Common Name, |
|
3472 | 3472 |
Subject, and username strings are allowed to include any printable character |
3473 | 3473 |
including space, but excluding control characters such as tab, newline, and |
3474 |
-carriage-return. |
|
3474 |
+carriage-return. no-remapping is only available on the server side. |
|
3475 | 3475 |
|
3476 | 3476 |
.B Please note: |
3477 |
-This option will not be around for a long time. It is only implemented |
|
3477 |
+This option is immediately deprecated. It is only implemented |
|
3478 | 3478 |
to make the transition to the new formatting less intrusive. It will be |
3479 |
-removed either in OpenVPN v2.4 or v2.5. So please make sure you start |
|
3480 |
-the process to support the new formatting as soon as possible. |
|
3479 |
+removed either in OpenVPN v2.4 or v2.5. So please make sure you use the |
|
3480 |
+.B \-\-verify-x509-name |
|
3481 |
+option instead of |
|
3482 |
+.B \-\-tls-remote |
|
3483 |
+as soon as possible and update your scripts where necessary. |
|
3481 | 3484 |
.\"********************************************************* |
3482 | 3485 |
.TP |
3483 | 3486 |
.B \-\-no\-name\-remapping (DEPRECATED) |
... | ... |
@@ -3485,7 +3488,7 @@ The |
3485 | 3485 |
.B \-\-no\-name\-remapping |
3486 | 3486 |
option is an alias for |
3487 | 3487 |
.B \-\-compat\-names\ no\-remapping. |
3488 |
-It ensures compatibility with configurations using the |
|
3488 |
+It ensures compatibility with server configurations using the |
|
3489 | 3489 |
.B \-\-no\-name\-remapping |
3490 | 3490 |
option. |
3491 | 3491 |
|
... | ... |
@@ -4671,11 +4674,11 @@ is available via the peer_cert environment variable. |
4671 | 4671 |
Field in x509 certificate subject to be used as username (default=CN). |
4672 | 4672 |
.B Fieldname |
4673 | 4673 |
will be uppercased before matching. When this option is used, the |
4674 |
-of the CN. |
|
4674 |
+.B \-\-verify-x509-username |
|
4675 |
+option will match against the chosen fieldname instead of the CN. |
|
4675 | 4676 |
.\"********************************************************* |
4676 | 4677 |
.TP |
4677 |
-.B \-\-tls-remote name |
|
4678 |
+.B \-\-tls-remote name (DEPRECATED) |
|
4678 | 4679 |
Accept connections only from a host with X509 name |
4679 | 4680 |
or common name equal to |
4680 | 4681 |
.B name. |
... | ... |
@@ -4707,6 +4710,59 @@ option to verify the remote host, because |
4707 | 4707 |
works in a |
4708 | 4708 |
.B \-\-chroot |
4709 | 4709 |
environment too. |
4710 |
+ |
|
4711 |
+.B Please also note: |
|
4712 |
+This option is now deprecated. It will be removed either in OpenVPN v2.4 |
|
4713 |
+or v2.5. So please make sure you support the new X.509 name formatting |
|
4714 |
+described with the |
|
4715 |
+.B \-\-compat-names |
|
4716 |
+option as soon as possible by updating your configurations to use |
|
4717 |
+.B \-\-verify-x509-name |
|
4718 |
+instead. |
|
4719 |
+.\"********************************************************* |
|
4720 |
+.TP |
|
4721 |
+.B \-\-verify-x509-name name type |
|
4722 |
+Accept connections only if a host's X.509 name is equal to |
|
4723 |
+.B name. |
|
4724 |
+The remote host must also pass all other tests of verification. |
|
4725 |
+ |
|
4726 |
+Which X.509 name is compared to |
|
4727 |
+.B name |
|
4728 |
+depends on the setting of type. |
|
4729 |
+.B type |
|
4730 |
+can be "subject" to match the complete subject DN (default), |
|
4731 |
+"name" to match a subject RDN or "name-prefix" to match a subject RDN prefix. |
|
4732 |
+Which RDN is verified as name depends on the |
|
4733 |
+.B \-\-x509-username-field |
|
4734 |
+option. But it defaults to the common name (CN), e.g. a certificate with a |
|
4735 |
+subject DN "C=KG, ST=NA, L=Bishkek, CN=Server-1" would be matched by: |
|
4736 |
+ |
|
4737 |
+.B \-\-verify-x509-name 'C=KG, ST=NA, L=Bishkek, CN=Server-1' |
|
4738 |
+and |
|
4739 |
+.B \-\-verify-x509-name Server-1 name |
|
4740 |
+or you could use |
|
4741 |
+.B \-\-verify-x509-name Server- name-prefix |
|
4742 |
+if you want a client to only accept connections to "Server-1", "Server-2", etc. |
|
4743 |
+ |
|
4744 |
+.B \-\-verify-x509-name |
|
4745 |
+is a useful replacement for the |
|
4746 |
+.B \-\-tls-verify |
|
4747 |
+option to verify the remote host, because |
|
4748 |
+.B \-\-verify-x509-name |
|
4749 |
+works in a |
|
4750 |
+.B \-\-chroot |
|
4751 |
+environment without any dependencies. |
|
4752 |
+ |
|
4753 |
+Using a name prefix is a useful alternative to managing |
|
4754 |
+a CRL (Certificate Revocation List) on the client, since it allows the client |
|
4755 |
+to refuse all certificates except for those associated |
|
4756 |
+with designated servers. |
|
4757 |
+ |
|
4758 |
+.B NOTE: |
|
4759 |
+Test against a name prefix only when you are using OpenVPN with |
|
4760 |
+a custom CA certificate that is under your control. |
|
4761 |
+Never use this option with type "name-prefix" when your client certificates |
|
4762 |
+are signed by a third party, such as a commercial web CA. |
|
4710 | 4763 |
.\"********************************************************* |
4711 | 4764 |
.TP |
4712 | 4765 |
.B \-\-x509-track attribute |
... | ... |
@@ -4744,7 +4800,7 @@ a man-in-the-middle attack where an authorized client |
4744 | 4744 |
attempts to connect to another client by impersonating the server. |
4745 | 4745 |
The attack is easily prevented by having clients verify |
4746 | 4746 |
the server certificate using any one of |
4747 |
-.B \-\-ns-cert-type, \-\-tls-remote, |
|
4747 |
+.B \-\-ns-cert-type, \-\-verify-x509-name, |
|
4748 | 4748 |
or |
4749 | 4749 |
.B \-\-tls-verify. |
4750 | 4750 |
.\"********************************************************* |
... | ... |
@@ -4802,7 +4858,7 @@ a man-in-the-middle attack where an authorized client |
4802 | 4802 |
attempts to connect to another client by impersonating the server. |
4803 | 4803 |
The attack is easily prevented by having clients verify |
4804 | 4804 |
the server certificate using any one of |
4805 |
-.B \-\-remote-cert-tls, \-\-tls-remote, |
|
4805 |
+.B \-\-remote-cert-tls, \-\-verify-x509-name, |
|
4806 | 4806 |
or |
4807 | 4807 |
.B \-\-tls-verify. |
4808 | 4808 |
.\"********************************************************* |
... | ... |
@@ -2205,7 +2205,8 @@ do_init_crypto_tls (struct context *c, const unsigned int flags) |
2205 | 2205 |
|
2206 | 2206 |
to.verify_command = options->tls_verify; |
2207 | 2207 |
to.verify_export_cert = options->tls_export_cert; |
2208 |
- to.verify_x509name = options->tls_remote; |
|
2208 |
+ to.verify_x509_type = (options->verify_x509_type & 0xff); |
|
2209 |
+ to.verify_x509_name = options->verify_x509_name; |
|
2209 | 2210 |
to.crl_file = options->crl_file; |
2210 | 2211 |
to.ssl_flags = options->ssl_flags; |
2211 | 2212 |
to.ns_cert_type = options->ns_cert_type; |
... | ... |
@@ -2467,12 +2468,10 @@ do_option_warnings (struct context *c) |
2467 | 2467 |
warn_on_use_of_common_subnets (); |
2468 | 2468 |
if (o->tls_client |
2469 | 2469 |
&& !o->tls_verify |
2470 |
- && !o->tls_remote |
|
2470 |
+ && o->verify_x509_type == VERIFY_X509_NONE |
|
2471 | 2471 |
&& !(o->ns_cert_type & NS_CERT_CHECK_SERVER) |
2472 | 2472 |
&& !o->remote_cert_eku) |
2473 | 2473 |
msg (M_WARN, "WARNING: No server certificate verification method has been enabled. See http://openvpn.net/howto.html#mitm for more info."); |
2474 |
- if (o->tls_remote) |
|
2475 |
- msg (M_WARN, "WARNING: Make sure you understand the semantics of --tls-remote before using it (see the man page)."); |
|
2476 | 2474 |
#endif |
2477 | 2475 |
#endif |
2478 | 2476 |
|
... | ... |
@@ -614,8 +614,8 @@ static const char usage_message[] = |
614 | 614 |
"--tls-export-cert [directory] : Get peer cert in PEM format and store it \n" |
615 | 615 |
" in an openvpn temporary file in [directory]. Peer cert is \n" |
616 | 616 |
" stored before tls-verify script execution and deleted after.\n" |
617 |
- "--tls-remote x509name: Accept connections only from a host with X509 name\n" |
|
618 |
- " x509name. The remote host must also pass all other tests\n" |
|
617 |
+ "--verify-x509-name name: Accept connections only from a host with X509 subject\n" |
|
618 |
+ " DN name. The remote host must also pass all other tests\n" |
|
619 | 619 |
" of verification.\n" |
620 | 620 |
"--ns-cert-type t: Require that peer certificate was signed with an explicit\n" |
621 | 621 |
" nsCertType designation t = 'client' | 'server'.\n" |
... | ... |
@@ -1596,7 +1596,8 @@ show_settings (const struct options *o) |
1596 | 1596 |
SHOW_STR (cipher_list); |
1597 | 1597 |
SHOW_STR (tls_verify); |
1598 | 1598 |
SHOW_STR (tls_export_cert); |
1599 |
- SHOW_STR (tls_remote); |
|
1599 |
+ SHOW_INT (verify_x509_type); |
|
1600 |
+ SHOW_STR (verify_x509_name); |
|
1600 | 1601 |
SHOW_STR (crl_file); |
1601 | 1602 |
SHOW_INT (ns_cert_type); |
1602 | 1603 |
{ |
... | ... |
@@ -2130,7 +2131,6 @@ options_postprocess_verify_ce (const struct options *options, const struct conne |
2130 | 2130 |
|
2131 | 2131 |
if (options->stale_routes_check_interval) |
2132 | 2132 |
msg (M_USAGE, "--stale-routes-check requires --mode server"); |
2133 |
- |
|
2134 | 2133 |
if (compat_flag (COMPAT_FLAG_QUERY | COMPAT_NO_NAME_REMAPPING)) |
2135 | 2134 |
msg (M_USAGE, "--compat-x509-names no-remapping requires --mode server"); |
2136 | 2135 |
} |
... | ... |
@@ -2302,7 +2302,7 @@ options_postprocess_verify_ce (const struct options *options, const struct conne |
2302 | 2302 |
MUST_BE_UNDEF (cipher_list); |
2303 | 2303 |
MUST_BE_UNDEF (tls_verify); |
2304 | 2304 |
MUST_BE_UNDEF (tls_export_cert); |
2305 |
- MUST_BE_UNDEF (tls_remote); |
|
2305 |
+ MUST_BE_UNDEF (verify_x509_name); |
|
2306 | 2306 |
MUST_BE_UNDEF (tls_timeout); |
2307 | 2307 |
MUST_BE_UNDEF (renegotiate_bytes); |
2308 | 2308 |
MUST_BE_UNDEF (renegotiate_packets); |
... | ... |
@@ -6514,27 +6514,97 @@ add_option (struct options *options, |
6514 | 6514 |
else if (streq (p[0], "compat-names")) |
6515 | 6515 |
{ |
6516 | 6516 |
VERIFY_PERMISSION (OPT_P_GENERAL); |
6517 |
+ if (options->verify_x509_type != VERIFY_X509_NONE && |
|
6518 |
+ options->verify_x509_type != TLS_REMOTE_SUBJECT_DN && |
|
6519 |
+ options->verify_x509_type != TLS_REMOTE_SUBJECT_RDN_PREFIX) |
|
6520 |
+ { |
|
6521 |
+ msg (msglevel, "you cannot use --compat-names with --verify-x509-name"); |
|
6522 |
+ goto err; |
|
6523 |
+ } |
|
6524 |
+ msg (M_WARN, "DEPRECATED OPTION: --compat-names, please update your configuration"); |
|
6517 | 6525 |
compat_flag (COMPAT_FLAG_SET | COMPAT_NAMES); |
6526 |
+#if P2MP_SERVER |
|
6518 | 6527 |
if (p[1] && streq (p[1], "no-remapping")) |
6519 | 6528 |
compat_flag (COMPAT_FLAG_SET | COMPAT_NO_NAME_REMAPPING); |
6520 | 6529 |
} |
6521 | 6530 |
else if (streq (p[0], "no-name-remapping")) |
6522 | 6531 |
{ |
6523 | 6532 |
VERIFY_PERMISSION (OPT_P_GENERAL); |
6533 |
+ if (options->verify_x509_type != VERIFY_X509_NONE && |
|
6534 |
+ options->verify_x509_type != TLS_REMOTE_SUBJECT_DN && |
|
6535 |
+ options->verify_x509_type != TLS_REMOTE_SUBJECT_RDN_PREFIX) |
|
6536 |
+ { |
|
6537 |
+ msg (msglevel, "you cannot use --no-name-remapping with --verify-x509-name"); |
|
6538 |
+ goto err; |
|
6539 |
+ } |
|
6524 | 6540 |
msg (M_WARN, "DEPRECATED OPTION: --no-name-remapping, please update your configuration"); |
6525 | 6541 |
compat_flag (COMPAT_FLAG_SET | COMPAT_NAMES); |
6526 | 6542 |
compat_flag (COMPAT_FLAG_SET | COMPAT_NO_NAME_REMAPPING); |
6543 |
+#endif |
|
6527 | 6544 |
} |
6528 | 6545 |
else if (streq (p[0], "tls-remote") && p[1]) |
6529 | 6546 |
{ |
6530 | 6547 |
VERIFY_PERMISSION (OPT_P_GENERAL); |
6531 |
- /* |
|
6532 |
- * Enable legacy openvpn format for DNs that have not been converted |
|
6533 |
- * yet and X.509 common names (not containing an '=' or ', ') |
|
6534 |
- */ |
|
6535 |
- if (p[1][0] == '/' || !strchr (p[1], '=') || !strstr (p[1], ", ")) |
|
6536 |
- compat_flag (COMPAT_FLAG_SET | COMPAT_NAMES); |
|
6537 |
- options->tls_remote = p[1]; |
|
6548 |
+ |
|
6549 |
+ if (options->verify_x509_type != VERIFY_X509_NONE && |
|
6550 |
+ options->verify_x509_type != TLS_REMOTE_SUBJECT_DN && |
|
6551 |
+ options->verify_x509_type != TLS_REMOTE_SUBJECT_RDN_PREFIX) |
|
6552 |
+ { |
|
6553 |
+ msg (msglevel, "you cannot use --tls-remote with --verify-x509-name"); |
|
6554 |
+ goto err; |
|
6555 |
+ } |
|
6556 |
+ msg (M_WARN, "DEPRECATED OPTION: --tls-remote, please update your configuration"); |
|
6557 |
+ |
|
6558 |
+ if (strlen (p[1])) |
|
6559 |
+ { |
|
6560 |
+ int is_username = (!strchr (p[1], '=') || !strstr (p[1], ", ")); |
|
6561 |
+ int type = TLS_REMOTE_SUBJECT_DN; |
|
6562 |
+ if (p[1][0] != '/' && is_username) |
|
6563 |
+ type = TLS_REMOTE_SUBJECT_RDN_PREFIX; |
|
6564 |
+ |
|
6565 |
+ /* |
|
6566 |
+ * Enable legacy openvpn format for DNs that have not been converted |
|
6567 |
+ * yet and --x509-username-field (not containing an '=' or ', ') |
|
6568 |
+ */ |
|
6569 |
+ if (p[1][0] == '/' || is_username) |
|
6570 |
+ compat_flag (COMPAT_FLAG_SET | COMPAT_NAMES); |
|
6571 |
+ |
|
6572 |
+ options->verify_x509_type = type; |
|
6573 |
+ options->verify_x509_name = p[1]; |
|
6574 |
+ } |
|
6575 |
+ } |
|
6576 |
+ else if (streq (p[0], "verify-x509-name") && p[1] && strlen (p[1])) |
|
6577 |
+ { |
|
6578 |
+ int type = VERIFY_X509_SUBJECT_DN; |
|
6579 |
+ VERIFY_PERMISSION (OPT_P_GENERAL); |
|
6580 |
+ if (options->verify_x509_type == TLS_REMOTE_SUBJECT_DN || |
|
6581 |
+ options->verify_x509_type == TLS_REMOTE_SUBJECT_RDN_PREFIX) |
|
6582 |
+ { |
|
6583 |
+ msg (msglevel, "you cannot use --verify-x509-name with --tls-remote"); |
|
6584 |
+ goto err; |
|
6585 |
+ } |
|
6586 |
+ if (compat_flag (COMPAT_FLAG_QUERY | COMPAT_NAMES)) |
|
6587 |
+ { |
|
6588 |
+ msg (msglevel, "you cannot use --verify-x509-name with " |
|
6589 |
+ "--compat-names or --no-name-remapping"); |
|
6590 |
+ goto err; |
|
6591 |
+ } |
|
6592 |
+ if (p[2]) |
|
6593 |
+ { |
|
6594 |
+ if (streq (p[2], "subject")) |
|
6595 |
+ type = VERIFY_X509_SUBJECT_DN; |
|
6596 |
+ else if (streq (p[2], "name")) |
|
6597 |
+ type = VERIFY_X509_SUBJECT_RDN; |
|
6598 |
+ else if (streq (p[2], "name-prefix")) |
|
6599 |
+ type = VERIFY_X509_SUBJECT_RDN_PREFIX; |
|
6600 |
+ else |
|
6601 |
+ { |
|
6602 |
+ msg (msglevel, "unknown X.509 name type: %s", p[2]); |
|
6603 |
+ goto err; |
|
6604 |
+ } |
|
6605 |
+ } |
|
6606 |
+ options->verify_x509_type = type; |
|
6607 |
+ options->verify_x509_name = p[1]; |
|
6538 | 6608 |
} |
6539 | 6609 |
else if (streq (p[0], "ns-cert-type") && p[1]) |
6540 | 6610 |
{ |
... | ... |
@@ -506,8 +506,9 @@ struct options |
506 | 506 |
const char *pkcs12_file; |
507 | 507 |
const char *cipher_list; |
508 | 508 |
const char *tls_verify; |
509 |
+ int verify_x509_type; |
|
510 |
+ const char *verify_x509_name; |
|
509 | 511 |
const char *tls_export_cert; |
510 |
- const char *tls_remote; |
|
511 | 512 |
const char *crl_file; |
512 | 513 |
|
513 | 514 |
const char *ca_file_inline; |
... | ... |
@@ -245,7 +245,8 @@ struct tls_options |
245 | 245 |
/* cert verification parms */ |
246 | 246 |
const char *verify_command; |
247 | 247 |
const char *verify_export_cert; |
248 |
- const char *verify_x509name; |
|
248 |
+ int verify_x509_type; |
|
249 |
+ const char *verify_x509_name; |
|
249 | 250 |
const char *crl_file; |
250 | 251 |
int ns_cert_type; |
251 | 252 |
unsigned remote_cert_ku[MAX_PARMS]; |
... | ... |
@@ -369,16 +369,21 @@ verify_peer_cert(const struct tls_options *opt, openvpn_x509_cert_t *peer_cert, |
369 | 369 |
|
370 | 370 |
#endif /* OPENSSL_VERSION_NUMBER */ |
371 | 371 |
|
372 |
- /* verify X509 name or common name against --tls-remote */ |
|
373 |
- if (opt->verify_x509name && strlen (opt->verify_x509name) > 0) |
|
372 |
+ /* verify X509 name or username against --verify-x509-[user]name */ |
|
373 |
+ if (opt->verify_x509_type != VERIFY_X509_NONE) |
|
374 | 374 |
{ |
375 |
- if (strcmp (opt->verify_x509name, subject) == 0 |
|
376 |
- || strncmp (opt->verify_x509name, common_name, strlen (opt->verify_x509name)) == 0) |
|
375 |
+ if ( (opt->verify_x509_type == VERIFY_X509_SUBJECT_DN |
|
376 |
+ && strcmp (opt->verify_x509_name, subject) == 0) |
|
377 |
+ || (opt->verify_x509_type == VERIFY_X509_SUBJECT_RDN |
|
378 |
+ && strcmp (opt->verify_x509_name, common_name) == 0) |
|
379 |
+ || (opt->verify_x509_type == VERIFY_X509_SUBJECT_RDN_PREFIX |
|
380 |
+ && strncmp (opt->verify_x509_name, common_name, |
|
381 |
+ strlen (opt->verify_x509_name)) == 0) ) |
|
377 | 382 |
msg (D_HANDSHAKE, "VERIFY X509NAME OK: %s", subject); |
378 | 383 |
else |
379 | 384 |
{ |
380 | 385 |
msg (D_HANDSHAKE, "VERIFY X509NAME ERROR: %s, must be %s", |
381 |
- subject, opt->verify_x509name); |
|
386 |
+ subject, opt->verify_x509_name); |
|
382 | 387 |
return FAILURE; /* Reject connection */ |
383 | 388 |
} |
384 | 389 |
} |
... | ... |
@@ -62,6 +62,12 @@ struct cert_hash_set { |
62 | 62 |
struct cert_hash *ch[MAX_CERT_DEPTH]; /**< Array of certificate hashes */ |
63 | 63 |
}; |
64 | 64 |
|
65 |
+#define VERIFY_X509_NONE 0 |
|
66 |
+#define VERIFY_X509_SUBJECT_DN 1 |
|
67 |
+#define VERIFY_X509_SUBJECT_RDN 2 |
|
68 |
+#define VERIFY_X509_SUBJECT_RDN_PREFIX 3 |
|
69 |
+#define TLS_REMOTE_SUBJECT_DN 1 + 0x100 |
|
70 |
+#define TLS_REMOTE_SUBJECT_RDN_PREFIX 3 + 0x100 |
|
65 | 71 |
|
66 | 72 |
#define TLS_AUTHENTICATION_SUCCEEDED 0 |
67 | 73 |
#define TLS_AUTHENTICATION_FAILED 1 |