diff options
Diffstat (limited to 'lib/x509/x509.c')
-rw-r--r-- | lib/x509/x509.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/lib/x509/x509.c b/lib/x509/x509.c index 2adb899914..758490100b 100644 --- a/lib/x509/x509.c +++ b/lib/x509/x509.c @@ -3073,6 +3073,52 @@ int ret; return 0; } +static int check_if_sorted(gnutls_x509_crt_t * crt, int nr) +{ +char prev_dn[MAX_DN]; +char dn[MAX_DN]; +size_t prev_dn_size, 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_size = sizeof(dn); + ret = gnutls_x509_crt_get_dn(crt[i], dn, &dn_size); + if (ret < 0) + { + ret = gnutls_assert_val(ret); + goto cleanup; + } + + 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_size = sizeof(prev_dn); + ret = gnutls_x509_crt_get_issuer_dn(crt[i], prev_dn, &prev_dn_size); + if (ret < 0) + { + ret = gnutls_assert_val(ret); + goto cleanup; + } + } + } + + ret = 0; + +cleanup: + return ret; +} + /** * gnutls_x509_crt_list_import: @@ -3086,6 +3132,12 @@ int ret; * to the native gnutls_x509_crt_t format. The output will be stored * in @certs. They will be automatically initialized. * + * The flag %GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED will cause + * import to fail if the certificates in the provided buffer are more + * than the available structures. The %GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED + * flag will cause the function to fail if the provided list is not + * sorted from subject to issuer. + * * If the Certificate is PEM encoded it should have a header of "X509 * CERTIFICATE", or "CERTIFICATE". * @@ -3205,6 +3257,16 @@ gnutls_x509_crt_list_import (gnutls_x509_crt_t * certs, *cert_max = count; + if (flags & GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED) + { + ret = check_if_sorted(certs, *cert_max); + if (ret < 0) + { + gnutls_assert(); + goto error; + } + } + if (nocopy == 0) return count; else |