From f13d639021199ec61bf3d716e146c0b29a2b2141 Mon Sep 17 00:00:00 2001
From: Brian Raderman <brian@irregularexpression.org>
Date: Wed, 28 Apr 2010 00:26:00 -0400
Subject: [PATCH] Adding functionality that allows the use of Mac OSX Keychain certificates to
 authenticate with the server so that the certificate and the private key
 don't need to be stored in the config file.  This also supports hardware
 tokens that conform to Apple's tokend specification and can be accessed
 like any other Keychain certificate.  The changes are based on the Crypto API
 functionality for Windows that already exists in the cryptoapi.c/.h files.

Signed-off-by: Brian Raderman <brian@irregularexpression.org>
---
 openvpn.8                                 |   57 ++
 options.c                                 |   45 +-
 options.h                                 |    4 +-
 osx/cert_data.c                           |  631 ++++++++++++
 osx/cert_data.h                           |   44 +
 osx/common_osx.c                          |   98 ++
 osx/common_osx.h                          |   35 +
 osx/crypto_osx.c                          |   76 ++
 osx/crypto_osx.h                          |   34 +
 osx/keychain.c                            |  274 ++++++
 osx/keychain.h                            |    7 +
 osx/openvpn.xcodeproj/brian.pbxuser       |  879 +++++++++++++++++
 osx/openvpn.xcodeproj/brian.perspectivev3 | 1511 +++++++++++++++++++++++++++++
 osx/openvpn.xcodeproj/project.pbxproj     |  619 ++++++++++++
 ssl.c                                     |   11 +-
 15 files changed, 4315 insertions(+), 10 deletions(-)
 mode change 100644 => 100755 options.c
 mode change 100644 => 100755 options.h
 create mode 100755 osx/cert_data.c
 create mode 100755 osx/cert_data.h
 create mode 100755 osx/common_osx.c
 create mode 100755 osx/common_osx.h
 create mode 100755 osx/crypto_osx.c
 create mode 100755 osx/crypto_osx.h
 create mode 100755 osx/keychain.c
 create mode 100755 osx/keychain.h
 create mode 100755 osx/openvpn.xcodeproj/brian.pbxuser
 create mode 100755 osx/openvpn.xcodeproj/brian.perspectivev3
 create mode 100755 osx/openvpn.xcodeproj/project.pbxproj
 mode change 100644 => 100755 ssl.c

diff --git a/openvpn.8 b/openvpn.8
index 45e61fa..f3ff3da 100644
--- a/openvpn.8
+++ b/openvpn.8
@@ -3928,6 +3928,63 @@ Certificate Store GUI.
 
 .\"*********************************************************
 .TP
+.B --keychaincert select-string
+Load the certificate and private key from the
+Mac OSX Keychain (Mac OSX Only).
+
+Use this option instead of
+.B --cert
+and
+.B --key.
+
+This makes it possible to use any smart card supported by Mac OSX using the tokend interface, but also any
+kind of certificate, residing in the Keychain, where you have access to
+the private key.  This option has been tested on the client side with an Aladdin eToken
+on Mac OSX Leopard and with software certificates stored in the Keychain on Mac OSX Leopard and
+Mac OSX Snow Leopard.  As of this writing (4/27/10) Aladdin has not yet released Snow Leopard drivers.
+
+To select a certificate based on a string search in the
+certificate's subject and/or issuer:
+
+.B keychaincert
+"SUBJECT:c=US/o=Apple Inc./ou=me.com/cn=username ISSUER:c=US/o=Apple Computer, Inc./ou=Apple Computer Certificate Authority/cn=Apple .Mac Certificate Authority"
+
+.I "Distinguished Name Component Abbreviations:" 
+.br
+o = organization
+.br
+ou = organizational unit
+.br
+c = country
+.br
+l = locality
+.br
+st = state
+.br
+cn = common name
+.br
+e = email
+.br
+
+All of the distinguished name components are optional, although you do need to specify at least one of them.  You can 
+add spaces around the '/' and '=' characters, e.g. "SUBJECT: c = US / o = Apple Inc.".  You do not need to specify
+both the subject and the issuer, one or the other will work fine.  The identity searching algorithm will return the first
+certificate it finds that matches all of the criteria you have specified.  You can also include the MD5 and/or SHA1 thumbprints 
+along with the subject and issuer (see example of thumbprint search criteria below).  
+
+To select a certificate based on certificate's MD5 or SHA1 thumbprint:
+
+.B keychaincert
+"SHA1: 30 F7 3A 7A B7 73 2A 98 54 33 4A A7 00 6F 6E AC EC D1 EF 02 MD5: D5 F5 11 F1 38 EB 5F 4D CF 23 B6 94 E8 33 D8 B5"
+
+Again, you can include both the SHA1 and the MD5 thumbprints, but you can also use just one of them.  The thumbprint hex
+strings can easily be copy-and-pasted from the OSX Keychain Access GUI in the Applications/Utilities folder.  The hex string comparison is
+not case sensitive.
+
+Note that this option cannot be used with the --daemon option.  Mac OSX needs to present the user with an authentication GUI when the Keychain
+is accessed by openvpn and the --daemon option will prevent the GUI from being shown and therefore cause the authentication to silently fail.
+.\"*********************************************************
+.TP
 .B --key-method m
 Use data channel key negotiation method
 .B m.
diff --git a/options.c b/options.c
old mode 100644
new mode 100755
index 812c3de..3364508
--- a/options.c
+++ b/options.c
@@ -499,9 +499,12 @@ static const char usage_message[] =
   "--key file      : Local private key in .pem format.\n"
   "--pkcs12 file   : PKCS#12 file containing local private key, local certificate\n"
   "                  and optionally the root CA certificate.\n"
-#ifdef WIN32
+#if defined(WIN32)
   "--cryptoapicert select-string : Load the certificate and private key from the\n"
   "                  Windows Certificate System Store.\n"
+#elif defined(__APPLE__)
+  "--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"
@@ -1320,8 +1323,10 @@ show_settings (const struct options *o)
   SHOW_STR (cert_file);
   SHOW_STR (priv_key_file);
   SHOW_STR (pkcs12_file);
-#ifdef WIN32
+#if defined(WIN32)
   SHOW_STR (cryptoapi_cert);
+#elif defined(__APPLE__)
+	SHOW_STR (keychain_cert);
 #endif
   SHOW_STR (cipher_list);
   SHOW_STR (tls_verify);
@@ -1837,15 +1842,18 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
 	  msg(M_USAGE, "Parameter --key cannot be used when --pkcs11-provider is also specified.");
 	if (options->pkcs12_file)
 	  msg(M_USAGE, "Parameter --pkcs12 cannot be used when --pkcs11-provider is also specified.");
-#ifdef WIN32
+#if defined(WIN32)
 	if (options->cryptoapi_cert)
 	  msg(M_USAGE, "Parameter --cryptoapicert cannot be used when --pkcs11-provider is also specified.");
+#elif defined(__APPLE__)
+	if (options->keychain_cert)
+	   msg(M_USAGE, "Parameter --keychaincert cannot be used when --pkcs11-provider is also specified.");
 #endif
        }
       else
 #endif
-#ifdef WIN32
-      if (options->cryptoapi_cert)
+#if defined(WIN32)
+	if (options->cryptoapi_cert)
 	{
 	  if ((!(options->ca_file)) && (!(options->ca_path)))
 	    msg(M_USAGE, "You must define CA file (--ca) or CA path (--capath)");
@@ -1856,9 +1864,24 @@ options_postprocess_verify_ce (const struct options *options, const struct conne
           if (options->pkcs12_file)
 	    msg(M_USAGE, "Parameter --pkcs12 cannot be used when --cryptoapicert is also specified.");
 	}
-      else
+	else
+#elif defined(__APPLE__)
+	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.");
+        if (options->daemon)
+            msg(M_USAGE, "Parameter --daemon cannot be used when --keychaincert is also specified.");
+	}
+	else
 #endif
-      if (options->pkcs12_file)
+       if (options->pkcs12_file)
         {
           if (options->ca_path)
 	    msg(M_USAGE, "Parameter --capath cannot be used when --pkcs12 is also specified.");
@@ -5465,12 +5488,18 @@ add_option (struct options *options,
 	}
 #endif
     }
-#ifdef WIN32
+#if defined(WIN32)
   else if (streq (p[0], "cryptoapicert") && p[1])
     {
       VERIFY_PERMISSION (OPT_P_GENERAL);
       options->cryptoapi_cert = p[1];
     }
+#elif defined(__APPLE__)
+  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])
     {
diff --git a/options.h b/options.h
old mode 100644
new mode 100755
index 740e18e..d6be33c
--- a/options.h
+++ b/options.h
@@ -464,8 +464,10 @@ struct options
   bool pkcs11_id_management;
 #endif
 
-#ifdef WIN32
+#if defined(WIN32)
   const char *cryptoapi_cert;
+#elif defined(__APPLE__)
+  const char *keychain_cert;
 #endif
 
   /* data channel key exchange method */
diff --git a/osx/cert_data.c b/osx/cert_data.c
new file mode 100755
index 0000000..b343245
--- /dev/null
+++ b/osx/cert_data.c
@@ -0,0 +1,631 @@
+/*
+ *  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>
+ *
+ *  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 <CommonCrypto/CommonDigest.h>
+#include "cert_data.h"
+#include "common_osx.h"
+
+CFStringRef kCertDataSubjectName = CFSTR("subject"), kCertDataIssuerName = CFSTR("issuer"), kCertDataSha1Name = CFSTR("SHA1"), kCertDataMd5Name = CFSTR("MD5"), kCertNameFwdSlash = CFSTR("/"), kCertNameEquals = CFSTR("=");
+CFStringRef kCertNameOrganization = CFSTR("o"), kCertNameOrganizationalUnit = CFSTR("ou"), kCertNameCountry = CFSTR("c"), kCertNameLocality = CFSTR("l"), kCertNameState = CFSTR("st"), kCertNameCommonName = CFSTR("cn"), kCertNameEmail = CFSTR("e"), kCertNameDomainComponent = CFSTR("dc");
+CFStringRef kStringSpace = CFSTR(" "), kStringEmpty = CFSTR("");
+
+typedef struct _CertName
+{
+	CFArrayRef countryName, organization, organizationalUnit, commonName, description, emailAddress, 
+	stateName, localityName, distinguishedName, domainComponent;
+} CertName, *CertNameRef;		
+
+typedef struct _DescData
+{
+	CFStringRef name, value;
+} DescData, *DescDataRef;
+
+
+CertNameRef createCertName()
+{
+	CertNameRef pCertName = (CertNameRef)malloc(sizeof(CertName));
+	pCertName->countryName = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+	pCertName->organization =  CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+	pCertName->organizationalUnit = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+	pCertName->commonName = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+	pCertName->description = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);	
+	pCertName->emailAddress = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+	pCertName->stateName = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+	pCertName->localityName = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+	pCertName->distinguishedName = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+	pCertName->domainComponent = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+	return pCertName;
+}
+
+void destroyCertName(CertNameRef pCertName)
+{	
+	if (!pCertName)
+		return;
+	
+	CFRelease(pCertName->countryName);
+	CFRelease(pCertName->organization);
+	CFRelease(pCertName->organizationalUnit);
+	CFRelease(pCertName->commonName);
+	CFRelease(pCertName->description);
+	CFRelease(pCertName->emailAddress);
+	CFRelease(pCertName->stateName);
+	CFRelease(pCertName->localityName);
+	CFRelease(pCertName->distinguishedName);
+	CFRelease(pCertName->domainComponent);
+	free(pCertName);
+}
+
+
+CertNameRef dataToName(CSSM_DATA_PTR pData)
+{
+    CSSM_X509_NAME_PTR pName = (CSSM_X509_NAME_PTR)pData->Data;
+	CertNameRef pCertName = createCertName();
+    int i, j;
+	    
+    for(i = 0;i < pName->numberOfRDNs;i++)
+    {
+        CSSM_X509_RDN rdn = pName->RelativeDistinguishedName[i];
+        
+        for(j = 0;j < rdn.numberOfPairs;j++)
+        {
+            CSSM_X509_TYPE_VALUE_PAIR nvp = rdn.AttributeTypeAndValue[j];
+			CFStringRef str = CFStringCreateWithBytes (NULL, nvp.value.Data, nvp.value.Length, kCFStringEncodingUTF8, false);
+            
+			if (memcmp(nvp.type.Data, CSSMOID_CountryName.Data, CSSMOID_CountryName.Length) == 0)
+				CFArrayAppendValue((CFMutableArrayRef)pCertName->countryName, str);
+			else if (memcmp(nvp.type.Data, CSSMOID_OrganizationName.Data, CSSMOID_OrganizationName.Length) == 0)
+				CFArrayAppendValue((CFMutableArrayRef)pCertName->organization, str);
+			else if (memcmp(nvp.type.Data, CSSMOID_OrganizationalUnitName.Data, CSSMOID_OrganizationalUnitName.Length) == 0)
+				CFArrayAppendValue((CFMutableArrayRef)pCertName->organizationalUnit, str);
+			else if (memcmp(nvp.type.Data, CSSMOID_CommonName.Data, CSSMOID_CommonName.Length) == 0)
+				CFArrayAppendValue((CFMutableArrayRef)pCertName->commonName, str);
+			else if (memcmp(nvp.type.Data, CSSMOID_Description.Data, CSSMOID_Description.Length) == 0)
+				CFArrayAppendValue((CFMutableArrayRef)pCertName->description, str);
+			else if (memcmp(nvp.type.Data, CSSMOID_EmailAddress.Data, CSSMOID_EmailAddress.Length) == 0)
+				CFArrayAppendValue((CFMutableArrayRef)pCertName->emailAddress, str);
+			else if (memcmp(nvp.type.Data, CSSMOID_StateProvinceName.Data, CSSMOID_StateProvinceName.Length) == 0)
+				CFArrayAppendValue((CFMutableArrayRef)pCertName->stateName, str);
+			else if (memcmp(nvp.type.Data, CSSMOID_LocalityName.Data, CSSMOID_LocalityName.Length) == 0)
+				CFArrayAppendValue((CFMutableArrayRef)pCertName->localityName, str);
+			else if (memcmp(nvp.type.Data, CSSMOID_DistinguishedName.Data, CSSMOID_DistinguishedName.Length) == 0)
+				CFArrayAppendValue((CFMutableArrayRef)pCertName->distinguishedName, str);
+			
+			CFRelease(str);
+        }
+    }
+    
+    return pCertName;
+}
+
+CFArrayRef GetFieldsFromCssmCertData(CSSM_CL_HANDLE hCL, CSSM_DATA_PTR pCertData, CSSM_OID oid)
+{
+	CSSM_DATA_PTR pData = NULL;
+	CFMutableArrayRef fields = CFArrayCreateMutable(NULL, 0, NULL);
+	uint32 numFields, i;
+	
+	CSSM_HANDLE ResultsHandle = (CSSM_HANDLE)NULL;
+	numFields = 0;
+	
+	CSSM_CL_CertGetFirstFieldValue(hCL, pCertData, &oid, &ResultsHandle, &numFields, &pData);
+	
+	if (!pData)
+	{
+		CSSM_CL_CertAbortQuery(hCL, ResultsHandle);
+		return NULL;
+	}
+	
+	for (i = 0; i < numFields; i++) 
+	{		
+		CertNameRef pName = dataToName(pData);
+		CFArrayAppendValue(fields, pName);
+		CSSM_CL_FreeFieldValue (hCL, &oid, pData);		
+		if (i < (numFields - 1))
+			CSSM_CL_CertGetNextFieldValue(hCL, ResultsHandle, &pData);
+	}
+
+	CSSM_CL_CertAbortQuery(hCL, ResultsHandle);
+	return fields;
+}
+
+CFArrayRef GetFieldsFromCertificate(SecCertificateRef certificate, CSSM_OID oid)
+{
+	CSSM_CL_HANDLE hCL;
+	CSSM_DATA certData;
+	CFArrayRef fieldValues;
+	
+	SecCertificateGetCLHandle(certificate, &hCL);
+	SecCertificateGetData(certificate, &certData);
+	
+	fieldValues = GetFieldsFromCssmCertData(hCL, &certData, oid);
+	
+	if (fieldValues == NULL) 		
+	{
+		return NULL; 
+	}
+	else if (CFArrayGetCount(fieldValues) == 0)
+	{
+		CFRelease(fieldValues);
+		return NULL;
+	}
+	
+	return fieldValues;
+}
+
+CertDataRef createCertDataFromCertificate(SecCertificateRef certificate)
+{
+	CertDataRef pCertData = (CertDataRef)malloc(sizeof(CertData));
+	pCertData->subject = GetFieldsFromCertificate(certificate, CSSMOID_X509V1SubjectNameCStruct);
+	pCertData->issuer = GetFieldsFromCertificate(certificate, CSSMOID_X509V1IssuerNameCStruct);
+
+	CSSM_DATA cssmCertData;
+	SecCertificateGetData (certificate, &cssmCertData);
+
+	unsigned char sha1[CC_SHA1_DIGEST_LENGTH]; 
+	CC_SHA1(cssmCertData.Data, cssmCertData.Length, sha1); 
+	pCertData->sha1 = createHexString(sha1, CC_SHA1_DIGEST_LENGTH);
+	
+	unsigned char md5[CC_MD5_DIGEST_LENGTH]; 
+	CC_MD5(cssmCertData.Data, cssmCertData.Length, md5); 
+	pCertData->md5 = createHexString((unsigned char*)md5, CC_MD5_DIGEST_LENGTH);
+	
+	return pCertData;
+}
+
+CFStringRef stringFromRange(const char *cstring, CFRange range)
+{
+	CFStringRef str = CFStringCreateWithBytes (NULL, (uint8*)&cstring[range.location], range.length, kCFStringEncodingUTF8, false);
+	CFMutableStringRef mutableStr = CFStringCreateMutableCopy(NULL, 0, str);
+	CFStringTrimWhitespace(mutableStr);
+	CFRelease(str);
+	return mutableStr;
+}
+
+DescDataRef createDescData(const char *description, CFRange nameRange, CFRange valueRange)
+{
+	DescDataRef pRetVal = (DescDataRef)malloc(sizeof(DescData));
+	
+	memset(pRetVal, 0, sizeof(DescData));
+	
+	if (nameRange.length > 0)
+		pRetVal->name = stringFromRange(description, nameRange);
+	
+	if (valueRange.length > 0)
+		pRetVal->value = stringFromRange(description, valueRange);
+	
+	return pRetVal;
+}
+
+void destroyDescData(DescDataRef pData)
+{
+	if (pData->name)
+		CFRelease(pData->name);
+	
+	if (pData->value)
+		CFRelease(pData->value);
+	
+	free(pData);
+}
+
+CFArrayRef createDescDataPairs(const char *description)
+{
+	int numChars = strlen(description);
+	CFRange nameRange, valueRange;
+	DescDataRef pData;
+	CFMutableArrayRef retVal = CFArrayCreateMutable(NULL, 0, NULL);
+	
+	int i = 0;
+	
+	nameRange = CFRangeMake(0, 0);
+	valueRange = CFRangeMake(0, 0);
+	bool bInValue = false;
+	
+	while(i < numChars)
+	{
+		if (!bInValue && (description[i] != ':'))
+		{
+			nameRange.length++;
+		}
+		else if (bInValue && (description[i] != ':'))
+		{
+			valueRange.length++;
+		}
+		else if(!bInValue)
+		{
+			bInValue = true;
+			valueRange.location = i + 1;
+			valueRange.length = 0;
+		}
+		else //(bInValue)
+		{
+			bInValue = false;
+			while(description[i] != ' ')
+			{
+				valueRange.length--;
+				i--;
+			}
+			
+			pData = createDescData(description, nameRange, valueRange);
+			CFArrayAppendValue(retVal, pData);
+			
+			nameRange.location = i + 1;
+			nameRange.length = 0;
+		}
+		
+		i++;
+	}
+	
+	pData = createDescData(description, nameRange, valueRange);
+	CFArrayAppendValue(retVal, pData);
+	return retVal;
+}
+
+void arrayDestroyDescData(const void *val, void *context)
+{
+	DescDataRef pData = (DescDataRef) val;
+	destroyDescData(pData);
+}
+
+
+void parseNameComponent(CFStringRef dn, CFStringRef *pName, CFStringRef *pValue)
+{
+	CFArrayRef nameStrings = CFStringCreateArrayBySeparatingStrings(NULL, dn, kCertNameEquals);
+	
+	*pName = *pValue = NULL;
+	
+	if (CFArrayGetCount(nameStrings) != 2)
+		return;
+	
+	CFMutableStringRef str;
+	
+	str = CFStringCreateMutableCopy(NULL, 0, CFArrayGetValueAtIndex(nameStrings, 0));
+	CFStringTrimWhitespace(str);
+	*pName = str;
+	
+	str = CFStringCreateMutableCopy(NULL, 0, CFArrayGetValueAtIndex(nameStrings, 1));
+	CFStringTrimWhitespace(str);
+	*pValue = str;
+	
+	CFRelease(nameStrings);
+}
+
+void parseCertName(CFStringRef nameDesc, CFMutableArrayRef names)
+{
+	CFArrayRef nameStrings = CFStringCreateArrayBySeparatingStrings(NULL, nameDesc, kCertNameFwdSlash);
+	int count = CFArrayGetCount(nameStrings);
+    int i;
+	
+	CertNameRef pCertName = createCertName();
+	
+	for(i = 0;i < count;i++)
+	{
+		CFMutableStringRef dn = CFStringCreateMutableCopy(NULL, 0, CFArrayGetValueAtIndex(nameStrings, i));
+		CFStringTrimWhitespace(dn);
+		
+		CFStringRef name, value;
+		
+		parseNameComponent(dn, &name, &value);
+		
+		if (!name || !value)
+		{
+			if (name)
+				CFRelease(name);
+			
+			if (value)
+				CFRelease(value);
+			
+			CFRelease(dn);
+			continue;
+		}
+		
+		if (CFStringCompareWithOptions(name, kCertNameOrganization, CFRangeMake(0, CFStringGetLength(name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+			CFArrayAppendValue((CFMutableArrayRef)pCertName->organization, value);
+		else if (CFStringCompareWithOptions(name, kCertNameOrganizationalUnit, CFRangeMake(0, CFStringGetLength(name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+			CFArrayAppendValue((CFMutableArrayRef)pCertName->organizationalUnit, value);
+		else if (CFStringCompareWithOptions(name, kCertNameCountry, CFRangeMake(0, CFStringGetLength(name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+			CFArrayAppendValue((CFMutableArrayRef)pCertName->countryName, value);
+		else if (CFStringCompareWithOptions(name, kCertNameLocality, CFRangeMake(0, CFStringGetLength(name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+			CFArrayAppendValue((CFMutableArrayRef)pCertName->localityName, value);
+		else if (CFStringCompareWithOptions(name, kCertNameState, CFRangeMake(0, CFStringGetLength(name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+			CFArrayAppendValue((CFMutableArrayRef)pCertName->stateName, value);
+		else if (CFStringCompareWithOptions(name, kCertNameCommonName, CFRangeMake(0, CFStringGetLength(name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+			CFArrayAppendValue((CFMutableArrayRef)pCertName->commonName, value);
+		else if (CFStringCompareWithOptions(name, kCertNameEmail, CFRangeMake(0, CFStringGetLength(name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+			CFArrayAppendValue((CFMutableArrayRef)pCertName->emailAddress, value);
+		else if (CFStringCompareWithOptions(name, kCertNameDomainComponent, CFRangeMake(0, CFStringGetLength(name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+			CFArrayAppendValue((CFMutableArrayRef)pCertName->domainComponent, value);
+		
+		CFRelease(name);
+		CFRelease(value);
+		CFRelease(dn);
+	}
+	
+	CFArrayAppendValue(names, pCertName);
+	CFRelease(nameStrings);
+}
+
+void arrayParseDescDataPair(const void *val, void *context)
+{
+	DescDataRef pDescData = (DescDataRef)val;
+	CertDataRef pCertData = (CertDataRef)context;
+	
+	if (!pDescData->name || !pDescData->value)
+		return;
+	
+	if (CFStringCompareWithOptions(pDescData->name, kCertDataSubjectName, CFRangeMake(0, CFStringGetLength(pDescData->name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+		parseCertName(pDescData->value, (CFMutableArrayRef)pCertData->subject);
+	else if (CFStringCompareWithOptions(pDescData->name, kCertDataIssuerName, CFRangeMake(0, CFStringGetLength(pDescData->name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+		parseCertName(pDescData->value, (CFMutableArrayRef)pCertData->issuer);
+	else if (CFStringCompareWithOptions(pDescData->name, kCertDataSha1Name, CFRangeMake(0, CFStringGetLength(pDescData->name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+		pCertData->sha1 = CFRetain(pDescData->value);
+	else if (CFStringCompareWithOptions(pDescData->name, kCertDataMd5Name, CFRangeMake(0, CFStringGetLength(pDescData->name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
+		pCertData->md5 = CFRetain(pDescData->value);
+}
+
+CertDataRef createCertDataFromString(const char *description)
+{
+	CertDataRef pCertData = (CertDataRef)malloc(sizeof(CertData));
+	pCertData->subject = CFArrayCreateMutable(NULL, 0, NULL);
+	pCertData->issuer = CFArrayCreateMutable(NULL, 0, NULL);
+	pCertData->sha1 = NULL;
+	pCertData->md5 = NULL;
+	
+	CFArrayRef pairs = createDescDataPairs(description);
+	CFArrayApplyFunction(pairs, CFRangeMake(0, CFArrayGetCount(pairs)), arrayParseDescDataPair, pCertData);
+	CFArrayApplyFunction(pairs, CFRangeMake(0, CFArrayGetCount(pairs)), arrayDestroyDescData, NULL);
+	CFRelease(pairs);
+	return pCertData;
+}
+
+void arrayDestroyCertName(const void *val, void *context)
+{
+	CertNameRef pCertName = (CertNameRef)val;
+	destroyCertName(pCertName);
+}
+
+void destroyCertData(CertDataRef pCertData)
+{
+	if (pCertData->subject)
+	{
+		CFArrayApplyFunction(pCertData->subject, CFRangeMake(0, CFArrayGetCount(pCertData->subject)), arrayDestroyCertName, NULL);
+		CFRelease(pCertData->subject);
+	}
+	
+	if (pCertData->issuer)
+	{
+		CFArrayApplyFunction(pCertData->issuer, CFRangeMake(0, CFArrayGetCount(pCertData->issuer)), arrayDestroyCertName, NULL);
+		CFRelease(pCertData->issuer);
+	}
+	
+	if (pCertData->sha1)
+		CFRelease(pCertData->sha1);
+	
+	if (pCertData->md5)
+		CFRelease(pCertData->md5);
+	
+	free(pCertData);
+}
+
+bool stringArrayMatchesTemplate(CFArrayRef strings, CFArrayRef templateArray)
+{
+	int templateCount, stringCount, i;
+	
+	templateCount = CFArrayGetCount(templateArray);
+	
+	if (templateCount > 0)
+	{
+		stringCount = CFArrayGetCount(strings);
+		if (stringCount != templateCount)
+			return false;
+		
+		for(i = 0;i < stringCount;i++)
+		{
+			CFStringRef str, template;
+			
+			template = (CFStringRef)CFArrayGetValueAtIndex(templateArray, i);
+			str = (CFStringRef)CFArrayGetValueAtIndex(strings, i);
+			
+			if (CFStringCompareWithOptions(template, str, CFRangeMake(0, CFStringGetLength(template)), kCFCompareCaseInsensitive) != kCFCompareEqualTo)
+				return false;
+		}
+	}
+	
+	return true;
+	
+}
+
+bool certNameMatchesTemplate(CertNameRef pCertName, CertNameRef pTemplate)
+{
+	if (!stringArrayMatchesTemplate(pCertName->countryName, pTemplate->countryName))
+		return false;
+	else if (!stringArrayMatchesTemplate(pCertName->organization, pTemplate->organization))
+		return false;
+	else if (!stringArrayMatchesTemplate(pCertName->organizationalUnit, pTemplate->organizationalUnit))
+		return false;
+	else if (!stringArrayMatchesTemplate(pCertName->commonName, pTemplate->commonName))
+		return false;
+	else if (!stringArrayMatchesTemplate(pCertName->emailAddress, pTemplate->emailAddress))
+		return false;
+	else if (!stringArrayMatchesTemplate(pCertName->stateName, pTemplate->stateName))
+		return false;
+	else if (!stringArrayMatchesTemplate(pCertName->localityName, pTemplate->localityName))
+		return false;
+	else
+		return true;
+}
+
+bool certNameArrayMatchesTemplate(CFArrayRef certNameArray, CFArrayRef templateArray)
+{
+	int templateCount, certCount, i;
+	
+	templateCount = CFArrayGetCount(templateArray);
+	
+	if (templateCount > 0)
+	{
+		certCount = CFArrayGetCount(certNameArray);
+		if (certCount != templateCount)
+			return false;
+		
+		for(i = 0;i < certCount;i++)
+		{
+			CertNameRef pName, pTemplateName;
+			
+			pTemplateName = (CertNameRef)CFArrayGetValueAtIndex(templateArray, i);
+			pName = (CertNameRef)CFArrayGetValueAtIndex(certNameArray, i);
+			
+			if (!certNameMatchesTemplate(pName, pTemplateName))
+				return false;
+		}
+	}
+	
+	return true;
+}
+
+bool hexStringMatchesTemplate(CFStringRef str, CFStringRef template)
+{
+	if (template)
+	{
+		if (!str)
+			return false;
+		
+		CFMutableStringRef strMutable, templateMutable;
+		
+		strMutable = CFStringCreateMutableCopy(NULL, 0, str);
+		templateMutable = CFStringCreateMutableCopy(NULL, 0, template);
+		
+		CFStringFindAndReplace(strMutable, kStringSpace, kStringEmpty, CFRangeMake(0, CFStringGetLength(strMutable)), 0);
+		CFStringFindAndReplace(templateMutable, kStringSpace, kStringEmpty, CFRangeMake(0, CFStringGetLength(templateMutable)), 0);
+
+        CFComparisonResult result = CFStringCompareWithOptions(templateMutable, strMutable, CFRangeMake(0, CFStringGetLength(templateMutable)), kCFCompareCaseInsensitive);
+		
+		CFRelease(strMutable);
+		CFRelease(templateMutable);
+				
+		if (result != kCFCompareEqualTo)
+			return false;
+	}
+	
+	return true;
+}
+
+bool certDataMatchesTemplate(CertDataRef pCertData, CertDataRef pTemplate)
+{
+	if (!certNameArrayMatchesTemplate(pCertData->subject, pTemplate->subject))
+		return false;
+	
+	if (!certNameArrayMatchesTemplate(pCertData->issuer, pTemplate->issuer))
+		return false;
+	
+	if (!hexStringMatchesTemplate(pCertData->sha1, pTemplate->sha1))
+		return false;
+	
+	if (!hexStringMatchesTemplate(pCertData->md5, pTemplate->md5))
+		return false;
+
+	return true;
+}
+
+void printString(const void *val, void *context) 
+{
+    CFStringRef str = (CFStringRef)val;
+	const char *label = (const char *)context;
+	printf("%s = ", label);
+	printCFString(str);
+	printf("\n");
+}
+
+void printCertName(CertNameRef pCertName) 
+{
+	CFArrayApplyFunction(pCertName->countryName, CFRangeMake(0, CFArrayGetCount(pCertName->countryName)), printString, "Country Name");
+	CFArrayApplyFunction(pCertName->organization, CFRangeMake(0, CFArrayGetCount(pCertName->organization)), printString, "Organization");
+	CFArrayApplyFunction(pCertName->organizationalUnit, CFRangeMake(0, CFArrayGetCount(pCertName->organizationalUnit)), printString, "Organizational Unit");
+	CFArrayApplyFunction(pCertName->commonName, CFRangeMake(0, CFArrayGetCount(pCertName->commonName)), printString, "Common Name");
+	CFArrayApplyFunction(pCertName->description, CFRangeMake(0, CFArrayGetCount(pCertName->description)), printString, "Description");
+	CFArrayApplyFunction(pCertName->emailAddress, CFRangeMake(0, CFArrayGetCount(pCertName->emailAddress)), printString, "Email Address");
+	CFArrayApplyFunction(pCertName->stateName, CFRangeMake(0, CFArrayGetCount(pCertName->stateName)), printString, "State Name");
+	CFArrayApplyFunction(pCertName->localityName, CFRangeMake(0, CFArrayGetCount(pCertName->localityName)), printString, "Locality Name");
+	CFArrayApplyFunction(pCertName->distinguishedName, CFRangeMake(0, CFArrayGetCount(pCertName->distinguishedName)), printString, "Distinguished Name");	
+}
+
+void arrayPrintCertName(const void *val, void *context)
+{
+	CertNameRef pCertName = (CertNameRef) val;
+	printCertName(pCertName);
+}
+
+void printCertData(CertDataRef pCertData)
+{
+	printf("*** Subject ***\n");
+	if (pCertData->subject)
+		CFArrayApplyFunction(pCertData->subject, CFRangeMake(0, CFArrayGetCount(pCertData->subject)), arrayPrintCertName, NULL);
+
+	printf("*** Issuer ***\n");
+	if (pCertData->issuer)
+		CFArrayApplyFunction(pCertData->issuer, CFRangeMake(0, CFArrayGetCount(pCertData->issuer)), arrayPrintCertName, NULL);
+	
+	printf("*** Fingerprints ***\n");
+	
+	printf("SHA1 = ");
+	if (pCertData->sha1)
+		printCFString(pCertData->sha1);
+	
+	printf("\n");
+		
+	printf("MD5 = ");
+	if (pCertData->md5)
+		printCFString(pCertData->md5);
+	
+	printf("\n");	
+}
+
+SecIdentityRef findIdentity(CertDataRef pCertDataTemplate)
+{
+	SecIdentitySearchRef search;
+	SecIdentitySearchCreate(NULL, 0, &search);
+	
+	SecIdentityRef identity;
+	while(SecIdentitySearchCopyNext(search, &identity) != errSecItemNotFound)
+	{
+		SecCertificateRef certificate;
+		SecIdentityCopyCertificate (identity, &certificate);
+		
+		CertDataRef pCertData = createCertDataFromCertificate(certificate);		
+		bool bMatches = certDataMatchesTemplate(pCertData, pCertDataTemplate);
+
+		destroyCertData(pCertData);
+		CFRelease(certificate);
+
+		if (bMatches)
+		{
+			break;
+		}
+		else
+		{			
+			CFRelease(identity);
+			identity = NULL;
+		}
+	}
+	
+	CFRelease(search);
+	return identity;
+}
diff --git a/osx/cert_data.h b/osx/cert_data.h
new file mode 100755
index 0000000..b3092de
--- /dev/null
+++ b/osx/cert_data.h
@@ -0,0 +1,44 @@
+/*
+ *  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>
+ *
+ *  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 __cert_data_h__
+#define __cert_data_h__
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/Security.h>
+
+typedef struct _CertData
+{
+	CFArrayRef subject;
+	CFArrayRef issuer;
+	CFStringRef md5, sha1;
+} CertData, *CertDataRef;
+
+CertDataRef createCertDataFromCertificate(SecCertificateRef certificate);
+CertDataRef createCertDataFromString(const char *description);
+void destroyCertData(CertDataRef pCertData);
+bool certDataMatchesTemplate(CertDataRef pCertData, CertDataRef pTemplate);
+void printCertData(CertDataRef pCertData);
+SecIdentityRef findIdentity(CertDataRef pCertDataTemplate);
+
+#endif
\ No newline at end of file
diff --git a/osx/common_osx.c b/osx/common_osx.c
new file mode 100755
index 0000000..fd39f50
--- /dev/null
+++ b/osx/common_osx.c
@@ -0,0 +1,98 @@
+/*
+ *  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>
+ *
+ *  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 "common_osx.h"
+
+void printCFString(CFStringRef str)
+{
+	CFIndex bufferLength = CFStringGetLength(str) + 1;
+	char *pBuffer = (char*)malloc(sizeof(char) * bufferLength);
+	CFStringGetCString(str, pBuffer, bufferLength, kCFStringEncodingUTF8);
+	printf("%s", 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);
+	
+	switch(halfByte)
+	{
+		case 10:
+			CFStringAppendCString(str, "A", kCFStringEncodingUTF8);
+			break;
+		case 11:
+			CFStringAppendCString(str, "B", kCFStringEncodingUTF8);
+			break;
+		case 12:
+			CFStringAppendCString(str, "C", kCFStringEncodingUTF8);
+			break;
+		case 13:
+			CFStringAppendCString(str, "D", kCFStringEncodingUTF8);
+			break;
+		case 14:
+			CFStringAppendCString(str, "E", kCFStringEncodingUTF8);
+			break;
+		case 15:
+			CFStringAppendCString(str, "F", kCFStringEncodingUTF8);
+			break;
+	}
+}
+
+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);
+}
\ No newline at end of file
diff --git a/osx/common_osx.h b/osx/common_osx.h
new file mode 100755
index 0000000..7cf6582
--- /dev/null
+++ b/osx/common_osx.h
@@ -0,0 +1,35 @@
+/*
+ *  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>
+ *
+ *  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 <CoreFoundation/CoreFoundation.h>
+
+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__
\ No newline at end of file
diff --git a/osx/crypto_osx.c b/osx/crypto_osx.c
new file mode 100755
index 0000000..a0b83bc
--- /dev/null
+++ b/osx/crypto_osx.c
@@ -0,0 +1,76 @@
+/*
+ *  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>
+ *
+ *  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 "crypto_osx.h"
+#include <CommonCrypto/CommonDigest.h>
+
+CSSM_DATA signData(SecIdentityRef identity, CSSM_DATA dataBuf)
+{
+    SecKeyRef privateKey;
+    
+    SecIdentityCopyPrivateKey(identity,  &privateKey); 
+    const CSSM_ACCESS_CREDENTIALS *pCredentials;
+    SecKeyGetCredentials(privateKey, CSSM_ACL_AUTHORIZATION_SIGN, kSecCredentialTypeDefault, &pCredentials); 
+    
+    CSSM_CSP_HANDLE cspHandle;
+    SecKeyGetCSPHandle(privateKey, &cspHandle);
+    
+    const CSSM_KEY *pCssmKey;
+    SecKeyGetCSSMKey (privateKey, &pCssmKey); 
+    
+    CSSM_DATA signBuf;
+    signBuf.Data = NULL;
+    signBuf.Length = 0;
+    
+    if (!(pCssmKey->KeyHeader.KeyUsage & CSSM_KEYUSE_SIGN))
+	{
+		CFRelease(privateKey);
+		return signBuf;
+	}
+    
+    CSSM_CC_HANDLE cryptoContextHandle;
+    CSSM_CSP_CreateSignatureContext(cspHandle, CSSM_ALGID_RSA, pCredentials, pCssmKey, &cryptoContextHandle);
+	
+    CSSM_SignData(cryptoContextHandle, &dataBuf, 1, CSSM_ALGID_NONE, &signBuf);
+    
+    CSSM_DeleteContext(cryptoContextHandle);
+    CFRelease(privateKey);
+    return signBuf;
+}
+
+void freeSignature(SecIdentityRef identity, CSSM_DATA sigBuf)
+{
+    SecKeyRef privateKey;
+    
+    SecIdentityCopyPrivateKey(identity,  &privateKey); 
+    
+    CSSM_CSP_HANDLE cspHandle;
+    SecKeyGetCSPHandle(privateKey, &cspHandle);
+	
+	CSSM_API_MEMORY_FUNCS memFuncs;
+	CSSM_GetAPIMemoryFunctions(cspHandle, &memFuncs);	
+	
+	memFuncs.free_func(sigBuf.Data, memFuncs.AllocRef);
+}
+
diff --git a/osx/crypto_osx.h b/osx/crypto_osx.h
new file mode 100755
index 0000000..b4fc8ee
--- /dev/null
+++ b/osx/crypto_osx.h
@@ -0,0 +1,34 @@
+/*
+ *  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>
+ *
+ *  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 __crypto_osx_h__
+#define __crypto_osx_h__
+
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/Security.h>
+
+CSSM_DATA signData(SecIdentityRef identity, CSSM_DATA dataBuf);
+void freeSignature(SecIdentityRef identity, CSSM_DATA sigBuf);
+
+#endif //__crypto_osx_h__
diff --git a/osx/keychain.c b/osx/keychain.c
new file mode 100755
index 0000000..4ab8b72
--- /dev/null
+++ b/osx/keychain.c
@@ -0,0 +1,274 @@
+/*
+ * File: keyhchain.c.  Original was named cryptoapi.c.
+ *
+ * Copyright (c) 2004 Peter 'Luna' Runestig <peter@runestig.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modifi-
+ * cation, are permitted provided that the following conditions are met:
+ *
+ *   o  Redistributions of source code must retain the above copyright notice,
+ *      this list of conditions and the following disclaimer.
+ *
+ *   o  Redistributions in binary form must reproduce the above copyright no-
+ *      tice, this list of conditions and the following disclaimer in the do-
+ *      cumentation and/or other materials provided with the distribution.
+ *
+ *   o  The names of the contributors may not be used to endorse or promote
+ *      products derived from this software without specific prior written
+ *      permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LI-
+ * ABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUEN-
+ * TIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEV-
+ * ER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABI-
+ * LITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This code has been modified from the original version by Brian Raderman 
+ * <brian@irregularexpression.org>.  It was changed to work with the Mac OSX
+ * Keychain services instead of the Microsoft Crypto API, which was its original
+ * intent.
+ */
+
+#include "syshead.h"
+
+#if defined(__APPLE__) && defined(USE_CRYPTO) && defined(USE_SSL)
+
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <assert.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <Security/Security.h>
+#include "cert_data.h"
+#include "common_osx.h"
+#include "crypto_osx.h"
+
+/* Size of an SSL signature: MD5+SHA1 */
+#define SSL_SIG_LENGTH	36
+
+/* try to funnel any Keychain/CSSM error messages to OpenSSL ERR_... */
+#define ERR_LIB_KEYCHAIN (ERR_LIB_USER + 70)
+#define KeychainErr(f)   err_put_apple_error((f), __FILE__, __LINE__)
+#define KEYCHAIN_F_FIND_IDENTITY	    101
+#define KEYCHAIN_F_CREATE_CERT_DATA_FROM_STRING   102
+#define KEYCHAIN_F_SIGN_DATA			    103
+
+static ERR_STRING_DATA KEYCHAIN_str_functs[] =	{
+    { ERR_PACK(ERR_LIB_KEYCHAIN, 0, 0),				    "Mac OSX Keychain"},
+    { ERR_PACK(0, KEYCHAIN_F_FIND_IDENTITY, 0),		    "findIdentity" },
+    { ERR_PACK(0, KEYCHAIN_F_CREATE_CERT_DATA_FROM_STRING, 0),	    "createCertDataFromString" },
+    { ERR_PACK(0, KEYCHAIN_F_SIGN_DATA, 0),    "signData" },
+    { 0, NULL }
+};
+
+static void err_put_apple_error(int func, const char *file, int line)
+{
+    static int init = 0;
+
+    if (!init) {
+		ERR_load_strings(ERR_LIB_KEYCHAIN, KEYCHAIN_str_functs);
+
+	    ERR_STRING_DATA *esd = calloc(4, sizeof(ERR_STRING_DATA));
+	    if (esd)
+		{
+			esd[0].error = 101;
+			esd[0].string = "Unable to find identity in keychain (certificate + private key)";
+
+			esd[1].error = 102;
+			esd[1].string = "Unable to parse certificate description string";
+
+			esd[2].error = 103;
+			esd[2].string = "Unable to sign data with private key";
+
+			ERR_load_strings(ERR_LIB_KEYCHAIN, esd);
+		}
+		
+		init++;
+    }
+	
+	ERR_PUT_error(ERR_LIB_KEYCHAIN, func, 0, file, line);
+}
+
+/* encrypt */
+static int rsa_pub_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
+{
+    /* I haven't been able to trigger this one, but I want to know if it happens... */
+    assert(0);
+    return 0;
+}
+
+/* verify arbitrary data */
+static int rsa_pub_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
+{
+    /* I haven't been able to trigger this one, but I want to know if it happens... */
+    assert(0);
+    return 0;
+}
+
+/* sign arbitrary data */
+static int rsa_priv_enc(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
+{
+    SecIdentityRef identity = (SecIdentityRef) rsa->meth->app_data;
+	int length;
+	
+    if (!identity) 
+	{
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_PASSED_NULL_PARAMETER);
+		return 0;
+    }
+	
+    if (padding != RSA_PKCS1_PADDING) 
+	{
+		RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE);
+		return 0;
+    }
+	
+	CSSM_DATA fromData;
+	fromData.Data = (uint8*)from;
+	fromData.Length = flen;
+	CSSM_DATA sigBuf = signData(identity, fromData);
+	length = sigBuf.Length;
+	memcpy(to, sigBuf.Data, sigBuf.Length);
+	freeSignature(identity, sigBuf);
+    return length;
+}
+
+/* decrypt */
+static int rsa_priv_dec(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding)
+{
+    /* I haven't been able to trigger this one, but I want to know if it happens... */
+    assert(0);
+    return 0;
+}
+
+/* called at RSA_new */
+static int init(RSA *rsa)
+{
+    return 0;
+}
+
+/* called at RSA_free */
+static int finish(RSA *rsa)
+{
+    SecIdentityRef identity = (SecIdentityRef) rsa->meth->app_data;
+
+    if (!identity)
+		return 0;
+	
+	CFRelease(identity);
+    free((char *) rsa->meth);
+    rsa->meth = NULL;
+    return 1;
+}
+
+int SSL_CTX_use_Keychain_certificate(SSL_CTX *ssl_ctx, const char *cert_prop)
+{
+    X509 *cert = NULL;
+    RSA *rsa = NULL, *pub_rsa;
+    RSA_METHOD *my_rsa_method = calloc(1, sizeof(RSA_METHOD));
+	SecIdentityRef identity = NULL;
+	
+    if (my_rsa_method == NULL) 
+	{
+		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_MALLOC_FAILURE);
+		goto err;
+    }
+	
+	CertDataRef pCertDataTemplate = createCertDataFromString(cert_prop);
+	identity = findIdentity(pCertDataTemplate);
+	destroyCertData(pCertDataTemplate);
+	
+ 	if (!identity) 
+	{
+	    KeychainErr(KEYCHAIN_F_FIND_IDENTITY);
+	    goto err;
+	}
+	
+    CSSM_DATA cssmCertData;
+	SecCertificateRef certificate;
+
+    SecIdentityCopyCertificate(identity, &certificate);
+	SecCertificateGetData (certificate, &cssmCertData);
+	CFRelease(certificate);
+
+    /* cert_context->pbCertEncoded is the cert X509 DER encoded. */
+    cert = d2i_X509(NULL, (unsigned char **) &cssmCertData.Data, cssmCertData.Length);
+    if (cert == NULL) 
+	{
+		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_ASN1_LIB);
+		goto err;
+    }
+
+    my_rsa_method->name = "Mac OSX Keychain RSA Method";
+    my_rsa_method->rsa_pub_enc = rsa_pub_enc;
+    my_rsa_method->rsa_pub_dec = rsa_pub_dec;
+    my_rsa_method->rsa_priv_enc = rsa_priv_enc;
+    my_rsa_method->rsa_priv_dec = rsa_priv_dec;
+    /* my_rsa_method->init = init; */
+    my_rsa_method->finish = finish;
+    my_rsa_method->flags = RSA_METHOD_FLAG_NO_CHECK;
+    my_rsa_method->app_data = (char *) identity;
+
+    rsa = RSA_new();
+    if (rsa == NULL)
+	{
+		SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_MALLOC_FAILURE);
+		goto err;
+    }
+
+    /* cert->cert_info->key->pkey is NULL until we call SSL_CTX_use_certificate(),
+     * so we do it here then...  */
+    if (!SSL_CTX_use_certificate(ssl_ctx, cert))
+		goto err;
+	
+    /* the public key */
+    pub_rsa = cert->cert_info->key->pkey->pkey.rsa;
+    /* SSL_CTX_use_certificate() increased the reference count in 'cert', so
+     * we decrease it here with X509_free(), or it will never be cleaned up. */
+    X509_free(cert);
+    cert = NULL;
+
+    /* I'm not sure about what we have to fill in in the RSA, trying out stuff... */
+    /* rsa->n indicates the key size */
+    rsa->n = BN_dup(pub_rsa->n);
+    rsa->flags |= RSA_FLAG_EXT_PKEY;
+    if (!RSA_set_method(rsa, my_rsa_method))
+		goto err;
+
+    if (!SSL_CTX_use_RSAPrivateKey(ssl_ctx, rsa))
+		goto err;
+	
+    /* SSL_CTX_use_RSAPrivateKey() increased the reference count in 'rsa', so
+     * we decrease it here with RSA_free(), or it will never be cleaned up. */
+    RSA_free(rsa);
+    return 1;
+
+  err:
+    if (cert)
+		X509_free(cert);
+	
+    if (rsa)
+	{
+		RSA_free(rsa);
+	}
+    else 
+	{
+		if (my_rsa_method)
+			free(my_rsa_method);
+		
+		if (identity) 
+			CFRelease(identity);
+    }
+    return 0;
+}
+
+#else
+static void dummy1 (void) {}
+#endif				/* __APPLE__ */
diff --git a/osx/keychain.h b/osx/keychain.h
new file mode 100755
index 0000000..ba6e1b1
--- /dev/null
+++ b/osx/keychain.h
@@ -0,0 +1,7 @@
+#ifndef _OSXKEYCHAIN_H_
+#define _OSXKEYCHAIN_H_
+
+int SSL_CTX_use_Keychain_certificate(SSL_CTX *ssl_ctx, const char *cert_prop);
+
+
+#endif /* !_OSXKEYCHAIN_H_ */
diff --git a/osx/openvpn.xcodeproj/brian.pbxuser b/osx/openvpn.xcodeproj/brian.pbxuser
new file mode 100755
index 0000000..1df9164
--- /dev/null
+++ b/osx/openvpn.xcodeproj/brian.pbxuser
@@ -0,0 +1,879 @@
+// !$*UTF8*$!
+{
+	08FB7793FE84155DC02AAC07 /* Project object */ = {
+		activeBuildConfigurationName = Release;
+		activeExecutable = D35B8B3811448FC100A7F080 /* openvpn */;
+		activeSDKPreference = macosx10.5;
+		activeTarget = 8DD76FA90486AB0100D96B5E /* openvpn */;
+		addToTargets = (
+			8DD76FA90486AB0100D96B5E /* openvpn */,
+		);
+		breakpoints = (
+		);
+		codeSenseManager = D35B8B4311448FC700A7F080 /* Code sense */;
+		executables = (
+			D35B8B3811448FC100A7F080 /* openvpn */,
+		);
+		perUserDictionary = {
+			"PBXConfiguration.PBXBreakpointsDataSource.v1:1CA23EDF0692099D00951B8B" = {
+				PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+				PBXFileTableDataSourceColumnSortingKey = PBXBreakpointsDataSource_BreakpointID;
+				PBXFileTableDataSourceColumnWidthsKey = (
+					20,
+					20,
+					354,
+					20,
+					253,
+					253,
+					182,
+					20,
+				);
+				PBXFileTableDataSourceColumnsKey = (
+					PBXBreakpointsDataSource_ActionID,
+					PBXBreakpointsDataSource_TypeID,
+					PBXBreakpointsDataSource_BreakpointID,
+					PBXBreakpointsDataSource_UseID,
+					PBXBreakpointsDataSource_LocationID,
+					PBXBreakpointsDataSource_ConditionID,
+					PBXBreakpointsDataSource_IgnoreCountID,
+					PBXBreakpointsDataSource_ContinueID,
+				);
+			};
+			PBXConfiguration.PBXFileTableDataSource3.PBXExecutablesDataSource = {
+				PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+				PBXFileTableDataSourceColumnSortingKey = PBXExecutablesDataSource_NameID;
+				PBXFileTableDataSourceColumnWidthsKey = (
+					22,
+					300,
+					820,
+				);
+				PBXFileTableDataSourceColumnsKey = (
+					PBXExecutablesDataSource_ActiveFlagID,
+					PBXExecutablesDataSource_NameID,
+					PBXExecutablesDataSource_CommentsID,
+				);
+			};
+			PBXConfiguration.PBXFileTableDataSource3.PBXFileTableDataSource = {
+				PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+				PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+				PBXFileTableDataSourceColumnWidthsKey = (
+					20,
+					10,
+					20,
+					48,
+					43,
+					43,
+					20,
+				);
+				PBXFileTableDataSourceColumnsKey = (
+					PBXFileDataSource_FiletypeID,
+					PBXFileDataSource_Filename_ColumnID,
+					PBXFileDataSource_Built_ColumnID,
+					PBXFileDataSource_ObjectSize_ColumnID,
+					PBXFileDataSource_Errors_ColumnID,
+					PBXFileDataSource_Warnings_ColumnID,
+					PBXFileDataSource_Target_ColumnID,
+				);
+			};
+			PBXConfiguration.PBXTargetDataSource.PBXTargetDataSource = {
+				PBXFileTableDataSourceColumnSortingDirectionKey = "-1";
+				PBXFileTableDataSourceColumnSortingKey = PBXFileDataSource_Filename_ColumnID;
+				PBXFileTableDataSourceColumnWidthsKey = (
+					20,
+					892,
+					60,
+					20,
+					48,
+					43,
+					43,
+				);
+				PBXFileTableDataSourceColumnsKey = (
+					PBXFileDataSource_FiletypeID,
+					PBXFileDataSource_Filename_ColumnID,
+					PBXTargetDataSource_PrimaryAttribute,
+					PBXFileDataSource_Built_ColumnID,
+					PBXFileDataSource_ObjectSize_ColumnID,
+					PBXFileDataSource_Errors_ColumnID,
+					PBXFileDataSource_Warnings_ColumnID,
+				);
+			};
+			PBXPerProjectTemplateStateSaveDate = 294111940;
+			PBXWorkspaceStateSaveDate = 294111940;
+		};
+		perUserProjectItems = {
+			D33D58781186A53B006C86CF /* PBXTextBookmark */ = D33D58781186A53B006C86CF /* PBXTextBookmark */;
+			D33D58791186A53B006C86CF /* PBXTextBookmark */ = D33D58791186A53B006C86CF /* PBXTextBookmark */;
+			D3FBF88F1187CBE80036C81E /* PBXTextBookmark */ = D3FBF88F1187CBE80036C81E /* PBXTextBookmark */;
+			D3FBF8D41187E6090036C81E /* PBXTextBookmark */ = D3FBF8D41187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8D51187E6090036C81E /* PBXTextBookmark */ = D3FBF8D51187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8D61187E6090036C81E /* PBXTextBookmark */ = D3FBF8D61187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8D71187E6090036C81E /* PBXTextBookmark */ = D3FBF8D71187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8D81187E6090036C81E /* PBXTextBookmark */ = D3FBF8D81187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8D91187E6090036C81E /* PBXTextBookmark */ = D3FBF8D91187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8DA1187E6090036C81E /* PBXTextBookmark */ = D3FBF8DA1187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8DB1187E6090036C81E /* PBXTextBookmark */ = D3FBF8DB1187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8DC1187E6090036C81E /* PBXTextBookmark */ = D3FBF8DC1187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8DD1187E6090036C81E /* PBXTextBookmark */ = D3FBF8DD1187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8DE1187E6090036C81E /* PBXTextBookmark */ = D3FBF8DE1187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8DF1187E6090036C81E /* PBXTextBookmark */ = D3FBF8DF1187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8E01187E6090036C81E /* PBXTextBookmark */ = D3FBF8E01187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8E11187E6090036C81E /* PBXTextBookmark */ = D3FBF8E11187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8E21187E6090036C81E /* PBXTextBookmark */ = D3FBF8E21187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8E41187E6090036C81E /* PBXTextBookmark */ = D3FBF8E41187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8E61187E6090036C81E /* PBXTextBookmark */ = D3FBF8E61187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8E71187E6090036C81E /* PBXTextBookmark */ = D3FBF8E71187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8E81187E6090036C81E /* PBXTextBookmark */ = D3FBF8E81187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8E91187E6090036C81E /* PBXTextBookmark */ = D3FBF8E91187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8EA1187E6090036C81E /* PBXTextBookmark */ = D3FBF8EA1187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8EB1187E6090036C81E /* PBXTextBookmark */ = D3FBF8EB1187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8EC1187E6090036C81E /* PBXTextBookmark */ = D3FBF8EC1187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8ED1187E6090036C81E /* PBXTextBookmark */ = D3FBF8ED1187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8EE1187E6090036C81E /* PBXTextBookmark */ = D3FBF8EE1187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8EF1187E6090036C81E /* PBXTextBookmark */ = D3FBF8EF1187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8F01187E6090036C81E /* PBXTextBookmark */ = D3FBF8F01187E6090036C81E /* PBXTextBookmark */;
+			D3FBF8F11187E6090036C81E /* PBXTextBookmark */ = D3FBF8F11187E6090036C81E /* PBXTextBookmark */;
+		};
+		sourceControlManager = D35B8B4211448FC700A7F080 /* Source Control */;
+		userBuildSettings = {
+		};
+	};
+	8DD76FA90486AB0100D96B5E /* openvpn */ = {
+		activeExec = 0;
+		executables = (
+			D35B8B3811448FC100A7F080 /* openvpn */,
+		);
+	};
+	D33D58781186A53B006C86CF /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D35B8BB3114490D800A7F080 /* session_id.c */;
+		name = "session_id.c: 1";
+		rLen = 0;
+		rLoc = 0;
+		rType = 0;
+		vrLen = 1710;
+		vrLoc = 0;
+	};
+	D33D58791186A53B006C86CF /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D35B8B90114490D800A7F080 /* options.c */;
+		name = "options.c: 3847";
+		rLen = 0;
+		rLoc = 121140;
+		rType = 0;
+		vrLen = 1095;
+		vrLoc = 120453;
+	};
+	D35B8B3811448FC100A7F080 /* openvpn */ = {
+		isa = PBXExecutable;
+		activeArgIndices = (
+			NO,
+			YES,
+			YES,
+			NO,
+			YES,
+			YES,
+			YES,
+			YES,
+			YES,
+		);
+		argumentStrings = (
+			"--management-query-passwords",
+			"--daemon",
+			"--cd \"/Users/brian/Library/Application Support/Tunnelblick/Configurations\"",
+			"--management 127.0.0.1 1337",
+			"--config \"/Users/brian/Library/Application Support/Tunnelblick/Configurations/gkar.ovpn\"",
+			"--script-security 2",
+			"--up \"/Applications/Tunnelblick.app/Contents/Resources/client.nomonitor.up.osx.sh\"",
+			"--down \"/Applications/Tunnelblick.app/Contents/Resources/client.nomonitor.down.osx.sh\"",
+			" --up-restart",
+		);
+		autoAttachOnCrash = 1;
+		breakpointsEnabled = 1;
+		configStateDict = {
+		};
+		customDataFormattersEnabled = 1;
+		dataTipCustomDataFormattersEnabled = 1;
+		dataTipShowTypeColumn = 1;
+		dataTipSortType = 0;
+		debuggerPlugin = GDBDebugging;
+		disassemblyDisplayState = 0;
+		dylibVariantSuffix = "";
+		enableDebugStr = 1;
+		environmentEntries = (
+		);
+		executableSystemSymbolLevel = 0;
+		executableUserSymbolLevel = 0;
+		libgmallocEnabled = 0;
+		name = openvpn;
+		savedGlobals = {
+		};
+		showTypeColumn = 0;
+		sourceDirectories = (
+		);
+		variableFormatDictionary = {
+		};
+	};
+	D35B8B4211448FC700A7F080 /* Source Control */ = {
+		isa = PBXSourceControlManager;
+		fallbackIsa = XCSourceControlManager;
+		isSCMEnabled = 0;
+		scmConfiguration = {
+			repositoryNamesForRoots = {
+				"" = "";
+			};
+		};
+	};
+	D35B8B4311448FC700A7F080 /* Code sense */ = {
+		isa = PBXCodeSenseManager;
+		indexTemplatePath = "";
+	};
+	D35B8B4D114490D800A7F080 /* basic.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1122, 658}}";
+			sepNavSelRange = "{812, 0}";
+			sepNavVisRange = "{0, 1443}";
+		};
+	};
+	D35B8B4F114490D800A7F080 /* buffer.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1121, 11141}}";
+			sepNavSelRange = "{699, 0}";
+			sepNavVisRange = "{0, 1983}";
+		};
+	};
+	D35B8B50114490D800A7F080 /* circ_list.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1121, 1014}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 2237}";
+		};
+	};
+	D35B8B51114490D800A7F080 /* common.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1121, 1274}}";
+			sepNavSelRange = "{0, 1088}";
+			sepNavVisRange = "{0, 2114}";
+		};
+	};
+	D35B8B52114490D800A7F080 /* config.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {644, 8428}}";
+			sepNavSelRange = "{14052, 10}";
+			sepNavVisRange = "{13481, 360}";
+		};
+	};
+	D35B8B53114490D800A7F080 /* crypto.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {864, 25018}}";
+			sepNavSelRange = "{1080, 0}";
+			sepNavVisRange = "{5458, 1218}";
+		};
+	};
+	D35B8B54114490D800A7F080 /* crypto.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1122, 5265}}";
+			sepNavSelRange = "{1134, 10}";
+			sepNavVisRange = "{0, 2290}";
+		};
+	};
+	D35B8B55114490D800A7F080 /* dhcp.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1122, 2379}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 2194}";
+		};
+	};
+	D35B8B56114490D800A7F080 /* dhcp.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1122, 1092}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 2611}";
+		};
+	};
+	D35B8B57114490D800A7F080 /* errlevel.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1122, 2561}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 3247}";
+		};
+	};
+	D35B8B58114490D800A7F080 /* error.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1122, 11336}}";
+			sepNavSelRange = "{1811, 8}";
+			sepNavVisRange = "{1115, 1684}";
+		};
+	};
+	D35B8B59114490D800A7F080 /* error.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1174, 4186}}";
+			sepNavSelRange = "{5141, 96}";
+			sepNavVisRange = "{0, 2297}";
+		};
+	};
+	D35B8B61114490D800A7F080 /* fragment.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1122, 5252}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 2286}";
+		};
+	};
+	D35B8B66114490D800A7F080 /* helper.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1122, 954}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 1369}";
+		};
+	};
+	D35B8B69114490D800A7F080 /* init.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1122, 43550}}";
+			sepNavSelRange = "{14496, 15}";
+			sepNavVisRange = "{13873, 1303}";
+			sepNavWindowFrame = "{{15, 63}, {874, 710}}";
+		};
+	};
+	D35B8B73114490D800A7F080 /* lzo.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1122, 1703}}";
+			sepNavSelRange = "{1172, 0}";
+			sepNavVisRange = "{0, 1599}";
+			sepNavWindowFrame = "{{153, 233}, {1202, 814}}";
+		};
+	};
+	D35B8B74114490D800A7F080 /* manage.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {755, 40810}}";
+			sepNavSelRange = "{64236, 26}";
+			sepNavVisRange = "{64411, 707}";
+		};
+	};
+	D35B8B75114490D800A7F080 /* manage.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {755, 6804}}";
+			sepNavSelRange = "{9148, 26}";
+			sepNavVisRange = "{8854, 830}";
+		};
+	};
+	D35B8B79114490D800A7F080 /* memdbg.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {755, 1610}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{2403, 1141}";
+		};
+	};
+	D35B8B7A114490D800A7F080 /* misc.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {755, 30744}}";
+			sepNavSelRange = "{29238, 13}";
+			sepNavVisRange = "{29191, 598}";
+		};
+	};
+	D35B8B7B114490D800A7F080 /* misc.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {755, 5166}}";
+			sepNavSelRange = "{7625, 26}";
+			sepNavVisRange = "{7494, 671}";
+		};
+	};
+	D35B8B7E114490D800A7F080 /* mss.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {755, 1554}}";
+			sepNavSelRange = "{575, 0}";
+			sepNavVisRange = "{1092, 987}";
+		};
+	};
+	D35B8B82114490D800A7F080 /* mtu.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1122, 3575}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 2336}";
+		};
+	};
+	D35B8B83114490D800A7F080 /* mtu.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1122, 3796}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 2429}";
+		};
+	};
+	D35B8B88114490D800A7F080 /* ntlm.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {542, 5180}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 239}";
+		};
+	};
+	D35B8B89114490D800A7F080 /* ntlm.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {618, 409}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 240}";
+		};
+	};
+	D35B8B8E114490D800A7F080 /* openvpn.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1122, 3172}}";
+			sepNavSelRange = "{1481, 0}";
+			sepNavVisRange = "{817, 1112}";
+		};
+	};
+	D35B8B8F114490D800A7F080 /* openvpn.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1122, 7293}}";
+			sepNavSelRange = "{11135, 15}";
+			sepNavVisRange = "{11074, 1385}";
+		};
+	};
+	D35B8B90114490D800A7F080 /* options.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1216, 74685}}";
+			sepNavSelRange = "{121140, 0}";
+			sepNavVisRange = "{120453, 1095}";
+		};
+	};
+	D35B8B91114490D800A7F080 /* options.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1122, 9334}}";
+			sepNavSelRange = "{11496, 9}";
+			sepNavVisRange = "{10875, 1348}";
+		};
+	};
+	D35B8B9C114490D800A7F080 /* ping.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1122, 1183}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 2348}";
+		};
+	};
+	D35B8BA8114490D800A7F080 /* ps.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1122, 11154}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 2329}";
+		};
+	};
+	D35B8BAA114490D800A7F080 /* push.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1122, 5525}}";
+			sepNavSelRange = "{5218, 0}";
+			sepNavVisRange = "{4311, 1110}";
+		};
+	};
+	D35B8BB3114490D800A7F080 /* session_id.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1122, 780}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 1710}";
+		};
+	};
+	D35B8BBD114490D800A7F080 /* ssl.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1122, 65390}}";
+			sepNavSelRange = "{39709, 0}";
+			sepNavVisRange = "{39358, 2120}";
+		};
+	};
+	D35B8BBE114490D800A7F080 /* ssl.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1122, 10699}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 2678}";
+		};
+	};
+	D35B8BBF114490D800A7F080 /* status.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1122, 3627}}";
+			sepNavSelRange = "{3747, 5}";
+			sepNavVisRange = "{3144, 1002}";
+		};
+	};
+	D35B8BC1114490D800A7F080 /* syshead.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {2035, 8619}}";
+			sepNavSelRange = "{5866, 15}";
+			sepNavVisRange = "{0, 1971}";
+			sepNavWindowFrame = "{{15, 68}, {874, 710}}";
+		};
+	};
+	D35B8BC2114490D800A7F080 /* thread.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {815, 2156}}";
+			sepNavSelRange = "{3265, 10}";
+			sepNavVisRange = "{2705, 873}";
+			sepNavWindowFrame = "{{15, 63}, {874, 710}}";
+		};
+	};
+	D35B8BC3114490D800A7F080 /* thread.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {644, 2968}}";
+			sepNavSelRange = "{0, 0}";
+			sepNavVisRange = "{0, 813}";
+		};
+	};
+	D35B8BC4114490D800A7F080 /* tun.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1139, 57057}}";
+			sepNavSelRange = "{23137, 5}";
+			sepNavVisRange = "{22524, 1399}";
+		};
+	};
+	D3BBF5A9114C6AF700311166 /* cert_data.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {2021, 7982}}";
+			sepNavSelRange = "{381, 0}";
+			sepNavVisRange = "{0, 3404}";
+		};
+	};
+	D3BBF5AA114C6AF700311166 /* cert_data.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1121, 954}}";
+			sepNavSelRange = "{1082, 0}";
+			sepNavVisRange = "{0, 1694}";
+		};
+	};
+	D3BBF5AB114C6AF700311166 /* common_osx.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1121, 1196}}";
+			sepNavSelRange = "{1082, 0}";
+			sepNavVisRange = "{0, 2380}";
+		};
+	};
+	D3BBF5AC114C6AF700311166 /* common_osx.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1121, 954}}";
+			sepNavSelRange = "{1082, 0}";
+			sepNavVisRange = "{0, 1393}";
+		};
+	};
+	D3BBF5AD114C6AF700311166 /* crypto_osx.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1121, 1001}}";
+			sepNavSelRange = "{1082, 0}";
+			sepNavVisRange = "{0, 2530}";
+		};
+	};
+	D3BBF5AE114C6AF700311166 /* crypto_osx.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1121, 954}}";
+			sepNavSelRange = "{554, 0}";
+			sepNavVisRange = "{0, 1364}";
+		};
+	};
+	D3BBF5C2114C738A00311166 /* keychain.c */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1121, 3250}}";
+			sepNavSelRange = "{2075, 0}";
+			sepNavVisRange = "{0, 3096}";
+		};
+	};
+	D3BBF5C3114C738A00311166 /* keychain.h */ = {
+		uiCtxt = {
+			sepNavIntBoundsRect = "{{0, 0}, {1121, 954}}";
+			sepNavSelRange = "{48, 0}";
+			sepNavVisRange = "{0, 160}";
+		};
+	};
+	D3FBF88F1187CBE80036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D35B8B73114490D800A7F080 /* lzo.h */;
+		name = "lzo.h: 31";
+		rLen = 0;
+		rLoc = 1172;
+		rType = 0;
+		vrLen = 1599;
+		vrLoc = 0;
+	};
+	D3FBF8D41187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D35B8B54114490D800A7F080 /* crypto.h */;
+		name = "crypto.h: 27";
+		rLen = 10;
+		rLoc = 1134;
+		rType = 0;
+		vrLen = 2290;
+		vrLoc = 0;
+	};
+	D3FBF8D51187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D35B8B55114490D800A7F080 /* dhcp.c */;
+		name = "dhcp.c: 1";
+		rLen = 0;
+		rLoc = 0;
+		rType = 0;
+		vrLen = 2194;
+		vrLoc = 0;
+	};
+	D3FBF8D61187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D35B8B56114490D800A7F080 /* dhcp.h */;
+		name = "dhcp.h: 1";
+		rLen = 0;
+		rLoc = 0;
+		rType = 0;
+		vrLen = 2611;
+		vrLoc = 0;
+	};
+	D3FBF8D71187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D35B8B57114490D800A7F080 /* errlevel.h */;
+		name = "errlevel.h: 1";
+		rLen = 0;
+		rLoc = 0;
+		rType = 0;
+		vrLen = 3247;
+		vrLoc = 0;
+	};
+	D3FBF8D81187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D35B8B58114490D800A7F080 /* error.c */;
+		name = "error.c: 64";
+		rLen = 8;
+		rLoc = 1811;
+		rType = 0;
+		vrLen = 1684;
+		vrLoc = 1115;
+	};
+	D3FBF8D91187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D35B8B59114490D800A7F080 /* error.h */;
+		name = "error.h: 150";
+		rLen = 96;
+		rLoc = 5141;
+		rType = 0;
+		vrLen = 2297;
+		vrLoc = 0;
+	};
+	D3FBF8DA1187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D35B8B61114490D800A7F080 /* fragment.c */;
+		name = "fragment.c: 1";
+		rLen = 0;
+		rLoc = 0;
+		rType = 0;
+		vrLen = 2286;
+		vrLoc = 0;
+	};
+	D3FBF8DB1187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D35B8B66114490D800A7F080 /* helper.h */;
+		name = "helper.h: 1";
+		rLen = 0;
+		rLoc = 0;
+		rType = 0;
+		vrLen = 1369;
+		vrLoc = 0;
+	};
+	D3FBF8DC1187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D35B8B82114490D800A7F080 /* mtu.c */;
+		name = "mtu.c: 1";
+		rLen = 0;
+		rLoc = 0;
+		rType = 0;
+		vrLen = 2336;
+		vrLoc = 0;
+	};
+	D3FBF8DD1187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D35B8B83114490D800A7F080 /* mtu.h */;
+		name = "mtu.h: 1";
+		rLen = 0;
+		rLoc = 0;
+		rType = 0;
+		vrLen = 2429;
+		vrLoc = 0;
+	};
+	D3FBF8DE1187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D35B8B9C114490D800A7F080 /* ping.c */;
+		name = "ping.c: 1";
+		rLen = 0;
+		rLoc = 0;
+		rType = 0;
+		vrLen = 2348;
+		vrLoc = 0;
+	};
+	D3FBF8DF1187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D35B8BA8114490D800A7F080 /* ps.c */;
+		name = "ps.c: 1";
+		rLen = 0;
+		rLoc = 0;
+		rType = 0;
+		vrLen = 2329;
+		vrLoc = 0;
+	};
+	D3FBF8E01187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D35B8BBE114490D800A7F080 /* ssl.h */;
+		name = "ssl.h: 1";
+		rLen = 0;
+		rLoc = 0;
+		rType = 0;
+		vrLen = 2678;
+		vrLoc = 0;
+	};
+	D3FBF8E11187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D35B8BC1114490D800A7F080 /* syshead.h */;
+		name = "syshead.h: 354";
+		rLen = 15;
+		rLoc = 5866;
+		rType = 0;
+		vrLen = 1971;
+		vrLoc = 0;
+	};
+	D3FBF8E21187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D3FBF8E31187E6090036C81E /* cryptoapi.c */;
+		name = "cryptoapi.c: 1";
+		rLen = 1592;
+		rLoc = 0;
+		rType = 0;
+		vrLen = 3494;
+		vrLoc = 0;
+	};
+	D3FBF8E31187E6090036C81E /* cryptoapi.c */ = {
+		isa = PBXFileReference;
+		name = cryptoapi.c;
+		path = "/Users/brian/Code/openvpn-testing/cryptoapi.c";
+		sourceTree = "<absolute>";
+	};
+	D3FBF8E41187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D3FBF8E51187E6090036C81E /* cryptoapi.h */;
+		name = "cryptoapi.h: 1";
+		rLen = 0;
+		rLoc = 0;
+		rType = 0;
+		vrLen = 155;
+		vrLoc = 0;
+	};
+	D3FBF8E51187E6090036C81E /* cryptoapi.h */ = {
+		isa = PBXFileReference;
+		name = cryptoapi.h;
+		path = "/Users/brian/Code/openvpn-testing/cryptoapi.h";
+		sourceTree = "<absolute>";
+	};
+	D3FBF8E61187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D35B8B50114490D800A7F080 /* circ_list.h */;
+		name = "circ_list.h: 1";
+		rLen = 0;
+		rLoc = 0;
+		rType = 0;
+		vrLen = 2237;
+		vrLoc = 0;
+	};
+	D3FBF8E71187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D35B8B4F114490D800A7F080 /* buffer.h */;
+		name = "buffer.h: 16";
+		rLen = 0;
+		rLoc = 699;
+		rType = 0;
+		vrLen = 1983;
+		vrLoc = 0;
+	};
+	D3FBF8E81187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D35B8B51114490D800A7F080 /* common.h */;
+		name = "common.h: 1";
+		rLen = 1088;
+		rLoc = 0;
+		rType = 0;
+		vrLen = 2114;
+		vrLoc = 0;
+	};
+	D3FBF8E91187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D3BBF5A9114C6AF700311166 /* cert_data.c */;
+		name = "cert_data.c: 10";
+		rLen = 0;
+		rLoc = 381;
+		rType = 0;
+		vrLen = 3404;
+		vrLoc = 0;
+	};
+	D3FBF8EA1187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D3BBF5AA114C6AF700311166 /* cert_data.h */;
+		name = "cert_data.h: 23";
+		rLen = 0;
+		rLoc = 1082;
+		rType = 0;
+		vrLen = 1694;
+		vrLoc = 0;
+	};
+	D3FBF8EB1187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D3BBF5AB114C6AF700311166 /* common_osx.c */;
+		name = "common_osx.c: 23";
+		rLen = 0;
+		rLoc = 1082;
+		rType = 0;
+		vrLen = 2380;
+		vrLoc = 0;
+	};
+	D3FBF8EC1187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D3BBF5AC114C6AF700311166 /* common_osx.h */;
+		name = "common_osx.h: 23";
+		rLen = 0;
+		rLoc = 1082;
+		rType = 0;
+		vrLen = 1393;
+		vrLoc = 0;
+	};
+	D3FBF8ED1187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D3BBF5AD114C6AF700311166 /* crypto_osx.c */;
+		name = "crypto_osx.c: 23";
+		rLen = 0;
+		rLoc = 1082;
+		rType = 0;
+		vrLen = 2530;
+		vrLoc = 0;
+	};
+	D3FBF8EE1187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D3BBF5AE114C6AF700311166 /* crypto_osx.h */;
+		name = "crypto_osx.h: 13";
+		rLen = 0;
+		rLoc = 554;
+		rType = 0;
+		vrLen = 1364;
+		vrLoc = 0;
+	};
+	D3FBF8EF1187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D3BBF5C3114C738A00311166 /* keychain.h */;
+		name = "keychain.h: 3";
+		rLen = 0;
+		rLoc = 48;
+		rType = 0;
+		vrLen = 160;
+		vrLoc = 0;
+	};
+	D3FBF8F01187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D3BBF5C2114C738A00311166 /* keychain.c */;
+		name = "keychain.c: 12";
+		rLen = 0;
+		rLoc = 450;
+		rType = 0;
+		vrLen = 3114;
+		vrLoc = 0;
+	};
+	D3FBF8F11187E6090036C81E /* PBXTextBookmark */ = {
+		isa = PBXTextBookmark;
+		fRef = D3BBF5C2114C738A00311166 /* keychain.c */;
+		name = "keychain.c: 45";
+		rLen = 0;
+		rLoc = 2075;
+		rType = 0;
+		vrLen = 3096;
+		vrLoc = 0;
+	};
+}
diff --git a/osx/openvpn.xcodeproj/brian.perspectivev3 b/osx/openvpn.xcodeproj/brian.perspectivev3
new file mode 100755
index 0000000..e3590e8
--- /dev/null
+++ b/osx/openvpn.xcodeproj/brian.perspectivev3
@@ -0,0 +1,1511 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+	<key>ActivePerspectiveName</key>
+	<string>Project</string>
+	<key>AllowedModules</key>
+	<array>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>PBXSmartGroupTreeModule</string>
+			<key>Name</key>
+			<string>Groups and Files Outline View</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>PBXNavigatorGroup</string>
+			<key>Name</key>
+			<string>Editor</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>XCTaskListModule</string>
+			<key>Name</key>
+			<string>Task List</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>XCDetailModule</string>
+			<key>Name</key>
+			<string>File and Smart Group Detail Viewer</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>1</string>
+			<key>Module</key>
+			<string>PBXBuildResultsModule</string>
+			<key>Name</key>
+			<string>Detailed Build Results Viewer</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>1</string>
+			<key>Module</key>
+			<string>PBXProjectFindModule</string>
+			<key>Name</key>
+			<string>Project Batch Find Tool</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>XCProjectFormatConflictsModule</string>
+			<key>Name</key>
+			<string>Project Format Conflicts List</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>PBXBookmarksModule</string>
+			<key>Name</key>
+			<string>Bookmarks Tool</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>PBXClassBrowserModule</string>
+			<key>Name</key>
+			<string>Class Browser</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>PBXCVSModule</string>
+			<key>Name</key>
+			<string>Source Code Control Tool</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>PBXDebugBreakpointsModule</string>
+			<key>Name</key>
+			<string>Debug Breakpoints Tool</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>XCDockableInspector</string>
+			<key>Name</key>
+			<string>Inspector</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>PBXOpenQuicklyModule</string>
+			<key>Name</key>
+			<string>Open Quickly Tool</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>1</string>
+			<key>Module</key>
+			<string>PBXDebugSessionModule</string>
+			<key>Name</key>
+			<string>Debugger</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>1</string>
+			<key>Module</key>
+			<string>PBXDebugCLIModule</string>
+			<key>Name</key>
+			<string>Debug Console</string>
+		</dict>
+		<dict>
+			<key>BundleLoadPath</key>
+			<string></string>
+			<key>MaxInstances</key>
+			<string>n</string>
+			<key>Module</key>
+			<string>XCSnapshotModule</string>
+			<key>Name</key>
+			<string>Snapshots Tool</string>
+		</dict>
+	</array>
+	<key>BundlePath</key>
+	<string>/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources</string>
+	<key>Description</key>
+	<string>AIODescriptionKey</string>
+	<key>DockingSystemVisible</key>
+	<false/>
+	<key>Extension</key>
+	<string>perspectivev3</string>
+	<key>FavBarConfig</key>
+	<dict>
+		<key>PBXProjectModuleGUID</key>
+		<string>D35B8B4111448FC700A7F080</string>
+		<key>XCBarModuleItemNames</key>
+		<dict/>
+		<key>XCBarModuleItems</key>
+		<array/>
+	</dict>
+	<key>FirstTimeWindowDisplayed</key>
+	<false/>
+	<key>Identifier</key>
+	<string>com.apple.perspectives.project.defaultV3</string>
+	<key>MajorVersion</key>
+	<integer>34</integer>
+	<key>MinorVersion</key>
+	<integer>0</integer>
+	<key>Name</key>
+	<string>All-In-One</string>
+	<key>Notifications</key>
+	<array/>
+	<key>OpenEditors</key>
+	<array/>
+	<key>PerspectiveWidths</key>
+	<array>
+		<integer>1378</integer>
+		<integer>1378</integer>
+	</array>
+	<key>Perspectives</key>
+	<array>
+		<dict>
+			<key>ChosenToolbarItems</key>
+			<array>
+				<string>XCToolbarPerspectiveControl</string>
+				<string>NSToolbarSeparatorItem</string>
+				<string>active-combo-popup</string>
+				<string>action</string>
+				<string>NSToolbarFlexibleSpaceItem</string>
+				<string>toggle-editor</string>
+				<string>buildOrClean</string>
+				<string>build-and-go</string>
+				<string>go</string>
+				<string>servicesModulebreakpoints</string>
+				<string>debugger-enable-breakpoints</string>
+				<string>com.apple.ide.PBXToolbarStopButton</string>
+				<string>get-info</string>
+				<string>NSToolbarFlexibleSpaceItem</string>
+				<string>com.apple.pbx.toolbar.searchfield</string>
+			</array>
+			<key>ControllerClassBaseName</key>
+			<string></string>
+			<key>IconName</key>
+			<string>WindowOfProject</string>
+			<key>Identifier</key>
+			<string>perspective.project</string>
+			<key>IsVertical</key>
+			<false/>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>ContentConfiguration</key>
+					<dict>
+						<key>PBXBottomSmartGroupGIDs</key>
+						<array>
+							<string>1C37FBAC04509CD000000102</string>
+							<string>1C37FAAC04509CD000000102</string>
+							<string>1C37FABC05509CD000000102</string>
+							<string>1C37FABC05539CD112110102</string>
+							<string>E2644B35053B69B200211256</string>
+							<string>1C37FABC04509CD000100104</string>
+							<string>1CC0EA4004350EF90044410B</string>
+							<string>1CC0EA4004350EF90041110B</string>
+							<string>1C77FABC04509CD000000102</string>
+						</array>
+						<key>PBXProjectModuleGUID</key>
+						<string>1CA23ED40692098700951B8B</string>
+						<key>PBXProjectModuleLabel</key>
+						<string>Files</string>
+						<key>PBXProjectStructureProvided</key>
+						<string>yes</string>
+						<key>PBXSmartGroupTreeModuleColumnData</key>
+						<dict>
+							<key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+							<array>
+								<real>186</real>
+							</array>
+							<key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+							<array>
+								<string>MainColumn</string>
+							</array>
+						</dict>
+						<key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+						<dict>
+							<key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+							<array>
+								<string>08FB7794FE84155DC02AAC07</string>
+								<string>D3BBF5A8114C6A6A00311166</string>
+								<string>08FB7795FE84155DC02AAC07</string>
+								<string>C6A0FF2B0290797F04C91782</string>
+								<string>1AB674ADFE9D54B511CA2CBB</string>
+								<string>1C37FBAC04509CD000000102</string>
+								<string>1C37FAAC04509CD000000102</string>
+								<string>1C77FABC04509CD000000102</string>
+							</array>
+							<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+							<array>
+								<array>
+									<integer>2</integer>
+									<integer>1</integer>
+									<integer>0</integer>
+								</array>
+							</array>
+							<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+							<string>{{0, 0}, {186, 973}}</string>
+						</dict>
+						<key>PBXTopSmartGroupGIDs</key>
+						<array/>
+						<key>XCIncludePerspectivesSwitch</key>
+						<false/>
+					</dict>
+					<key>GeometryConfiguration</key>
+					<dict>
+						<key>Frame</key>
+						<string>{{0, 0}, {203, 991}}</string>
+						<key>GroupTreeTableConfiguration</key>
+						<array>
+							<string>MainColumn</string>
+							<real>186</real>
+						</array>
+						<key>RubberWindowFrame</key>
+						<string>-43 146 1378 1032 0 0 1920 1178 </string>
+					</dict>
+					<key>Module</key>
+					<string>PBXSmartGroupTreeModule</string>
+					<key>Proportion</key>
+					<string>203pt</string>
+				</dict>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>BecomeActive</key>
+							<true/>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>PBXProjectModuleGUID</key>
+								<string>D35B8B3C11448FC700A7F080</string>
+								<key>PBXProjectModuleLabel</key>
+								<string>keychain.c</string>
+								<key>PBXSplitModuleInNavigatorKey</key>
+								<dict>
+									<key>Split0</key>
+									<dict>
+										<key>PBXProjectModuleGUID</key>
+										<string>D35B8B3D11448FC700A7F080</string>
+										<key>PBXProjectModuleLabel</key>
+										<string>keychain.c</string>
+										<key>_historyCapacity</key>
+										<integer>0</integer>
+										<key>bookmark</key>
+										<string>D3FBF8F11187E6090036C81E</string>
+										<key>history</key>
+										<array>
+											<string>D33D58781186A53B006C86CF</string>
+											<string>D33D58791186A53B006C86CF</string>
+											<string>D3FBF88F1187CBE80036C81E</string>
+											<string>D3FBF8D41187E6090036C81E</string>
+											<string>D3FBF8D51187E6090036C81E</string>
+											<string>D3FBF8D61187E6090036C81E</string>
+											<string>D3FBF8D71187E6090036C81E</string>
+											<string>D3FBF8D81187E6090036C81E</string>
+											<string>D3FBF8D91187E6090036C81E</string>
+											<string>D3FBF8DA1187E6090036C81E</string>
+											<string>D3FBF8DB1187E6090036C81E</string>
+											<string>D3FBF8DC1187E6090036C81E</string>
+											<string>D3FBF8DD1187E6090036C81E</string>
+											<string>D3FBF8DE1187E6090036C81E</string>
+											<string>D3FBF8DF1187E6090036C81E</string>
+											<string>D3FBF8E01187E6090036C81E</string>
+											<string>D3FBF8E11187E6090036C81E</string>
+											<string>D3FBF8E21187E6090036C81E</string>
+											<string>D3FBF8E41187E6090036C81E</string>
+											<string>D3FBF8E61187E6090036C81E</string>
+											<string>D3FBF8E71187E6090036C81E</string>
+											<string>D3FBF8E81187E6090036C81E</string>
+											<string>D3FBF8E91187E6090036C81E</string>
+											<string>D3FBF8EA1187E6090036C81E</string>
+											<string>D3FBF8EB1187E6090036C81E</string>
+											<string>D3FBF8EC1187E6090036C81E</string>
+											<string>D3FBF8ED1187E6090036C81E</string>
+											<string>D3FBF8EE1187E6090036C81E</string>
+											<string>D3FBF8EF1187E6090036C81E</string>
+											<string>D3FBF8F01187E6090036C81E</string>
+										</array>
+									</dict>
+									<key>SplitCount</key>
+									<string>1</string>
+								</dict>
+								<key>StatusBarVisibility</key>
+								<true/>
+								<key>XCSharingToken</key>
+								<string>com.apple.Xcode.CommonNavigatorGroupSharingToken</string>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>Frame</key>
+								<string>{{0, 0}, {1170, 986}}</string>
+								<key>RubberWindowFrame</key>
+								<string>-43 146 1378 1032 0 0 1920 1178 </string>
+							</dict>
+							<key>Module</key>
+							<string>PBXNavigatorGroup</string>
+							<key>Proportion</key>
+							<string>986pt</string>
+						</dict>
+						<dict>
+							<key>Proportion</key>
+							<string>0pt</string>
+							<key>Tabs</key>
+							<array>
+								<dict>
+									<key>ContentConfiguration</key>
+									<dict>
+										<key>PBXProjectModuleGUID</key>
+										<string>1CA23EDF0692099D00951B8B</string>
+										<key>PBXProjectModuleLabel</key>
+										<string>Detail</string>
+									</dict>
+									<key>GeometryConfiguration</key>
+									<dict>
+										<key>Frame</key>
+										<string>{{10, 27}, {1170, -27}}</string>
+										<key>RubberWindowFrame</key>
+										<string>-43 146 1378 1032 0 0 1920 1178 </string>
+									</dict>
+									<key>Module</key>
+									<string>XCDetailModule</string>
+								</dict>
+								<dict>
+									<key>ContentConfiguration</key>
+									<dict>
+										<key>PBXProjectModuleGUID</key>
+										<string>1CA23EE00692099D00951B8B</string>
+										<key>PBXProjectModuleLabel</key>
+										<string>Project Find</string>
+									</dict>
+									<key>GeometryConfiguration</key>
+									<dict>
+										<key>Frame</key>
+										<string>{{10, 27}, {1171, 269}}</string>
+									</dict>
+									<key>Module</key>
+									<string>PBXProjectFindModule</string>
+								</dict>
+								<dict>
+									<key>ContentConfiguration</key>
+									<dict>
+										<key>PBXCVSModuleFilterTypeKey</key>
+										<integer>1032</integer>
+										<key>PBXProjectModuleGUID</key>
+										<string>1CA23EE10692099D00951B8B</string>
+										<key>PBXProjectModuleLabel</key>
+										<string>SCM Results</string>
+									</dict>
+									<key>GeometryConfiguration</key>
+									<dict>
+										<key>Frame</key>
+										<string>{{10, 31}, {603, 297}}</string>
+									</dict>
+									<key>Module</key>
+									<string>PBXCVSModule</string>
+								</dict>
+								<dict>
+									<key>ContentConfiguration</key>
+									<dict>
+										<key>PBXProjectModuleGUID</key>
+										<string>XCMainBuildResultsModuleGUID</string>
+										<key>PBXProjectModuleLabel</key>
+										<string>Build Results</string>
+										<key>XCBuildResultsTrigger_Collapse</key>
+										<integer>1021</integer>
+										<key>XCBuildResultsTrigger_Open</key>
+										<integer>1011</integer>
+									</dict>
+									<key>GeometryConfiguration</key>
+									<dict>
+										<key>Frame</key>
+										<string>{{10, 27}, {1171, 269}}</string>
+									</dict>
+									<key>Module</key>
+									<string>PBXBuildResultsModule</string>
+								</dict>
+							</array>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>1170pt</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>Project</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>XCModuleDock</string>
+				<string>PBXSmartGroupTreeModule</string>
+				<string>XCModuleDock</string>
+				<string>PBXNavigatorGroup</string>
+				<string>XCDockableTabModule</string>
+				<string>XCDetailModule</string>
+				<string>PBXProjectFindModule</string>
+				<string>PBXCVSModule</string>
+				<string>PBXBuildResultsModule</string>
+			</array>
+			<key>TableOfContents</key>
+			<array>
+				<string>D3FBF8881187CACB0036C81E</string>
+				<string>1CA23ED40692098700951B8B</string>
+				<string>D3FBF8891187CACB0036C81E</string>
+				<string>D35B8B3C11448FC700A7F080</string>
+				<string>D3FBF88A1187CACB0036C81E</string>
+				<string>1CA23EDF0692099D00951B8B</string>
+				<string>1CA23EE00692099D00951B8B</string>
+				<string>1CA23EE10692099D00951B8B</string>
+				<string>XCMainBuildResultsModuleGUID</string>
+			</array>
+			<key>ToolbarConfigUserDefaultsMinorVersion</key>
+			<string>2</string>
+			<key>ToolbarConfiguration</key>
+			<string>xcode.toolbar.config.defaultV3</string>
+		</dict>
+		<dict>
+			<key>ChosenToolbarItems</key>
+			<array>
+				<string>XCToolbarPerspectiveControl</string>
+				<string>NSToolbarSeparatorItem</string>
+				<string>build-and-go</string>
+				<string>go</string>
+				<string>NSToolbarFlexibleSpaceItem</string>
+				<string>debugger-fix-and-continue</string>
+				<string>debugger-restart-executable</string>
+				<string>debugger-pause</string>
+				<string>debugger-step-over</string>
+				<string>debugger-step-into</string>
+				<string>debugger-step-out</string>
+				<string>debugger-step-instruction</string>
+				<string>NSToolbarFlexibleSpaceItem</string>
+			</array>
+			<key>ControllerClassBaseName</key>
+			<string>PBXDebugSessionModule</string>
+			<key>IconName</key>
+			<string>DebugTabIcon</string>
+			<key>Identifier</key>
+			<string>perspective.debug</string>
+			<key>IsVertical</key>
+			<true/>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>ContentConfiguration</key>
+					<dict>
+						<key>PBXProjectModuleGUID</key>
+						<string>1CCC7628064C1048000F2A68</string>
+						<key>PBXProjectModuleLabel</key>
+						<string>Debugger Console</string>
+					</dict>
+					<key>GeometryConfiguration</key>
+					<dict>
+						<key>Frame</key>
+						<string>{{0, 0}, {1378, 260}}</string>
+					</dict>
+					<key>Module</key>
+					<string>PBXDebugCLIModule</string>
+					<key>Proportion</key>
+					<string>260pt</string>
+				</dict>
+				<dict>
+					<key>ContentConfiguration</key>
+					<dict>
+						<key>Debugger</key>
+						<dict>
+							<key>HorizontalSplitView</key>
+							<dict>
+								<key>_collapsingFrameDimension</key>
+								<real>0.0</real>
+								<key>_indexOfCollapsedView</key>
+								<integer>0</integer>
+								<key>_percentageOfCollapsedView</key>
+								<real>0.0</real>
+								<key>isCollapsed</key>
+								<string>yes</string>
+								<key>sizes</key>
+								<array>
+									<string>{{0, 0}, {672, 255}}</string>
+									<string>{{672, 0}, {706, 255}}</string>
+								</array>
+							</dict>
+							<key>VerticalSplitView</key>
+							<dict>
+								<key>_collapsingFrameDimension</key>
+								<real>0.0</real>
+								<key>_indexOfCollapsedView</key>
+								<integer>0</integer>
+								<key>_percentageOfCollapsedView</key>
+								<real>0.0</real>
+								<key>isCollapsed</key>
+								<string>yes</string>
+								<key>sizes</key>
+								<array>
+									<string>{{0, 0}, {1378, 255}}</string>
+									<string>{{0, 255}, {1378, 471}}</string>
+								</array>
+							</dict>
+						</dict>
+						<key>LauncherConfigVersion</key>
+						<string>8</string>
+						<key>PBXProjectModuleGUID</key>
+						<string>1CCC7629064C1048000F2A68</string>
+						<key>PBXProjectModuleLabel</key>
+						<string>Debug</string>
+					</dict>
+					<key>GeometryConfiguration</key>
+					<dict>
+						<key>DebugConsoleVisible</key>
+						<string>None</string>
+						<key>DebugConsoleWindowFrame</key>
+						<string>{{200, 200}, {500, 300}}</string>
+						<key>DebugSTDIOWindowFrame</key>
+						<string>{{200, 200}, {500, 300}}</string>
+						<key>Frame</key>
+						<string>{{0, 265}, {1378, 726}}</string>
+						<key>PBXDebugSessionStackFrameViewKey</key>
+						<dict>
+							<key>DebugVariablesTableConfiguration</key>
+							<array>
+								<string>Name</string>
+								<real>120</real>
+								<string>Value</string>
+								<real>85</real>
+								<string>Summary</string>
+								<real>476</real>
+							</array>
+							<key>Frame</key>
+							<string>{{672, 0}, {706, 255}}</string>
+						</dict>
+					</dict>
+					<key>Module</key>
+					<string>PBXDebugSessionModule</string>
+					<key>Proportion</key>
+					<string>726pt</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>Debug</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>XCModuleDock</string>
+				<string>PBXDebugCLIModule</string>
+				<string>PBXDebugSessionModule</string>
+				<string>PBXDebugProcessAndThreadModule</string>
+				<string>PBXDebugProcessViewModule</string>
+				<string>PBXDebugThreadViewModule</string>
+				<string>PBXDebugStackFrameViewModule</string>
+				<string>PBXNavigatorGroup</string>
+			</array>
+			<key>TableOfContents</key>
+			<array>
+				<string>D3FBF8F21187E6090036C81E</string>
+				<string>1CCC7628064C1048000F2A68</string>
+				<string>1CCC7629064C1048000F2A68</string>
+				<string>D3FBF8F31187E6090036C81E</string>
+				<string>D3FBF8F41187E6090036C81E</string>
+				<string>D3FBF8F51187E6090036C81E</string>
+				<string>D3FBF8F61187E6090036C81E</string>
+				<string>D3FBF8F71187E6090036C81E</string>
+			</array>
+			<key>ToolbarConfigUserDefaultsMinorVersion</key>
+			<string>2</string>
+			<key>ToolbarConfiguration</key>
+			<string>xcode.toolbar.config.debugV3</string>
+		</dict>
+	</array>
+	<key>PerspectivesBarVisible</key>
+	<true/>
+	<key>ShelfIsVisible</key>
+	<false/>
+	<key>SourceDescription</key>
+	<string>file at '/Developer/Library/PrivateFrameworks/DevToolsInterface.framework/Resources/XCPerspectivesSpecification.xcperspec'</string>
+	<key>StatusbarIsVisible</key>
+	<true/>
+	<key>TimeStamp</key>
+	<real>0.0</real>
+	<key>ToolbarDisplayMode</key>
+	<integer>1</integer>
+	<key>ToolbarIsVisible</key>
+	<true/>
+	<key>ToolbarSizeMode</key>
+	<integer>1</integer>
+	<key>Type</key>
+	<string>Perspectives</string>
+	<key>UpdateMessage</key>
+	<string></string>
+	<key>WindowJustification</key>
+	<integer>5</integer>
+	<key>WindowOrderList</key>
+	<array>
+		<string>/Users/brian/Code/openvpn-testing/osx/openvpn.xcodeproj</string>
+	</array>
+	<key>WindowString</key>
+	<string>-43 146 1378 1032 0 0 1920 1178 </string>
+	<key>WindowToolsV3</key>
+	<array>
+		<dict>
+			<key>Identifier</key>
+			<string>windowTool.debugger</string>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>Debugger</key>
+								<dict>
+									<key>HorizontalSplitView</key>
+									<dict>
+										<key>_collapsingFrameDimension</key>
+										<real>0.0</real>
+										<key>_indexOfCollapsedView</key>
+										<integer>0</integer>
+										<key>_percentageOfCollapsedView</key>
+										<real>0.0</real>
+										<key>isCollapsed</key>
+										<string>yes</string>
+										<key>sizes</key>
+										<array>
+											<string>{{0, 0}, {317, 164}}</string>
+											<string>{{317, 0}, {377, 164}}</string>
+										</array>
+									</dict>
+									<key>VerticalSplitView</key>
+									<dict>
+										<key>_collapsingFrameDimension</key>
+										<real>0.0</real>
+										<key>_indexOfCollapsedView</key>
+										<integer>0</integer>
+										<key>_percentageOfCollapsedView</key>
+										<real>0.0</real>
+										<key>isCollapsed</key>
+										<string>yes</string>
+										<key>sizes</key>
+										<array>
+											<string>{{0, 0}, {694, 164}}</string>
+											<string>{{0, 164}, {694, 216}}</string>
+										</array>
+									</dict>
+								</dict>
+								<key>LauncherConfigVersion</key>
+								<string>8</string>
+								<key>PBXProjectModuleGUID</key>
+								<string>1C162984064C10D400B95A72</string>
+								<key>PBXProjectModuleLabel</key>
+								<string>Debug - GLUTExamples (Underwater)</string>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>DebugConsoleDrawerSize</key>
+								<string>{100, 120}</string>
+								<key>DebugConsoleVisible</key>
+								<string>None</string>
+								<key>DebugConsoleWindowFrame</key>
+								<string>{{200, 200}, {500, 300}}</string>
+								<key>DebugSTDIOWindowFrame</key>
+								<string>{{200, 200}, {500, 300}}</string>
+								<key>Frame</key>
+								<string>{{0, 0}, {694, 380}}</string>
+								<key>RubberWindowFrame</key>
+								<string>321 238 694 422 0 0 1440 878 </string>
+							</dict>
+							<key>Module</key>
+							<string>PBXDebugSessionModule</string>
+							<key>Proportion</key>
+							<string>100%</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>100%</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>Debugger</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>PBXDebugSessionModule</string>
+			</array>
+			<key>StatusbarIsVisible</key>
+			<integer>1</integer>
+			<key>TableOfContents</key>
+			<array>
+				<string>1CD10A99069EF8BA00B06720</string>
+				<string>1C0AD2AB069F1E9B00FABCE6</string>
+				<string>1C162984064C10D400B95A72</string>
+				<string>1C0AD2AC069F1E9B00FABCE6</string>
+			</array>
+			<key>ToolbarConfiguration</key>
+			<string>xcode.toolbar.config.debugV3</string>
+			<key>WindowString</key>
+			<string>321 238 694 422 0 0 1440 878 </string>
+			<key>WindowToolGUID</key>
+			<string>1CD10A99069EF8BA00B06720</string>
+			<key>WindowToolIsVisible</key>
+			<integer>0</integer>
+		</dict>
+		<dict>
+			<key>Identifier</key>
+			<string>windowTool.build</string>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>PBXProjectModuleGUID</key>
+								<string>1CD0528F0623707200166675</string>
+								<key>PBXProjectModuleLabel</key>
+								<string>&lt;No Editor&gt;</string>
+								<key>PBXSplitModuleInNavigatorKey</key>
+								<dict>
+									<key>Split0</key>
+									<dict>
+										<key>PBXProjectModuleGUID</key>
+										<string>1CD052900623707200166675</string>
+									</dict>
+									<key>SplitCount</key>
+									<string>1</string>
+								</dict>
+								<key>StatusBarVisibility</key>
+								<integer>1</integer>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>Frame</key>
+								<string>{{0, 0}, {500, 215}}</string>
+								<key>RubberWindowFrame</key>
+								<string>192 257 500 500 0 0 1280 1002 </string>
+							</dict>
+							<key>Module</key>
+							<string>PBXNavigatorGroup</string>
+							<key>Proportion</key>
+							<string>218pt</string>
+						</dict>
+						<dict>
+							<key>BecomeActive</key>
+							<integer>1</integer>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>PBXProjectModuleGUID</key>
+								<string>XCMainBuildResultsModuleGUID</string>
+								<key>PBXProjectModuleLabel</key>
+								<string>Build</string>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>Frame</key>
+								<string>{{0, 222}, {500, 236}}</string>
+								<key>RubberWindowFrame</key>
+								<string>192 257 500 500 0 0 1280 1002 </string>
+							</dict>
+							<key>Module</key>
+							<string>PBXBuildResultsModule</string>
+							<key>Proportion</key>
+							<string>236pt</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>458pt</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>Build Results</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>PBXBuildResultsModule</string>
+			</array>
+			<key>StatusbarIsVisible</key>
+			<integer>1</integer>
+			<key>TableOfContents</key>
+			<array>
+				<string>1C78EAA5065D492600B07095</string>
+				<string>1C78EAA6065D492600B07095</string>
+				<string>1CD0528F0623707200166675</string>
+				<string>XCMainBuildResultsModuleGUID</string>
+			</array>
+			<key>ToolbarConfiguration</key>
+			<string>xcode.toolbar.config.buildV3</string>
+			<key>WindowString</key>
+			<string>192 257 500 500 0 0 1280 1002 </string>
+		</dict>
+		<dict>
+			<key>Identifier</key>
+			<string>windowTool.find</string>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>Dock</key>
+							<array>
+								<dict>
+									<key>ContentConfiguration</key>
+									<dict>
+										<key>PBXProjectModuleGUID</key>
+										<string>1CDD528C0622207200134675</string>
+										<key>PBXProjectModuleLabel</key>
+										<string>&lt;No Editor&gt;</string>
+										<key>PBXSplitModuleInNavigatorKey</key>
+										<dict>
+											<key>Split0</key>
+											<dict>
+												<key>PBXProjectModuleGUID</key>
+												<string>1CD0528D0623707200166675</string>
+											</dict>
+											<key>SplitCount</key>
+											<string>1</string>
+										</dict>
+										<key>StatusBarVisibility</key>
+										<integer>1</integer>
+									</dict>
+									<key>GeometryConfiguration</key>
+									<dict>
+										<key>Frame</key>
+										<string>{{0, 0}, {781, 167}}</string>
+										<key>RubberWindowFrame</key>
+										<string>62 385 781 470 0 0 1440 878 </string>
+									</dict>
+									<key>Module</key>
+									<string>PBXNavigatorGroup</string>
+									<key>Proportion</key>
+									<string>781pt</string>
+								</dict>
+							</array>
+							<key>Proportion</key>
+							<string>50%</string>
+						</dict>
+						<dict>
+							<key>BecomeActive</key>
+							<integer>1</integer>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>PBXProjectModuleGUID</key>
+								<string>1CD0528E0623707200166675</string>
+								<key>PBXProjectModuleLabel</key>
+								<string>Project Find</string>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>Frame</key>
+								<string>{{8, 0}, {773, 254}}</string>
+								<key>RubberWindowFrame</key>
+								<string>62 385 781 470 0 0 1440 878 </string>
+							</dict>
+							<key>Module</key>
+							<string>PBXProjectFindModule</string>
+							<key>Proportion</key>
+							<string>50%</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>428pt</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>Project Find</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>PBXProjectFindModule</string>
+			</array>
+			<key>StatusbarIsVisible</key>
+			<integer>1</integer>
+			<key>TableOfContents</key>
+			<array>
+				<string>1C530D57069F1CE1000CFCEE</string>
+				<string>1C530D58069F1CE1000CFCEE</string>
+				<string>1C530D59069F1CE1000CFCEE</string>
+				<string>1CDD528C0622207200134675</string>
+				<string>1C530D5A069F1CE1000CFCEE</string>
+				<string>1CE0B1FE06471DED0097A5F4</string>
+				<string>1CD0528E0623707200166675</string>
+			</array>
+			<key>WindowString</key>
+			<string>62 385 781 470 0 0 1440 878 </string>
+			<key>WindowToolGUID</key>
+			<string>1C530D57069F1CE1000CFCEE</string>
+			<key>WindowToolIsVisible</key>
+			<integer>0</integer>
+		</dict>
+		<dict>
+			<key>Identifier</key>
+			<string>windowTool.snapshots</string>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>Module</key>
+							<string>XCSnapshotModule</string>
+							<key>Proportion</key>
+							<string>100%</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>100%</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>Snapshots</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>XCSnapshotModule</string>
+			</array>
+			<key>StatusbarIsVisible</key>
+			<string>Yes</string>
+			<key>ToolbarConfiguration</key>
+			<string>xcode.toolbar.config.snapshots</string>
+			<key>WindowString</key>
+			<string>315 824 300 550 0 0 1440 878 </string>
+			<key>WindowToolIsVisible</key>
+			<string>Yes</string>
+		</dict>
+		<dict>
+			<key>Identifier</key>
+			<string>windowTool.debuggerConsole</string>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>BecomeActive</key>
+							<integer>1</integer>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>PBXProjectModuleGUID</key>
+								<string>1C78EAAC065D492600B07095</string>
+								<key>PBXProjectModuleLabel</key>
+								<string>Debugger Console</string>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>Frame</key>
+								<string>{{0, 0}, {700, 358}}</string>
+								<key>RubberWindowFrame</key>
+								<string>149 87 700 400 0 0 1440 878 </string>
+							</dict>
+							<key>Module</key>
+							<string>PBXDebugCLIModule</string>
+							<key>Proportion</key>
+							<string>358pt</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>358pt</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>Debugger Console</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>PBXDebugCLIModule</string>
+			</array>
+			<key>StatusbarIsVisible</key>
+			<integer>1</integer>
+			<key>TableOfContents</key>
+			<array>
+				<string>1C530D5B069F1CE1000CFCEE</string>
+				<string>1C530D5C069F1CE1000CFCEE</string>
+				<string>1C78EAAC065D492600B07095</string>
+			</array>
+			<key>ToolbarConfiguration</key>
+			<string>xcode.toolbar.config.consoleV3</string>
+			<key>WindowString</key>
+			<string>149 87 440 400 0 0 1440 878 </string>
+			<key>WindowToolGUID</key>
+			<string>1C530D5B069F1CE1000CFCEE</string>
+			<key>WindowToolIsVisible</key>
+			<integer>0</integer>
+		</dict>
+		<dict>
+			<key>Identifier</key>
+			<string>windowTool.scm</string>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>PBXProjectModuleGUID</key>
+								<string>1C78EAB2065D492600B07095</string>
+								<key>PBXProjectModuleLabel</key>
+								<string>&lt;No Editor&gt;</string>
+								<key>PBXSplitModuleInNavigatorKey</key>
+								<dict>
+									<key>Split0</key>
+									<dict>
+										<key>PBXProjectModuleGUID</key>
+										<string>1C78EAB3065D492600B07095</string>
+									</dict>
+									<key>SplitCount</key>
+									<string>1</string>
+								</dict>
+								<key>StatusBarVisibility</key>
+								<integer>1</integer>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>Frame</key>
+								<string>{{0, 0}, {452, 0}}</string>
+								<key>RubberWindowFrame</key>
+								<string>743 379 452 308 0 0 1280 1002 </string>
+							</dict>
+							<key>Module</key>
+							<string>PBXNavigatorGroup</string>
+							<key>Proportion</key>
+							<string>0pt</string>
+						</dict>
+						<dict>
+							<key>BecomeActive</key>
+							<integer>1</integer>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>PBXProjectModuleGUID</key>
+								<string>1CD052920623707200166675</string>
+								<key>PBXProjectModuleLabel</key>
+								<string>SCM</string>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>ConsoleFrame</key>
+								<string>{{0, 259}, {452, 0}}</string>
+								<key>Frame</key>
+								<string>{{0, 7}, {452, 259}}</string>
+								<key>RubberWindowFrame</key>
+								<string>743 379 452 308 0 0 1280 1002 </string>
+								<key>TableConfiguration</key>
+								<array>
+									<string>Status</string>
+									<real>30</real>
+									<string>FileName</string>
+									<real>199</real>
+									<string>Path</string>
+									<real>197.09500122070312</real>
+								</array>
+								<key>TableFrame</key>
+								<string>{{0, 0}, {452, 250}}</string>
+							</dict>
+							<key>Module</key>
+							<string>PBXCVSModule</string>
+							<key>Proportion</key>
+							<string>262pt</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>266pt</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>SCM</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>PBXCVSModule</string>
+			</array>
+			<key>StatusbarIsVisible</key>
+			<integer>1</integer>
+			<key>TableOfContents</key>
+			<array>
+				<string>1C78EAB4065D492600B07095</string>
+				<string>1C78EAB5065D492600B07095</string>
+				<string>1C78EAB2065D492600B07095</string>
+				<string>1CD052920623707200166675</string>
+			</array>
+			<key>ToolbarConfiguration</key>
+			<string>xcode.toolbar.config.scmV3</string>
+			<key>WindowString</key>
+			<string>743 379 452 308 0 0 1280 1002 </string>
+		</dict>
+		<dict>
+			<key>Identifier</key>
+			<string>windowTool.breakpoints</string>
+			<key>IsVertical</key>
+			<integer>0</integer>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>BecomeActive</key>
+							<integer>1</integer>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>PBXBottomSmartGroupGIDs</key>
+								<array>
+									<string>1C77FABC04509CD000000102</string>
+								</array>
+								<key>PBXProjectModuleGUID</key>
+								<string>1CE0B1FE06471DED0097A5F4</string>
+								<key>PBXProjectModuleLabel</key>
+								<string>Files</string>
+								<key>PBXProjectStructureProvided</key>
+								<string>no</string>
+								<key>PBXSmartGroupTreeModuleColumnData</key>
+								<dict>
+									<key>PBXSmartGroupTreeModuleColumnWidthsKey</key>
+									<array>
+										<real>168</real>
+									</array>
+									<key>PBXSmartGroupTreeModuleColumnsKey_v4</key>
+									<array>
+										<string>MainColumn</string>
+									</array>
+								</dict>
+								<key>PBXSmartGroupTreeModuleOutlineStateKey_v7</key>
+								<dict>
+									<key>PBXSmartGroupTreeModuleOutlineStateExpansionKey</key>
+									<array>
+										<string>1C77FABC04509CD000000102</string>
+									</array>
+									<key>PBXSmartGroupTreeModuleOutlineStateSelectionKey</key>
+									<array>
+										<array>
+											<integer>0</integer>
+										</array>
+									</array>
+									<key>PBXSmartGroupTreeModuleOutlineStateVisibleRectKey</key>
+									<string>{{0, 0}, {168, 350}}</string>
+								</dict>
+								<key>PBXTopSmartGroupGIDs</key>
+								<array/>
+								<key>XCIncludePerspectivesSwitch</key>
+								<integer>0</integer>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>Frame</key>
+								<string>{{0, 0}, {185, 368}}</string>
+								<key>GroupTreeTableConfiguration</key>
+								<array>
+									<string>MainColumn</string>
+									<real>168</real>
+								</array>
+								<key>RubberWindowFrame</key>
+								<string>315 424 744 409 0 0 1440 878 </string>
+							</dict>
+							<key>Module</key>
+							<string>PBXSmartGroupTreeModule</string>
+							<key>Proportion</key>
+							<string>185pt</string>
+						</dict>
+						<dict>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>PBXProjectModuleGUID</key>
+								<string>1CA1AED706398EBD00589147</string>
+								<key>PBXProjectModuleLabel</key>
+								<string>Detail</string>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>Frame</key>
+								<string>{{190, 0}, {554, 368}}</string>
+								<key>RubberWindowFrame</key>
+								<string>315 424 744 409 0 0 1440 878 </string>
+							</dict>
+							<key>Module</key>
+							<string>XCDetailModule</string>
+							<key>Proportion</key>
+							<string>554pt</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>368pt</string>
+				</dict>
+			</array>
+			<key>MajorVersion</key>
+			<integer>3</integer>
+			<key>MinorVersion</key>
+			<integer>0</integer>
+			<key>Name</key>
+			<string>Breakpoints</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>PBXSmartGroupTreeModule</string>
+				<string>XCDetailModule</string>
+			</array>
+			<key>StatusbarIsVisible</key>
+			<integer>1</integer>
+			<key>TableOfContents</key>
+			<array>
+				<string>1CDDB66807F98D9800BB5817</string>
+				<string>1CDDB66907F98D9800BB5817</string>
+				<string>1CE0B1FE06471DED0097A5F4</string>
+				<string>1CA1AED706398EBD00589147</string>
+			</array>
+			<key>ToolbarConfiguration</key>
+			<string>xcode.toolbar.config.breakpointsV3</string>
+			<key>WindowString</key>
+			<string>315 424 744 409 0 0 1440 878 </string>
+			<key>WindowToolGUID</key>
+			<string>1CDDB66807F98D9800BB5817</string>
+			<key>WindowToolIsVisible</key>
+			<integer>1</integer>
+		</dict>
+		<dict>
+			<key>Identifier</key>
+			<string>windowTool.debugAnimator</string>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>Module</key>
+							<string>PBXNavigatorGroup</string>
+							<key>Proportion</key>
+							<string>100%</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>100%</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>Debug Visualizer</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>PBXNavigatorGroup</string>
+			</array>
+			<key>StatusbarIsVisible</key>
+			<integer>1</integer>
+			<key>ToolbarConfiguration</key>
+			<string>xcode.toolbar.config.debugAnimatorV3</string>
+			<key>WindowString</key>
+			<string>100 100 700 500 0 0 1280 1002 </string>
+		</dict>
+		<dict>
+			<key>Identifier</key>
+			<string>windowTool.bookmarks</string>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>Module</key>
+							<string>PBXBookmarksModule</string>
+							<key>Proportion</key>
+							<string>166pt</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>166pt</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>Bookmarks</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>PBXBookmarksModule</string>
+			</array>
+			<key>StatusbarIsVisible</key>
+			<integer>0</integer>
+			<key>WindowString</key>
+			<string>538 42 401 187 0 0 1280 1002 </string>
+		</dict>
+		<dict>
+			<key>Identifier</key>
+			<string>windowTool.projectFormatConflicts</string>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>Module</key>
+							<string>XCProjectFormatConflictsModule</string>
+							<key>Proportion</key>
+							<string>100%</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>100%</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>Project Format Conflicts</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>XCProjectFormatConflictsModule</string>
+			</array>
+			<key>StatusbarIsVisible</key>
+			<integer>0</integer>
+			<key>WindowContentMinSize</key>
+			<string>450 300</string>
+			<key>WindowString</key>
+			<string>50 850 472 307 0 0 1440 877</string>
+		</dict>
+		<dict>
+			<key>Identifier</key>
+			<string>windowTool.classBrowser</string>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>BecomeActive</key>
+							<integer>1</integer>
+							<key>ContentConfiguration</key>
+							<dict>
+								<key>OptionsSetName</key>
+								<string>Hierarchy, all classes</string>
+								<key>PBXProjectModuleGUID</key>
+								<string>1CA6456E063B45B4001379D8</string>
+								<key>PBXProjectModuleLabel</key>
+								<string>Class Browser - NSObject</string>
+							</dict>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>ClassesFrame</key>
+								<string>{{0, 0}, {369, 96}}</string>
+								<key>ClassesTreeTableConfiguration</key>
+								<array>
+									<string>PBXClassNameColumnIdentifier</string>
+									<real>208</real>
+									<string>PBXClassBookColumnIdentifier</string>
+									<real>22</real>
+								</array>
+								<key>Frame</key>
+								<string>{{0, 0}, {616, 353}}</string>
+								<key>MembersFrame</key>
+								<string>{{0, 105}, {369, 395}}</string>
+								<key>MembersTreeTableConfiguration</key>
+								<array>
+									<string>PBXMemberTypeIconColumnIdentifier</string>
+									<real>22</real>
+									<string>PBXMemberNameColumnIdentifier</string>
+									<real>216</real>
+									<string>PBXMemberTypeColumnIdentifier</string>
+									<real>94</real>
+									<string>PBXMemberBookColumnIdentifier</string>
+									<real>22</real>
+								</array>
+								<key>PBXModuleWindowStatusBarHidden2</key>
+								<integer>1</integer>
+								<key>RubberWindowFrame</key>
+								<string>597 125 616 374 0 0 1280 1002 </string>
+							</dict>
+							<key>Module</key>
+							<string>PBXClassBrowserModule</string>
+							<key>Proportion</key>
+							<string>354pt</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>354pt</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>Class Browser</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>PBXClassBrowserModule</string>
+			</array>
+			<key>StatusbarIsVisible</key>
+			<integer>0</integer>
+			<key>TableOfContents</key>
+			<array>
+				<string>1C78EABA065D492600B07095</string>
+				<string>1C78EABB065D492600B07095</string>
+				<string>1CA6456E063B45B4001379D8</string>
+			</array>
+			<key>ToolbarConfiguration</key>
+			<string>xcode.toolbar.config.classbrowser</string>
+			<key>WindowString</key>
+			<string>597 125 616 374 0 0 1280 1002 </string>
+		</dict>
+		<dict>
+			<key>Identifier</key>
+			<string>windowTool.refactoring</string>
+			<key>IncludeInToolsMenu</key>
+			<integer>0</integer>
+			<key>Layout</key>
+			<array>
+				<dict>
+					<key>Dock</key>
+					<array>
+						<dict>
+							<key>BecomeActive</key>
+							<integer>1</integer>
+							<key>GeometryConfiguration</key>
+							<dict>
+								<key>Frame</key>
+								<string>{0, 0}, {500, 335}</string>
+								<key>RubberWindowFrame</key>
+								<string>{0, 0}, {500, 335}</string>
+							</dict>
+							<key>Module</key>
+							<string>XCRefactoringModule</string>
+							<key>Proportion</key>
+							<string>100%</string>
+						</dict>
+					</array>
+					<key>Proportion</key>
+					<string>100%</string>
+				</dict>
+			</array>
+			<key>Name</key>
+			<string>Refactoring</string>
+			<key>ServiceClasses</key>
+			<array>
+				<string>XCRefactoringModule</string>
+			</array>
+			<key>WindowString</key>
+			<string>200 200 500 356 0 0 1920 1200 </string>
+		</dict>
+	</array>
+</dict>
+</plist>
diff --git a/osx/openvpn.xcodeproj/project.pbxproj b/osx/openvpn.xcodeproj/project.pbxproj
new file mode 100755
index 0000000..56b86c8
--- /dev/null
+++ b/osx/openvpn.xcodeproj/project.pbxproj
@@ -0,0 +1,619 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 45;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		D35B8BC6114490D800A7F080 /* base64.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B4B114490D800A7F080 /* base64.c */; };
+		D35B8BC7114490D800A7F080 /* buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B4E114490D800A7F080 /* buffer.c */; };
+		D35B8BC8114490D800A7F080 /* crypto.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B53114490D800A7F080 /* crypto.c */; };
+		D35B8BC9114490D800A7F080 /* dhcp.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B55114490D800A7F080 /* dhcp.c */; };
+		D35B8BCA114490D800A7F080 /* error.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B58114490D800A7F080 /* error.c */; };
+		D35B8BCB114490D800A7F080 /* event.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B5A114490D800A7F080 /* event.c */; };
+		D35B8BCC114490D800A7F080 /* fdmisc.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B5C114490D800A7F080 /* fdmisc.c */; };
+		D35B8BCD114490D800A7F080 /* forward.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B5F114490D800A7F080 /* forward.c */; };
+		D35B8BCE114490D800A7F080 /* fragment.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B61114490D800A7F080 /* fragment.c */; };
+		D35B8BCF114490D800A7F080 /* gremlin.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B63114490D800A7F080 /* gremlin.c */; };
+		D35B8BD0114490D800A7F080 /* helper.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B65114490D800A7F080 /* helper.c */; };
+		D35B8BD1114490D800A7F080 /* ieproxy.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B67114490D800A7F080 /* ieproxy.c */; };
+		D35B8BD2114490D800A7F080 /* init.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B69114490D800A7F080 /* init.c */; };
+		D35B8BD3114490D800A7F080 /* interval.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B6C114490D800A7F080 /* interval.c */; };
+		D35B8BD4114490D800A7F080 /* list.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B6E114490D800A7F080 /* list.c */; };
+		D35B8BD5114490D800A7F080 /* lladdr.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B70114490D800A7F080 /* lladdr.c */; };
+		D35B8BD6114490D800A7F080 /* lzo.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B72114490D800A7F080 /* lzo.c */; };
+		D35B8BD7114490D800A7F080 /* manage.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B74114490D800A7F080 /* manage.c */; };
+		D35B8BD8114490D800A7F080 /* mbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B76114490D800A7F080 /* mbuf.c */; };
+		D35B8BD9114490D800A7F080 /* memcmp.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B78114490D800A7F080 /* memcmp.c */; };
+		D35B8BDA114490D800A7F080 /* misc.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B7A114490D800A7F080 /* misc.c */; };
+		D35B8BDB114490D800A7F080 /* mroute.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B7C114490D800A7F080 /* mroute.c */; };
+		D35B8BDC114490D800A7F080 /* mss.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B7E114490D800A7F080 /* mss.c */; };
+		D35B8BDD114490D800A7F080 /* mtcp.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B80114490D800A7F080 /* mtcp.c */; };
+		D35B8BDE114490D800A7F080 /* mtu.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B82114490D800A7F080 /* mtu.c */; };
+		D35B8BDF114490D800A7F080 /* mudp.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B84114490D800A7F080 /* mudp.c */; };
+		D35B8BE0114490D800A7F080 /* multi.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B86114490D800A7F080 /* multi.c */; };
+		D35B8BE1114490D800A7F080 /* ntlm.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B88114490D800A7F080 /* ntlm.c */; };
+		D35B8BE2114490D800A7F080 /* occ.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B8B114490D800A7F080 /* occ.c */; };
+		D35B8BE3114490D800A7F080 /* openvpn.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B8E114490D800A7F080 /* openvpn.c */; };
+		D35B8BE4114490D800A7F080 /* options.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B90114490D800A7F080 /* options.c */; };
+		D35B8BE5114490D800A7F080 /* otime.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B92114490D800A7F080 /* otime.c */; };
+		D35B8BE6114490D800A7F080 /* packet_id.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B94114490D800A7F080 /* packet_id.c */; };
+		D35B8BE7114490D800A7F080 /* perf.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B96114490D800A7F080 /* perf.c */; };
+		D35B8BE8114490D800A7F080 /* pf.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B99114490D800A7F080 /* pf.c */; };
+		D35B8BE9114490D800A7F080 /* ping.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B9C114490D800A7F080 /* ping.c */; };
+		D35B8BEA114490D800A7F080 /* pkcs11.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8B9E114490D800A7F080 /* pkcs11.c */; };
+		D35B8BEB114490D800A7F080 /* plugin.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8BA0114490D800A7F080 /* plugin.c */; };
+		D35B8BEC114490D800A7F080 /* pool.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8BA2114490D800A7F080 /* pool.c */; };
+		D35B8BED114490D800A7F080 /* proto.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8BA4114490D800A7F080 /* proto.c */; };
+		D35B8BEE114490D800A7F080 /* proxy.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8BA6114490D800A7F080 /* proxy.c */; };
+		D35B8BEF114490D800A7F080 /* ps.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8BA8114490D800A7F080 /* ps.c */; };
+		D35B8BF0114490D800A7F080 /* push.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8BAA114490D800A7F080 /* push.c */; };
+		D35B8BF1114490D800A7F080 /* reliable.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8BAD114490D800A7F080 /* reliable.c */; };
+		D35B8BF2114490D800A7F080 /* route.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8BAF114490D800A7F080 /* route.c */; };
+		D35B8BF3114490D800A7F080 /* schedule.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8BB1114490D800A7F080 /* schedule.c */; };
+		D35B8BF4114490D800A7F080 /* session_id.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8BB3114490D800A7F080 /* session_id.c */; };
+		D35B8BF5114490D800A7F080 /* shaper.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8BB5114490D800A7F080 /* shaper.c */; };
+		D35B8BF6114490D800A7F080 /* sig.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8BB7114490D800A7F080 /* sig.c */; };
+		D35B8BF7114490D800A7F080 /* socket.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8BB9114490D800A7F080 /* socket.c */; };
+		D35B8BF8114490D800A7F080 /* socks.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8BBB114490D800A7F080 /* socks.c */; };
+		D35B8BF9114490D800A7F080 /* ssl.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8BBD114490D800A7F080 /* ssl.c */; };
+		D35B8BFA114490D800A7F080 /* status.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8BBF114490D800A7F080 /* status.c */; };
+		D35B8BFB114490D800A7F080 /* thread.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8BC2114490D800A7F080 /* thread.c */; };
+		D35B8BFC114490D800A7F080 /* tun.c in Sources */ = {isa = PBXBuildFile; fileRef = D35B8BC4114490D800A7F080 /* tun.c */; };
+		D3BBF5AF114C6AF700311166 /* cert_data.c in Sources */ = {isa = PBXBuildFile; fileRef = D3BBF5A9114C6AF700311166 /* cert_data.c */; };
+		D3BBF5B0114C6AF700311166 /* common_osx.c in Sources */ = {isa = PBXBuildFile; fileRef = D3BBF5AB114C6AF700311166 /* common_osx.c */; };
+		D3BBF5B1114C6AF700311166 /* crypto_osx.c in Sources */ = {isa = PBXBuildFile; fileRef = D3BBF5AD114C6AF700311166 /* crypto_osx.c */; };
+		D3BBF5B7114C6B9F00311166 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D3BBF5B6114C6B9F00311166 /* Security.framework */; };
+		D3BBF5BB114C6BAE00311166 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D3BBF5BA114C6BAE00311166 /* CoreFoundation.framework */; };
+		D3BBF5C4114C738A00311166 /* keychain.c in Sources */ = {isa = PBXBuildFile; fileRef = D3BBF5C2114C738A00311166 /* keychain.c */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+		8DD76FAF0486AB0100D96B5E /* CopyFiles */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 8;
+			dstPath = /usr/share/man/man1/;
+			dstSubfolderSpec = 0;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 1;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+		8DD76FB20486AB0100D96B5E /* openvpn */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = openvpn; sourceTree = BUILT_PRODUCTS_DIR; };
+		D35B8B4B114490D800A7F080 /* base64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = base64.c; path = ../base64.c; sourceTree = SOURCE_ROOT; };
+		D35B8B4C114490D800A7F080 /* base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = base64.h; path = ../base64.h; sourceTree = SOURCE_ROOT; };
+		D35B8B4D114490D800A7F080 /* basic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = basic.h; path = ../basic.h; sourceTree = SOURCE_ROOT; };
+		D35B8B4E114490D800A7F080 /* buffer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = buffer.c; path = ../buffer.c; sourceTree = SOURCE_ROOT; };
+		D35B8B4F114490D800A7F080 /* buffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = buffer.h; path = ../buffer.h; sourceTree = SOURCE_ROOT; };
+		D35B8B50114490D800A7F080 /* circ_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = circ_list.h; path = ../circ_list.h; sourceTree = SOURCE_ROOT; };
+		D35B8B51114490D800A7F080 /* common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = common.h; path = ../common.h; sourceTree = SOURCE_ROOT; };
+		D35B8B52114490D800A7F080 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = config.h; path = ../config.h; sourceTree = SOURCE_ROOT; };
+		D35B8B53114490D800A7F080 /* crypto.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = crypto.c; path = ../crypto.c; sourceTree = SOURCE_ROOT; };
+		D35B8B54114490D800A7F080 /* crypto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = crypto.h; path = ../crypto.h; sourceTree = SOURCE_ROOT; };
+		D35B8B55114490D800A7F080 /* dhcp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = dhcp.c; path = ../dhcp.c; sourceTree = SOURCE_ROOT; };
+		D35B8B56114490D800A7F080 /* dhcp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = dhcp.h; path = ../dhcp.h; sourceTree = SOURCE_ROOT; };
+		D35B8B57114490D800A7F080 /* errlevel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = errlevel.h; path = ../errlevel.h; sourceTree = SOURCE_ROOT; };
+		D35B8B58114490D800A7F080 /* error.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = error.c; path = ../error.c; sourceTree = SOURCE_ROOT; };
+		D35B8B59114490D800A7F080 /* error.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = error.h; path = ../error.h; sourceTree = SOURCE_ROOT; };
+		D35B8B5A114490D800A7F080 /* event.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = event.c; path = ../event.c; sourceTree = SOURCE_ROOT; };
+		D35B8B5B114490D800A7F080 /* event.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = event.h; path = ../event.h; sourceTree = SOURCE_ROOT; };
+		D35B8B5C114490D800A7F080 /* fdmisc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = fdmisc.c; path = ../fdmisc.c; sourceTree = SOURCE_ROOT; };
+		D35B8B5D114490D800A7F080 /* fdmisc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fdmisc.h; path = ../fdmisc.h; sourceTree = SOURCE_ROOT; };
+		D35B8B5E114490D800A7F080 /* forward-inline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "forward-inline.h"; path = "../forward-inline.h"; sourceTree = SOURCE_ROOT; };
+		D35B8B5F114490D800A7F080 /* forward.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = forward.c; path = ../forward.c; sourceTree = SOURCE_ROOT; };
+		D35B8B60114490D800A7F080 /* forward.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = forward.h; path = ../forward.h; sourceTree = SOURCE_ROOT; };
+		D35B8B61114490D800A7F080 /* fragment.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = fragment.c; path = ../fragment.c; sourceTree = SOURCE_ROOT; };
+		D35B8B62114490D800A7F080 /* fragment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fragment.h; path = ../fragment.h; sourceTree = SOURCE_ROOT; };
+		D35B8B63114490D800A7F080 /* gremlin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = gremlin.c; path = ../gremlin.c; sourceTree = SOURCE_ROOT; };
+		D35B8B64114490D800A7F080 /* gremlin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = gremlin.h; path = ../gremlin.h; sourceTree = SOURCE_ROOT; };
+		D35B8B65114490D800A7F080 /* helper.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = helper.c; path = ../helper.c; sourceTree = SOURCE_ROOT; };
+		D35B8B66114490D800A7F080 /* helper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = helper.h; path = ../helper.h; sourceTree = SOURCE_ROOT; };
+		D35B8B67114490D800A7F080 /* ieproxy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ieproxy.c; path = ../ieproxy.c; sourceTree = SOURCE_ROOT; };
+		D35B8B68114490D800A7F080 /* ieproxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ieproxy.h; path = ../ieproxy.h; sourceTree = SOURCE_ROOT; };
+		D35B8B69114490D800A7F080 /* init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = init.c; path = ../init.c; sourceTree = SOURCE_ROOT; };
+		D35B8B6A114490D800A7F080 /* init.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = init.h; path = ../init.h; sourceTree = SOURCE_ROOT; };
+		D35B8B6B114490D800A7F080 /* integer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = integer.h; path = ../integer.h; sourceTree = SOURCE_ROOT; };
+		D35B8B6C114490D800A7F080 /* interval.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = interval.c; path = ../interval.c; sourceTree = SOURCE_ROOT; };
+		D35B8B6D114490D800A7F080 /* interval.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = interval.h; path = ../interval.h; sourceTree = SOURCE_ROOT; };
+		D35B8B6E114490D800A7F080 /* list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = list.c; path = ../list.c; sourceTree = SOURCE_ROOT; };
+		D35B8B6F114490D800A7F080 /* list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = list.h; path = ../list.h; sourceTree = SOURCE_ROOT; };
+		D35B8B70114490D800A7F080 /* lladdr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lladdr.c; path = ../lladdr.c; sourceTree = SOURCE_ROOT; };
+		D35B8B71114490D800A7F080 /* lladdr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lladdr.h; path = ../lladdr.h; sourceTree = SOURCE_ROOT; };
+		D35B8B72114490D800A7F080 /* lzo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = lzo.c; path = ../lzo.c; sourceTree = SOURCE_ROOT; };
+		D35B8B73114490D800A7F080 /* lzo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = lzo.h; path = ../lzo.h; sourceTree = SOURCE_ROOT; };
+		D35B8B74114490D800A7F080 /* manage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = manage.c; path = ../manage.c; sourceTree = SOURCE_ROOT; };
+		D35B8B75114490D800A7F080 /* manage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = manage.h; path = ../manage.h; sourceTree = SOURCE_ROOT; };
+		D35B8B76114490D800A7F080 /* mbuf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mbuf.c; path = ../mbuf.c; sourceTree = SOURCE_ROOT; };
+		D35B8B77114490D800A7F080 /* mbuf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mbuf.h; path = ../mbuf.h; sourceTree = SOURCE_ROOT; };
+		D35B8B78114490D800A7F080 /* memcmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = memcmp.c; path = ../memcmp.c; sourceTree = SOURCE_ROOT; };
+		D35B8B79114490D800A7F080 /* memdbg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = memdbg.h; path = ../memdbg.h; sourceTree = SOURCE_ROOT; };
+		D35B8B7A114490D800A7F080 /* misc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = misc.c; path = ../misc.c; sourceTree = SOURCE_ROOT; };
+		D35B8B7B114490D800A7F080 /* misc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = misc.h; path = ../misc.h; sourceTree = SOURCE_ROOT; };
+		D35B8B7C114490D800A7F080 /* mroute.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mroute.c; path = ../mroute.c; sourceTree = SOURCE_ROOT; };
+		D35B8B7D114490D800A7F080 /* mroute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mroute.h; path = ../mroute.h; sourceTree = SOURCE_ROOT; };
+		D35B8B7E114490D800A7F080 /* mss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mss.c; path = ../mss.c; sourceTree = SOURCE_ROOT; };
+		D35B8B7F114490D800A7F080 /* mss.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mss.h; path = ../mss.h; sourceTree = SOURCE_ROOT; };
+		D35B8B80114490D800A7F080 /* mtcp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mtcp.c; path = ../mtcp.c; sourceTree = SOURCE_ROOT; };
+		D35B8B81114490D800A7F080 /* mtcp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mtcp.h; path = ../mtcp.h; sourceTree = SOURCE_ROOT; };
+		D35B8B82114490D800A7F080 /* mtu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mtu.c; path = ../mtu.c; sourceTree = SOURCE_ROOT; };
+		D35B8B83114490D800A7F080 /* mtu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mtu.h; path = ../mtu.h; sourceTree = SOURCE_ROOT; };
+		D35B8B84114490D800A7F080 /* mudp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = mudp.c; path = ../mudp.c; sourceTree = SOURCE_ROOT; };
+		D35B8B85114490D800A7F080 /* mudp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = mudp.h; path = ../mudp.h; sourceTree = SOURCE_ROOT; };
+		D35B8B86114490D800A7F080 /* multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = multi.c; path = ../multi.c; sourceTree = SOURCE_ROOT; };
+		D35B8B87114490D800A7F080 /* multi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = multi.h; path = ../multi.h; sourceTree = SOURCE_ROOT; };
+		D35B8B88114490D800A7F080 /* ntlm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ntlm.c; path = ../ntlm.c; sourceTree = SOURCE_ROOT; };
+		D35B8B89114490D800A7F080 /* ntlm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ntlm.h; path = ../ntlm.h; sourceTree = SOURCE_ROOT; };
+		D35B8B8A114490D800A7F080 /* occ-inline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "occ-inline.h"; path = "../occ-inline.h"; sourceTree = SOURCE_ROOT; };
+		D35B8B8B114490D800A7F080 /* occ.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = occ.c; path = ../occ.c; sourceTree = SOURCE_ROOT; };
+		D35B8B8C114490D800A7F080 /* occ.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = occ.h; path = ../occ.h; sourceTree = SOURCE_ROOT; };
+		D35B8B8D114490D800A7F080 /* openvpn-plugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "openvpn-plugin.h"; path = "../openvpn-plugin.h"; sourceTree = SOURCE_ROOT; };
+		D35B8B8E114490D800A7F080 /* openvpn.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = openvpn.c; path = ../openvpn.c; sourceTree = SOURCE_ROOT; };
+		D35B8B8F114490D800A7F080 /* openvpn.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = openvpn.h; path = ../openvpn.h; sourceTree = SOURCE_ROOT; };
+		D35B8B90114490D800A7F080 /* options.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = options.c; path = ../options.c; sourceTree = SOURCE_ROOT; };
+		D35B8B91114490D800A7F080 /* options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = options.h; path = ../options.h; sourceTree = SOURCE_ROOT; };
+		D35B8B92114490D800A7F080 /* otime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = otime.c; path = ../otime.c; sourceTree = SOURCE_ROOT; };
+		D35B8B93114490D800A7F080 /* otime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = otime.h; path = ../otime.h; sourceTree = SOURCE_ROOT; };
+		D35B8B94114490D800A7F080 /* packet_id.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = packet_id.c; path = ../packet_id.c; sourceTree = SOURCE_ROOT; };
+		D35B8B95114490D800A7F080 /* packet_id.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = packet_id.h; path = ../packet_id.h; sourceTree = SOURCE_ROOT; };
+		D35B8B96114490D800A7F080 /* perf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = perf.c; path = ../perf.c; sourceTree = SOURCE_ROOT; };
+		D35B8B97114490D800A7F080 /* perf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = perf.h; path = ../perf.h; sourceTree = SOURCE_ROOT; };
+		D35B8B98114490D800A7F080 /* pf-inline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "pf-inline.h"; path = "../pf-inline.h"; sourceTree = SOURCE_ROOT; };
+		D35B8B99114490D800A7F080 /* pf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pf.c; path = ../pf.c; sourceTree = SOURCE_ROOT; };
+		D35B8B9A114490D800A7F080 /* pf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pf.h; path = ../pf.h; sourceTree = SOURCE_ROOT; };
+		D35B8B9B114490D800A7F080 /* ping-inline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "ping-inline.h"; path = "../ping-inline.h"; sourceTree = SOURCE_ROOT; };
+		D35B8B9C114490D800A7F080 /* ping.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ping.c; path = ../ping.c; sourceTree = SOURCE_ROOT; };
+		D35B8B9D114490D800A7F080 /* ping.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ping.h; path = ../ping.h; sourceTree = SOURCE_ROOT; };
+		D35B8B9E114490D800A7F080 /* pkcs11.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pkcs11.c; path = ../pkcs11.c; sourceTree = SOURCE_ROOT; };
+		D35B8B9F114490D800A7F080 /* pkcs11.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pkcs11.h; path = ../pkcs11.h; sourceTree = SOURCE_ROOT; };
+		D35B8BA0114490D800A7F080 /* plugin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = plugin.c; path = ../plugin.c; sourceTree = SOURCE_ROOT; };
+		D35B8BA1114490D800A7F080 /* plugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = plugin.h; path = ../plugin.h; sourceTree = SOURCE_ROOT; };
+		D35B8BA2114490D800A7F080 /* pool.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pool.c; path = ../pool.c; sourceTree = SOURCE_ROOT; };
+		D35B8BA3114490D800A7F080 /* pool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pool.h; path = ../pool.h; sourceTree = SOURCE_ROOT; };
+		D35B8BA4114490D800A7F080 /* proto.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = proto.c; path = ../proto.c; sourceTree = SOURCE_ROOT; };
+		D35B8BA5114490D800A7F080 /* proto.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = proto.h; path = ../proto.h; sourceTree = SOURCE_ROOT; };
+		D35B8BA6114490D800A7F080 /* proxy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = proxy.c; path = ../proxy.c; sourceTree = SOURCE_ROOT; };
+		D35B8BA7114490D800A7F080 /* proxy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = proxy.h; path = ../proxy.h; sourceTree = SOURCE_ROOT; };
+		D35B8BA8114490D800A7F080 /* ps.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ps.c; path = ../ps.c; sourceTree = SOURCE_ROOT; };
+		D35B8BA9114490D800A7F080 /* ps.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ps.h; path = ../ps.h; sourceTree = SOURCE_ROOT; };
+		D35B8BAA114490D800A7F080 /* push.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = push.c; path = ../push.c; sourceTree = SOURCE_ROOT; };
+		D35B8BAB114490D800A7F080 /* push.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = push.h; path = ../push.h; sourceTree = SOURCE_ROOT; };
+		D35B8BAC114490D800A7F080 /* pushlist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pushlist.h; path = ../pushlist.h; sourceTree = SOURCE_ROOT; };
+		D35B8BAD114490D800A7F080 /* reliable.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = reliable.c; path = ../reliable.c; sourceTree = SOURCE_ROOT; };
+		D35B8BAE114490D800A7F080 /* reliable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = reliable.h; path = ../reliable.h; sourceTree = SOURCE_ROOT; };
+		D35B8BAF114490D800A7F080 /* route.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = route.c; path = ../route.c; sourceTree = SOURCE_ROOT; };
+		D35B8BB0114490D800A7F080 /* route.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = route.h; path = ../route.h; sourceTree = SOURCE_ROOT; };
+		D35B8BB1114490D800A7F080 /* schedule.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = schedule.c; path = ../schedule.c; sourceTree = SOURCE_ROOT; };
+		D35B8BB2114490D800A7F080 /* schedule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = schedule.h; path = ../schedule.h; sourceTree = SOURCE_ROOT; };
+		D35B8BB3114490D800A7F080 /* session_id.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = session_id.c; path = ../session_id.c; sourceTree = SOURCE_ROOT; };
+		D35B8BB4114490D800A7F080 /* session_id.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = session_id.h; path = ../session_id.h; sourceTree = SOURCE_ROOT; };
+		D35B8BB5114490D800A7F080 /* shaper.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = shaper.c; path = ../shaper.c; sourceTree = SOURCE_ROOT; };
+		D35B8BB6114490D800A7F080 /* shaper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = shaper.h; path = ../shaper.h; sourceTree = SOURCE_ROOT; };
+		D35B8BB7114490D800A7F080 /* sig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sig.c; path = ../sig.c; sourceTree = SOURCE_ROOT; };
+		D35B8BB8114490D800A7F080 /* sig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sig.h; path = ../sig.h; sourceTree = SOURCE_ROOT; };
+		D35B8BB9114490D800A7F080 /* socket.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = socket.c; path = ../socket.c; sourceTree = SOURCE_ROOT; };
+		D35B8BBA114490D800A7F080 /* socket.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = socket.h; path = ../socket.h; sourceTree = SOURCE_ROOT; };
+		D35B8BBB114490D800A7F080 /* socks.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = socks.c; path = ../socks.c; sourceTree = SOURCE_ROOT; };
+		D35B8BBC114490D800A7F080 /* socks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = socks.h; path = ../socks.h; sourceTree = SOURCE_ROOT; };
+		D35B8BBD114490D800A7F080 /* ssl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ssl.c; path = ../ssl.c; sourceTree = SOURCE_ROOT; };
+		D35B8BBE114490D800A7F080 /* ssl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ssl.h; path = ../ssl.h; sourceTree = SOURCE_ROOT; };
+		D35B8BBF114490D800A7F080 /* status.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = status.c; path = ../status.c; sourceTree = SOURCE_ROOT; };
+		D35B8BC0114490D800A7F080 /* status.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = status.h; path = ../status.h; sourceTree = SOURCE_ROOT; };
+		D35B8BC1114490D800A7F080 /* syshead.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = syshead.h; path = ../syshead.h; sourceTree = SOURCE_ROOT; };
+		D35B8BC2114490D800A7F080 /* thread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = thread.c; path = ../thread.c; sourceTree = SOURCE_ROOT; };
+		D35B8BC3114490D800A7F080 /* thread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = thread.h; path = ../thread.h; sourceTree = SOURCE_ROOT; };
+		D35B8BC4114490D800A7F080 /* tun.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tun.c; path = ../tun.c; sourceTree = SOURCE_ROOT; };
+		D35B8BC5114490D800A7F080 /* tun.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tun.h; path = ../tun.h; sourceTree = SOURCE_ROOT; };
+		D3BBF5A9114C6AF700311166 /* cert_data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cert_data.c; sourceTree = "<group>"; };
+		D3BBF5AA114C6AF700311166 /* cert_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cert_data.h; sourceTree = "<group>"; };
+		D3BBF5AB114C6AF700311166 /* common_osx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = common_osx.c; sourceTree = "<group>"; };
+		D3BBF5AC114C6AF700311166 /* common_osx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = common_osx.h; sourceTree = "<group>"; };
+		D3BBF5AD114C6AF700311166 /* crypto_osx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = crypto_osx.c; sourceTree = "<group>"; };
+		D3BBF5AE114C6AF700311166 /* crypto_osx.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = crypto_osx.h; sourceTree = "<group>"; };
+		D3BBF5B6114C6B9F00311166 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
+		D3BBF5BA114C6BAE00311166 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; };
+		D3BBF5C2114C738A00311166 /* keychain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = keychain.c; sourceTree = "<group>"; };
+		D3BBF5C3114C738A00311166 /* keychain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = keychain.h; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		8DD76FAD0486AB0100D96B5E /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				D3BBF5B7114C6B9F00311166 /* Security.framework in Frameworks */,
+				D3BBF5BB114C6BAE00311166 /* CoreFoundation.framework in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		08FB7794FE84155DC02AAC07 /* openvpn */ = {
+			isa = PBXGroup;
+			children = (
+				D3BBF5A8114C6A6A00311166 /* osx */,
+				08FB7795FE84155DC02AAC07 /* Source */,
+				C6A0FF2B0290797F04C91782 /* Documentation */,
+				1AB674ADFE9D54B511CA2CBB /* Products */,
+				D3BBF5B6114C6B9F00311166 /* Security.framework */,
+				D3BBF5BA114C6BAE00311166 /* CoreFoundation.framework */,
+			);
+			name = openvpn;
+			sourceTree = "<group>";
+		};
+		08FB7795FE84155DC02AAC07 /* Source */ = {
+			isa = PBXGroup;
+			children = (
+				D35B8B4B114490D800A7F080 /* base64.c */,
+				D35B8B4C114490D800A7F080 /* base64.h */,
+				D35B8B4D114490D800A7F080 /* basic.h */,
+				D35B8B4E114490D800A7F080 /* buffer.c */,
+				D35B8B4F114490D800A7F080 /* buffer.h */,
+				D35B8B50114490D800A7F080 /* circ_list.h */,
+				D35B8B51114490D800A7F080 /* common.h */,
+				D35B8B52114490D800A7F080 /* config.h */,
+				D35B8B53114490D800A7F080 /* crypto.c */,
+				D35B8B54114490D800A7F080 /* crypto.h */,
+				D35B8B55114490D800A7F080 /* dhcp.c */,
+				D35B8B56114490D800A7F080 /* dhcp.h */,
+				D35B8B57114490D800A7F080 /* errlevel.h */,
+				D35B8B58114490D800A7F080 /* error.c */,
+				D35B8B59114490D800A7F080 /* error.h */,
+				D35B8B5A114490D800A7F080 /* event.c */,
+				D35B8B5B114490D800A7F080 /* event.h */,
+				D35B8B5C114490D800A7F080 /* fdmisc.c */,
+				D35B8B5D114490D800A7F080 /* fdmisc.h */,
+				D35B8B5E114490D800A7F080 /* forward-inline.h */,
+				D35B8B5F114490D800A7F080 /* forward.c */,
+				D35B8B60114490D800A7F080 /* forward.h */,
+				D35B8B61114490D800A7F080 /* fragment.c */,
+				D35B8B62114490D800A7F080 /* fragment.h */,
+				D35B8B63114490D800A7F080 /* gremlin.c */,
+				D35B8B64114490D800A7F080 /* gremlin.h */,
+				D35B8B65114490D800A7F080 /* helper.c */,
+				D35B8B66114490D800A7F080 /* helper.h */,
+				D35B8B67114490D800A7F080 /* ieproxy.c */,
+				D35B8B68114490D800A7F080 /* ieproxy.h */,
+				D35B8B69114490D800A7F080 /* init.c */,
+				D35B8B6A114490D800A7F080 /* init.h */,
+				D35B8B6B114490D800A7F080 /* integer.h */,
+				D35B8B6C114490D800A7F080 /* interval.c */,
+				D35B8B6D114490D800A7F080 /* interval.h */,
+				D35B8B6E114490D800A7F080 /* list.c */,
+				D35B8B6F114490D800A7F080 /* list.h */,
+				D35B8B70114490D800A7F080 /* lladdr.c */,
+				D35B8B71114490D800A7F080 /* lladdr.h */,
+				D35B8B72114490D800A7F080 /* lzo.c */,
+				D35B8B73114490D800A7F080 /* lzo.h */,
+				D35B8B74114490D800A7F080 /* manage.c */,
+				D35B8B75114490D800A7F080 /* manage.h */,
+				D35B8B76114490D800A7F080 /* mbuf.c */,
+				D35B8B77114490D800A7F080 /* mbuf.h */,
+				D35B8B78114490D800A7F080 /* memcmp.c */,
+				D35B8B79114490D800A7F080 /* memdbg.h */,
+				D35B8B7A114490D800A7F080 /* misc.c */,
+				D35B8B7B114490D800A7F080 /* misc.h */,
+				D35B8B7C114490D800A7F080 /* mroute.c */,
+				D35B8B7D114490D800A7F080 /* mroute.h */,
+				D35B8B7E114490D800A7F080 /* mss.c */,
+				D35B8B7F114490D800A7F080 /* mss.h */,
+				D35B8B80114490D800A7F080 /* mtcp.c */,
+				D35B8B81114490D800A7F080 /* mtcp.h */,
+				D35B8B82114490D800A7F080 /* mtu.c */,
+				D35B8B83114490D800A7F080 /* mtu.h */,
+				D35B8B84114490D800A7F080 /* mudp.c */,
+				D35B8B85114490D800A7F080 /* mudp.h */,
+				D35B8B86114490D800A7F080 /* multi.c */,
+				D35B8B87114490D800A7F080 /* multi.h */,
+				D35B8B88114490D800A7F080 /* ntlm.c */,
+				D35B8B89114490D800A7F080 /* ntlm.h */,
+				D35B8B8A114490D800A7F080 /* occ-inline.h */,
+				D35B8B8B114490D800A7F080 /* occ.c */,
+				D35B8B8C114490D800A7F080 /* occ.h */,
+				D35B8B8D114490D800A7F080 /* openvpn-plugin.h */,
+				D35B8B8E114490D800A7F080 /* openvpn.c */,
+				D35B8B8F114490D800A7F080 /* openvpn.h */,
+				D35B8B90114490D800A7F080 /* options.c */,
+				D35B8B91114490D800A7F080 /* options.h */,
+				D35B8B92114490D800A7F080 /* otime.c */,
+				D35B8B93114490D800A7F080 /* otime.h */,
+				D35B8B94114490D800A7F080 /* packet_id.c */,
+				D35B8B95114490D800A7F080 /* packet_id.h */,
+				D35B8B96114490D800A7F080 /* perf.c */,
+				D35B8B97114490D800A7F080 /* perf.h */,
+				D35B8B98114490D800A7F080 /* pf-inline.h */,
+				D35B8B99114490D800A7F080 /* pf.c */,
+				D35B8B9A114490D800A7F080 /* pf.h */,
+				D35B8B9B114490D800A7F080 /* ping-inline.h */,
+				D35B8B9C114490D800A7F080 /* ping.c */,
+				D35B8B9D114490D800A7F080 /* ping.h */,
+				D35B8B9E114490D800A7F080 /* pkcs11.c */,
+				D35B8B9F114490D800A7F080 /* pkcs11.h */,
+				D35B8BA0114490D800A7F080 /* plugin.c */,
+				D35B8BA1114490D800A7F080 /* plugin.h */,
+				D35B8BA2114490D800A7F080 /* pool.c */,
+				D35B8BA3114490D800A7F080 /* pool.h */,
+				D35B8BA4114490D800A7F080 /* proto.c */,
+				D35B8BA5114490D800A7F080 /* proto.h */,
+				D35B8BA6114490D800A7F080 /* proxy.c */,
+				D35B8BA7114490D800A7F080 /* proxy.h */,
+				D35B8BA8114490D800A7F080 /* ps.c */,
+				D35B8BA9114490D800A7F080 /* ps.h */,
+				D35B8BAA114490D800A7F080 /* push.c */,
+				D35B8BAB114490D800A7F080 /* push.h */,
+				D35B8BAC114490D800A7F080 /* pushlist.h */,
+				D35B8BAD114490D800A7F080 /* reliable.c */,
+				D35B8BAE114490D800A7F080 /* reliable.h */,
+				D35B8BAF114490D800A7F080 /* route.c */,
+				D35B8BB0114490D800A7F080 /* route.h */,
+				D35B8BB1114490D800A7F080 /* schedule.c */,
+				D35B8BB2114490D800A7F080 /* schedule.h */,
+				D35B8BB3114490D800A7F080 /* session_id.c */,
+				D35B8BB4114490D800A7F080 /* session_id.h */,
+				D35B8BB5114490D800A7F080 /* shaper.c */,
+				D35B8BB6114490D800A7F080 /* shaper.h */,
+				D35B8BB7114490D800A7F080 /* sig.c */,
+				D35B8BB8114490D800A7F080 /* sig.h */,
+				D35B8BB9114490D800A7F080 /* socket.c */,
+				D35B8BBA114490D800A7F080 /* socket.h */,
+				D35B8BBB114490D800A7F080 /* socks.c */,
+				D35B8BBC114490D800A7F080 /* socks.h */,
+				D35B8BBD114490D800A7F080 /* ssl.c */,
+				D35B8BBE114490D800A7F080 /* ssl.h */,
+				D35B8BBF114490D800A7F080 /* status.c */,
+				D35B8BC0114490D800A7F080 /* status.h */,
+				D35B8BC1114490D800A7F080 /* syshead.h */,
+				D35B8BC2114490D800A7F080 /* thread.c */,
+				D35B8BC3114490D800A7F080 /* thread.h */,
+				D35B8BC4114490D800A7F080 /* tun.c */,
+				D35B8BC5114490D800A7F080 /* tun.h */,
+			);
+			name = Source;
+			sourceTree = "<group>";
+		};
+		1AB674ADFE9D54B511CA2CBB /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				8DD76FB20486AB0100D96B5E /* openvpn */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		C6A0FF2B0290797F04C91782 /* Documentation */ = {
+			isa = PBXGroup;
+			children = (
+			);
+			name = Documentation;
+			sourceTree = "<group>";
+		};
+		D3BBF5A8114C6A6A00311166 /* osx */ = {
+			isa = PBXGroup;
+			children = (
+				D3BBF5C2114C738A00311166 /* keychain.c */,
+				D3BBF5C3114C738A00311166 /* keychain.h */,
+				D3BBF5A9114C6AF700311166 /* cert_data.c */,
+				D3BBF5AA114C6AF700311166 /* cert_data.h */,
+				D3BBF5AB114C6AF700311166 /* common_osx.c */,
+				D3BBF5AC114C6AF700311166 /* common_osx.h */,
+				D3BBF5AD114C6AF700311166 /* crypto_osx.c */,
+				D3BBF5AE114C6AF700311166 /* crypto_osx.h */,
+			);
+			name = osx;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		8DD76FA90486AB0100D96B5E /* openvpn */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 1DEB928508733DD80010E9CD /* Build configuration list for PBXNativeTarget "openvpn" */;
+			buildPhases = (
+				8DD76FAB0486AB0100D96B5E /* Sources */,
+				8DD76FAD0486AB0100D96B5E /* Frameworks */,
+				8DD76FAF0486AB0100D96B5E /* CopyFiles */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = openvpn;
+			productInstallPath = "$(HOME)/bin";
+			productName = openvpn;
+			productReference = 8DD76FB20486AB0100D96B5E /* openvpn */;
+			productType = "com.apple.product-type.tool";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		08FB7793FE84155DC02AAC07 /* Project object */ = {
+			isa = PBXProject;
+			buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "openvpn" */;
+			compatibilityVersion = "Xcode 3.1";
+			hasScannedForEncodings = 1;
+			mainGroup = 08FB7794FE84155DC02AAC07 /* openvpn */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				8DD76FA90486AB0100D96B5E /* openvpn */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+		8DD76FAB0486AB0100D96B5E /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				D35B8BC6114490D800A7F080 /* base64.c in Sources */,
+				D35B8BC7114490D800A7F080 /* buffer.c in Sources */,
+				D35B8BC8114490D800A7F080 /* crypto.c in Sources */,
+				D35B8BC9114490D800A7F080 /* dhcp.c in Sources */,
+				D35B8BCA114490D800A7F080 /* error.c in Sources */,
+				D35B8BCB114490D800A7F080 /* event.c in Sources */,
+				D35B8BCC114490D800A7F080 /* fdmisc.c in Sources */,
+				D35B8BCD114490D800A7F080 /* forward.c in Sources */,
+				D35B8BCE114490D800A7F080 /* fragment.c in Sources */,
+				D35B8BCF114490D800A7F080 /* gremlin.c in Sources */,
+				D35B8BD0114490D800A7F080 /* helper.c in Sources */,
+				D35B8BD1114490D800A7F080 /* ieproxy.c in Sources */,
+				D35B8BD2114490D800A7F080 /* init.c in Sources */,
+				D35B8BD3114490D800A7F080 /* interval.c in Sources */,
+				D35B8BD4114490D800A7F080 /* list.c in Sources */,
+				D35B8BD5114490D800A7F080 /* lladdr.c in Sources */,
+				D35B8BD6114490D800A7F080 /* lzo.c in Sources */,
+				D35B8BD7114490D800A7F080 /* manage.c in Sources */,
+				D35B8BD8114490D800A7F080 /* mbuf.c in Sources */,
+				D35B8BD9114490D800A7F080 /* memcmp.c in Sources */,
+				D35B8BDA114490D800A7F080 /* misc.c in Sources */,
+				D35B8BDB114490D800A7F080 /* mroute.c in Sources */,
+				D35B8BDC114490D800A7F080 /* mss.c in Sources */,
+				D35B8BDD114490D800A7F080 /* mtcp.c in Sources */,
+				D35B8BDE114490D800A7F080 /* mtu.c in Sources */,
+				D35B8BDF114490D800A7F080 /* mudp.c in Sources */,
+				D35B8BE0114490D800A7F080 /* multi.c in Sources */,
+				D35B8BE1114490D800A7F080 /* ntlm.c in Sources */,
+				D35B8BE2114490D800A7F080 /* occ.c in Sources */,
+				D35B8BE3114490D800A7F080 /* openvpn.c in Sources */,
+				D35B8BE4114490D800A7F080 /* options.c in Sources */,
+				D35B8BE5114490D800A7F080 /* otime.c in Sources */,
+				D35B8BE6114490D800A7F080 /* packet_id.c in Sources */,
+				D35B8BE7114490D800A7F080 /* perf.c in Sources */,
+				D35B8BE8114490D800A7F080 /* pf.c in Sources */,
+				D35B8BE9114490D800A7F080 /* ping.c in Sources */,
+				D35B8BEA114490D800A7F080 /* pkcs11.c in Sources */,
+				D35B8BEB114490D800A7F080 /* plugin.c in Sources */,
+				D35B8BEC114490D800A7F080 /* pool.c in Sources */,
+				D35B8BED114490D800A7F080 /* proto.c in Sources */,
+				D35B8BEE114490D800A7F080 /* proxy.c in Sources */,
+				D35B8BEF114490D800A7F080 /* ps.c in Sources */,
+				D35B8BF0114490D800A7F080 /* push.c in Sources */,
+				D35B8BF1114490D800A7F080 /* reliable.c in Sources */,
+				D35B8BF2114490D800A7F080 /* route.c in Sources */,
+				D35B8BF3114490D800A7F080 /* schedule.c in Sources */,
+				D35B8BF4114490D800A7F080 /* session_id.c in Sources */,
+				D35B8BF5114490D800A7F080 /* shaper.c in Sources */,
+				D35B8BF6114490D800A7F080 /* sig.c in Sources */,
+				D35B8BF7114490D800A7F080 /* socket.c in Sources */,
+				D35B8BF8114490D800A7F080 /* socks.c in Sources */,
+				D35B8BF9114490D800A7F080 /* ssl.c in Sources */,
+				D35B8BFA114490D800A7F080 /* status.c in Sources */,
+				D35B8BFB114490D800A7F080 /* thread.c in Sources */,
+				D35B8BFC114490D800A7F080 /* tun.c in Sources */,
+				D3BBF5AF114C6AF700311166 /* cert_data.c in Sources */,
+				D3BBF5B0114C6AF700311166 /* common_osx.c in Sources */,
+				D3BBF5B1114C6AF700311166 /* crypto_osx.c in Sources */,
+				D3BBF5C4114C738A00311166 /* keychain.c in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+		1DEB928608733DD80010E9CD /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				ARCHS = (
+					x86_64,
+					i386,
+				);
+				COPY_PHASE_STRIP = NO;
+				GCC_C_LANGUAGE_STANDARD = "compiler-default";
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_MODEL_TUNING = G5;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = HAVE_CONFIG_H;
+				INSTALL_PATH = /usr/local/bin;
+				LIBRARY_SEARCH_PATHS = /opt/local/lib;
+				LINK_WITH_STANDARD_LIBRARIES = YES;
+				OTHER_LDFLAGS = (
+					/opt/local/lib/liblzo2.a,
+					"-lcrypto",
+					"-lssl",
+				);
+				PRODUCT_NAME = openvpn;
+				USER_HEADER_SEARCH_PATHS = /opt/local/include;
+			};
+			name = Debug;
+		};
+		1DEB928708733DD80010E9CD /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				ARCHS = (
+					x86_64,
+					i386,
+				);
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				GCC_C_LANGUAGE_STANDARD = "compiler-default";
+				GCC_MODEL_TUNING = G5;
+				GCC_PREPROCESSOR_DEFINITIONS = HAVE_CONFIG_H;
+				INSTALL_PATH = /usr/local/bin;
+				LIBRARY_SEARCH_PATHS = /opt/local/lib;
+				LINK_WITH_STANDARD_LIBRARIES = YES;
+				OTHER_LDFLAGS = (
+					/opt/local/lib/liblzo2.a,
+					"-lcrypto",
+					"-lssl",
+				);
+				PRODUCT_NAME = openvpn;
+				USER_HEADER_SEARCH_PATHS = /opt/local/include;
+			};
+			name = Release;
+		};
+		1DEB928A08733DD80010E9CD /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				GCC_C_LANGUAGE_STANDARD = c99;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+				SDKROOT = macosx10.5;
+			};
+			name = Debug;
+		};
+		1DEB928B08733DD80010E9CD /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				GCC_C_LANGUAGE_STANDARD = c99;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				PREBINDING = NO;
+				SDKROOT = macosx10.5;
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		1DEB928508733DD80010E9CD /* Build configuration list for PBXNativeTarget "openvpn" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				1DEB928608733DD80010E9CD /* Debug */,
+				1DEB928708733DD80010E9CD /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "openvpn" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				1DEB928A08733DD80010E9CD /* Debug */,
+				1DEB928B08733DD80010E9CD /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
+}
diff --git a/ssl.c b/ssl.c
old mode 100644
new mode 100755
index 1b275af..0699ef1
--- a/ssl.c
+++ b/ssl.c
@@ -1591,7 +1591,7 @@ init_ssl (const struct options *options)
       else
 #endif
 
-#ifdef WIN32
+#if defined(WIN32)
       if (options->cryptoapi_cert)
 	{
 	  /* Load Certificate and Private Key */
@@ -1600,6 +1600,15 @@ init_ssl (const struct options *options)
 		 options->cryptoapi_cert);
 	}
       else
+#elif defined(__APPLE__)
+	if (options->keychain_cert)
+	{
+	  /* Load Certificate and Private Key */
+	  if (!SSL_CTX_use_Keychain_certificate (ctx, options->keychain_cert))
+		  msg (M_SSLERR, "Cannot load certificate \"%s\" from Mac OSX Keychain",
+			   options->keychain_cert);
+	}
+	else
 #endif
 	{
 	  /* Load Certificate */
-- 
1.6.6.2

