/** * gnutls_x509_trust_list_add_trust_file: * @list: The list * @ca_file: A file containing a list of CAs (optional) * @crl_file: A file containing a list of CRLs (optional) * @type: The format of the certificates * @tl_flags: flags from %gnutls_trust_list_flags_t * @tl_vflags: gnutls_certificate_verify_flags if flags specifies GNUTLS_TL_VERIFY_CRL * * This function will add the given certificate authorities * to the trusted list. PKCS #11 URLs are also accepted, instead * of files, by this function. A PKCS #11 URL implies a trust * database (a specially marked module in p11-kit); the URL "pkcs11:" * implies all trust databases in the system. Only a single URL specifying * trust databases can be set; they cannot be stacked with multiple calls. * * Returns: The number of added elements is returned. * * Since: 3.1 **/ int gnutls_x509_trust_list_add_trust_file(gnutls_x509_trust_list_t list, const char *ca_file, const char *crl_file, gnutls_x509_crt_fmt_t type, unsigned int tl_flags, unsigned int tl_vflags) { gnutls_datum_t cas = { NULL, 0 }; gnutls_datum_t crls = { NULL, 0 }; size_t size; int ret; if (ca_file != NULL) { #ifdef ENABLE_PKCS11 if (strncmp(ca_file, "pkcs11:", 7) == 0) { unsigned pcrt_list_size = 0; /* in case of a token URL import it as a PKCS #11 token, * otherwise import the individual certificates. */ if (is_pkcs11_url_object(ca_file) != 0) { return add_trust_list_pkcs11_object_url(list, ca_file, tl_flags); } else { /* token */ if (list->pkcs11_token != NULL) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); list->pkcs11_token = gnutls_strdup(ca_file); /* enumerate the certificates */ ret = gnutls_pkcs11_obj_list_import_url(NULL, &pcrt_list_size, ca_file, (GNUTLS_PKCS11_OBJ_FLAG_CRT|GNUTLS_PKCS11_OBJ_FLAG_MARK_CA|GNUTLS_PKCS11_OBJ_FLAG_MARK_TRUSTED), 0); if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) return gnutls_assert_val(ret); return pcrt_list_size; } } else #endif { cas.data = (void *) read_binary_file(ca_file, &size); if (cas.data == NULL) { gnutls_assert(); return GNUTLS_E_FILE_ERROR; } cas.size = size; } } if (crl_file) { crls.data = (void *) read_binary_file(crl_file, &size); if (crls.data == NULL) { gnutls_assert(); return GNUTLS_E_FILE_ERROR; } crls.size = size; } ret = gnutls_x509_trust_list_add_trust_mem(list, &cas, &crls, type, tl_flags, tl_vflags); free(crls.data); free(cas.data); return ret; }
/* lists certificates from a token */ void pkcs11_list (FILE * outfile, const char *url, int type, unsigned int login, unsigned int detailed, common_info_st * info) { gnutls_pkcs11_obj_t *crt_list; gnutls_x509_crt_t xcrt; unsigned int crt_list_size = 0; int ret; char *output; int i, attrs; unsigned int obj_flags = 0; if (login) obj_flags = GNUTLS_PKCS11_OBJ_FLAG_LOGIN; pkcs11_common (); if (url == NULL) url = "pkcs11:"; if (type == PKCS11_TYPE_TRUSTED) { attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED; } else if (type == PKCS11_TYPE_PK) { attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_WITH_PRIVKEY; } else if (type == PKCS11_TYPE_CRT_ALL) { attrs = GNUTLS_PKCS11_OBJ_ATTR_CRT_ALL; } else if (type == PKCS11_TYPE_PRIVKEY) { attrs = GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY; } else { attrs = GNUTLS_PKCS11_OBJ_ATTR_ALL; } /* give some initial value to avoid asking for the pkcs11 pin twice. */ crt_list_size = 128; crt_list = malloc (sizeof (*crt_list) * crt_list_size); if (crt_list == NULL) { fprintf (stderr, "Memory error\n"); exit (1); } ret = gnutls_pkcs11_obj_list_import_url (crt_list, &crt_list_size, url, attrs, obj_flags); if (ret < 0 && ret != GNUTLS_E_SHORT_MEMORY_BUFFER) { fprintf (stderr, "Error in crt_list_import (1): %s\n", gnutls_strerror (ret)); exit (1); } if (crt_list_size == 0) { fprintf (stderr, "No matching objects found\n"); exit (0); } if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER) { crt_list = realloc (crt_list, sizeof (*crt_list) * crt_list_size); if (crt_list == NULL) { fprintf (stderr, "Memory error\n"); exit (1); } ret = gnutls_pkcs11_obj_list_import_url (crt_list, &crt_list_size, url, attrs, obj_flags); if (ret < 0) { fprintf (stderr, "Error in crt_list_import: %s\n", gnutls_strerror (ret)); exit (1); } } for (i = 0; i < crt_list_size; i++) { char buf[128]; size_t size; ret = gnutls_pkcs11_obj_export_url (crt_list[i], detailed, &output); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } fprintf (outfile, "Object %d:\n\tURL: %s\n", i, output); fprintf (outfile, "\tType: %s\n", gnutls_pkcs11_type_get_name (gnutls_pkcs11_obj_get_type (crt_list[i]))); size = sizeof (buf); ret = gnutls_pkcs11_obj_get_info (crt_list[i], GNUTLS_PKCS11_OBJ_LABEL, buf, &size); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } fprintf (outfile, "\tLabel: %s\n", buf); size = sizeof (buf); ret = gnutls_pkcs11_obj_get_info (crt_list[i], GNUTLS_PKCS11_OBJ_ID_HEX, buf, &size); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } fprintf (outfile, "\tID: %s\n\n", buf); if (attrs == GNUTLS_PKCS11_OBJ_ATTR_ALL || attrs == GNUTLS_PKCS11_OBJ_ATTR_PRIVKEY) continue; ret = gnutls_x509_crt_init (&xcrt); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } ret = gnutls_x509_crt_import_pkcs11 (xcrt, crt_list[i]); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } #if 0 size = buffer_size; ret = gnutls_x509_crt_export (xcrt, GNUTLS_X509_FMT_PEM, buffer, &size); if (ret < 0) { fprintf (stderr, "Error in %s:%d: %s\n", __func__, __LINE__, gnutls_strerror (ret)); exit (1); } fwrite (buffer, 1, size, outfile); fputs ("\n\n", outfile); #endif gnutls_x509_crt_deinit (xcrt); } return; }