diff options
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | configure.ac | 20 | ||||
-rw-r--r-- | libopkg/Makefile.am | 9 | ||||
-rw-r--r-- | libopkg/opkg_download.c | 22 | ||||
-rw-r--r-- | libopkg/opkg_pathfinder.c | 99 | ||||
-rw-r--r-- | libopkg/opkg_pathfinder.h | 32 |
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 |