diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2013-12-16 12:56:02 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2013-12-16 13:10:09 +0100 |
commit | 7e30a3b578c24a7762e43bb353d21ab425584258 (patch) | |
tree | 994ccb730c1ebd92851b42cc09af05f37a6a0bc4 | |
parent | 9872063efaefa06eabc9125c2fa5bb15e0418705 (diff) | |
download | gnutls-7e30a3b578c24a7762e43bb353d21ab425584258.tar.gz |
gnutls_x509_trust_list_remove_cas() and derivatives will utilize a black list.
When a CA or certificate is removed from the trusted list, it is also
added in a blacklist to ensure that it will not be accepted due to
interdependency (e.g., it is a subordinate CA), or because it is not a CA.
-rw-r--r-- | lib/x509/verify-high.c | 84 | ||||
-rw-r--r-- | lib/x509/verify-high2.c | 9 |
2 files changed, 90 insertions, 3 deletions
diff --git a/lib/x509/verify-high.c b/lib/x509/verify-high.c index 72e6656519..4156f7671c 100644 --- a/lib/x509/verify-high.c +++ b/lib/x509/verify-high.c @@ -50,11 +50,15 @@ struct node_st { /* The trusted CRLs */ gnutls_x509_crl_t *crls; unsigned int crl_size; + }; struct gnutls_x509_trust_list_st { unsigned int size; struct node_st *node; + + gnutls_x509_crt_t *blacklisted; + unsigned int blacklisted_size; }; #define DEFAULT_SIZE 127 @@ -115,6 +119,11 @@ gnutls_x509_trust_list_deinit(gnutls_x509_trust_list_t list, if (!list) return; + for (j = 0; j < list->blacklisted_size; j++) { + gnutls_x509_crt_deinit(list->blacklisted[j]); + } + gnutls_free(list->blacklisted); + for (i = 0; i < list->size; i++) { if (all) for (j = 0; j < list->node[i].trusted_ca_size; j++) { @@ -123,6 +132,7 @@ gnutls_x509_trust_list_deinit(gnutls_x509_trust_list_t list, } gnutls_free(list->node[i].trusted_cas); + if (all) for (j = 0; j < list->node[i].crl_size; j++) { gnutls_x509_crl_deinit(list->node[i]. @@ -191,6 +201,26 @@ gnutls_x509_trust_list_add_cas(gnutls_x509_trust_list_t list, return i; } +static gnutls_x509_crt_t crt_cpy(gnutls_x509_crt_t src) +{ +gnutls_x509_crt_t dst; +int ret; + + ret = gnutls_x509_crt_init(&dst); + if (ret < 0) { + gnutls_assert(); + return NULL; + } + + ret = _gnutls_x509_crt_cpy(dst, src); + if (ret < 0) { + gnutls_assert(); + return NULL; + } + + return dst; +} + /** * gnutls_x509_trust_list_remove_cas: * @list: The structure of the list @@ -198,7 +228,13 @@ gnutls_x509_trust_list_add_cas(gnutls_x509_trust_list_t list, * @clist_size: The length of the CA list * * This function will remove the given certificate authorities - * from the trusted list. + * from the trusted list. + * + * Note that this function can accept certificates and authorities + * not yet known. In that case they will be kept in a separate + * black list that will be used during certificate verification. + * Unlike gnutls_x509_trust_list_add_cas() there is no deinitialization + * restriction for certificate list provided in this function. * * Returns: The number of removed elements is returned. * @@ -223,6 +259,8 @@ gnutls_x509_trust_list_remove_cas(gnutls_x509_trust_list_t list, if (_gnutls_check_if_same_cert (clist[i], list->node[hash].trusted_cas[j]) != 0) { + + fprintf(stderr, "removing CA with hash %.4x\n", (unsigned)hash); gnutls_x509_crt_deinit(list->node[hash]. trusted_cas[j]); list->node[hash].trusted_cas[j] = @@ -233,8 +271,24 @@ gnutls_x509_trust_list_remove_cas(gnutls_x509_trust_list_t list, - 1]; list->node[hash].trusted_ca_size--; r++; + break; } } + + /* Add the CA (or plain) certificate to the black list as well. + * This will prevent a subordinate CA from being valid, and + * ensure that a server certificate will also get rejected. + */ + list->blacklisted = + gnutls_realloc_fast(list->blacklisted, + (list->blacklisted_size + 1) * + sizeof(list->blacklisted[0])); + if (list->blacklisted == NULL) + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + + list->blacklisted[list->blacklisted_size] = crt_cpy(clist[i]); + if (list->blacklisted[list->blacklisted_size] != NULL) + list->blacklisted_size++; } return r; @@ -538,6 +592,26 @@ int gnutls_x509_trust_list_get_issuer(gnutls_x509_trust_list_t list, return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; } +static +int check_if_in_blacklist(gnutls_x509_crt_t * cert_list, unsigned int cert_list_size, + gnutls_x509_crt_t * blacklist, unsigned int blacklist_size) +{ +unsigned i, j; + + if (blacklist_size == 0) + return 0; + + for (i=0;i<cert_list_size;i++) { + for (j=0;j<blacklist_size;j++) { + if (_gnutls_check_if_same_cert(cert_list[i], blacklist[j]) != 0) { + return 1; + } + } + } + + return 0; +} + /** * gnutls_x509_trust_list_verify_crt: * @list: The structure of the list @@ -586,6 +660,14 @@ gnutls_x509_trust_list_verify_crt(gnutls_x509_trust_list_t list, 1]->raw_issuer_dn.size); hash %= list->size; + ret = check_if_in_blacklist(cert_list, cert_list_size, + list->blacklisted, list->blacklisted_size); + if (ret != 0) { + *verify |= GNUTLS_CERT_REVOKED; + *verify |= GNUTLS_CERT_INVALID; + return 0; + } + *verify = _gnutls_x509_verify_certificate(cert_list, cert_list_size, list->node[hash].trusted_cas, diff --git a/lib/x509/verify-high2.c b/lib/x509/verify-high2.c index 36ee214c4a..1c3c365026 100644 --- a/lib/x509/verify-high2.c +++ b/lib/x509/verify-high2.c @@ -114,7 +114,9 @@ gnutls_x509_trust_list_add_trust_mem(gnutls_x509_trust_list_t list, * @type: The format of the certificates * * This function will remove the provided certificate authorities - * from the trusted list. + * from the trusted list, and add them into a black list when needed. + * + * See also gnutls_x509_trust_list_remove_cas(). * * Returns: The number of removed elements is returned. * @@ -330,9 +332,12 @@ gnutls_x509_trust_list_add_trust_file(gnutls_x509_trust_list_t list, * @type: The format of the certificates * * This function will remove the given certificate authorities - * from the trusted list. pkcs11 URLs are also accepted, instead + * from the trusted list, and add them into a black list when needed. + * PKCS 11 URLs are also accepted, instead * of files, by this function. * + * See also gnutls_x509_trust_list_remove_cas(). + * * Returns: The number of added elements is returned. * * Since: 3.1.10 |