summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpixdamix <pixdamix@e8e0d7a0-c8d9-11dd-a880-a1081c7ac358>2009-11-05 03:46:33 (EST)
committer pixdamix <pixdamix@e8e0d7a0-c8d9-11dd-a880-a1081c7ac358>2009-11-05 03:46:33 (EST)
commit00d9ca3aaa56c083cfbb051235f3bdcbe6c8c253 (patch)
tree35f945f01329ccb860f33f81a494eb17c9eed549
parentaf66c658642635a3c951bb0ee130e40e7f084fd9 (diff)
Add pathfinder support for certificate validation
From http://code.google.com/p/pathfinder-pki/ PathFinder is designed to provide a mechanism for any program to perform RFC3280-compliant path validation of X509 certificates, even when some of the intermediate certificates are not present on the local machine. By design, Pathfinder automatically downloads any such certificates from the Internet as needed using the AIA and CRL distribution point extensions of the certificates it is processing. It has the ability to do revocation status checking either using CRL or OCSP, or both. And, given the recent vulnerabilities that have rendered the MD5 algorithm highly suspect, it allows the administrator to choose to not validate certificates using that algorithm anywhere in the trust path. git-svn-id: http://opkg.googlecode.com/svn/trunk@261 e8e0d7a0-c8d9-11dd-a880-a1081c7ac358
-rw-r--r--Makefile.am3
-rw-r--r--configure.ac20
-rw-r--r--libopkg/Makefile.am9
-rw-r--r--libopkg/opkg_download.c22
-rw-r--r--libopkg/opkg_pathfinder.c99
-rw-r--r--libopkg/opkg_pathfinder.h32
6 files changed, 180 insertions, 5 deletions
diff --git a/Makefile.am b/Makefile.am
index a746e60..b1980bf 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,6 +5,9 @@ BUILD_CPU=@build_cpu@
OPKGLIBDIR=@opkglibdir@
ALL_CFLAGS=-g -O -Wall -DHOST_CPU_STR=\"@host_cpu@\" -DBUILD_CPU=@build_cpu@ -DLIBDIR=\"@libdir@\" -DOPKGLIBDIR=\"@opkglibdir@\" -DDATADIR=\"@datadir@\"
+PATHFINDER_CFLAGS = @PATHFINDER_CFLAGS@
+PATHFINDER_LIBS = @PATHFINDER_LIBS@
+
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = libopkg.pc
diff --git a/configure.ac b/configure.ac
index 95233b5..df58817 100644
--- a/configure.ac
+++ b/configure.ac
@@ -29,6 +29,22 @@ AC_PROG_LIBTOOL
# Checks for libraries
+dnl extra argument: --with-pathfinder
+AC_ARG_ENABLE(pathfinder,
+ AC_HELP_STRING([--with-pathfinder], [With libpathfinder support.
+ [[default=no]] ]),
+ [want_pathfinder="$enableval"], [want_pathfinder="no"])
+dnl Check for libpathfinder
+if test "x$want_pathfinder" = "xyes"; then
+ PKG_CHECK_MODULES([PATHFINDER], [pathfinder-openssl dbus-1 openssl])
+ if test -n "$PATHFINDER_CFLAGS$PATHFINDER_LIBS"; then
+ AC_DEFINE(HAVE_PATHFINDER, 1, [we have pathfinder])
+ fi
+ AC_SUBST(PATHFINDER_CFLAGS)
+ AC_SUBST(PATHFINDER_LIBS)
+fi
+AM_CONDITIONAL(HAVE_PATHFINDER, test "x$want_pathfinder" = "xyes")
+
# check for libcurl
AC_ARG_ENABLE(curl,
AC_HELP_STRING([--enable-curl], [Enable downloading with curl
@@ -36,7 +52,7 @@ AC_ARG_ENABLE(curl,
[want_curl="$enableval"], [want_curl="yes"])
if test "x$want_curl" = "xyes"; then
- PKG_CHECK_MODULES(CURL, libcurl)
+ PKG_CHECK_MODULES(CURL, [libcurl])
AC_DEFINE(HAVE_CURL, 1, [Define if you want CURL support])
fi
@@ -65,7 +81,7 @@ fi
# check for libssl-curl
AC_ARG_ENABLE(ssl-curl,
AC_HELP_STRING([--enable-ssl-curl], [Enable certificate authentication with curl
- [[default="$default_sslcurl"]] ]),
+ [[default="yes"]] ]),
[want_sslcurl="$enableval"], [want_sslcurl="yes"])
if test "x$want_curl" = "xyes" -a "x$want_sslcurl" = "xyes"; then
diff --git a/libopkg/Makefile.am b/libopkg/Makefile.am
index 5aee171..067d867 100644
--- a/libopkg/Makefile.am
+++ b/libopkg/Makefile.am
@@ -1,5 +1,5 @@
-AM_CFLAGS=-Wall -Werror -DHOST_CPU_STR=\"@host_cpu@\" -DBUILD_CPU=@build_cpu@ -DLIBDIR=\"@libdir@\" -DOPKGLIBDIR=\"@opkglibdir@\" -DOPKGETCDIR=\"@opkgetcdir@\" -DDATADIR=\"@datadir@\" -I$(top_srcdir) $(BIGENDIAN_CFLAGS) $(CURL_CFLAGS) $(GPGME_CFLAGS)
+AM_CFLAGS=-Wall -Werror -DHOST_CPU_STR=\"@host_cpu@\" -DBUILD_CPU=@build_cpu@ -DLIBDIR=\"@libdir@\" -DOPKGLIBDIR=\"@opkglibdir@\" -DOPKGETCDIR=\"@opkgetcdir@\" -DDATADIR=\"@datadir@\" -I$(top_srcdir) $(BIGENDIAN_CFLAGS) $(CURL_CFLAGS) $(GPGME_CFLAGS) $(PATHFINDER_CFLAGS)
libopkg_includedir=$(includedir)/libopkg
libopkg_include_HEADERS= opkg.h
@@ -29,7 +29,9 @@ opkg_list_sources = conffile.c conffile.h conffile_list.c conffile_list.h \
opkg_util_sources = file_util.c file_util.h opkg_message.h opkg_message.c md5.c md5.h \
sprintf_alloc.c sprintf_alloc.h str_util.c str_util.h \
xregex.c xregex.h xsystem.c xsystem.h
-
+if HAVE_PATHFINDER
+opkg_util_sources += opkg_pathfinder.c opkg_pathfinder.h
+endif
if HAVE_SHA256
opkg_util_sources += sha256.c sha256.h
endif
@@ -40,7 +42,8 @@ libopkg_la_SOURCES = \
$(opkg_cmd_sources) $(opkg_db_sources) \
$(opkg_util_sources) $(opkg_list_sources)
-libopkg_la_LIBADD = $(top_builddir)/libbb/libbb.la $(CURL_LIBS) $(GPGME_LIBS) $(OPENSSL_LIBS)
+libopkg_la_LIBADD = $(top_builddir)/libbb/libbb.la $(CURL_LIBS) $(GPGME_LIBS) $(OPENSSL_LIBS) $(PATHFINDER_LIBS)
+
# make sure we only export symbols that are for public use
libopkg_la_LDFLAGS = -export-symbols-regex "^opkg_.*"
diff --git a/libopkg/opkg_download.c b/libopkg/opkg_download.c
index 77dc8e4..0e67927 100644
--- a/libopkg/opkg_download.c
+++ b/libopkg/opkg_download.c
@@ -26,6 +26,7 @@
#include <openssl/conf.h>
#include <openssl/evp.h>
#include <openssl/err.h>
+#include <openssl/ssl.h>
#endif
#if defined(HAVE_GPGME)
@@ -49,6 +50,10 @@
#include "opkg_defines.h"
#include "libbb/libbb.h"
+#ifdef HAVE_PATHFINDER
+#include "opkg_pathfinder.h"
+#endif
+
#if defined(HAVE_OPENSSL) || defined(HAVE_SSLCURL)
static void openssl_init(void);
#endif
@@ -413,6 +418,13 @@ opkg_verify_file (opkg_conf_t *conf, char *text_file, char *sig_file)
"Can't read signature file (Corrupted ?)\n");
goto verify_file_end;
}
+#if defined(HAVE_PATHFINDER)
+ if(!pkcs7_pathfinder_verify_signers(p7)){
+ opkg_message(conf, OPKG_ERROR, "pkcs7_pathfinder_verify_signers: "
+ "Path verification failed\n");
+ }
+
+#endif
// Open the Package file to authenticate
if (!(indata = BIO_new_file(text_file, "rb"))){
@@ -595,6 +607,16 @@ static CURL *opkg_curl_init(opkg_conf_t *conf, curl_progress_func cb, void *data
* CURLOPT_SSL_VERIFYPEER default is nonzero (curl => 7.10)
*/
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
+ }else{
+#ifdef HAVE_PATHFINDER
+ if (curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, curl_ssl_ctx_function) != CURLE_OK){
+ opkg_message(conf, OPKG_DEBUG, "Failed to set ssl path verification callback\n");
+ }else{
+ curl_easy_setopt(curl, CURLOPT_SSL_CTX_DATA, NULL);
+ }
+
+ //curl_easy_setopt(curl, CURLOPT_SSL_CERT_VERIFY_FUNCTION, curlcb_pathfinder);
+#endif
}
/* certification authority file and/or path */
diff --git a/libopkg/opkg_pathfinder.c b/libopkg/opkg_pathfinder.c
new file mode 100644
index 0000000..793c3a4
--- /dev/null
+++ b/libopkg/opkg_pathfinder.c
@@ -0,0 +1,99 @@
+/* vi: set noexpandtab sw=4 sts=4: */
+/* opkg_download.c - the opkg package management system
+
+ Carl D. Worth
+
+ Copyright (C) 2001 University of Southern California
+ Copyright (C) 2008 OpenMoko Inc
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+*/
+#include "config.h"
+
+#include <openssl/ssl.h>
+#include <libpathfinder.h>
+#include "includes.h"
+#include "opkg_message.h"
+
+#if defined(HAVE_SSLCURL)
+#include <curl/curl.h>
+#endif
+
+#if defined(HAVE_SSLCURL) || defined(HAVE_OPENSSL)
+/*
+ * This callback is called instead of X509_verify_cert to perform path
+ * validation on a certificate using pathfinder.
+ *
+ */
+static int pathfinder_verify_callback(X509_STORE_CTX *ctx, void *arg)
+{
+ char *errmsg;
+ const char *hex = "0123456789ABCDEF";
+ size_t size = i2d_X509(ctx->cert, NULL);
+ unsigned char *keybuf, *iend;
+ iend = keybuf = malloc(size);
+ i2d_X509(ctx->cert, &iend);
+ char *certdata_str = malloc(size * 2 + 1);
+ unsigned char *cp = keybuf;
+ char *certdata_str_i = certdata_str;
+ while (cp < iend)
+ {
+ unsigned char ch = *cp++;
+ *certdata_str_i++ = hex[(ch >> 4) & 0xf];
+ *certdata_str_i++ = hex[ch & 0xf];
+ }
+ *certdata_str_i = 0;
+ free(keybuf);
+
+ const char *policy = "2.5.29.32.0"; // anyPolicy
+ int validated = pathfinder_dbus_verify(certdata_str, policy, 0, 0, &errmsg);
+
+ if (!validated)
+ fprintf(stderr, "curlcb_pathfinder: Path verification failed: %s", errmsg);
+
+ free(certdata_str);
+ free(errmsg);
+
+ return validated;
+}
+#endif
+
+
+#if defined(HAVE_OPENSSL)
+int pkcs7_pathfinder_verify_signers(PKCS7* p7)
+{
+ STACK_OF(X509) *signers;
+ int i;
+
+ signers = PKCS7_get0_signers(p7, NULL, 0);
+
+ for(i = 0; i < sk_X509_num(signers); i++){
+ X509_STORE_CTX ctx = {
+ .cert = sk_X509_value(signers, i),
+ };
+
+ if(!pathfinder_verify_callback(&ctx, NULL))
+ return 0;
+ }
+
+ return 1;
+}
+#endif
+
+#if defined(HAVE_SSLCURL)
+CURLcode curl_ssl_ctx_function(CURL * curl, void * sslctx, void * parm) {
+
+ SSL_CTX * ctx = (SSL_CTX *) sslctx;
+ SSL_CTX_set_cert_verify_callback(ctx, pathfinder_verify_callback, parm);
+
+ return CURLE_OK ;
+}
+#endif
diff --git a/libopkg/opkg_pathfinder.h b/libopkg/opkg_pathfinder.h
new file mode 100644
index 0000000..446d861
--- /dev/null
+++ b/libopkg/opkg_pathfinder.h
@@ -0,0 +1,32 @@
+/* opkg_download.h - the opkg package management system
+
+ Camille Moncelier <moncelier@devlife.org>
+
+ Copyright (C) 2009 Camille Moncelier
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2, or (at
+ your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+*/
+
+#ifndef OPKG_PATHFINDER_H
+#define OPKG_PATHFINDER_H
+
+#include "config.h"
+
+#if defined(HAVE_OPENSSL)
+int pkcs7_pathfinder_verify_signers(PKCS7* p7);
+#endif
+
+#if defined(HAVE_SSLCURL)
+CURLcode curl_ssl_ctx_function(CURL * curl, void * sslctx, void * parm);
+#endif
+
+
+#endif