/** * gnutls_certificate_set_x509_trust: * @res: is a #gnutls_certificate_credentials_t type. * @ca_list: is a list of trusted CAs * @ca_list_size: holds the size of the CA list * * This function adds the trusted CAs in order to verify client * or server certificates. In case of a client this is not required * to be called if the certificates are not verified using * gnutls_certificate_verify_peers2(). * This function may be called multiple times. * * In case of a server the CAs set here will be sent to the client if * a certificate request is sent. This can be disabled using * gnutls_certificate_send_x509_rdn_sequence(). * * Returns: the number of certificates processed or a negative error code * on error. * * Since: 2.4.0 **/ int gnutls_certificate_set_x509_trust(gnutls_certificate_credentials_t res, gnutls_x509_crt_t * ca_list, int ca_list_size) { int ret, i, j; gnutls_x509_crt_t *new_list = gnutls_malloc(ca_list_size * sizeof(gnutls_x509_crt_t)); if (!new_list) return GNUTLS_E_MEMORY_ERROR; for (i = 0; i < ca_list_size; i++) { ret = gnutls_x509_crt_init(&new_list[i]); if (ret < 0) { gnutls_assert(); goto cleanup; } ret = _gnutls_x509_crt_cpy(new_list[i], ca_list[i]); if (ret < 0) { gnutls_assert(); goto cleanup; } } ret = gnutls_x509_trust_list_add_cas(res->tlist, new_list, ca_list_size, GNUTLS_TL_USE_IN_TLS); if (ret < 0) { gnutls_assert(); goto cleanup; } gnutls_free(new_list); return ret; cleanup: for (j = 0; j < i; j++) gnutls_x509_crt_deinit(new_list[j]); gnutls_free(new_list); return ret; }
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_x509_crt_deinit(dst); gnutls_assert(); return NULL; } return dst; }
/** * gnutls_x509_trust_list_iter_get_ca: * @list: The structure of the list * @iter: A pointer to an iterator (initially the iterator should be %NULL) * @crt: where the certificate will be copied * * This function obtains a certificate in the trust list and advances the * iterator to the next certificate. The certificate returned in @crt must be * deallocated with gnutls_x509_crt_deinit(). * * When past the last element is accessed %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE * is returned and the iterator is reset. * * After use, the iterator must be deinitialized usin * gnutls_x509_trust_list_iter_deinit(). * * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a * negative error value. * * Since: 3.4.0 **/ int gnutls_x509_trust_list_iter_get_ca(gnutls_x509_trust_list_t list, gnutls_x509_trust_list_iter_t *iter, gnutls_x509_crt_t *crt) { int ret; /* initialize iterator */ if (*iter == NULL) { *iter = gnutls_malloc(sizeof (struct gnutls_x509_trust_list_iter)); if (*iter == NULL) return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); (*iter)->node_index = 0; (*iter)->ca_index = 0; #ifdef ENABLE_PKCS11 (*iter)->pkcs11_list = NULL; (*iter)->pkcs11_size = 0; (*iter)->pkcs11_index = 0; #endif /* Advance iterator to the first valid entry */ if (list->node[0].trusted_ca_size == 0) { ret = advance_iter(list, *iter); if (ret != 0) { gnutls_x509_trust_list_iter_deinit(*iter); *iter = NULL; *crt = NULL; return gnutls_assert_val(ret); } } } /* obtain the certificate at the current iterator position */ if ((*iter)->node_index < list->size) { ret = gnutls_x509_crt_init(crt); if (ret < 0) return gnutls_assert_val(ret); ret = _gnutls_x509_crt_cpy(*crt, list->node[(*iter)->node_index].trusted_cas[(*iter)->ca_index]); if (ret < 0) { gnutls_x509_crt_deinit(*crt); return gnutls_assert_val(ret); } } #ifdef ENABLE_PKCS11 else if ( (*iter)->pkcs11_index < (*iter)->pkcs11_size) { ret = gnutls_x509_crt_init(crt); if (ret < 0) return gnutls_assert_val(ret); ret = gnutls_x509_crt_import_pkcs11(*crt, (*iter)->pkcs11_list[(*iter)->pkcs11_index]); if (ret < 0) { gnutls_x509_crt_deinit(*crt); return gnutls_assert_val(ret); } } #endif else { /* iterator is at end */ gnutls_x509_trust_list_iter_deinit(*iter); *iter = NULL; *crt = NULL; return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE); } /* Move iterator to the next position. * GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE is returned if the iterator * has been moved to the end position. That is okay, we return the * certificate that we read and when this function is called again we * report GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE to our caller. */ ret = advance_iter(list, *iter); if (ret < 0 && ret != GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { gnutls_x509_crt_deinit(*crt); *crt = NULL; return gnutls_assert_val(ret); } return 0; }