Commit 77a91693 authored by David Woodhouse's avatar David Woodhouse

Add PKCS#11 support for OpenSSL using libp11

Not that I'm overly worried about feature parity, but it was an interesting
exercise in working out how OpenSSL applications can Do The Right Thing
with PKCS#11. Perhaps I can turn openssl-pkcs11.c into a generic library
function to load EVP_PKEY/X509 from PKCS#11 URIs.
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent e570fbba
......@@ -21,7 +21,7 @@ openconnect_LDADD = libopenconnect.la $(LIBXML2_LIBS) $(LIBPROXY_LIBS) $(INTL_LI
library_srcs = ssl.c http.c auth.c library.c compat.c dtls.c cstp.c \
mainloop.c script.c ntlm.c digest.c
lib_srcs_gnutls = gnutls.c gnutls_pkcs12.c gnutls_tpm.c
lib_srcs_openssl = openssl.c
lib_srcs_openssl = openssl.c openssl-pkcs11.c
lib_srcs_win32 = tun-win32.c sspi.c
lib_srcs_posix = tun.c
lib_srcs_gssapi = gssapi.c
......@@ -62,8 +62,8 @@ library_srcs += $(lib_srcs_posix)
endif
libopenconnect_la_SOURCES = version.c $(library_srcs)
libopenconnect_la_CFLAGS = $(AM_CFLAGS) $(SSL_CFLAGS) $(DTLS_SSL_CFLAGS) $(LIBXML2_CFLAGS) $(LIBPROXY_CFLAGS) $(ZLIB_CFLAGS) $(P11KIT_CFLAGS) $(TSS_CFLAGS) $(LIBSTOKEN_CFLAGS) $(LIBOATH_CFLAGS) $(LIBPSKC_CFLAGS) $(GSSAPI_CFLAGS) $(INTL_CFLAGS) $(ICONV_CFLAGS) $(LIBPCSCLITE_CFLAGS)
libopenconnect_la_LIBADD = $(SSL_LIBS) $(DTLS_SSL_LIBS) $(LIBXML2_LIBS) $(LIBPROXY_LIBS) $(ZLIB_LIBS) $(P11KIT_LIBS) $(TSS_LIBS) $(LIBSTOKEN_LIBS) $(LIBOATH_LIBS) $(LIBPSKC_LIBS) $(GSSAPI_LIBS) $(INTL_LIBS) $(ICONV_LIBS) $(LIBPCSCLITE_LIBS)
libopenconnect_la_CFLAGS = $(AM_CFLAGS) $(SSL_CFLAGS) $(DTLS_SSL_CFLAGS) $(LIBXML2_CFLAGS) $(LIBPROXY_CFLAGS) $(ZLIB_CFLAGS) $(P11KIT_CFLAGS) $(TSS_CFLAGS) $(LIBSTOKEN_CFLAGS) $(LIBOATH_CFLAGS) $(LIBPSKC_CFLAGS) $(GSSAPI_CFLAGS) $(INTL_CFLAGS) $(ICONV_CFLAGS) $(LIBPCSCLITE_CFLAGS) $(LIBP11_CFLAGS)
libopenconnect_la_LIBADD = $(SSL_LIBS) $(DTLS_SSL_LIBS) $(LIBXML2_LIBS) $(LIBPROXY_LIBS) $(ZLIB_LIBS) $(P11KIT_LIBS) $(TSS_LIBS) $(LIBSTOKEN_LIBS) $(LIBOATH_LIBS) $(LIBPSKC_LIBS) $(GSSAPI_LIBS) $(INTL_LIBS) $(ICONV_LIBS) $(LIBPCSCLITE_LIBS) $(LIBP11_LIBS)
if OPENBSD_LIBTOOL
# OpenBSD's libtool doesn't have -version-number, but its -version-info arg
# does what GNU libtool's -version-number does. Which arguably is what the
......
......@@ -458,6 +458,13 @@ case "$ssl_library" in
check_openssl_dtls=no
;;
openssl)
PKG_CHECK_MODULES(P11KIT, p11-kit-1,
[PKG_CHECK_MODULES(LIBP11, libp11,
[AC_DEFINE(HAVE_LIBP11, 1, [Have libp11 and p11-kit for OpenSSL])
AC_SUBST(P11KIT_PC, ["libp11 p11-kit-1"])
proxy_module="`$PKG_CONFIG --variable=proxy_module p11-kit-1`"
AC_DEFINE_UNQUOTED([DEFAULT_PKCS11_MODULE], "${proxy_module}", [p11-kit proxy])],
[:])], [:])
AC_DEFINE(OPENCONNECT_OPENSSL, 1, [Using OpenSSL])
AC_DEFINE(DTLS_OPENSSL, 1, [Using OpenSSL for DTLS])
AC_SUBST(SSL_DTLS_PC, [openssl])
......
......@@ -276,6 +276,17 @@ void openconnect_vpninfo_free(struct openconnect_info *vpninfo)
}
memset(vpninfo->yubikey_pwhash, 0, sizeof(vpninfo->yubikey_pwhash));
free(vpninfo->yubikey_objname);
#endif
#ifdef HAVE_LIBP11
if (vpninfo->pkcs11_ctx) {
if (vpninfo->pkcs11_slot_list)
PKCS11_release_all_slots(vpninfo->pkcs11_ctx,
vpninfo->pkcs11_slot_list,
vpninfo->pkcs11_slot_count);
PKCS11_CTX_unload(vpninfo->pkcs11_ctx);
PKCS11_CTX_free(vpninfo->pkcs11_ctx);
}
free(vpninfo->pkcs11_cert_id);
#endif
/* These check strm->state so they are safe to call multiple times */
inflateEnd(&vpninfo->inflate_strm);
......@@ -519,6 +530,8 @@ int openconnect_has_pkcs11_support(void)
{
#if defined(OPENCONNECT_GNUTLS) && defined(HAVE_P11KIT)
return 1;
#elif defined(OPENCONNECT_OPENSSL) && defined(HAVE_LIBP11)
return 1;
#else
return 0;
#endif
......
......@@ -89,6 +89,10 @@
#include <pskc/pskc.h>
#endif
#ifdef HAVE_LIBP11
#include <libp11.h>
#endif
#ifdef HAVE_LIBPCSCLITE
#ifdef __APPLE__
#include <PCSC/wintypes.h>
......@@ -310,6 +314,14 @@ struct openconnect_info {
unsigned pfs;
#if defined(OPENCONNECT_OPENSSL)
#ifdef HAVE_LIBP11
PKCS11_CTX *pkcs11_ctx;
PKCS11_SLOT *pkcs11_slot_list;
unsigned int pkcs11_slot_count;
PKCS11_SLOT *pkcs11_cert_slot;
unsigned char *pkcs11_cert_id;
size_t pkcs11_cert_id_len;
#endif
X509 *cert_x509;
SSL_CTX *https_ctx;
SSL *https_ssl;
......@@ -636,6 +648,10 @@ FILE *openconnect_fopen_utf8(struct openconnect_info *vpninfo,
void openconnect_clear_cookies(struct openconnect_info *vpninfo);
/* openssl-pkcs11.c */
int load_pkcs11_key(struct openconnect_info *vpninfo);
int load_pkcs11_certificate(struct openconnect_info *vpninfo);
/* {gnutls,openssl}.c */
int openconnect_open_https(struct openconnect_info *vpninfo);
void openconnect_close_https(struct openconnect_info *vpninfo, int final);
......
This diff is collapsed.
......@@ -734,11 +734,11 @@ static int load_certificate(struct openconnect_info *vpninfo)
FILE *f;
char buf[256];
if (!strncmp(vpninfo->sslkey, "pkcs11:", 7) ||
!strncmp(vpninfo->cert, "pkcs11:", 7)) {
vpn_progress(vpninfo, PRG_ERR,
_("This binary built without PKCS#11 support\n"));
return -EINVAL;
if (!strncmp(vpninfo->cert, "pkcs11:", 7)) {
int ret = load_pkcs11_certificate(vpninfo);
if (ret)
return ret;
goto got_cert;
}
vpn_progress(vpninfo, PRG_DEBUG,
......@@ -792,6 +792,8 @@ static int load_certificate(struct openconnect_info *vpninfo)
if (ret)
return ret;
}
got_cert:
#ifdef ANDROID_KEYSTORE
if (!strncmp(vpninfo->sslkey, "keystore:", 9)) {
EVP_PKEY *key;
......@@ -819,6 +821,8 @@ static int load_certificate(struct openconnect_info *vpninfo)
return 0;
}
#endif /* ANDROID_KEYSTORE */
if (!strncmp(vpninfo->sslkey, "pkcs11:", 7))
return load_pkcs11_key(vpninfo);
f = openconnect_fopen_utf8(vpninfo, vpninfo->sslkey, "rb");
if (!f) {
......
......@@ -28,6 +28,8 @@ libraries and tools installed:</p>
</ul>
And <em>optionally</em> also:
<ul>
<li><b><tt><a href="http://p11-glue.freedesktop.org/p11-kit.html">p11-kit</a></tt></b> <i>(for PKCS#11 support)</i></li>
<li><b><tt><a href="https://github.com/OpenSC/libp11/wiki">libp11</a></tt></b> <i>(also needed for PKCS#11 support if using OpenSSL)</i></li>
<li><b><tt><a href="http://code.google.com/p/libproxy/">libproxy</a></tt></b></li>
<li><b><tt><a href="http://trousers.sourceforge.net/">trousers</a></tt></b> <i>(for TPM support if using GnuTLS)</i></li>
<li><b><tt><a href="http://stoken.sourceforge.net/">libstoken</a></tt></b> <i>(for SecurID software token support)</i></li>
......
......@@ -15,7 +15,7 @@
<ul>
<li><b>OpenConnect HEAD</b>
<ul>
<li><i>No changelog entries yet</i></li>
<li>Add PKCS#11 support for OpenSSL.</li>
</ul><br/>
</li>
<li><b><a href="ftp://ftp.infradead.org/pub/openconnect/openconnect-7.01.tar.gz">OpenConnect v7.01</a></b>
......
......@@ -14,7 +14,7 @@
<li>Connection through SOCKS5 proxy.</li>
<li>Automatic detection of IPv4 and IPv6 address, routes.</li>
<li>Authentication via HTTP forms.</li>
<li>Authentication using SSL certificates &#8212; from local file, <a href="http://en.wikipedia.org/wiki/Trusted_Platform_Module">Trusted Platform Module</a> and <i>(when built with GnuTLS)</i> PKCS#11 smartcards.</li>
<li>Authentication using SSL certificates &#8212; from local file, <a href="http://en.wikipedia.org/wiki/Trusted_Platform_Module">Trusted Platform Module</a> and PKCS#11 smartcards.</li>
<li>Authentication using SecurID software tokens <i>(when built with libstoken)</i></li>
<li>Authentication using OATH TOTP or HOTP software tokens <i>(when built with liboath)</i></li>
<li>Authentication using Yubikey OATH tokens <i>(when built with libpcsclite)</i></li>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment