Skip to contentSkip to conversation

Add Mac OS X keychain support

PATCH In review Vasily Kulikov 7 participants 13 messages Dec 8, 2014 – Jan 8, 2015

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Add Mac OS X keychain support

This patch adds support for using certificates stored in the Mac OSX Keychain to authenticate with the OpenVPN server. This works with certificates stored on the computer as well as certificates on hardware tokens that support Apple's tokend interface. The patch is very similar to, and also based on, the Windows Crypto API certificate functionality that currently exists in OpenVPN.

The previous version of the patch was sent by Brian Raderman
(http://thread.gmane.org/gmane.network.openvpn.devel/3631). The current version uses autoconf, doesn't use printf, fixes several small bugs like ignoring errors, and it now works with Tunnelblick. The previous version has been tested with an Aladdin eToken on Mac OSX Leopard and with software only certificates on Mac OSX Leopard and Snow Leopard, as reported by Brian Raderman in his email. The current version of the patch was tested in Yandex company on ~3000 hosts using several Mac OS X versions (10.7, 10.8. 10.9. 10.10) using Tunnelblick.

It was tested both on OpenVPN started from the terminal and using Tunnelblick. Renegotiation was tested too.

There are several warnings on Mac OS X related to functions deprecation like RSA_new() and similar. However, they are used in other OpenVPN code, so I decided not to touch it.

The patch is against commit 3341a98c2852d1d0c1eafdc70a3bdb218ec29049.

--

configure.ac +14 -0
index 608ab6d..127e173 100644
@@ -258,6 +258,13 @@ AC_ARG_ENABLE(
 )
 
 AC_ARG_ENABLE(
+	[macosx-keychain],
+	[AS_HELP_STRING([--enable-macosx-keychain], [enable MAC OS X keychain support @<:@default=yes@:>@])],
+	,
+	[enable_keychain="no"]
+)
+
+AC_ARG_ENABLE(
 	[systemd],
 	[AS_HELP_STRING([--enable-systemd], [enable systemd suppport @<:@default=no@:>@])],
 	,
@@ -330,6 +337,7 @@ case "$host" in
 		have_tap_header="yes"
 		dnl some Mac OS X tendering (we use vararg macros...)
 		CPPFLAGS="$CPPFLAGS -no-cpp-precomp"
+		MACOSX=yes
 		;;
 	*-mingw*)
 		AC_DEFINE([TARGET_WIN32], [1], [Are we running WIN32?])
@@ -1088,6 +1096,11 @@ if test "${enable_ssl}" = "yes"; then
 	AC_DEFINE([ENABLE_SSL], [1], [Enable ssl library])
 fi
 
+if test "${enable_macosx_keychain}" = "yes"; then
+	test "${MACOSX}" != "yes" && AC_MSG_ERROR([keychain is available on MAC OS X only])
+	AC_DEFINE([ENABLE_KEYCHAIN], [1], [Enable MAC OS X keychain support])
+fi
+
 if test "${enable_crypto}" = "yes"; then
 	test "${have_crypto_crypto}" != "yes" && AC_MSG_ERROR([${with_crypto_library} crypto is required but missing])
 	test "${enable_crypto_ofb_cfb}" = "yes" && AC_DEFINE([ENABLE_OFB_CFB_MODE], [1], [Enable OFB and CFB cipher modes])
@@ -1199,6 +1212,7 @@ AC_SUBST([PLUGIN_AUTH_PAM_CFLAGS])
 AC_SUBST([PLUGIN_AUTH_PAM_LIBS])
 
 AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"])
+AM_CONDITIONAL([MACOSX], [test "${MACOSX}" = "yes"])
 AM_CONDITIONAL([GIT_CHECKOUT], [test "${GIT_CHECKOUT}" = "yes"])
 AM_CONDITIONAL([ENABLE_PLUGIN_AUTH_PAM], [test "${enable_plugin_auth_pam}" = "yes"])
 AM_CONDITIONAL([ENABLE_PLUGIN_DOWN_ROOT], [test "${enable_plugin_down_root}" = "yes"])
doc/openvpn.8 +71 -0

77 lines not on this page · raw message

src/compat/compat.h +1 -1
index 021573e..81a678e 100644
@@ -49,7 +49,7 @@ char * dirname(char *str);
 char * basename(char *str);
 #endif /* HAVE_BASENAME */
 
-#ifndef HAVE_GETTIMEOFDAY
+#if !defined(HAVE_GETTIMEOFDAY) && !defined(ENABLE_KEYCHAIN)
 int gettimeofday (struct timeval *tv, void *tz);
 #endif
 
src/openvpn/Makefile.am +8 -1
index d089f50..da40079 100644
@@ -116,7 +116,11 @@ openvpn_SOURCES = \
 	syshead.h \
 	tun.c tun.h \
 	win32.h win32.c \
-	cryptoapi.h cryptoapi.c
+	cryptoapi.h cryptoapi.c \
+	common_osx.c common_osx.h \
+	crypto_osx.c crypto_osx.h \
+	cert_data.c cert_data.h \
+	keychain.c keychain.h
 openvpn_LDADD = \
 	$(top_builddir)/src/compat/libcompat.la \
 	$(SOCKETS_LIBS) \
@@ -132,3 +136,6 @@ if WIN32
 openvpn_SOURCES += openvpn_win32_resources.rc
 openvpn_LDADD += -lgdi32 -lws2_32 -lwininet -lcrypt32 -liphlpapi -lwinmm
 endif
+if MACOSX
+openvpn_LDFLAGS = -framework CoreFoundation -framework Security
+endif
src/openvpn/cert_data.c new file +766 -0

766 lines not on this page · raw message

src/openvpn/cert_data.h new file +46 -0

46 lines not on this page · raw message

src/openvpn/common_osx.c new file +93 -0

93 lines not on this page · raw message

src/openvpn/common_osx.h new file +40 -0
new file mode 100644
index 0000000..0485334
@@ -0,0 +1,40 @@
+/*
+ *  OpenVPN -- An application to securely tunnel IP networks
+ *             over a single UDP port, with support for SSL/TLS-based
+ *             session authentication and key exchange,
+ *             packet encryption, packet authentication, and
+ *             packet compression.
+ *
+ *  Copyright (C) 2010 Brian Raderman <[email protected]...>
+ *  Copyright (C) 2013-2014 Vasily Kulikov <[email protected]...>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  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.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program (see the file COPYING included with this
+ *  distribution); if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __common_osx_h__
+#define __common_osx_h__
+
+#include "config.h"
+
+#ifdef ENABLE_KEYCHAIN
+#include <CoreFoundation/CoreFoundation.h>
+#endif
+
+void printCFString(CFStringRef str);
+char* cfstringToCstr(CFStringRef str);
+CFStringRef createHexString(unsigned char *pData, int length);
+void printHex(unsigned char *pData, int length);
+
+#endif //__Common_osx_h__
src/openvpn/crypto_osx.c new file +80 -0

80 lines not on this page · raw message

src/openvpn/crypto_osx.h new file +44 -0

44 lines not on this page · raw message

src/openvpn/init.c +5 -0
index a673be5..c076c8b 100644
@@ -39,6 +39,7 @@
 #include "pool.h"
 #include "gremlin.h"
 #include "pkcs11.h"
+#include "keychain.h"
 #include "ps.h"
 #include "lladdr.h"
 #include "ping.h"
@@ -929,6 +930,10 @@ possibly_become_daemon (const struct options *options, const bool first_time)
   bool ret = false;
   if (first_time && options->daemon)
     {
+#if defined(ENABLE_KEYCHAIN)
+      if (options->keychain_cert)
+        keychain_daemonFixup(options);
+#endif
       ASSERT (!options->inetd);
       if (daemon (options->cd_dir != NULL, options->log) < 0)
 	msg (M_ERR, "daemon() failed or unsupported");
src/openvpn/keychain.c new file +312 -0

312 lines not on this page · raw message

src/openvpn/keychain.h new file +10 -0
new file mode 100644
index 0000000..05e75d4
@@ -0,0 +1,10 @@
+#ifndef _OSXKEYCHAIN_H_
+#define _OSXKEYCHAIN_H_
+
+#include "options.h"
+
+int SSL_CTX_use_Keychain_certificate(SSL_CTX *ssl_ctx, const char *cert_prop);
+void keychain_daemonFixup(const struct options *options);
+
+
+#endif /* !_OSXKEYCHAIN_H_ */
src/openvpn/openvpn.c +4 -0
index fd87fc1..6942b87 100644
@@ -30,6 +30,10 @@
 
 #include "syshead.h"
 
+#ifdef ENABLE_KEYCHAIN
+#include <Security/Security.h>
+#endif
+
 #include "init.h"
 #include "forward.h"
 #include "multi.h"
src/openvpn/options.c +37 -2
index 64ded09..9d0b217 100644
@@ -586,6 +586,10 @@ static const char usage_message[] =
   "--cryptoapicert select-string : Load the certificate and private key from the\n"
   "                  Windows Certificate System Store.\n"
 #endif
+#ifdef ENABLE_KEYCHAIN
+  "--keychaincert  select-string : Load the certificate and private key from the\n"
+  "                  Mac OSX Keychain.\n"
+#endif
   "--tls-cipher l  : A list l of allowable TLS ciphers separated by : (optional).\n"
   "                : Use --show-tls to see a list of supported TLS ciphers.\n"
   "--tls-timeout n : Packet retransmit timeout on TLS control channel\n"
@@ -1605,6 +1609,9 @@ show_settings (const struct options *o)
 #ifdef ENABLE_CRYPTOAPI
   SHOW_STR (cryptoapi_cert);
 #endif
+#ifdef ENABLE_KEYCHAIN
+  SHOW_STR (keychain_cert);
+#endif
   SHOW_STR (cipher_list);
   SHOW_STR (tls_verify);
   SHOW_STR (tls_export_cert);
@@ -2179,6 +2186,10 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
 	if (options->cryptoapi_cert)
 	  msg(M_USAGE, "Parameter --cryptoapicert cannot be used when --pkcs11-provider is also specified.");
 #endif
+#ifdef ENABLE_KEYCHAIN
+	if (options->keychain_cert)
+	   msg(M_USAGE, "Parameter --keychaincert cannot be used when --pkcs11-provider is also specified.");
+#endif
        }
       else
 #endif
@@ -2205,9 +2216,26 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
 	    msg(M_USAGE, "Parameter --management-external-key cannot be used when --cryptoapicert is also specified.");
 #endif
 	}
-      else
+	else
+#elif defined(ENABLE_KEYCHAIN)
+	if (options->keychain_cert)
+	{
+		if ((!(options->ca_file)) && (!(options->ca_path)))
+			msg(M_USAGE, "You must define CA file (--ca) or CA path (--capath)");
+		if (options->cert_file)
+			msg(M_USAGE, "Parameter --cert cannot be used when --keychaincert is also specified.");
+		if (options->priv_key_file)
+			msg(M_USAGE, "Parameter --key cannot be used when --keychaincert is also specified.");
+		if (options->pkcs12_file)
+			msg(M_USAGE, "Parameter --pkcs12 cannot be used when --keychaincert is also specified.");
+#ifdef MANAGMENT_EXTERNAL_KEY
+          if (options->management_flags & MF_EXTERNAL_KEY)
+	    msg(M_USAGE, "Parameter --management-external-key cannot be used when --cryptoapicert is also specified.");
+#endif
+	}
+	else
 #endif
-      if (options->pkcs12_file)
+       if (options->pkcs12_file)
         {
 #ifdef ENABLE_CRYPTO_POLARSSL
 	  msg(M_USAGE, "Parameter --pkcs12 cannot be used with the PolarSSL version version of OpenVPN.");
@@ -6565,6 +6593,13 @@ add_option (struct options *options,
       options->cryptoapi_cert = p[1];
     }
 #endif
+#ifdef ENABLE_KEYCHAIN
+  else if (streq (p[0], "keychaincert") && p[1])
+  {
+      VERIFY_PERMISSION (OPT_P_GENERAL);
+      options->keychain_cert = p[1];
+  }
+#endif
   else if (streq (p[0], "key") && p[1])
     {
       VERIFY_PERMISSION (OPT_P_GENERAL);
src/openvpn/options.h +3 -0
index 5ba4f2f..037f362 100644
@@ -545,6 +545,9 @@ struct options
 #ifdef ENABLE_CRYPTOAPI
   const char *cryptoapi_cert;
 #endif
+#ifdef ENABLE_KEYCHAIN
+  const char *keychain_cert;
+#endif
 
   /* data channel key exchange method */
   int key_method;
src/openvpn/ssl.c +6 -0
index c81659f..205bc42 100644
@@ -515,6 +515,12 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx)
       tls_ctx_load_cryptoapi(new_ctx, options->cryptoapi_cert);
     }
 #endif
+#ifdef ENABLE_KEYCHAIN
+  else if (options->keychain_cert)
+  {
+    tls_ctx_load_keychain(new_ctx, options->keychain_cert);
+  }
+#endif
 #ifdef MANAGMENT_EXTERNAL_KEY
   else if ((options->management_flags & MF_EXTERNAL_KEY) && options->cert_file)
     {
src/openvpn/ssl_backend.h +11 -0
index b0777bf..c7233a1 100644
@@ -224,6 +224,17 @@ void tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert
 #endif /* WIN32 */
 
 /**
+ * Use Mac OS X keychain for key and cert, and add to library-specific TLS
+ * context.
+ *
+ * @param ctx			TLS context to use
+ * @param keychain_cert		String representing the certificate to load.
+ */
+#ifdef ENABLE_KEYCHAIN
+void tls_ctx_load_keychain(struct tls_root_ctx *ctx, const char *keychain_cert);
+#endif /* ENABLE_KEYCHAIN */
+
+/**
  * Load certificate file into the given TLS context. If the given certificate
  * file contains a certificate chain, load the whole chain.
  *
src/openvpn/ssl_openssl.c +15 -0
index 6782a95..bddf14d 100644
@@ -50,6 +50,10 @@
 #include "cryptoapi.h"
 #endif
 
+#ifdef ENABLE_KEYCHAIN
+#include "keychain.h"
+#endif
+
 #include "ssl_verify_openssl.h"
 
 #include <openssl/err.h>
@@ -535,6 +539,17 @@ tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert)
 }
 #endif /* WIN32 */
 
+#ifdef ENABLE_KEYCHAIN
+void
+tls_ctx_load_keychain(struct tls_root_ctx *ctx, const char *keychain_cert)
+{
+  /* Load Certificate and Private Key */
+  if (!SSL_CTX_use_Keychain_certificate (ctx->ctx, keychain_cert))
+    msg (M_SSLERR, "Cannot load certificate \"%s\" from Mac OSX Keychain",
+		    keychain_cert);
+}
+#endif /* ENABLE_KEYCHAIN */
+
 static void
 tls_ctx_add_extra_certs (struct tls_root_ctx *ctx, BIO *bio)
 {
#1 lore raw

Hi,

Quoted 20 lines · Vasily Kulikov

This patch adds support for using certificates stored in the Mac OSX Keychain to authenticate with the OpenVPN server. This works with certificates stored on the computer as well as certificates on hardware tokens that support Apple's tokend interface. The patch is very similar to, and also based on, the Windows Crypto API certificate functionality that currently exists in OpenVPN.

The previous version of the patch was sent by Brian Raderman
(http://thread.gmane.org/gmane.network.openvpn.devel/3631). The current version uses autoconf, doesn't use printf, fixes several small bugs like ignoring errors, and it now works with Tunnelblick. The previous version has been tested with an Aladdin eToken on Mac OSX Leopard and with software only certificates on Mac OSX Leopard and Snow Leopard, as reported by Brian Raderman in his email. The current version of the patch was tested in Yandex company on ~3000 hosts using several Mac OS X versions (10.7, 10.8. 10.9. 10.10) using Tunnelblick.

It was tested both on OpenVPN started from the terminal and using Tunnelblick. Renegotiation was tested too.

Quoted 8 lines

There are several warnings on Mac OS X related to functions deprecation like RSA_new() and similar. However, they are used in other OpenVPN code, so I decided not to touch it.

The patch is against commit 3341a98c2852d1d0c1eafdc70a3bdb218ec29049.

--

Any comments?

Signature · 2 lines
Vasily Kulikov
http://www.openwall.com - bringing security into open computing environments
#2 lore raw

Am 12.12.14 17:52, schrieb Vasily Kulikov:

Quoted 27 lines

Hi,

Quoted 24 lines · Vasily Kulikov

This patch adds support for using certificates stored in the Mac OSX Keychain to authenticate with the OpenVPN server. This works with certificates stored on the computer as well as certificates on hardware tokens that support Apple's tokend interface. The patch is very similar to, and also based on, the Windows Crypto API certificate functionality that currently exists in OpenVPN.

The previous version of the patch was sent by Brian Raderman
(http://thread.gmane.org/gmane.network.openvpn.devel/3631). The current version uses autoconf, doesn't use printf, fixes several small bugs like ignoring errors, and it now works with Tunnelblick. The previous version has been tested with an Aladdin eToken on Mac OSX Leopard and with software only certificates on Mac OSX Leopard and Snow Leopard, as reported by Brian Raderman in his email. The current version of the patch was tested in Yandex company on ~3000 hosts using several Mac OS X versions (10.7, 10.8. 10.9. 10.10) using Tunnelblick.

It was tested both on OpenVPN started from the terminal and using Tunnelblick. Renegotiation was tested too.

There are several warnings on Mac OS X related to functions deprecation like RSA_new() and similar. However, they are used in other OpenVPN code, so I decided not to touch it.

Quoted 6 lines
Quoted 4 lines

The patch is against commit 3341a98c2852d1d0c1eafdc70a3bdb218ec29049.

--

Any comments?

None yet. The patch is very large and our time is unfortenately limited. And the number of people how do crypto and Mac OS is even smaller. I haven't have found time yet to look at the code yet. (We don't want to commit unreviewed code).

Arne

#3 lore raw

Hi Arne,

Quoted 7 lines · Arne Schwabe

Am 12.12.14 17:52, schrieb Vasily Kulikov:

Quoted 2 lines

Any comments?

None yet. The patch is very large and our time is unfortenately limited. And the number of people how do crypto and Mac OS is even smaller. I haven't have found time yet to look at the code yet. (We don't want to commit unreviewed code).

Thank you! I don't want anybody to commit unreviewed code too. Do you think I should just wait until some people read the code or should I divide the code into smaller parts? However, I don't see the way it can be divided as it is a rather monolithic feature, only Tunnelblick support can be isolated (however, this second part would be very small and the first part would be still very big).

Signature · 2 lines
Vasily Kulikov
http://www.openwall.com - bringing security into open computing environments
#4 lore raw
In reply to Arne Schwabe

Hi,

Quoted 7 lines · Arne Schwabe
Quoted 7 lines · Vasily Kulikov
Quoted 6 lines

This patch adds support for using certificates stored in the Mac OSX Keychain to authenticate with the OpenVPN server. This works with certificates stored on the computer as well as certificates on hardware tokens that support Apple's tokend interface. The patch is very similar to, and also based on, the Windows Crypto API certificate functionality that currently exists in OpenVPN.

...

Quoted 3 lines
Quoted 3 lines
Quoted 2 lines

--

Any comments?

Some ideas about keychain implementation out of OpenVPN core.

I see 4 possible alternatives here:
1) implement keychain rsa offloading in Tunnelblick
2) make my patch use plugin interface
3) implement external daemon that communicated with openvpn process via management interface
4) the same as 3) but make openvpn able to handle more than 1 management client

There are problems with all these alternatives:
(1) is limited to Tunnelblick users and doesn't work for users who start openvpn from the terminal or use any other GUI
(2) implies plugin interface is expanded to handle two new actions: 'user certificate request' and 'rsa-sign request'
(3) implies management interface is expanded to handle 'user certificate request'; also it doesn't work with Tunnelblick or any other tool that communicates with openvpn via management interface as MI currently supports only a single client
(4) needs 'user certificate request' addition and expanding management interface to support more than a single client

So, (1) is a no-go as it works only with Tunnelblick; (3) is a no-go as it breaks Tunnelblick and probably someone else. We stay with only two interface expantions: plugin interface or management interface. Either
(a) add 'user certificate request' to plugin interface or (b) add 'user certificate request' to management interface and support more than a single client.

I'm not sure which way is better. Do you have any plans/objections on these interfaces expantion? Maybe I missed some critical limitations of the interfaces and they must not be used this way? If no strict objections I'd prefer to implement it via plugin interface as my patch would need to change only several hooks registration and handling functions in this case.

Thanks,

Signature · 2 lines
Vasily Kulikov
http://www.openwall.com - bringing security into open computing environments
#5 lore raw

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Quoted 8 lines

Hi,

Quoted 5 lines · Arne Schwabe
Quoted 5 lines · Vasily Kulikov
Quoted 4 lines

This patch adds support for using certificates stored in the Mac OSX Keychain to authenticate with the OpenVPN server. This works with certificates stored on the computer as well as certificates on hardware tokens that support Apple's tokend interface. The patch is very

similar

Quoted 36 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

to, and also based on, the Windows Crypto API certificate functionality that currently exists in OpenVPN.

...

Quoted 3 lines
Quoted 3 lines
Quoted 2 lines

--

Any comments?

Some ideas about keychain implementation out of OpenVPN core.

I see 4 possible alternatives here:
1) implement keychain rsa offloading in Tunnelblick
2) make my patch use plugin interface
3) implement external daemon that communicated with openvpn process via management interface
4) the same as 3) but make openvpn able to handle more than 1 management client

There are problems with all these alternatives:
(1) is limited to Tunnelblick users and doesn't work for users who start openvpn from the terminal or use any other GUI
(2) implies plugin interface is expanded to handle two new actions: 'user certificate request' and 'rsa-sign request'
(3) implies management interface is expanded to handle 'user certificate request'; also it doesn't work with Tunnelblick or any other tool that communicates with openvpn via management interface as MI currently supports only a single client
(4) needs 'user certificate request' addition and expanding management interface to support more than a single client

So, (1) is a no-go as it works only with Tunnelblick; (3) is a no-go as it breaks Tunnelblick and probably someone else. We stay with only two interface expantions: plugin interface or management interface. Either
(a) add 'user certificate request' to plugin interface or (b) add 'user certificate request' to management interface and support more than a single client.

Quoted 9 lines

I'm not sure which way is better. Do you have any plans/objections on these interfaces expantion? Maybe I missed some critical limitations of the interfaces and they must not be used this way? If no strict objections I'd prefer to implement it via plugin interface as my patch would need to change only several hooks registration and handling functions in this case.

Thanks,

Hi,

I've discussed this topic with James Bekkema, a Viscosity developer who was unfortunately unable to attend the previous IRC meeting. He suggested the following:

"I also noticed some confusion as to how OpenVPN was able to access the local user’s Keychain in the IRC chat log: while I haven’t looked in detail at the patch, I suspect this is due to how Tunnelblick is launching OpenVPN with elevated permissions. Tunnelblick uses a SUID helper to have effective root permissions, and so OpenVPN in inheriting the user’s environment. For clients using a more secure (i.e. launchd) elevation approach (such as OpenVPN Connect, Viscosity, etc.) this approach won’t work (assuming it is indeed what is going on) which may make it a bit useless."

"My recommendation would be to expand upon the support already in place for getting identity details over the management interface for Android devices. That way the actual accessing of the Keychain can be performed by a process running as the end user, without any signing issues etc. coming into play. It looks like this was pretty much the conclusion drawn from the meeting ."

Best regards,

- --
Samuli Seppänen
Community Manager
OpenVPN Technologies, Inc

irc freenode net: mattock
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iEYEARECAAYFAlSrpiIACgkQwp2X7RmNIqOioACgx+xqO+Z7cVJZtGClgWdK0nDh eCMAn2Emks41PQCbKsaA9pt5U19DGhSS
=63NW
-----END PGP SIGNATURE-----

#6 lore raw

Hi All,

Just to expand on the comments Samuli included below:

#7 lore raw
In reply to Vasily Kulikov
Quoted 23 lines
Quoted 1 line
Quoted 1 line

Any comments?

Some ideas about keychain implementation out of OpenVPN core.

I see 4 possible alternatives here:
1) implement keychain rsa offloading in Tunnelblick
2) make my patch use plugin interface
3) implement external daemon that communicated with openvpn process via management interface
4) the same as 3) but make openvpn able to handle more than 1 management client

There are problems with all these alternatives:
(1) is limited to Tunnelblick users and doesn't work for users who start openvpn from the terminal or use any other GUI
(2) implies plugin interface is expanded to handle two new actions: 'user certificate request' and 'rsa-sign request'
(3) implies management interface is expanded to handle 'user certificate request'; also it doesn't work with Tunnelblick or any other tool that communicates with openvpn via management interface as MI currently supports only a single client
(4) needs 'user certificate request' addition and expanding management interface to support more than a single client

Quoted 6 lines

So, (1) is a no-go as it works only with Tunnelblick (3) is a no-go as it breaks Tunnelblick and probably someone else. We stay with only two interface expantions: plugin interface or management interface. Either
(a) add 'user certificate request' to plugin interface or (b) add 'user certificate request' to management interface and support more than a single client.

But if you encapsulate that stuff in a library or something similar you could use that library from TunnelBlick and from a small standalone tool/OpenVPN plugin.

For (4) Implementing a request for managament ca/cert is relatively easy. At the moment this has not been implemented because nobody needed it so far. All current users managment-query-key (or what the option is called) generate the configuration with the right <ca>, <cert> options instead of querying for these values at startup.

I disagress that (3) is inheritly incompatible with Tunnelblick. Tunnelblick could spawn an openvpn process and the external daemon. On the rsa-sign request, Tunnelblick would just connect to the external daemon ask that daemon to process the rsa-sign request.

Arne

#8 lore raw
Quoted 33 lines · Arne Schwabe
Quoted 23 lines
Quoted 1 line
Quoted 1 line

Any comments?

Some ideas about keychain implementation out of OpenVPN core.

I see 4 possible alternatives here:
1) implement keychain rsa offloading in Tunnelblick
2) make my patch use plugin interface
3) implement external daemon that communicated with openvpn process via management interface
4) the same as 3) but make openvpn able to handle more than 1 management client

There are problems with all these alternatives:
(1) is limited to Tunnelblick users and doesn't work for users who start openvpn from the terminal or use any other GUI
(2) implies plugin interface is expanded to handle two new actions: 'user certificate request' and 'rsa-sign request'
(3) implies management interface is expanded to handle 'user certificate request'; also it doesn't work with Tunnelblick or any other tool that communicates with openvpn via management interface as MI currently supports only a single client
(4) needs 'user certificate request' addition and expanding management interface to support more than a single client

Quoted 6 lines

So, (1) is a no-go as it works only with Tunnelblick (3) is a no-go as it breaks Tunnelblick and probably someone else. We stay with only two interface expantions: plugin interface or management interface. Either
(a) add 'user certificate request' to plugin interface or (b) add 'user certificate request' to management interface and support more than a single client.

But if you encapsulate that stuff in a library or something similar you could use that library from TunnelBlick and from a small standalone tool/OpenVPN plugin.

Quoted 5 lines

For (4) Implementing a request for managament ca/cert is relatively easy. At the moment this has not been implemented because nobody needed it so far. All current users managment-query-key (or what the option is called) generate the configuration with the right <ca>, <cert> options instead of querying for these values at startup.

I'm thinking about using existing 'needstr' command. Looking at the '#ifdef TARGET_ANDROID' code, it should be a very small patch to openvpn which adds a command line option like '--management-external-cert' and using management_query_user_pass() for certificate request (e.g. BASE64 encoded).

Quoted 4 lines

I disagress that (3) is inheritly incompatible with Tunnelblick. Tunnelblick could spawn an openvpn process and the external daemon. On the rsa-sign request, Tunnelblick would just connect to the external daemon ask that daemon to process the rsa-sign request.

Right. I was talking more about breaking current state of affairs rather than completely incompatible changes that cannot be fixed on the Tunnelblick side.

Signature · 2 lines
Vasily Kulikov
http://www.openwall.com - bringing security into open computing environments
#9 lore raw
In reply to Vasily Kulikov
Quoted 9 lines · Vasily Kulikov

I see 4 possible alternatives here:
1) implement keychain rsa offloading in Tunnelblick
2) make my patch use plugin interface
3) implement external daemon that communicated with openvpn process via management interface
4) the same as 3) but make openvpn able to handle more than 1 management client

Quoted 11 lines

There are problems with all these alternatives:
(1) is limited to Tunnelblick users and doesn't work for users who start openvpn from the terminal or use any other GUI
(2) implies plugin interface is expanded to handle two new actions: 'user certificate request' and 'rsa-sign request'
(3) implies management interface is expanded to handle 'user certificate request'; also it doesn't work with Tunnelblick or any other tool that communicates with openvpn via management interface as MI currently supports only a single client
(4) needs 'user certificate request' addition and expanding management interface to support more than a single client

It is perhaps worth noting that OpenVPN already *has* a plugin API which supports the "user certificate request" and "rsa-sign request" methods.

That is, after all, fairly much what PKCS#11 was *designed* to provide.

There are also existing implementations of PKCS#11 RPC such that the actual manipulation of the token can occur in a user-owned process separately from the caller.

Perhaps the way forward is to implement the keychain support in the form of a PKCS#11 provider module, which can either be loaded directly in OpenVPN or proxied to run in a user's context.

In fact, doesn't such an implementation already exist at
https://github.com/slushpupie/KeychainToken ?

Signature · 1 line
dwmw2
#10 lore raw

Hi,

Quoted 1 line · David Woodhouse

That is, after all, fairly much what PKCS#11 was *designed* to provide.

Thanks for that hint. Seems we (as in "the currently active developers") really need to look more closely into the gifts we inherited :-)

Quoted 2 lines

In fact, doesn't such an implementation already exist at
https://github.com/slushpupie/KeychainToken ?

This looks quite promising :-) (if a bit "dead", hope it still works)

gert

Signature · 4 lines
USENET is *not* the non-clickable part of WWW!
                                                           //www.muc.de/~gert/
Gert Doering - Munich, Germany                             [email protected]...
fax: +49-89-35655025                        [email protected]...
#11 lore raw

Hi *,

Quoted 11 lines · Gert Doering

Hi,

Quoted 1 line · David Woodhouse

That is, after all, fairly much what PKCS#11 was *designed* to provide.

Thanks for that hint. Seems we (as in "the currently active developers") really need to look more closely into the gifts we inherited :-)

Quoted 2 lines

In fact, doesn't such an implementation already exist at
https://github.com/slushpupie/KeychainToken ?

This looks quite promising :-) (if a bit "dead", hope it still works)

when reading this thread I also thought of "that's what we have pkcs#11 for" . However, a pkcs#11 interface is a clunky thing - we could also consider a different (longer-term) approach:

- create a higher level interface/plugin that allows OpenVPN to use an external certificate store
- this plugin/interface could then have implementations for
+ Microsoft CryptoAPI
+ Mac OS Keychain
+ PKCS#11
+ Linux keyring-like drivers (kwallet? gnome-keyring?)

- the plugin/interface should be able to offer most of what pkcs#11 offers: key+cert storage, possibly offloading of certain encryption/decryption operations.

Writing a pkcs#11 shim that talks to the mac OS keychain, which itself can talk to pkcs#11 drivers seems a bit overkill to me. BTW, the same thing can be said about the MS CryptoAPI: there are pkcs#11 driver shims that utilize the Windows CryptoStore, which itself can use pkcs#11 devices ...

JM2CW,

JJK

#12 lore raw
In reply to David Woodhouse
Quoted 22 lines · David Woodhouse
Quoted 9 lines · Vasily Kulikov

I see 4 possible alternatives here:
1) implement keychain rsa offloading in Tunnelblick
2) make my patch use plugin interface
3) implement external daemon that communicated with openvpn process via management interface
4) the same as 3) but make openvpn able to handle more than 1 management client

Quoted 11 lines

There are problems with all these alternatives:
(1) is limited to Tunnelblick users and doesn't work for users who start openvpn from the terminal or use any other GUI
(2) implies plugin interface is expanded to handle two new actions: 'user certificate request' and 'rsa-sign request'
(3) implies management interface is expanded to handle 'user certificate request'; also it doesn't work with Tunnelblick or any other tool that communicates with openvpn via management interface as MI currently supports only a single client
(4) needs 'user certificate request' addition and expanding management interface to support more than a single client

Quoted 8 lines

It is perhaps worth noting that OpenVPN already *has* a plugin API which supports the "user certificate request" and "rsa-sign request" methods.

That is, after all, fairly much what PKCS#11 was *designed* to provide.

There are also existing implementations of PKCS#11 RPC such that the actual manipulation of the token can occur in a user-owned process separately from the caller.

Right, PKCS#11 is a yet-another-interface to extend OpenVPN :) I'm not familiar with PKCS#11 and its interface looks too complex for my relatively simple task, at least from the first glance it is an overkill.

Quoted 6 lines

Perhaps the way forward is to implement the keychain support in the form of a PKCS#11 provider module, which can either be loaded directly in OpenVPN or proxied to run in a user's context.

In fact, doesn't such an implementation already exist at
https://github.com/slushpupie/KeychainToken ?

Looks like so, but it uses a deprecated CSSM API. Also the last commit was done 4 years ago, probably the code has more issues.

Signature · 2 lines
Vasily Kulikov
http://www.openwall.com - bringing security into open computing environments