[openssl-commits] [openssl] OpenSSL_1_0_2-stable update
Richard Levitte
levitte at openssl.org
Wed Jun 29 21:14:03 UTC 2016
The branch OpenSSL_1_0_2-stable has been updated
via 6ad8c48291622a6ccc51489b9a230c9a05ca5614 (commit)
via 30aeb3128199c15760a785d88a4eda9e156d5af6 (commit)
via 338fb1688fbfb7efe0bdd475b01791a6de5ef94b (commit)
from ad64a69e02f7dda422d0f4f53dce7b1278715380 (commit)
- Log -----------------------------------------------------------------
commit 6ad8c48291622a6ccc51489b9a230c9a05ca5614
Author: Richard Levitte <levitte at openssl.org>
Date: Sun Jun 19 10:55:43 2016 +0200
Allow proxy certs to be present when verifying a chain
Reviewed-by: Rich Salz <rsalz at openssl.org>
commit 30aeb3128199c15760a785d88a4eda9e156d5af6
Author: Richard Levitte <levitte at openssl.org>
Date: Sun Jun 19 10:55:29 2016 +0200
Fix proxy certificate pathlength verification
While travelling up the certificate chain, the internal
proxy_path_length must be updated with the pCPathLengthConstraint
value, or verification will not work properly. This corresponds to
RFC 3820, 4.1.4 (a).
Reviewed-by: Rich Salz <rsalz at openssl.org>
commit 338fb1688fbfb7efe0bdd475b01791a6de5ef94b
Author: Richard Levitte <levitte at openssl.org>
Date: Sun Jun 19 10:55:16 2016 +0200
Check that the subject name in a proxy cert complies to RFC 3820
The subject name MUST be the same as the issuer name, with a single CN
entry added.
RT#1852
Reviewed-by: Rich Salz <rsalz at openssl.org>
-----------------------------------------------------------------------
Summary of changes:
apps/apps.c | 2 +
crypto/x509/x509.h | 6 ++-
crypto/x509/x509_err.c | 3 +-
crypto/x509/x509_txt.c | 2 +
crypto/x509/x509_vfy.c | 103 +++++++++++++++++++++++++++++++++++++++++++++----
crypto/x509/x509_vfy.h | 2 +
doc/apps/verify.pod | 5 +++
7 files changed, 113 insertions(+), 10 deletions(-)
diff --git a/apps/apps.c b/apps/apps.c
index b1dd970..0385490 100644
--- a/apps/apps.c
+++ b/apps/apps.c
@@ -2374,6 +2374,8 @@ int args_verify(char ***pargs, int *pargc,
flags |= X509_V_FLAG_PARTIAL_CHAIN;
else if (!strcmp(arg, "-no_alt_chains"))
flags |= X509_V_FLAG_NO_ALT_CHAINS;
+ else if (!strcmp(arg, "-allow_proxy_certs"))
+ flags |= X509_V_FLAG_ALLOW_PROXY_CERTS;
else
return 0;
diff --git a/crypto/x509/x509.h b/crypto/x509/x509.h
index fc613ce..6fa28eb 100644
--- a/crypto/x509/x509.h
+++ b/crypto/x509/x509.h
@@ -1234,6 +1234,7 @@ int X509_TRUST_get_trust(X509_TRUST *xp);
* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
*/
+
void ERR_load_X509_strings(void);
/* Error codes for the X509 functions. */
@@ -1241,6 +1242,7 @@ void ERR_load_X509_strings(void);
/* Function codes. */
# define X509_F_ADD_CERT_DIR 100
# define X509_F_BY_FILE_CTRL 101
+# define X509_F_CHECK_NAME_CONSTRAINTS 106
# define X509_F_CHECK_POLICY 145
# define X509_F_DIR_CTRL 102
# define X509_F_GET_CERT_BY_SUBJECT 103
@@ -1322,7 +1324,7 @@ void ERR_load_X509_strings(void);
# define X509_R_WRONG_LOOKUP_TYPE 112
# define X509_R_WRONG_TYPE 122
-#ifdef __cplusplus
+# ifdef __cplusplus
}
-#endif
+# endif
#endif
diff --git a/crypto/x509/x509_err.c b/crypto/x509/x509_err.c
index 1e779fe..a2a8e1b 100644
--- a/crypto/x509/x509_err.c
+++ b/crypto/x509/x509_err.c
@@ -1,6 +1,6 @@
/* crypto/x509/x509_err.c */
/* ====================================================================
- * Copyright (c) 1999-2012 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2016 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -72,6 +72,7 @@
static ERR_STRING_DATA X509_str_functs[] = {
{ERR_FUNC(X509_F_ADD_CERT_DIR), "ADD_CERT_DIR"},
{ERR_FUNC(X509_F_BY_FILE_CTRL), "BY_FILE_CTRL"},
+ {ERR_FUNC(X509_F_CHECK_NAME_CONSTRAINTS), "CHECK_NAME_CONSTRAINTS"},
{ERR_FUNC(X509_F_CHECK_POLICY), "CHECK_POLICY"},
{ERR_FUNC(X509_F_DIR_CTRL), "DIR_CTRL"},
{ERR_FUNC(X509_F_GET_CERT_BY_SUBJECT), "GET_CERT_BY_SUBJECT"},
diff --git a/crypto/x509/x509_txt.c b/crypto/x509/x509_txt.c
index 4475715..35db095 100644
--- a/crypto/x509/x509_txt.c
+++ b/crypto/x509/x509_txt.c
@@ -208,6 +208,8 @@ const char *X509_verify_cert_error_string(long n)
return ("Invalid certificate verification context");
case X509_V_ERR_STORE_LOOKUP:
return ("Issuer certificate lookup error");
+ case X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION:
+ return ("proxy subject name violation");
default:
BIO_snprintf(buf, sizeof buf, "error number %ld", n);
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index f3fe255..389b1c2 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -713,13 +713,27 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
* the next certificate must be a CA certificate.
*/
if (x->ex_flags & EXFLAG_PROXY) {
- if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) {
- ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
- ctx->error_depth = i;
- ctx->current_cert = x;
- ok = cb(0, ctx);
- if (!ok)
- goto end;
+ /*
+ * RFC3820, 4.1.3 (b)(1) stipulates that if pCPathLengthConstraint
+ * is less than max_path_length, the former should be copied to
+ * the latter, and 4.1.4 (a) stipulates that max_path_length
+ * should be verified to be larger than zero and decrement it.
+ *
+ * Because we're checking the certs in the reverse order, we start
+ * with verifying that proxy_path_length isn't larger than pcPLC,
+ * and copy the latter to the former if it is, and finally,
+ * increment proxy_path_length.
+ */
+ if (x->ex_pcpathlen != -1) {
+ if (proxy_path_length > x->ex_pcpathlen) {
+ ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ ok = cb(0, ctx);
+ if (!ok)
+ goto end;
+ }
+ proxy_path_length = x->ex_pcpathlen;
}
proxy_path_length++;
must_be_ca = 0;
@@ -742,6 +756,81 @@ static int check_name_constraints(X509_STORE_CTX *ctx)
/* Ignore self issued certs unless last in chain */
if (i && (x->ex_flags & EXFLAG_SI))
continue;
+
+ /*
+ * Proxy certificates policy has an extra constraint, where the
+ * certificate subject MUST be the issuer with a single CN entry
+ * added.
+ * (RFC 3820: 3.4, 4.1.3 (a)(4))
+ */
+ if (x->ex_flags & EXFLAG_PROXY) {
+ X509_NAME *tmpsubject = X509_get_subject_name(x);
+ X509_NAME *tmpissuer = X509_get_issuer_name(x);
+ X509_NAME_ENTRY *tmpentry = NULL;
+ int last_object_nid = 0;
+ int err = X509_V_OK;
+ int last_object_loc = X509_NAME_entry_count(tmpsubject) - 1;
+
+ /* Check that there are at least two RDNs */
+ if (last_object_loc < 1) {
+ err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION;
+ goto proxy_name_done;
+ }
+
+ /*
+ * Check that there is exactly one more RDN in subject as
+ * there is in issuer.
+ */
+ if (X509_NAME_entry_count(tmpsubject)
+ != X509_NAME_entry_count(tmpissuer) + 1) {
+ err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION;
+ goto proxy_name_done;
+ }
+
+ /*
+ * Check that the last subject component isn't part of a
+ * multivalued RDN
+ */
+ if (X509_NAME_get_entry(tmpsubject, last_object_loc)->set
+ == X509_NAME_get_entry(tmpsubject, last_object_loc - 1)->set) {
+ err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION;
+ goto proxy_name_done;
+ }
+
+ /*
+ * Check that the last subject RDN is a commonName, and that
+ * all the previous RDNs match the issuer exactly
+ */
+ tmpsubject = X509_NAME_dup(tmpsubject);
+ if (tmpsubject == NULL) {
+ X509err(X509_F_CHECK_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
+ ctx->error = X509_V_ERR_OUT_OF_MEM;
+ return 0;
+ }
+
+ tmpentry =
+ X509_NAME_delete_entry(tmpsubject, last_object_loc);
+ last_object_nid =
+ OBJ_obj2nid(X509_NAME_ENTRY_get_object(tmpentry));
+
+ if (last_object_nid != NID_commonName
+ || X509_NAME_cmp(tmpsubject, tmpissuer) != 0) {
+ err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION;
+ }
+
+ X509_NAME_ENTRY_free(tmpentry);
+ X509_NAME_free(tmpsubject);
+
+ proxy_name_done:
+ if (err != X509_V_OK) {
+ ctx->error = err;
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ if (!ctx->verify_cb(0, ctx))
+ return 0;
+ }
+ }
+
/*
* Check against constraints for all certificates higher in chain
* including trust anchor. Trust anchor not strictly speaking needed
diff --git a/crypto/x509/x509_vfy.h b/crypto/x509/x509_vfy.h
index f54ecc5..5062682 100644
--- a/crypto/x509/x509_vfy.h
+++ b/crypto/x509/x509_vfy.h
@@ -392,6 +392,8 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
/* Issuer lookup error */
# define X509_V_ERR_STORE_LOOKUP 66
+# define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 67
+
/* Certificate verify flags */
/* Send issuer+subject checks to verify_cb */
diff --git a/doc/apps/verify.pod b/doc/apps/verify.pod
index bffa6c0..b376732 100644
--- a/doc/apps/verify.pod
+++ b/doc/apps/verify.pod
@@ -27,6 +27,7 @@ B<openssl> B<verify>
[B<-use_deltas>]
[B<-policy_print>]
[B<-no_alt_chains>]
+[B<-allow_proxy_certs>]
[B<-untrusted file>]
[B<-help>]
[B<-issuer_checks>]
@@ -139,6 +140,10 @@ be found that is trusted. With this option that behaviour is suppressed so that
only the first chain found is ever used. Using this option will force the
behaviour to match that of previous OpenSSL versions.
+=item B<-allow_proxy_certs>
+
+Allow the verification of proxy certificates.
+
=item B<-trusted file>
A file of additional trusted certificates. The file should contain multiple
More information about the openssl-commits
mailing list