提交 c8223538 编写于 作者: R Richard Levitte

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: NRich Salz <rsalz@openssl.org>
Reviewed-by: NStephen Henson <steve@openssl.org>
上级 54f24e3e
......@@ -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 */
......
......@@ -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
......
......@@ -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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册