]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
GNUTLS_E_CERTIFICATE_LIST_UNSORTED can be returned from gnutls_pcert_import_x509_list
authorNikos Mavrogiannopoulos <nmav@gnutls.org>
Thu, 27 Nov 2014 21:39:08 +0000 (22:39 +0100)
committerNikos Mavrogiannopoulos <nmav@gnutls.org>
Thu, 27 Nov 2014 22:08:21 +0000 (23:08 +0100)
That is when it cannot sort the list and GNUTLS_X509_CRT_LIST_SORT is specified.

lib/gnutls_pcert.c
lib/gnutls_x509.c
lib/x509/common.c
lib/x509/common.h
lib/x509/x509.c

index 580bb48bdc6aea2f3c7549ddfe12c9a448750e8f..53e9a21d3a952a7c6efabd64d6849cc87eed6b2f 100644 (file)
@@ -96,6 +96,11 @@ int gnutls_pcert_import_x509(gnutls_pcert_st * pcert,
  * #gnutls_pcert_st structure. The structure must be deinitialized
  * afterwards using gnutls_pcert_deinit();
  *
+ * In the case %GNUTLS_X509_CRT_LIST_SORT is specified and that
+ * function cannot sort the list, %GNUTLS_E_CERTIFICATE_LIST_UNSORTED
+ * will be returned. Currently sorting can fail if the list size
+ * exceeds an internal constraint (16).
+ *
  * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
  *   negative error value.
  *
@@ -112,11 +117,20 @@ int gnutls_pcert_import_x509_list(gnutls_pcert_st * pcert,
        gnutls_x509_crt_t *s;
 
        s = crt;
-       if (flags & GNUTLS_X509_CRT_LIST_SORT && *ncrt > 1 && *ncrt < DEFAULT_MAX_VERIFY_DEPTH) {
-               s = _gnutls_sort_clist(sorted, crt, ncrt, NULL);
-               if (s == crt) {
-                       gnutls_assert();
-                       return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+
+       if (flags & GNUTLS_X509_CRT_LIST_SORT && *ncrt > 1) {
+               if (*ncrt > DEFAULT_MAX_VERIFY_DEPTH) {
+                       ret = _gnutls_check_if_sorted(crt, *ncrt);
+                       if (ret < 0) {
+                               gnutls_assert();
+                               return GNUTLS_E_CERTIFICATE_LIST_UNSORTED;
+                       }
+               } else {
+                       s = _gnutls_sort_clist(sorted, crt, ncrt, NULL);
+                       if (s == crt) {
+                               gnutls_assert();
+                               return GNUTLS_E_UNIMPLEMENTED_FEATURE;
+                       }
                }
        }
 
index c9b099b55caeb4fe19a36ee8a4e29aadbe967d27..8703cd96e21430c0d41afb0ca27f6805ed7c4abc 100644 (file)
@@ -949,51 +949,6 @@ gnutls_certificate_set_x509_key_mem2(gnutls_certificate_credentials_t res,
        return 0;
 }
 
-static int check_if_sorted(gnutls_pcert_st * crt, int nr)
-{
-       gnutls_x509_crt_t x509;
-       gnutls_x509_crt_t prev = NULL;
-       int i, ret;
-
-       /* check if the X.509 list is ordered */
-       if (nr > 1 && crt[0].type == GNUTLS_CRT_X509) {
-
-               for (i = 0; i < nr; i++) {
-                       ret = gnutls_x509_crt_init(&x509);
-                       if (ret < 0)
-                               return gnutls_assert_val(ret);
-                       ret =
-                           gnutls_x509_crt_import(x509, &crt[i].cert,
-                                                  GNUTLS_X509_FMT_DER);
-                       if (ret < 0) {
-                               ret = gnutls_assert_val(ret);
-                               goto cleanup;
-                       }
-
-                       if (i > 0) {
-                               if (gnutls_x509_crt_check_issuer(prev, x509) == 0) {
-                                       ret =
-                                           gnutls_assert_val
-                                           (GNUTLS_E_CERTIFICATE_LIST_UNSORTED);
-                                       goto cleanup;
-                               }
-
-                               gnutls_x509_crt_deinit(prev);
-                       }
-
-                       prev = x509;
-               }
-               gnutls_x509_crt_deinit(prev);
-       }
-
-       return 0;
-
-cleanup:
-       gnutls_x509_crt_deinit(prev);
-       gnutls_x509_crt_deinit(x509);
-       return ret;
-}
-
 int
 certificate_credential_append_crt_list(gnutls_certificate_credentials_t
                                       res, gnutls_str_array_t names,
@@ -1001,10 +956,6 @@ certificate_credential_append_crt_list(gnutls_certificate_credentials_t
 {
        int ret;
 
-       ret = check_if_sorted(crt, nr);
-       if (ret < 0)
-               return gnutls_assert_val(ret);
-
        res->certs = gnutls_realloc_fast(res->certs,
                                         (1 + res->ncerts) *
                                         sizeof(certs_st));
index a34cdd5582f9104f1c30fabe7df040c76717cd16..cfb4ad9195edc33ea404b3132c67667bb1fa3fbe 100644 (file)
@@ -2048,3 +2048,36 @@ gnutls_x509_crt_t *_gnutls_sort_clist(gnutls_x509_crt_t
 
        return sorted;
 }
+
+int _gnutls_check_if_sorted(gnutls_x509_crt_t * crt, int nr)
+{
+       void *prev_dn = NULL;
+       void *dn;
+       size_t prev_dn_size = 0, dn_size;
+       int i, ret;
+
+       /* check if the X.509 list is ordered */
+       if (nr > 1) {
+               for (i = 0; i < nr; i++) {
+                       if (i > 0) {
+                               dn = crt[i]->raw_dn.data;
+                               dn_size = crt[i]->raw_dn.size;
+
+                               if (dn_size != prev_dn_size
+                                   || memcmp(dn, prev_dn, dn_size) != 0) {
+                                       ret =
+                                           gnutls_assert_val
+                                           (GNUTLS_E_CERTIFICATE_LIST_UNSORTED);
+                                       goto cleanup;
+                               }
+                       }
+
+                       prev_dn = crt[i]->raw_issuer_dn.data;
+                       prev_dn_size = crt[i]->raw_issuer_dn.size;
+               }
+       }
+       ret = 0;
+
+cleanup:
+       return ret;
+}
index f319b5be1e151b9ac325c2a201840f7fb8f9ef61..e7431e8c0109c7d06ec74a7639732e51f56a5cee 100644 (file)
@@ -240,4 +240,6 @@ gnutls_x509_crt_t *_gnutls_sort_clist(gnutls_x509_crt_t
                                     unsigned int *clist_size,
                                     gnutls_cert_vfunc func);
 
+int _gnutls_check_if_sorted(gnutls_x509_crt_t * crt, int nr);
+
 #endif
index d2b594876c43a61ba116752a4a38c9e8434b64fb..83b127259733334beffd32f626dbf67ba1e13868 100644 (file)
@@ -3281,40 +3281,6 @@ gnutls_x509_crt_list_import2(gnutls_x509_crt_t ** certs,
        return 0;
 }
 
-static int check_if_sorted(gnutls_x509_crt_t * crt, int nr)
-{
-       void *prev_dn = NULL;
-       void *dn;
-       size_t prev_dn_size = 0, dn_size;
-       int i, ret;
-
-       /* check if the X.509 list is ordered */
-       if (nr > 1) {
-               for (i = 0; i < nr; i++) {
-                       if (i > 0) {
-                               dn = crt[i]->raw_dn.data;
-                               dn_size = crt[i]->raw_dn.size;
-
-                               if (dn_size != prev_dn_size
-                                   || memcmp(dn, prev_dn, dn_size) != 0) {
-                                       ret =
-                                           gnutls_assert_val
-                                           (GNUTLS_E_CERTIFICATE_LIST_UNSORTED);
-                                       goto cleanup;
-                               }
-                       }
-
-                       prev_dn = crt[i]->raw_issuer_dn.data;
-                       prev_dn_size = crt[i]->raw_issuer_dn.size;
-               }
-       }
-       ret = 0;
-
-cleanup:
-       return ret;
-}
-
-
 /**
  * gnutls_x509_crt_list_import:
  * @certs: The structures to store the parsed certificate. Must not be initialized.
@@ -3463,7 +3429,7 @@ gnutls_x509_crt_list_import(gnutls_x509_crt_t * certs,
        }
 
        if (flags & GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED) {
-               ret = check_if_sorted(certs, *cert_max);
+               ret = _gnutls_check_if_sorted(certs, *cert_max);
                if (ret < 0) {
                        gnutls_assert();
                        goto error;