]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
when verifying name constrains enforce the single CN rule
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Tue, 26 Aug 2014 09:22:37 +0000 (11:22 +0200)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Tue, 26 Aug 2014 10:02:37 +0000 (12:02 +0200)
lib/x509/name_constraints.c

index cd7341cd0d1a2a90f08def8e3e68bd07554ddfb2..29dca30bfbef24417487cc87abdc42a3a20a701b 100644 (file)
@@ -622,29 +622,36 @@ unsigned found_one;
                                return gnutls_assert_val(t);
                } while(ret >= 0);
 
-               if (found_one != 0)
-                       return 1;
 
-               idx = 0;
                do {
+                       /* ensure there is only a single EMAIL, similarly to CN handling (rfc6125) */
+                       name_size = sizeof(name);
+                       ret = gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_PKCS9_EMAIL,
+                                                           1, 0, name, &name_size);
+                       if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+                               return gnutls_assert_val(0);
+
                        name_size = sizeof(name);
                        ret = gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_PKCS9_EMAIL,
-                               idx++, 0, name, &name_size);
+                                                           0, 0, name, &name_size);
                        if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
                                break;
                        else if (ret < 0)
                                return gnutls_assert_val(0);
 
+                       found_one = 1;
                        n.data = (void*)name;
                        n.size = name_size;
-                       t = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_RFC822NAME,
-                               &n);
+                       t = gnutls_x509_name_constraints_check(nc, GNUTLS_SAN_RFC822NAME, &n);
                        if (t == 0)
                                return gnutls_assert_val(t);
-               } while(ret >= 0);
+               } while(0);
 
                /* passed */
-               return 1;
+               if (found_one != 0)
+                       return 1;
+               else /* nothing was found */
+                       return 0;
        } else if (type == GNUTLS_SAN_DNSNAME) {
                idx = found_one = 0;
                do {
@@ -668,29 +675,38 @@ unsigned found_one;
                                return gnutls_assert_val(t);
                } while(ret >= 0);
 
-               if (found_one != 0)
-                       return 1;
 
-               idx = 0;
+               /* verify the name constraints against the CN as well */
                do {
+                       /* ensure there is only a single CN, according to rfc6125 */
+                       name_size = sizeof(name);
+                       ret = gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME,
+                                                           1, 0, name, &name_size);
+                       if (ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
+                               return gnutls_assert_val(0);
+
                        name_size = sizeof(name);
                        ret = gnutls_x509_crt_get_dn_by_oid(cert, GNUTLS_OID_X520_COMMON_NAME,
-                               idx++, 0, name, &name_size);
+                                                           0, 0, name, &name_size);
                        if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE)
                                break;
                        else if (ret < 0)
                                return gnutls_assert_val(0);
 
+                       found_one = 1;
                        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);
+               } while(0);
 
                /* passed */
-               return 1;
+               if (found_one != 0)
+                       return 1;
+               else /* nothing was found */
+                       return 0;
        } else
                return check_unsupported_constraint(nc, type);
 }