summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2014-02-19 10:19:43 +0100
committerNikos Mavrogiannopoulos <nmav@redhat.com>2014-02-19 10:19:43 +0100
commitc62c660fd884ae7aab5d64b7c856dc0398c3057c (patch)
tree0c1da26c8da03309bf487bb270fd1704670c50f8
parent7375d8c0ae30ade0ac805914b8cee31a80913398 (diff)
downloadgnutls-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--NEWS1
-rw-r--r--lib/includes/gnutls/x509.h3
-rw-r--r--lib/libgnutls.map1
-rw-r--r--lib/x509/name_constraints.c115
4 files changed, 120 insertions, 0 deletions
diff --git a/NEWS b/NEWS
index 654eb93fa0..390754c917 100644
--- a/NEWS
+++ b/NEWS
@@ -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