diff options
author | Vasily Kulikov <segoon@openwall.com> | 2015-02-25 19:07:18 +0300 |
---|---|---|
committer | Gert Doering <gert@greenie.muc.de> | 2015-04-13 20:36:11 +0200 |
commit | 39e3d336d4eeab847a3395ddeb430e0a9ca387b9 (patch) | |
tree | 59a97e3e7fe699286562ebe76be3f11bdcc2f97c /contrib/keychain-mcd/common_osx.c | |
parent | ec2fbf374f018366c18644d271cd4d793d04244b (diff) | |
download | openvpn-39e3d336d4eeab847a3395ddeb430e0a9ca387b9.tar.gz openvpn-39e3d336d4eeab847a3395ddeb430e0a9ca387b9.tar.xz openvpn-39e3d336d4eeab847a3395ddeb430e0a9ca387b9.zip |
Mac OS X Keychain management client
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 based on
the Windows Crypto API certificate functionality that currently exists
in OpenVPN.
This patch version implements management client which handles RSA-SIGN
command for RSA offloading. Also it handles new 'NEED-CERTIFICATE'
request to pass a certificate from the keychain to OpenVPN.
OpenVPN itself gets new 'NEED-CERTIFICATE" command which is called when
--management-external-cert is used. It is implemented as a multiline
command very similar to an existing 'RSA-SIGN' command.
The patch is against commit 3341a98c2852d1d0c1eafdc70a3bdb218ec29049.
v4:
- added '--management-external-cert' argument
- keychain-mcd now parses NEED-CERTIFICATE argument if 'auto' is passed
as cmdline's identity template
- fixed typo in help output option name
- added '--management-external-cert' info in openvpn(8) manpage
- added 'certificate' command documentation into doc/management-notes.txt
v3:
- used new 'NEED-CERTIFICATE' command for certificate data request
instead of 'NEED-OK'
- improved option checking
- improved invalid certificate selection string handling
- added man page for keychain-mcd
- handle INFO, FATAL commands from openvpn and show them to user
* ACK from Arne Schwabe for OpenVPN part
* ACK from James based on Arne's testing
v2 (http://sourceforge.net/p/openvpn/mailman/message/33225603/):
- used management interface to communicate with OpenVPN process
v1 (http://sourceforge.net/p/openvpn/mailman/message/33125844/):
- used RSA_METHOD to extend openvpn itself
Signed-off-by: Vasily Kulikov <segoon@openwall.com>
--
Acked-by: Arne Schwabe <arne@rfc2549.org>
Message-Id: <20150225160718.GA6306@cachalot>
URL: http://article.gmane.org/gmane.network.openvpn.devel/9486
Signed-off-by: Gert Doering <gert@greenie.muc.de>
Diffstat (limited to 'contrib/keychain-mcd/common_osx.c')
-rw-r--r-- | contrib/keychain-mcd/common_osx.c | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/contrib/keychain-mcd/common_osx.c b/contrib/keychain-mcd/common_osx.c new file mode 100644 index 0000000..3effa8b --- /dev/null +++ b/contrib/keychain-mcd/common_osx.c @@ -0,0 +1,94 @@ +/* + * 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 <brian@irregularexpression.org> + * Copyright (C) 2013-2015 Vasily Kulikov <segoon@openwall.com> + * + * 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 + */ + +/* +#include "config.h" +#include "syshead.h" +#include "common.h" +#include "buffer.h" +#include "error.h" +*/ + +#include "common_osx.h" +#include <err.h> + +void printCFString(CFStringRef str) +{ + CFIndex bufferLength = CFStringGetLength(str) + 1; + char *pBuffer = (char*)malloc(sizeof(char) * bufferLength); + CFStringGetCString(str, pBuffer, bufferLength, kCFStringEncodingUTF8); + warnx("%s\n", pBuffer); + free(pBuffer); +} + +char* cfstringToCstr(CFStringRef str) +{ + CFIndex bufferLength = CFStringGetLength(str) + 1; + char *pBuffer = (char*)malloc(sizeof(char) * bufferLength); + CFStringGetCString(str, pBuffer, bufferLength, kCFStringEncodingUTF8); + return pBuffer; +} + +void appendHexChar(CFMutableStringRef str, unsigned char halfByte) +{ + if (halfByte < 10) + { + CFStringAppendFormat (str, NULL, CFSTR("%d"), halfByte); + } + else + { + char tmp[2] = {'A'+halfByte-10, 0}; + CFStringAppendCString(str, tmp, kCFStringEncodingUTF8); + } +} + +CFStringRef createHexString(unsigned char *pData, int length) +{ + unsigned char byte, low, high; + int i; + CFMutableStringRef str = CFStringCreateMutable(NULL, 0); + + for(i = 0;i < length;i++) + { + byte = pData[i]; + low = byte & 0x0F; + high = (byte >> 4); + + appendHexChar(str, high); + appendHexChar(str, low); + + if (i != (length - 1)) + CFStringAppendCString(str, " ", kCFStringEncodingUTF8); + } + + return str; +} + +void printHex(unsigned char *pData, int length) +{ + CFStringRef hexStr = createHexString(pData, length); + printCFString(hexStr); + CFRelease(hexStr); +} |