gnutls_x509_crt_get_dn2: Added
gnutls_x509_crl_get_issuer_dn2: Added
gnutls_x509_crq_get_dn2: Added
+gnutls_x509_trust_list_remove_trust_mem: Added
+gnutls_x509_trust_list_remove_trust_file: Added
+gnutls_x509_trust_list_remove_cas: Added
* Version 3.1.9 (released 2013-02-27)
int
gnutls_x509_trust_list_add_cas (gnutls_x509_trust_list_t list,
const gnutls_x509_crt_t * clist, int clist_size, unsigned int flags);
+ int gnutls_x509_trust_list_remove_cas(gnutls_x509_trust_list_t list,
+ const gnutls_x509_crt_t * clist,
+ int clist_size);
int gnutls_x509_trust_list_add_named_crt (gnutls_x509_trust_list_t list,
gnutls_x509_crt_t cert, const void* name, size_t name_size, unsigned int flags);
unsigned int tl_flags,
unsigned int tl_vflags);
+int
+gnutls_x509_trust_list_remove_trust_file(gnutls_x509_trust_list_t list,
+ const char* ca_file,
+ gnutls_x509_crt_fmt_t type);
+
+int
+gnutls_x509_trust_list_remove_trust_mem(gnutls_x509_trust_list_t list,
+ const gnutls_datum_t * cas,
+ gnutls_x509_crt_fmt_t type);
+
int
gnutls_x509_trust_list_add_system_trust(gnutls_x509_trust_list_t list,
unsigned int tl_flags, unsigned int tl_vflags);
gnutls_x509_crt_get_dn2;
gnutls_x509_crl_get_issuer_dn2;
gnutls_x509_crq_get_dn2;
+ gnutls_x509_trust_list_remove_trust_mem;
+ gnutls_x509_trust_list_remove_trust_file;
+ gnutls_x509_trust_list_remove_cas;
} GNUTLS_3_0_0;
GNUTLS_PRIVATE {
# include <dirent.h>
# include <unistd.h>
static int load_dir_certs(const char* dirname, gnutls_x509_trust_list_t list,
- unsigned int tl_flags, unsigned int tl_vflags, unsigned type,
- unsigned check_revoked)
+ unsigned int tl_flags, unsigned int tl_vflags, unsigned type)
{
DIR * dirp;
struct dirent *d;
d = readdir(dirp);
if (d != NULL && d->d_type == DT_REG)
{
-
- if (check_revoked)
- {
- snprintf(path, sizeof(path),
- "/data/misc/keychain/cacerts-removed/%s", d->d_name);
- if (access(path, R_OK) == 0)
- /* revoked -> do not add */
- continue;
- }
-
snprintf(path, sizeof(path), "%s/%s", dirname, d->d_name);
ret = gnutls_x509_trust_list_add_trust_file(list, path, NULL, type, tl_flags, tl_vflags);
return r;
}
+static int load_revoked_certs(gnutls_x509_trust_list_t list,
+ unsigned int tl_flags, unsigned int tl_vflags, unsigned type)
+{
+DIR * dirp;
+struct dirent *d;
+int ret;
+int r = 0;
+char path[GNUTLS_PATH_MAX];
+
+ dirp = opendir("/data/misc/keychain/cacerts-removed/");
+ if (dirp != NULL)
+ {
+ do
+ {
+ d = readdir(dirp);
+ if (d != NULL && d->d_type == DT_REG)
+ {
+ snprintf(path, sizeof(path), "/data/misc/keychain/cacerts-removed/%s", d->d_name);
+
+ ret = gnutls_x509_trust_list_remove_trust_file(list, path, type);
+ if (ret >= 0)
+ r += ret;
+ }
+ }
+ while(d != NULL);
+ closedir(dirp);
+ }
+
+ return r;
+}
+
/* This works on android 4.x
*/
static
{
int r = 0, ret;
- ret = load_dir_certs("/system/etc/security/cacerts/", list, tl_flags, tl_vflags, GNUTLS_X509_FMT_PEM, 1);
+ ret = load_dir_certs("/system/etc/security/cacerts/", list, tl_flags, tl_vflags, GNUTLS_X509_FMT_PEM);
if (ret >= 0)
r += ret;
- ret = load_dir_certs("/data/misc/keychain/cacerts-added/", list, tl_flags, tl_vflags, GNUTLS_X509_FMT_DER, 0);
+ ret = load_dir_certs("/data/misc/keychain/cacerts-added/", list, tl_flags, tl_vflags, GNUTLS_X509_FMT_DER);
if (ret >= 0)
r += ret;
-
+
+ ret = load_revoked_certs(list, tl_flags, tl_vflags);
+ if (ret >= 0)
+ r -= ret;
+
return r;
}
#else
return 0;
}
#endif
+
return i;
}
+/**
+ * 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.
+ *
+ * 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)
+ {
+ 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++;
+ }
+ }
+ }
+
+ return r;
+}
+
/**
* gnutls_x509_trust_list_add_named_crt:
* @list: The structure of the list
return r;
}
+/**
+ * gnutls_x509_trust_list_remove_trust_mem:
+ * @list: The structure of the list
+ * @cas: A buffer containing a list of CAs (optional)
+ * @type: The format of the certificates
+ *
+ * This function will add the given certificate authorities
+ * to the trusted list.
+ *
+ * Returns: The number of added elements is returned.
+ *
+ * Since: 3.1.10
+ **/
+int
+gnutls_x509_trust_list_remove_trust_mem(gnutls_x509_trust_list_t list,
+ const gnutls_datum_t * cas,
+ gnutls_x509_crt_fmt_t type)
+{
+ int ret;
+ gnutls_x509_crt_t *x509_ca_list = NULL;
+ unsigned int x509_ncas;
+ unsigned int r = 0, i;
+
+ if (cas != NULL && cas->data != NULL)
+ {
+ ret = gnutls_x509_crt_list_import2( &x509_ca_list, &x509_ncas, cas, type, 0);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ ret = gnutls_x509_trust_list_remove_cas(list, x509_ca_list, x509_ncas);
+
+ for (i=0;i<x509_ncas;i++)
+ gnutls_x509_crt_deinit(x509_ca_list[i]);
+ gnutls_free(x509_ca_list);
+
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ else
+ r += ret;
+ }
+
+ return r;
+}
+
#ifdef ENABLE_PKCS11
static
int import_pkcs11_url(gnutls_x509_trust_list_t list, const char* ca_file, unsigned int flags)
return ret;
}
+static
+int remove_pkcs11_url(gnutls_x509_trust_list_t list, const char* ca_file)
+{
+gnutls_x509_crt_t *xcrt_list = NULL;
+gnutls_pkcs11_obj_t *pcrt_list = NULL;
+unsigned int pcrt_list_size = 0, i;
+int ret;
+
+ ret = gnutls_pkcs11_obj_list_import_url2(&pcrt_list, &pcrt_list_size, ca_file,
+ GNUTLS_PKCS11_OBJ_ATTR_CRT_TRUSTED_CA, 0);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
+ if (pcrt_list_size == 0)
+ {
+ ret = 0;
+ goto cleanup;
+ }
+
+ xcrt_list = gnutls_malloc(sizeof(gnutls_x509_crt_t)*pcrt_list_size);
+ if (xcrt_list == NULL)
+ {
+ ret = GNUTLS_E_MEMORY_ERROR;
+ goto cleanup;
+ }
+
+ ret = gnutls_x509_crt_list_import_pkcs11( xcrt_list, pcrt_list_size, pcrt_list, 0);
+ if (ret < 0)
+ {
+ gnutls_assert();
+ goto cleanup;
+ }
+
+ ret = gnutls_x509_trust_list_remove_cas(list, xcrt_list, pcrt_list_size);
+
+cleanup:
+ for (i=0;i<pcrt_list_size;i++)
+ {
+ gnutls_pkcs11_obj_deinit(pcrt_list[i]);
+ gnutls_x509_crt_deinit(xcrt_list[i]);
+ }
+ gnutls_free(pcrt_list);
+ gnutls_free(xcrt_list);
+
+ return ret;
+}
#endif
return ret;
}
+/**
+ * gnutls_x509_trust_list_remove_trust_file:
+ * @list: The structure of the list
+ * @ca_file: A file containing a list of CAs
+ * @type: The format of the certificates
+ *
+ * This function will add the given certificate authorities
+ * to the trusted list. pkcs11 URLs are also accepted, instead
+ * of files, by this function.
+ *
+ * Returns: The number of added elements is returned.
+ *
+ * Since: 3.1.10
+ **/
+int
+gnutls_x509_trust_list_remove_trust_file(gnutls_x509_trust_list_t list,
+ const char* ca_file,
+ gnutls_x509_crt_fmt_t type)
+{
+ gnutls_datum_t cas = { NULL, 0 };
+ size_t size;
+ int ret;
+
+#ifdef ENABLE_PKCS11
+ if (strncmp (ca_file, "pkcs11:", 7) == 0)
+ {
+ ret = remove_pkcs11_url(list, ca_file);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ }
+ 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;
+ }
+
+ ret = gnutls_x509_trust_list_remove_trust_mem(list, &cas, type);
+ free(cas.data);
+
+ return ret;
+}
+
if (ret < 1)
fail("gnutls_x509_trust_list_add_trust_mem: %d (%s)\n", __LINE__, gnutls_strerror(ret));
+ ret = gnutls_x509_trust_list_remove_trust_mem(tl, &data, GNUTLS_X509_FMT_PEM);
+ if (ret < 1)
+ fail("gnutls_x509_trust_list_add_trust_mem: %d (%s)\n", __LINE__, gnutls_strerror(ret));
+
data.data = cert_der;
data.size = sizeof(cert_der);
ret = gnutls_x509_trust_list_add_trust_mem(tl, &data, NULL, GNUTLS_X509_FMT_DER, 0, 0);
if (ret < 1)
fail("gnutls_x509_trust_list_add_trust_mem: %d (%s)\n", __LINE__, gnutls_strerror(ret));
+ ret = gnutls_x509_trust_list_remove_trust_mem(tl, &data, GNUTLS_X509_FMT_DER);
+ if (ret < 1)
+ fail("gnutls_x509_trust_list_add_trust_mem: %d (%s)\n", __LINE__, gnutls_strerror(ret));
+
+ ret = gnutls_x509_trust_list_remove_cas(tl, &ca_crt, 1);
+ if (ret < 1)
+ fail("gnutls_x509_trust_list_add_cas");
+
+ ret = gnutls_x509_trust_list_verify_crt(tl, &server_crt, 1, 0, &status, NULL);
+ if (ret == 0 && status == 0)
+ fail("gnutls_x509_trust_list_verify_crt\n");
+
gnutls_x509_trust_list_deinit(tl, 1);
gnutls_global_deinit();