LogoopenSUSE Build Service > Projects
Sign Up | Log In

View File gnutls-implement-trust-store-dir.diff of Package gnutls (Project openSUSE:Factory)

From a6cef9220ae251e3b8f8d663c5fa7f888e3176d8 Mon Sep 17 00:00:00 2001
From: Ludwig Nussel <ludwig.nussel@suse.de>
Date: Tue, 8 May 2012 15:47:02 +0200
Subject: [PATCH gnutls] implement trust store dir

---
 configure.ac      |   18 ++++++++++++-
 lib/gnutls_x509.c |   74 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 90 insertions(+), 2 deletions(-)

diff --git a/configure.ac b/configure.ac
index f826704..d099e05 100644
--- a/configure.ac
+++ b/configure.ac
@@ -296,17 +296,27 @@ AC_ARG_WITH([default-trust-store-file],
   [AS_HELP_STRING([--with-default-trust-store-file=FILE],
     [use the given file default trust store])])
 
+AC_ARG_WITH([default-trust-store-dir],
+  [AS_HELP_STRING([--with-default-trust-store-dir=DIR],
+     [use the given directory default trust store])])
+
 AC_ARG_WITH([default-crl-file],
   [AS_HELP_STRING([--with-default-crl-file=FILE],
     [use the given CRL file as default])])
 
-if test "x$with_default_trust_store_pkcs11" = x -a "x$with_default_trust_store_file" = x; then
+if test "x$with_default_trust_store_pkcs11" = x -a "x$with_default_trust_store_file" = x \
+	 -a "x$with_default_trust_store_dir" = x; then
   # auto detect http://lists.gnu.org/archive/html/help-gnutls/2012-05/msg00004.html
   for i in \
+    /etc/ssl/certs \
     /etc/ssl/certs/ca-certificates.crt \
     /etc/pki/tls/cert.pem \
     /usr/local/share/certs/ca-root-nss.crt
     do
+    if test -d $i; then
+      with_default_trust_store_dir="$i"
+      break
+    fi
     if test -e $i; then
       with_default_trust_store_file="$i"
       break
@@ -319,6 +329,11 @@ if test "x$with_default_trust_store_file" != x; then
     ["$with_default_trust_store_file"], [use the given file default trust store])
 fi
 
+if test "x$with_default_trust_store_dir" != x; then
+  AC_DEFINE_UNQUOTED([DEFAULT_TRUST_STORE_DIR],
+    ["$with_default_trust_store_dir"], [use the given directory default trust store])
+fi
+
 if test "x$with_default_crl_file" != x; then
   AC_DEFINE_UNQUOTED([DEFAULT_CRL_FILE],
     ["$with_default_crl_file"], [use the given CRL file])
@@ -560,6 +575,7 @@ if features are disabled)
 
   Trust store pkcs: $with_default_trust_store_pkcs11
   Trust store file: $with_default_trust_store_file
+  Trust store dir:  $with_default_trust_store_dir
   CRL file: $with_default_crl_file
 ])
 
diff --git a/lib/gnutls_x509.c b/lib/gnutls_x509.c
index 71e0d69..87eaa0c 100644
--- a/lib/gnutls_x509.c
+++ b/lib/gnutls_x509.c
@@ -36,6 +36,7 @@
 #include <gnutls_pk.h>
 #include <gnutls_str.h>
 #include <debug.h>
+#include <dirent.h>
 #include <x509_b64.h>
 #include <gnutls_x509.h>
 #include "x509/common.h"
@@ -1692,6 +1693,72 @@ set_x509_system_trust_file (gnutls_certificate_credentials_t cred)
 }
 #endif
 
+#ifdef DEFAULT_TRUST_STORE_DIR
+static int
+_gnutls_certificate_set_x509_system_trust_dir (gnutls_certificate_credentials_t cred)
+{
+  DIR* dir;
+  struct dirent* buf, *de;
+  int ret, r = 0;
+  gnutls_datum_t cas;
+  size_t size;
+  char cafile[PATH_MAX];
+
+  dir = opendir(DEFAULT_TRUST_STORE_DIR);
+  if (dir == NULL)
+    {
+      gnutls_assert ();
+      return GNUTLS_E_FILE_ERROR;
+    }
+
+  buf = alloca(offsetof(struct dirent, d_name) + pathconf(DEFAULT_TRUST_STORE_DIR, _PC_NAME_MAX) + 1);
+
+  while (1)
+    {
+      if (readdir_r(dir, buf, &de))
+	{
+	  gnutls_assert();
+	  break;
+	}
+      if (de == NULL)
+	{
+	  break;
+	}
+      if (strlen(de->d_name) < 4 || strcmp(de->d_name+strlen(de->d_name)-4, ".pem"))
+	{
+	  continue;
+	}
+
+      strcpy(cafile, DEFAULT_TRUST_STORE_DIR "/");
+      strncat(cafile, de->d_name, sizeof(cafile)-strlen(cafile)-1);
+      cas.data = (void*)read_binary_file (cafile, &size);
+      if (cas.data == NULL)
+	{
+	  gnutls_assert ();
+	  continue;
+	}
+
+      cas.size = size;
+
+      ret = gnutls_certificate_set_x509_trust_mem(cred, &cas, GNUTLS_X509_FMT_PEM);
+
+      free (cas.data);
+
+      if (ret < 0)
+	{
+	  gnutls_assert ();
+	}
+      else
+	{
+	  r += ret;
+	}
+    }
+  closedir(dir);
+
+  return r;
+}
+#endif
+
 /**
  * gnutls_certificate_set_x509_system_trust:
  * @cred: is a #gnutls_certificate_credentials_t structure.
@@ -1710,7 +1777,7 @@ set_x509_system_trust_file (gnutls_certificate_credentials_t cred)
 int
 gnutls_certificate_set_x509_system_trust (gnutls_certificate_credentials_t cred)
 {
-#if !defined(_WIN32) && !defined(DEFAULT_TRUST_STORE_PKCS11) && !defined(DEFAULT_TRUST_STORE_FILE)
+#if !defined(_WIN32) && !defined(DEFAULT_TRUST_STORE_PKCS11) && !defined(DEFAULT_TRUST_STORE_FILE) && !defined(DEFAULT_TRUST_STORE_DIR)
   int r = GNUTLS_E_UNIMPLEMENTED_FEATURE;
 #else
   int ret, r = 0;
@@ -1728,6 +1795,11 @@ gnutls_certificate_set_x509_system_trust (gnutls_certificate_credentials_t cred)
     r += ret;
 #endif
 
+#ifdef DEFAULT_TRUST_STORE_DIR
+  ret = _gnutls_certificate_set_x509_system_trust_dir(cred);
+  if (ret > 0)
+    r += ret;
+#endif
   return r;
 }
 
-- 
1.7.7