This patch adds to opkg several option which allows to
configure curl to use openssl autenticate an https session.

The client when downloading packages will be able to verify
the sever signature, authenticate itself, via certificates on
disk or on a smartcard.

# example opkg.conf settings

option ssl_ca_path /etc/ssl/certs
option ssl_key_type ENG

option ssl_cert_type PEM
option ssl_cert /etc/opkg/client.pem

option ssl_engine pkcs11

diff --git a/configure.ac b/configure.ac
index 4346373..2e17b70 100644
--- a/configure.ac
+++ b/configure.ac
@@ -37,6 +37,22 @@ if test "x$want_curl" = "xyes"; then
   AC_DEFINE(HAVE_CURL, 1, [Define if you want CURL support])
 fi
 
+# check for libssl-curl
+AC_ARG_ENABLE(ssl-curl,
+              AC_HELP_STRING([--enable-ssl-curl], [Enable certificate 
authentication with curl
+                              [[default=yes]] ]),
+                              [want_sslcurl="$enableval"], 
[want_sslcurl="yes"])
+
+if test "x$want_sslcurl" = "xyes"; then
+  PKG_CHECK_MODULES(OPENSSL, openssl)
+  PKG_CHECK_MODULES(CURL, libcurl)
+  AC_DEFINE(HAVE_CURL, 1, [Define if you want CURL support])
+  AC_DEFINE(HAVE_SSLCURL, 1, [Define if you want certificate authentication 
with curl])
+  OPENSSL_LIBS="-lssl -lcrypto"
+fi
+AC_SUBST(OPENSSL_LIBS)
+
+
 
 dnl **********
 dnl GPGME
diff --git a/libopkg/Makefile.am b/libopkg/Makefile.am
index 0e9d3a9..8fca9ac 100644
--- a/libopkg/Makefile.am
+++ b/libopkg/Makefile.am
@@ -36,7 +36,7 @@ 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)
+libopkg_la_LIBADD = $(top_builddir)/libbb/libbb.la $(CURL_LIBS) $(GPGME_LIBS) 
$(OPENSSL_LIBS)
 # make sure we only export symbols that are for public use
 libopkg_la_LDFLAGS = -export-symbols-regex "^opkg_.*"
 
diff --git a/libopkg/opkg_conf.c b/libopkg/opkg_conf.c
index 4d1306e..8ef63ad 100644
--- a/libopkg/opkg_conf.c
+++ b/libopkg/opkg_conf.c
@@ -75,6 +75,17 @@ int opkg_init_options_array(const opkg_conf_t *conf, 
opkg_option_t **options)
          { "proxy_user", OPKG_OPT_TYPE_STRING, &conf->proxy_user },
          { "query-all", OPKG_OPT_TYPE_BOOL, &conf->query_all },
          { "verbosity", OPKG_OPT_TYPE_BOOL, &conf->verbosity },
+#if defined(HAVE_SSLCURL) && defined(HAVE_CURL)
+          { "ssl_engine", OPKG_OPT_TYPE_STRING, &conf->ssl_engine },
+          { "ssl_cert", OPKG_OPT_TYPE_STRING, &conf->ssl_cert },
+          { "ssl_cert_type", OPKG_OPT_TYPE_STRING, &conf->ssl_cert_type },
+          { "ssl_key", OPKG_OPT_TYPE_STRING, &conf->ssl_key },
+          { "ssl_key_type", OPKG_OPT_TYPE_STRING, &conf->ssl_key_type },
+          { "ssl_key_passwd", OPKG_OPT_TYPE_STRING, &conf->ssl_key_passwd },
+          { "ssl_ca_file", OPKG_OPT_TYPE_STRING, &conf->ssl_ca_file },
+          { "ssl_ca_path", OPKG_OPT_TYPE_STRING, &conf->ssl_ca_path },
+          { "ssl_dont_verify_peer", OPKG_OPT_TYPE_BOOL, 
&conf->ssl_dont_verify_peer },
+#endif
          { NULL }
      };
 
diff --git a/libopkg/opkg_conf.h b/libopkg/opkg_conf.h
index ca2661b..7e16d13 100644
--- a/libopkg/opkg_conf.h
+++ b/libopkg/opkg_conf.h
@@ -75,6 +75,22 @@ struct opkg_conf
      int noaction;
      char *cache;
 
+#ifdef HAVE_SSLCURL
+     /* some options could be used by
+      * wget if curl support isn't builtin
+      * If someone want to try...
+      */
+     char *ssl_engine;
+     char *ssl_cert;
+     char *ssl_cert_type;
+     char *ssl_key;
+     char *ssl_key_type;
+     char *ssl_key_passwd;
+     char *ssl_ca_file;
+     char *ssl_ca_path;
+     int ssl_dont_verify_peer;
+#endif
+
      /* proxy options */
      char *http_proxy;
      char *ftp_proxy;
diff --git a/libopkg/opkg_download.c b/libopkg/opkg_download.c
index f185f22..d2ff04b 100644
--- a/libopkg/opkg_download.c
+++ b/libopkg/opkg_download.c
@@ -20,10 +20,15 @@
 #ifdef HAVE_CURL
 #include <curl/curl.h>
 #endif
+
 #ifdef HAVE_GPGME
 #include <gpgme.h>
 #endif
 
+#ifdef HAVE_SSLCURL
+#include <openssl/conf.h>
+#endif
+
 #include "includes.h"
 #include "opkg_download.h"
 #include "opkg_message.h"
@@ -84,6 +89,11 @@ int opkg_download(opkg_conf_t *conf, const char *src,
     CURLcode res;
     FILE * file = fopen (tmp_file_location, "w");
 
+#ifdef HAVE_SSLCURL
+    static char openssl_init = 0;
+#endif
+
+
     curl = curl_easy_init ();
     if (curl)
     {
@@ -105,6 +115,85 @@ int opkg_download(opkg_conf_t *conf, const char *src,
            curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, userpwd);
            free (userpwd);
        }
+#ifdef HAVE_SSLCURL
+       if (conf->ssl_engine) {
+
+           /* Tels openssl to read it's configuration if not already 
+            * done
+            */
+           if(!openssl_init){
+               OPENSSL_config(NULL);
+               openssl_init = 1;
+           }
+
+           /* use crypto engine */
+           if (curl_easy_setopt(curl, CURLOPT_SSLENGINE, conf->ssl_engine) != 
CURLE_OK){
+               opkg_message(conf, OPKG_ERROR, "can't set crypto engine: 
'%s'\n",
+                       conf->ssl_engine);
+
+               fclose (file);
+               free(tmp_file_location);
+               free(src_basec);
+               curl_easy_cleanup (curl);
+               return -1;
+           }
+           /* set the crypto engine as default */
+           if (curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1L) != 
CURLE_OK){
+               opkg_message(conf, OPKG_ERROR, "can't set crypto engine as 
default\n");
+
+               fclose (file);
+               free(tmp_file_location);
+               free(src_basec);
+               curl_easy_cleanup (curl);
+               return -1;
+           }
+       }
+
+       /* cert & key can only be in PEM case in the same file */
+       if(conf->ssl_key_passwd){
+           res = curl_easy_setopt(curl, CURLOPT_SSLKEYPASSWD, 
conf->ssl_key_passwd);
+           if(res != CURLE_OK){
+               opkg_message(conf,OPKG_DEBUG, "Failed to set key password\n");
+           }
+       }
+
+       /* sets the client certificate */
+       if(conf->ssl_cert_type){
+           res = curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, 
conf->ssl_cert_type);
+           if(res != CURLE_OK){
+               opkg_message(conf,OPKG_DEBUG, "Failed to set certificate 
format\n");
+           }
+       }
+       /* SSL cert name isn't mandatory */
+       if(conf->ssl_cert){
+           curl_easy_setopt(curl, CURLOPT_SSLCERT, conf->ssl_cert);
+       }
+       /* sets the client key */
+       if(conf->ssl_key_type){
+           res = curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, 
conf->ssl_key_type);
+           if(res != CURLE_OK){
+               opkg_message(conf,OPKG_DEBUG, "Failed to set key format\n");
+           }
+       }
+       if(conf->ssl_key){
+           curl_easy_setopt(curl, CURLOPT_SSLKEY, conf->ssl_key);
+       }
+
+       /* Should we verify the peer certificate ? */
+       if(conf->ssl_dont_verify_peer){
+           // CURLOPT_SSL_VERIFYPEER default is nonzero (curl => 7.10)
+           res = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
+       }
+
+       /* certification authority file and/or path */
+       if(conf->ssl_ca_file){
+           curl_easy_setopt(curl, CURLOPT_CAINFO, conf->ssl_ca_file);
+       }
+       if(conf->ssl_ca_path){
+           curl_easy_setopt(curl, CURLOPT_CAPATH, conf->ssl_ca_path);
+       }
+#endif
+
        res = curl_easy_perform (curl);
        fclose (file);
        if (res)

_______________________________________________
Openembedded-devel mailing list
Openembedded-devel@lists.openembedded.org
http://lists.linuxtogo.org/cgi-bin/mailman/listinfo/openembedded-devel

Reply via email to