]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
Added gnutls_x509_name_constraints_check_crt
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Wed, 19 Feb 2014 09:19:43 +0000 (10:19 +0100)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Wed, 19 Feb 2014 09:19:43 +0000 (10:19 +0100)
This function will check name constraints against all the names
in a certificate.

NEWS
lib/includes/gnutls/x509.h
lib/libgnutls.map
lib/x509/name_constraints.c

diff --git a/NEWS b/NEWS
index 654eb93fa0203f57e4624aa99d67190d21abdb03..390754c9179f7fcb136cfcbd7f97a6f59f559ed1 100644 (file)
--- 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)
index 4cf109a7adb45c0f2f8b10d5b18286ffe10ff8ec..7cc0062c8830874c7df5d828edd6c922b8910aa3 100644 (file)
@@ -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);
index b4cdd3c6ce977429ad7e45b233f7ec2fa90b0224..c92d6db4fb9829c0b1914be7446251c6cea2d535 100644 (file)
@@ -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 {
index 2c0da148e6b8ab538f18a20b70aa8b72ce98f176..6c22f92914802785a3199f75f23f5fd3c7697668 100644 (file)
@@ -680,6 +680,121 @@ unsigned gnutls_x509_name_constraints_check(gnutls_x509_name_constraints_t nc,
        return check_unsupported_constraint(nc, type);
 }
 
+/**
+ * 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