summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2016-06-19 10:55:16 +0200
committerRichard Levitte <levitte@openssl.org>2016-06-20 21:34:37 +0200
commitc8223538cb05e5aac6418a5ba6dc4775b7ab486b (patch)
tree470e805fe8d9dc9da5fbfca69ee103c86a0dec8a
parent54f24e3ed411b19a3647a0aa114b0ea20421bbe7 (diff)
downloadopenssl-new-c8223538cb05e5aac6418a5ba6dc4775b7ab486b.tar.gz
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@openssl.org> Reviewed-by: Stephen Henson <steve@openssl.org>
-rw-r--r--crypto/x509/x509_txt.c2
-rw-r--r--crypto/x509/x509_vfy.c73
-rw-r--r--include/openssl/x509_vfy.h2
3 files changed, 77 insertions, 0 deletions
diff --git a/crypto/x509/x509_txt.c b/crypto/x509/x509_txt.c
index ae54de1c31..66e5fcd02f 100644
--- a/crypto/x509/x509_txt.c
+++ b/crypto/x509/x509_txt.c
@@ -167,6 +167,8 @@ const char *X509_verify_cert_error_string(long n)
return ("Issuer certificate lookup error");
case X509_V_ERR_NO_VALID_SCTS:
return ("Certificate Transparency required, but no valid SCTs found");
+ case X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION:
+ return ("proxy subject name violation");
default:
/* Printing an error number into a static buffer is not thread-safe */
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index a5e77896f8..360664a813 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -558,6 +558,79 @@ 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_ENTRY_set(X509_NAME_get_entry(tmpsubject,
+ last_object_loc))
+ == X509_NAME_ENTRY_set(X509_NAME_get_entry(tmpsubject,
+ last_object_loc - 1))) {
+ 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
+ && !verify_cb_cert(ctx, x, i, err))
+ return 0;
+ }
+
/*
* Check against constraints for all certificates higher in chain
* including trust anchor. Trust anchor not strictly speaking needed
diff --git a/include/openssl/x509_vfy.h b/include/openssl/x509_vfy.h
index f012265573..4e44e1daea 100644
--- a/include/openssl/x509_vfy.h
+++ b/include/openssl/x509_vfy.h
@@ -165,6 +165,8 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
/* Certificate transparency */
# define X509_V_ERR_NO_VALID_SCTS 71
+# define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 72
+
/* Certificate verify flags */
# if OPENSSL_API_COMPAT < 0x10100000L