diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2014-02-19 10:19:43 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2014-02-19 10:19:43 +0100 |
commit | c62c660fd884ae7aab5d64b7c856dc0398c3057c (patch) | |
tree | 0c1da26c8da03309bf487bb270fd1704670c50f8 | |
parent | 7375d8c0ae30ade0ac805914b8cee31a80913398 (diff) | |
download | gnutls-c62c660fd884ae7aab5d64b7c856dc0398c3057c.tar.gz |
Added gnutls_x509_name_constraints_check_crt
This function will check name constraints against all the names
in a certificate.
-rw-r--r-- | NEWS | 1 | ||||
-rw-r--r-- | lib/includes/gnutls/x509.h | 3 | ||||
-rw-r--r-- | lib/libgnutls.map | 1 | ||||
-rw-r--r-- | lib/x509/name_constraints.c | 115 |
4 files changed, 120 insertions, 0 deletions
@@ -103,6 +103,7 @@ gnutls_x509_crt_set_name_constraints: Added gnutls_x509_name_constraints_get_permitted: Added gnutls_x509_name_constraints_get_excluded: Added gnutls_x509_name_constraints_check: Added +gnutls_x509_name_constraints_check_crt: Added gnutls_digest_self_test: Added (conditionally) gnutls_mac_self_test: Added (conditionally) gnutls_pk_self_test: Added (conditionally) diff --git a/lib/includes/gnutls/x509.h b/lib/includes/gnutls/x509.h index 4cf109a7ad..7cc0062c88 100644 --- a/lib/includes/gnutls/x509.h +++ b/lib/includes/gnutls/x509.h @@ -238,6 +238,9 @@ typedef struct gnutls_name_constraints_st *gnutls_x509_name_constraints_t; unsigned gnutls_x509_name_constraints_check(gnutls_x509_name_constraints_t nc, gnutls_x509_subject_alt_name_t type, const gnutls_datum_t * name); +unsigned gnutls_x509_name_constraints_check_crt(gnutls_x509_name_constraints_t nc, + gnutls_x509_subject_alt_name_t type, + gnutls_x509_crt_t crt); int gnutls_x509_name_constraints_init(gnutls_x509_name_constraints_t *nc); void gnutls_x509_name_constraints_deinit(gnutls_x509_name_constraints_t nc); diff --git a/lib/libgnutls.map b/lib/libgnutls.map index b4cdd3c6ce..c92d6db4fb 100644 --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -952,6 +952,7 @@ GNUTLS_3_1_0 { gnutls_x509_name_constraints_get_permitted; gnutls_x509_name_constraints_get_excluded; gnutls_x509_name_constraints_check; + gnutls_x509_name_constraints_check_crt; } GNUTLS_3_0_0; GNUTLS_PRIVATE { diff --git a/lib/x509/name_constraints.c b/lib/x509/name_constraints.c index 2c0da148e6..6c22f92914 100644 --- a/lib/x509/name_constraints.c +++ b/lib/x509/name_constraints.c @@ -681,6 +681,121 @@ unsigned gnutls_x509_name_constraints_check(gnutls_x509_name_constraints_t nc, } /** + * gnutls_x509_name_constraints_check_crt: + * @nc: the extracted name constraints structure + * @type: the type of the constraint to check (of type gnutls_x509_subject_alt_name_t) + * @cert: the certificate to be checked + * + * This function will check the provided certificate names against the constraints in + * @nc using the RFC5280 rules. It will traverse all the certificate's names and + * alternative names. + * + * Currently this function is limited to DNS + * names and emails (of type %GNUTLS_SAN_DNSNAME and %GNUTLS_SAN_RFC822NAME). + * + * Returns: zero if the provided name is not acceptable, and non-zero otherwise. + * + * Since: 3.3.0 + **/ +unsigned gnutls_x509_name_constraints_check_crt(gnutls_x509_name_constraints_t nc, + gnutls_x509_subject_alt_name_t type, + gnutls_x509_crt_t cert) +{ +char name[MAX_CN]; +size_t name_size; +int ret; +unsigned idx, t, san_type; +gnutls_datum_t n; + + if (type == GNUTLS_SAN_RFC822NAME) { + idx = 0; + do { + name_size = sizeof(name); + ret = gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_PKCS9_EMAIL, + idx++, 0, name, &name_size); + if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) + break; + else if (ret < 0) + return gnutls_assert_val(0); + + n.data = (void*)name; + n.size = name_size; + t = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_RFC822NAME, + &n); + if (t == 0) + return gnutls_assert_val(t); + } while(ret >= 0); + + idx = 0; + do { + name_size = sizeof(name); + ret = gnutls_x509_crt_get_subject_alt_name2(cert, + idx++, name, &name_size, &san_type, NULL); + if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) + break; + else if (ret < 0) + return gnutls_assert_val(0); + + if (san_type != GNUTLS_SAN_RFC822NAME) + continue; + + n.data = (void*)name; + n.size = name_size; + t = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_RFC822NAME, + &n); + if (t == 0) + return gnutls_assert_val(t); + } while(ret >= 0); + + /* passed */ + return 1; + } else if (type == GNUTLS_SAN_DNSNAME) { + idx = 0; + do { + name_size = sizeof(name); + ret = gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME, + idx++, 0, name, &name_size); + if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) + break; + else if (ret < 0) + return gnutls_assert_val(0); + + n.data = (void*)name; + n.size = name_size; + t = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_DNSNAME, + &n); + if (t == 0) + return gnutls_assert_val(t); + } while(ret >= 0); + + idx = 0; + do { + name_size = sizeof(name); + ret = gnutls_x509_crt_get_subject_alt_name2(cert, + idx++, name, &name_size, &san_type, NULL); + if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) + break; + else if (ret < 0) + return gnutls_assert_val(0); + + if (san_type != GNUTLS_SAN_DNSNAME) + continue; + + n.data = (void*)name; + n.size = name_size; + t = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_DNSNAME, + &n); + if (t == 0) + return gnutls_assert_val(t); + } while(ret >= 0); + + /* passed */ + return 1; + } else + return check_unsupported_constraint(nc, type); +} + +/** * gnutls_x509_name_constraints_get_permitted: * @nc: the extracted name constraints structure * @idx: the index of the constraint |