static int trust_list_get_issuer_by_dn(gnutls_x509_trust_list_t list, const gnutls_datum_t *dn, const gnutls_datum_t *spki, gnutls_x509_crt_t * issuer, unsigned int flags) { int ret; unsigned int i, j; uint32_t hash; uint8_t tmp[256]; size_t tmp_size; if (dn) { hash = hash_pjw_bare(dn->data, dn->size); hash %= list->size; for (i = 0; i < list->node[hash].trusted_ca_size; i++) { ret = _gnutls_x509_compare_raw_dn(dn, &list->node[hash].trusted_cas[i]->raw_dn); if (ret != 0) { if (spki && spki->size > 0) { tmp_size = sizeof(tmp); ret = gnutls_x509_crt_get_subject_key_id(list->node[hash].trusted_cas[i], tmp, &tmp_size, NULL); if (ret < 0) continue; if (spki->size != tmp_size || memcmp(spki->data, tmp, spki->size) != 0) continue; } *issuer = crt_cpy(list->node[hash].trusted_cas[i]); return 0; } } } else if (spki) { /* search everything! */ for (i = 0; i < list->size; i++) { for (j = 0; j < list->node[i].trusted_ca_size; j++) { tmp_size = sizeof(tmp); ret = gnutls_x509_crt_get_subject_key_id(list->node[i].trusted_cas[j], tmp, &tmp_size, NULL); if (ret < 0) continue; if (spki->size != tmp_size || memcmp(spki->data, tmp, spki->size) != 0) continue; *issuer = crt_cpy(list->node[i].trusted_cas[j]); return 0; } } } return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; }
static int trust_list_get_issuer_by_dn(gnutls_x509_trust_list_t list, const gnutls_datum_t *dn, gnutls_x509_crt_t * issuer, unsigned int flags) { int ret; unsigned int i; uint32_t hash; hash = hash_pjw_bare(dn->data, dn->size); hash %= list->size; for (i = 0; i < list->node[hash].trusted_ca_size; i++) { ret = _gnutls_x509_compare_raw_dn(dn, &list->node[hash].trusted_cas[i]->raw_dn); if (ret != 0) { *issuer = crt_cpy(list->node[hash].trusted_cas[i]); return 0; } } return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; }
static int trust_list_get_issuer(gnutls_x509_trust_list_t list, gnutls_x509_crt_t cert, gnutls_x509_crt_t * issuer, unsigned int flags) { int ret; unsigned int i; uint32_t hash; hash = hash_pjw_bare(cert->raw_issuer_dn.data, cert->raw_issuer_dn.size); hash %= list->size; for (i = 0; i < list->node[hash].trusted_ca_size; i++) { ret = gnutls_x509_crt_check_issuer(cert, list->node[hash]. trusted_cas[i]); if (ret != 0) { if (flags & GNUTLS_TL_GET_COPY) { *issuer = crt_cpy(list->node[hash].trusted_cas[i]); } else { *issuer = list->node[hash].trusted_cas[i]; } return 0; } } return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE; }
/** * gnutls_x509_trust_list_remove_cas: * @list: The structure of the list * @clist: A list of CAs * @clist_size: The length of the CA list * * This function will remove the given certificate authorities * 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. * * Since: 3.1.10 **/ int gnutls_x509_trust_list_remove_cas(gnutls_x509_trust_list_t list, const gnutls_x509_crt_t * clist, int clist_size) { int i, r = 0; unsigned j; uint32_t hash; for (i = 0; i < clist_size; i++) { hash = hash_pjw_bare(clist[i]->raw_dn.data, clist[i]->raw_dn.size); hash %= list->size; for (j = 0; j < list->node[hash].trusted_ca_size; j++) { if (_gnutls_check_if_same_cert (clist[i], list->node[hash].trusted_cas[j]) != 0) { gnutls_x509_crt_deinit(list->node[hash]. trusted_cas[j]); list->node[hash].trusted_cas[j] = list->node[hash].trusted_cas[list-> node [hash]. trusted_ca_size - 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; }