[gnutls-devel] [PATCH 9/9] Add an interface to iterate the trusted CA certificates in a trust list

Armin Burgmeier armin at arbur.net
Thu Sep 18 17:22:35 CEST 2014


Signed-off-by: Armin Burgmeier <armin at arbur.net>
---
 lib/includes/gnutls/x509.h |  9 +++++
 lib/libgnutls.map          |  2 ++
 lib/x509/verify-high.c     | 88 ++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 99 insertions(+)

diff --git a/lib/includes/gnutls/x509.h b/lib/includes/gnutls/x509.h
index fd02f0c..c30eca7 100644
--- a/lib/includes/gnutls/x509.h
+++ b/lib/includes/gnutls/x509.h
@@ -1234,6 +1234,7 @@ gnutls_x509_crt_get_extension_by_oid2(gnutls_x509_crt_t cert,
 				     unsigned int *critical);
 
 typedef struct gnutls_x509_trust_list_st *gnutls_x509_trust_list_t;
+typedef struct gnutls_x509_trust_list_iter *gnutls_x509_trust_list_iter_t;
 
 int
 gnutls_x509_trust_list_init(gnutls_x509_trust_list_t * list,
@@ -1275,6 +1276,14 @@ gnutls_x509_trust_list_add_crls(gnutls_x509_trust_list_t list,
 				unsigned int flags,
 				unsigned int verification_flags);
 
+
+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);
+
+void gnutls_x509_trust_list_iter_deinit(gnutls_x509_trust_list_iter_t iter);
+
 typedef int gnutls_verify_output_function(gnutls_x509_crt_t cert, gnutls_x509_crt_t issuer,	/* The issuer if verification failed 
 												 * because of him. might be null.
 												 */
diff --git a/lib/libgnutls.map b/lib/libgnutls.map
index 3a2263f..1d9aa36 100644
--- a/lib/libgnutls.map
+++ b/lib/libgnutls.map
@@ -788,6 +788,8 @@ GNUTLS_3_1_0 {
 	gnutls_x509_trust_list_add_system_trust;
 	gnutls_x509_trust_list_add_trust_file;
 	gnutls_x509_trust_list_add_trust_mem;
+	gnutls_x509_trust_list_iter_get_ca;
+	gnutls_x509_trust_list_iter_deinit;
 	gnutls_pkcs12_simple_parse;
 	gnutls_privkey_import_openpgp_raw;
 	gnutls_privkey_import_x509_raw;
diff --git a/lib/x509/verify-high.c b/lib/x509/verify-high.c
index 065920d..9b4ac8c 100644
--- a/lib/x509/verify-high.c
+++ b/lib/x509/verify-high.c
@@ -54,6 +54,11 @@ struct node_st {
 
 };
 
+struct gnutls_x509_trust_list_iter {
+	unsigned int node_index;
+	unsigned int ca_index;
+};
+
 #define DEFAULT_SIZE 127
 
 /**
@@ -289,6 +294,89 @@ gnutls_x509_trust_list_add_cas(gnutls_x509_trust_list_t list,
 	return i;
 }
 
+/**
+ * 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;
+
+	/* advance to next entry */
+	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;
+	} else {
+		++(*iter)->ca_index;
+	}
+
+	/* skip empty nodes */
+	while ((*iter)->ca_index >= list->node[(*iter)->node_index].trusted_ca_size) {
+		++(*iter)->node_index;
+		(*iter)->ca_index = 0;
+
+		if ((*iter)->node_index >= list->size) {
+			gnutls_free(*iter);
+			*iter = NULL;
+
+			*crt = NULL;
+			return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
+		}
+	}
+
+	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);
+	}
+
+	return 0;
+}
+
+/**
+ * gnutls_x509_trust_list_iter_deinit:
+ * @iter: The iterator structure to be deinitialized
+ *
+ * This function will deinitialize an iterator structure.
+ *
+ * Since: 3.4.0
+ **/
+void gnutls_x509_trust_list_iter_deinit(gnutls_x509_trust_list_iter_t iter)
+{
+	if (!iter)
+		return;
+
+	gnutls_free(iter);
+}
+
 static gnutls_x509_crt_t crt_cpy(gnutls_x509_crt_t src)
 {
 gnutls_x509_crt_t dst;
-- 
2.1.0




More information about the Gnutls-devel mailing list