summaryrefslogtreecommitdiff
path: root/main/openvpn/contrib/keychain-mcd
diff options
context:
space:
mode:
Diffstat (limited to 'main/openvpn/contrib/keychain-mcd')
m---------main/openvpn0
-rw-r--r--main/openvpn/contrib/keychain-mcd/cert_data.c733
-rw-r--r--main/openvpn/contrib/keychain-mcd/cert_data.h46
-rw-r--r--main/openvpn/contrib/keychain-mcd/common_osx.c94
-rw-r--r--main/openvpn/contrib/keychain-mcd/common_osx.h36
-rw-r--r--main/openvpn/contrib/keychain-mcd/crypto_osx.c75
-rw-r--r--main/openvpn/contrib/keychain-mcd/crypto_osx.h44
-rw-r--r--main/openvpn/contrib/keychain-mcd/keychain-mcd.8149
-rw-r--r--main/openvpn/contrib/keychain-mcd/main.c244
9 files changed, 0 insertions, 1421 deletions
diff --git a/main/openvpn b/main/openvpn
new file mode 160000
+Subproject 7aaf01766f9718375986600216607aeb6397200
diff --git a/main/openvpn/contrib/keychain-mcd/cert_data.c b/main/openvpn/contrib/keychain-mcd/cert_data.c
deleted file mode 100644
index f2b33edc..00000000
--- a/main/openvpn/contrib/keychain-mcd/cert_data.c
+++ /dev/null
@@ -1,733 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2010 Brian Raderman <brian@irregularexpression.org>
- * Copyright (C) 2013-2015 Vasily Kulikov <segoon@openwall.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include "cert_data.h"
-#include <CommonCrypto/CommonDigest.h>
-#include <openssl/ssl.h>
-
-#include "common_osx.h"
-#include "crypto_osx.h"
-#include <err.h>
-
-CFStringRef kCertDataSubjectName = CFSTR("subject"),
- kCertDataIssuerName = CFSTR("issuer"),
- kCertDataSha1Name = CFSTR("SHA1"),
- kCertDataMd5Name = CFSTR("MD5"),
- kCertDataSerialName = CFSTR("serial"),
- 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");
-CFStringRef kStringSpace = CFSTR(" "),
- kStringEmpty = CFSTR("");
-
-typedef struct _CertName
-{
- CFArrayRef countryName, organization, organizationalUnit, commonName, description, emailAddress,
- stateName, localityName;
-} CertName, *CertNameRef;
-
-typedef struct _DescData
-{
- CFStringRef name, value;
-} DescData, *DescDataRef;
-
-void destroyDescData(DescDataRef pData);
-
-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);
- 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);
- free(pCertName);
-}
-
-bool CFStringRefCmpCString(CFStringRef cfstr, const char *str)
-{
- CFStringRef tmp = CFStringCreateWithCStringNoCopy(NULL, str, kCFStringEncodingUTF8, kCFAllocatorNull);
- CFComparisonResult cresult = CFStringCompare(cfstr, tmp, 0);
- bool result = cresult == kCFCompareEqualTo;
- CFRelease(tmp);
- return result;
-}
-
-CFDateRef GetDateFieldFromCertificate(SecCertificateRef certificate, CFTypeRef oid)
-{
- const void *keys[] = { oid };
- CFDictionaryRef dict = NULL;
- CFErrorRef error;
- CFDateRef date = NULL;
-
- CFArrayRef keySelection = CFArrayCreate(NULL, keys , sizeof(keys)/sizeof(keys[0]), &kCFTypeArrayCallBacks);
- dict = SecCertificateCopyValues(certificate, keySelection, &error);
- if (dict == NULL)
- {
- printErrorMsg("GetDateFieldFromCertificate: SecCertificateCopyValues", error);
- goto release_ks;
- }
- CFDictionaryRef vals = dict ? CFDictionaryGetValue(dict, oid) : NULL;
- CFNumberRef vals2 = vals ? CFDictionaryGetValue(vals, kSecPropertyKeyValue) : NULL;
- if (vals2 == NULL)
- goto release_dict;
-
- CFAbsoluteTime validityNotBefore;
- if (CFNumberGetValue(vals2, kCFNumberDoubleType, &validityNotBefore))
- date = CFDateCreate(kCFAllocatorDefault,validityNotBefore);
-
-release_dict:
- CFRelease(dict);
-release_ks:
- CFRelease(keySelection);
- return date;
-}
-
-CFArrayRef GetFieldsFromCertificate(SecCertificateRef certificate, CFTypeRef oid)
-{
- CFMutableArrayRef fields = CFArrayCreateMutable(NULL, 0, NULL);
- CertNameRef pCertName = createCertName();
- const void* keys[] = { oid, };
- CFDictionaryRef dict;
- CFErrorRef error;
-
- CFArrayRef keySelection = CFArrayCreate(NULL, keys , 1, NULL);
-
- dict = SecCertificateCopyValues(certificate, keySelection, &error);
- if (dict == NULL) {
- printErrorMsg("GetFieldsFromCertificate: SecCertificateCopyValues", error);
- CFRelease(keySelection);
- CFRelease(fields);
- return NULL;
- }
- CFDictionaryRef vals = CFDictionaryGetValue(dict, oid);
- CFArrayRef vals2 = vals ? CFDictionaryGetValue(vals, kSecPropertyKeyValue) : NULL;
- if (vals2)
- {
- for(int i = 0; i < CFArrayGetCount(vals2); i++) {
- CFDictionaryRef subDict = CFArrayGetValueAtIndex(vals2, i);
- CFStringRef label = CFDictionaryGetValue(subDict, kSecPropertyKeyLabel);
- CFStringRef value = CFDictionaryGetValue(subDict, kSecPropertyKeyValue);
-
- if (CFStringCompare(label, kSecOIDEmailAddress, 0) == kCFCompareEqualTo)
- CFArrayAppendValue((CFMutableArrayRef)pCertName->emailAddress, value);
- else if (CFStringCompare(label, kSecOIDCountryName, 0) == kCFCompareEqualTo)
- CFArrayAppendValue((CFMutableArrayRef)pCertName->countryName, value);
- else if (CFStringCompare(label, kSecOIDOrganizationName, 0) == kCFCompareEqualTo)
- CFArrayAppendValue((CFMutableArrayRef)pCertName->organization, value);
- else if (CFStringCompare(label, kSecOIDOrganizationalUnitName, 0) == kCFCompareEqualTo)
- CFArrayAppendValue((CFMutableArrayRef)pCertName->organizationalUnit, value);
- else if (CFStringCompare(label, kSecOIDCommonName, 0) == kCFCompareEqualTo)
- CFArrayAppendValue((CFMutableArrayRef)pCertName->commonName, value);
- else if (CFStringCompare(label, kSecOIDDescription, 0) == kCFCompareEqualTo)
- CFArrayAppendValue((CFMutableArrayRef)pCertName->description, value);
- else if (CFStringCompare(label, kSecOIDStateProvinceName, 0) == kCFCompareEqualTo)
- CFArrayAppendValue((CFMutableArrayRef)pCertName->stateName, value);
- else if (CFStringCompare(label, kSecOIDLocalityName, 0) == kCFCompareEqualTo)
- CFArrayAppendValue((CFMutableArrayRef)pCertName->localityName, value);
- }
- CFArrayAppendValue(fields, pCertName);
- }
-
- CFRelease(dict);
- CFRelease(keySelection);
- return fields;
-}
-
-CertDataRef createCertDataFromCertificate(SecCertificateRef certificate)
-{
- CertDataRef pCertData = (CertDataRef)malloc(sizeof(CertData));
- pCertData->subject = GetFieldsFromCertificate(certificate, kSecOIDX509V1SubjectName);
- pCertData->issuer = GetFieldsFromCertificate(certificate, kSecOIDX509V1IssuerName);
-
- CFDataRef data = SecCertificateCopyData(certificate);
- if (data == NULL)
- {
- warnx("SecCertificateCopyData() returned NULL");
- destroyCertData(pCertData);
- return NULL;
- }
-
- unsigned char sha1[CC_SHA1_DIGEST_LENGTH];
- CC_SHA1(CFDataGetBytePtr(data), CFDataGetLength(data), sha1);
- pCertData->sha1 = createHexString(sha1, CC_SHA1_DIGEST_LENGTH);
-
- unsigned char md5[CC_MD5_DIGEST_LENGTH];
- CC_MD5(CFDataGetBytePtr(data), CFDataGetLength(data), md5);
- pCertData->md5 = createHexString((unsigned char*)md5, CC_MD5_DIGEST_LENGTH);
-
- CFDataRef serial = SecCertificateCopySerialNumber(certificate, NULL);
- pCertData->serial = createHexString((unsigned char *)CFDataGetBytePtr(serial), CFDataGetLength(serial));
- CFRelease(serial);
-
- 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);
-
-#if 0
- fprintf(stderr, "name = '%s', value = '%s'\n",
- CFStringGetCStringPtr(pRetVal->name, kCFStringEncodingUTF8),
- CFStringGetCStringPtr(pRetVal->value, kCFStringEncodingUTF8));
-#endif
- 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);
-}
-
-
-int parseNameComponent(CFStringRef dn, CFStringRef *pName, CFStringRef *pValue)
-{
- CFArrayRef nameStrings = CFStringCreateArrayBySeparatingStrings(NULL, dn, kCertNameEquals);
-
- *pName = *pValue = NULL;
-
- if (CFArrayGetCount(nameStrings) != 2)
- return 0;
-
- 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);
- return 1;
-}
-
-int tryAppendSingleCertField(CertNameRef pCertName, CFArrayRef where, CFStringRef key,
- CFStringRef name, CFStringRef value)
-{
- if (CFStringCompareWithOptions(name, key, CFRangeMake(0, CFStringGetLength(name)), kCFCompareCaseInsensitive)
- == kCFCompareEqualTo) {
- CFArrayAppendValue((CFMutableArrayRef)where, value);
- return 1;
- }
- return 0;
-}
-
-int appendCertField(CertNameRef pCert, CFStringRef name, CFStringRef value)
-{
- struct {
- CFArrayRef field;
- CFStringRef key;
- } fields[] = {
- { pCert->organization, kCertNameOrganization},
- { pCert->organizationalUnit, kCertNameOrganizationalUnit},
- { pCert->countryName, kCertNameCountry},
- { pCert->localityName, kCertNameLocality},
- { pCert->stateName, kCertNameState},
- { pCert->commonName, kCertNameCommonName},
- { pCert->emailAddress, kCertNameEmail},
- };
- int i;
- int ret = 0;
-
- for (i=0; i<sizeof(fields)/sizeof(fields[0]); i++)
- ret += tryAppendSingleCertField(pCert, fields[i].field, fields[i].key, name, value);
- return ret;
-}
-
-int parseCertName(CFStringRef nameDesc, CFMutableArrayRef names)
-{
- CFArrayRef nameStrings = CFStringCreateArrayBySeparatingStrings(NULL, nameDesc, kCertNameFwdSlash);
- int count = CFArrayGetCount(nameStrings);
- int i;
- int ret = 1;
-
- CertNameRef pCertName = createCertName();
-
- for(i = 0;i < count;i++)
- {
- CFMutableStringRef dn = CFStringCreateMutableCopy(NULL, 0, CFArrayGetValueAtIndex(nameStrings, i));
- CFStringTrimWhitespace(dn);
-
- CFStringRef name, value;
-
- if (!parseNameComponent(dn, &name, &value))
- ret = 0;
-
- if (!name || !value)
- {
- if (name)
- CFRelease(name);
-
- if (value)
- CFRelease(value);
- if (name && !value)
- ret = 0;
-
- CFRelease(dn);
- continue;
- }
-
- if (!appendCertField(pCertName, name, value))
- ret = 0;
- CFRelease(name);
- CFRelease(value);
- CFRelease(dn);
- }
-
- CFArrayAppendValue(names, pCertName);
- CFRelease(nameStrings);
- return ret;
-}
-
-int arrayParseDescDataPair(const void *val, void *context)
-{
- DescDataRef pDescData = (DescDataRef)val;
- CertDataRef pCertData = (CertDataRef)context;
- int ret = 1;
-
- if (!pDescData->name || !pDescData->value)
- return 0;
-
- if (CFStringCompareWithOptions(pDescData->name, kCertDataSubjectName, CFRangeMake(0, CFStringGetLength(pDescData->name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
- ret = parseCertName(pDescData->value, (CFMutableArrayRef)pCertData->subject);
- else if (CFStringCompareWithOptions(pDescData->name, kCertDataIssuerName, CFRangeMake(0, CFStringGetLength(pDescData->name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
- ret = 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);
- else if (CFStringCompareWithOptions(pDescData->name, kCertDataSerialName, CFRangeMake(0, CFStringGetLength(pDescData->name)), kCFCompareCaseInsensitive) == kCFCompareEqualTo)
- pCertData->serial = CFRetain(pDescData->value);
- else
- return 0;
-
- return ret;
-}
-
-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;
- pCertData->serial = NULL;
-
- CFArrayRef pairs = createDescDataPairs(description);
- for (int i=0; i<CFArrayGetCount(pairs); i++)
- if (!arrayParseDescDataPair(CFArrayGetValueAtIndex(pairs, i), pCertData)) {
- arrayDestroyDescData(pCertData, NULL);
- CFArrayApplyFunction(pairs, CFRangeMake(0, CFArrayGetCount(pairs)), arrayDestroyDescData, NULL);
- CFRelease(pairs);
- return 0;
- }
-
- 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);
-
- if (pCertData->serial)
- CFRelease(pCertData->serial);
-
- 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;
-
- if (!hexStringMatchesTemplate(pCertData->serial, pTemplate->serial))
- return false;
-
- return true;
-}
-
-bool certExpired(SecCertificateRef certificate)
-{
- bool result;
- CFDateRef notAfter = GetDateFieldFromCertificate(certificate, kSecOIDX509V1ValidityNotAfter);
- CFDateRef notBefore = GetDateFieldFromCertificate(certificate, kSecOIDX509V1ValidityNotBefore);
- CFDateRef now = CFDateCreate(kCFAllocatorDefault, CFAbsoluteTimeGetCurrent());
-
- if (!notAfter || !notBefore || !now)
- {
- warnx("GetDateFieldFromCertificate() returned NULL");
- result = true;
- }
- else
- {
- if (CFDateCompare(notBefore, now, NULL) != kCFCompareLessThan ||
- CFDateCompare(now, notAfter, NULL) != kCFCompareLessThan)
- result = true;
- else
- result = false;
- }
-
- CFRelease(notAfter);
- CFRelease(notBefore);
- CFRelease(now);
- return result;
-}
-
-SecIdentityRef findIdentity(CertDataRef pCertDataTemplate)
-{
- const void *keys[] = {
- kSecClass,
- kSecReturnRef,
- kSecMatchLimit
- };
- const void *values[] = {
- kSecClassIdentity,
- kCFBooleanTrue,
- kSecMatchLimitAll
- };
- CFArrayRef result = NULL;
-
- CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values,
- sizeof(keys) / sizeof(*keys),
- &kCFTypeDictionaryKeyCallBacks,
- &kCFTypeDictionaryValueCallBacks);
- OSStatus status = SecItemCopyMatching(query, (CFTypeRef*)&result);
- CFRelease(query);
- if (status != noErr)
- {
- warnx ("No identities in keychain found");
- return NULL;
- }
-
- SecIdentityRef bestIdentity = NULL;
- CFDateRef bestNotBeforeDate = NULL;
-
- for (int i=0; i<CFArrayGetCount(result); i++)
- {
- SecIdentityRef identity = (SecIdentityRef)CFArrayGetValueAtIndex(result, i);
- if (identity == NULL)
- {
- warnx ("identity == NULL");
- continue;
- }
-
- SecCertificateRef certificate = NULL;
- SecIdentityCopyCertificate (identity, &certificate);
- if (certificate == NULL)
- {
- warnx ("SecIdentityCopyCertificate() returned NULL");
- continue;
- }
-
- CertDataRef pCertData2 = createCertDataFromCertificate(certificate);
- if (pCertData2 == NULL)
- {
- warnx ("createCertDataFromCertificate() returned NULL");
- goto release_cert;
- }
- bool bMatches = certDataMatchesTemplate(pCertData2, pCertDataTemplate);
- bool bExpired = certExpired(certificate);
- destroyCertData(pCertData2);
-
- if (bMatches && !bExpired)
- {
- CFDateRef notBeforeDate = GetDateFieldFromCertificate(certificate, kSecOIDX509V1ValidityNotBefore);
- if (!notBeforeDate)
- {
- warnx ("GetDateFieldFromCertificate() returned NULL");
- goto release_cert;
- }
- if (bestIdentity == NULL)
- {
- CFRetain(identity);
- bestIdentity = identity;
-
- bestNotBeforeDate = notBeforeDate;
- CFRetain(notBeforeDate);
- }
- else if (CFDateCompare(bestNotBeforeDate, notBeforeDate, NULL) == kCFCompareLessThan)
- {
- CFRelease(bestIdentity);
- CFRetain(identity);
- bestIdentity = identity;
-
- bestNotBeforeDate = notBeforeDate;
- CFRetain(notBeforeDate);
- }
- CFRelease(notBeforeDate);
- }
- release_cert:
- CFRelease(certificate);
- }
- CFRelease(result);
-
- return bestIdentity;
-}
diff --git a/main/openvpn/contrib/keychain-mcd/cert_data.h b/main/openvpn/contrib/keychain-mcd/cert_data.h
deleted file mode 100644
index 407cca1c..00000000
--- a/main/openvpn/contrib/keychain-mcd/cert_data.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2010 Brian Raderman <brian@irregularexpression.org>
- * Copyright (C) 2013-2015 Vasily Kulikov <segoon@openwall.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifndef __cert_data_h__
-#define __cert_data_h__
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <Security/Security.h>
-
-typedef struct _CertData
-{
- CFArrayRef subject;
- CFArrayRef issuer;
- CFStringRef serial;
- 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
diff --git a/main/openvpn/contrib/keychain-mcd/common_osx.c b/main/openvpn/contrib/keychain-mcd/common_osx.c
deleted file mode 100644
index 3effa8b0..00000000
--- a/main/openvpn/contrib/keychain-mcd/common_osx.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2010 Brian Raderman <brian@irregularexpression.org>
- * Copyright (C) 2013-2015 Vasily Kulikov <segoon@openwall.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
-#include "config.h"
-#include "syshead.h"
-#include "common.h"
-#include "buffer.h"
-#include "error.h"
-*/
-
-#include "common_osx.h"
-#include <err.h>
-
-void printCFString(CFStringRef str)
-{
- CFIndex bufferLength = CFStringGetLength(str) + 1;
- char *pBuffer = (char*)malloc(sizeof(char) * bufferLength);
- CFStringGetCString(str, pBuffer, bufferLength, kCFStringEncodingUTF8);
- warnx("%s\n", pBuffer);
- free(pBuffer);
-}
-
-char* cfstringToCstr(CFStringRef str)
-{
- CFIndex bufferLength = CFStringGetLength(str) + 1;
- char *pBuffer = (char*)malloc(sizeof(char) * bufferLength);
- CFStringGetCString(str, pBuffer, bufferLength, kCFStringEncodingUTF8);
- return pBuffer;
-}
-
-void appendHexChar(CFMutableStringRef str, unsigned char halfByte)
-{
- if (halfByte < 10)
- {
- CFStringAppendFormat (str, NULL, CFSTR("%d"), halfByte);
- }
- else
- {
- char tmp[2] = {'A'+halfByte-10, 0};
- CFStringAppendCString(str, tmp, kCFStringEncodingUTF8);
- }
-}
-
-CFStringRef createHexString(unsigned char *pData, int length)
-{
- unsigned char byte, low, high;
- int i;
- CFMutableStringRef str = CFStringCreateMutable(NULL, 0);
-
- for(i = 0;i < length;i++)
- {
- byte = pData[i];
- low = byte & 0x0F;
- high = (byte >> 4);
-
- appendHexChar(str, high);
- appendHexChar(str, low);
-
- if (i != (length - 1))
- CFStringAppendCString(str, " ", kCFStringEncodingUTF8);
- }
-
- return str;
-}
-
-void printHex(unsigned char *pData, int length)
-{
- CFStringRef hexStr = createHexString(pData, length);
- printCFString(hexStr);
- CFRelease(hexStr);
-}
diff --git a/main/openvpn/contrib/keychain-mcd/common_osx.h b/main/openvpn/contrib/keychain-mcd/common_osx.h
deleted file mode 100644
index 42735486..00000000
--- a/main/openvpn/contrib/keychain-mcd/common_osx.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2010 Brian Raderman <brian@irregularexpression.org>
- * Copyright (C) 2013-2015 Vasily Kulikov <segoon@openwall.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#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__
diff --git a/main/openvpn/contrib/keychain-mcd/crypto_osx.c b/main/openvpn/contrib/keychain-mcd/crypto_osx.c
deleted file mode 100644
index 87ba09ba..00000000
--- a/main/openvpn/contrib/keychain-mcd/crypto_osx.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2010 Brian Raderman <brian@irregularexpression.org>
- * Copyright (C) 2013-2015 Vasily Kulikov <segoon@openwall.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <CommonCrypto/CommonDigest.h>
-#include <Security/SecKey.h>
-#include <Security/Security.h>
-
-#include "crypto_osx.h"
-#include <err.h>
-
-void printErrorMsg(const char *func, CFErrorRef error)
-{
- CFStringRef desc = CFErrorCopyDescription(error);
- warnx("%s failed: %s", func, CFStringGetCStringPtr(desc, kCFStringEncodingUTF8));
- CFRelease(desc);
-}
-
-void printErrorStatusMsg(const char *func, OSStatus status)
-{
- CFStringRef error;
- error = SecCopyErrorMessageString(status, NULL);
- if (error)
- {
- warnx("%s failed: %s", func, CFStringGetCStringPtr(error, kCFStringEncodingUTF8));
- CFRelease(error);
- }
- else
- warnx("%s failed: %X", func, (int)status);
-}
-
-void signData(SecIdentityRef identity, const uint8_t *from, int flen, uint8_t *to, size_t *tlen)
-{
- SecKeyRef privateKey = NULL;
- OSStatus status;
-
- status = SecIdentityCopyPrivateKey(identity, &privateKey);
- if (status != noErr)
- {
- printErrorStatusMsg("signData: SecIdentityCopyPrivateKey", status);
- *tlen = 0;
- return;
- }
-
- status = SecKeyRawSign(privateKey, kSecPaddingPKCS1, from, flen, to, tlen);
- CFRelease(privateKey);
- if (status != noErr)
- {
- printErrorStatusMsg("signData: SecKeyRawSign", status);
- *tlen = 0;
- return;
- }
-}
diff --git a/main/openvpn/contrib/keychain-mcd/crypto_osx.h b/main/openvpn/contrib/keychain-mcd/crypto_osx.h
deleted file mode 100644
index 0da58b60..00000000
--- a/main/openvpn/contrib/keychain-mcd/crypto_osx.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * OpenVPN -- An application to securely tunnel IP networks
- * over a single UDP port, with support for SSL/TLS-based
- * session authentication and key exchange,
- * packet encryption, packet authentication, and
- * packet compression.
- *
- * Copyright (C) 2010 Brian Raderman <brian@irregularexpression.org>
- * Copyright (C) 2013-2015 Vasily Kulikov <segoon@openwall.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __crypto_osx_h__
-#define __crypto_osx_h__
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <Security/Security.h>
-
-extern OSStatus SecKeyRawSign (
- SecKeyRef key,
- SecPadding padding,
- const uint8_t *dataToSign,
- size_t dataToSignLen,
- uint8_t *sig,
- size_t *sigLen
-);
-
-void signData(SecIdentityRef identity, const uint8_t *from, int flen, uint8_t *to, size_t *tlen);
-void printErrorMsg(const char *func, CFErrorRef error);
-
-#endif //__crypto_osx_h__
diff --git a/main/openvpn/contrib/keychain-mcd/keychain-mcd.8 b/main/openvpn/contrib/keychain-mcd/keychain-mcd.8
deleted file mode 100644
index c4581e7b..00000000
--- a/main/openvpn/contrib/keychain-mcd/keychain-mcd.8
+++ /dev/null
@@ -1,149 +0,0 @@
-.TH keychain-mcd 8
-.SH NAME
-
-keychain-mcd \- Mac OS X Keychain management daemon for OpenVPN
-
-.SH SYNOPSIS
-
-.B keychain-mcd
-.I identity-template management-server-ip management-server-port
-[
-.I password-file
-]
-
-.SH DESCRIPTION
-
-.B keychain-mcd
-is Mac OS X Keychain management daemon for OpenVPN.
-It loads the certificate and private key from the Mac OSX Keychain (Mac OSX Only).
-.B keychain-mcd
-connects to OpenVPN via management interface and handles
-certificate and private key commands (namely
-.B NEED-CERTIFICATE
-and
-.B RSA-SIGN
-commands).
-
-.B keychain-mcd
-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 OS X.
-
-Note that Mac OS X might need to present the user with an authentication GUI when the Keychain
-is accessed by keychain-mcd.
-
-Use
-.B keychain-mcd
-along with
-.B --management-external-key
-and/or
-.B --management-external-cert
-passed to
-.B openvpn.
-
-.SH OPTIONS
-
-.TP
-.BR identity-template
-
-A select string which is used to choose a keychain identity from
-Mac OS X Keychain.
-
-\fBSubject\fR, \fBIssuer\fR, \fBSerial\fR, \fBSHA1\fR, \fBMD5\fR selectors can be used.
-
-To select a certificate based on a string search in the
-certificate's subject and/or issuer:
-
-.nf
-
-"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"
-
-.fi
-
-.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
-certificate it finds that matches all of the criteria you have specified.
-If there are several certificates matching all of the criteria then the youngest certificate is returned
-(i.e. with the greater "not before" validity field).
-You can also include the MD5 and/or SHA1 thumbprints and/or serial number
-along with the subject and issuer.
-
-To select a certificate based on certificate's MD5 or SHA1 thumbprint:
-
-.nf
-"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"
-.fi
-
-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.
-
-To select a certificate based on certificate's serial number:
-
-"Serial: 3E 9B 6F 02 00 00 00 01 1F 20"
-
-.TP
-.BR management-server-ip
-OpenVPN management IP to connect to.
-Both IPv4 and IPv6 addresses can be used.
-
-.TP
-.BR management-server-port
-OpenVPN management port to connect to.
-Use
-.B unix
-for
-.I management-server-port
-and socket path for
-.I management-server-ip
-to connect to a local unix socket.
-
-.TP
-.BR password-file
-
-Password file containing the management password on first line.
-The password will be used to connect to
-.B openvpn
-management interface.
-
-Pass
-.I password-file
-to
-.B keychain-mcd
-if
-.I pw-file
-was specified in
-.B --management
-option to
-.B openvpn.
-
-
-.SH AUTHOR
-
-Vasily Kulikov <segoon@openwall.com>
-
-.SH "SEE ALSO"
-
-.BR openvpn (8)
diff --git a/main/openvpn/contrib/keychain-mcd/main.c b/main/openvpn/contrib/keychain-mcd/main.c
deleted file mode 100644
index 5f59403c..00000000
--- a/main/openvpn/contrib/keychain-mcd/main.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
- * 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) 2015 Vasily Kulikov <segoon@openwall.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program (see the file COPYING included with this
- * distribution); if not, write to the Free Software Foundation, Inc.,
- * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/un.h>
-#include <err.h>
-#include <netdb.h>
-
-#include <Security/Security.h>
-#include <CoreServices/CoreServices.h>
-
-#include "cert_data.h"
-#include "crypto_osx.h"
-#include "../../src/openvpn/base64.h"
-
-
-SecIdentityRef template_to_identity(const char *template)
-{
- SecIdentityRef identity;
- CertDataRef pCertDataTemplate = createCertDataFromString(template);
- if (pCertDataTemplate == NULL)
- errx(1, "Bad certificate template");
- identity = findIdentity(pCertDataTemplate);
- if (identity == NULL)
- errx(1, "No such identify");
- fprintf(stderr, "Identity found\n");
- destroyCertData(pCertDataTemplate);
- return identity;
-}
-
-int connect_to_management_server(const char *ip, const char *port)
-{
- int fd;
- struct sockaddr_un addr_un;
- struct sockaddr *addr;
- size_t addr_len;
-
- if (strcmp(port, "unix") == 0) {
- addr = (struct sockaddr*)&addr_un;
- addr_len = sizeof(addr_un);
-
- addr_un.sun_family = AF_UNIX;
- strncpy(addr_un.sun_path, ip, sizeof(addr_un.sun_path));
- fd = socket(AF_UNIX, SOCK_STREAM, 0);
- }
- else {
- int rv;
- struct addrinfo *result;
- struct addrinfo hints;
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
-
- rv = getaddrinfo(ip, port, &hints, &result);
- if (rv < 0)
- errx(1, "getaddrinfo: %s", gai_strerror(rv));
- if (result == NULL)
- errx(1, "getaddrinfo returned 0 addressed");
-
- /* Use the first found address */
- fd = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
- addr = result->ai_addr;
- addr_len = result->ai_addrlen;
- }
- if (fd < 0)
- err(1, "socket");
-
- if (connect(fd, addr, addr_len) < 0)
- err(1, "connect");
-
- return fd;
-}
-
-int is_prefix(const char *s, const char *prefix)
-{
- return strncmp(s, prefix, strlen(prefix)) == 0;
-}
-
-void handle_rsasign(FILE *man_file, SecIdentityRef identity, const char *input)
-{
- const char *input_b64 = strchr(input, ':') + 1;
- char *input_binary;
- int input_len;
- char *output_binary;
- size_t output_len;
- char *output_b64;
-
- input_len = strlen(input_b64)*8/6 + 4;
- input_binary = malloc(input_len);
- input_len = openvpn_base64_decode(input_b64, input_binary, input_len);
- if (input_len < 0)
- errx(1, "openvpn_base64_decode: overflow");
-
- output_len = 1024;
- output_binary = malloc(output_len);
- signData(identity, (const uint8_t *)input_binary, input_len, (uint8_t *)output_binary, &output_len);
- if (output_len == 0)
- errx(1, "handle_rsasign: failed to sign data");
-
- openvpn_base64_encode(output_binary, output_len, &output_b64);
- fprintf(man_file, "rsa-sig\n%s\nEND\n", output_b64);
- free(output_b64);
- free(input_binary);
- free(output_binary);
-
- fprintf(stderr, "Handled RSA_SIGN command\n");
-}
-
-void handle_needcertificate(FILE *man_file, SecIdentityRef identity)
-{
- OSStatus status;
- SecCertificateRef certificate = NULL;
- CFDataRef data;
- const unsigned char *cert;
- size_t cert_len;
- char *result_b64, *tmp_b64;
-
- status = SecIdentityCopyCertificate(identity, &certificate);
- if (status != noErr) {
- const char *msg = GetMacOSStatusErrorString(status);
- err(1, "SecIdentityCopyCertificate() failed: %s", msg);
- }
-
- data = SecCertificateCopyData(certificate);
- if (data == NULL)
- err(1, "SecCertificateCopyData() returned NULL");
-
- cert = CFDataGetBytePtr(data);
- cert_len = CFDataGetLength(data);
-
- openvpn_base64_encode(cert, cert_len, &result_b64);
-#if 0
- fprintf(stderr, "certificate %s\n", result_b64);
-#endif
-
- fprintf(man_file, "certificate\n");
- fprintf(man_file, "-----BEGIN CERTIFICATE-----\n");
- tmp_b64 = result_b64;
- while (strlen(tmp_b64) > 64) {
- fprintf(man_file, "%.64s\n", tmp_b64);
- tmp_b64 += 64;
- }
- if (*tmp_b64)
- fprintf(man_file, "%s\n", tmp_b64);
- fprintf(man_file, "-----END CERTIFICATE-----\n");
- fprintf(man_file, "END\n");
-
- free(result_b64);
- CFRelease(data);
- CFRelease(certificate);
-
- fprintf(stderr, "Handled NEED 'cert' command\n");
-}
-
-void management_loop(SecIdentityRef identity, int man_fd, const char *password)
-{
- char *buffer = NULL;
- size_t buffer_len = 0;
- FILE *man = fdopen(man_fd, "w+");
- if (man == 0)
- err(1, "fdopen");
-
- if (password)
- fprintf(man, "%s\n", password);
-
- while (1) {
- if (getline(&buffer, &buffer_len, man) < 0)
- err(1, "getline");
-#if 0
- fprintf(stderr, "M: %s", buffer);
-#endif
-
- if (is_prefix(buffer, ">RSA_SIGN:"))
- handle_rsasign(man, identity, buffer);
- if (is_prefix(buffer, ">NEED-CERTIFICATE"))
- handle_needcertificate(man, identity);
- if (is_prefix(buffer, ">FATAL"))
- fprintf(stderr, "Fatal message from OpenVPN: %s\n", buffer+7);
- if (is_prefix(buffer, ">INFO"))
- fprintf(stderr, "INFO message from OpenVPN: %s\n", buffer+6);
- }
-}
-
-char *read_password(const char *fname)
-{
- char *password = NULL;
- FILE *pwf = fopen(fname, "r");
- size_t n = 0;
-
- if (pwf == NULL)
- errx(1, "fopen(%s) failed", fname);
- if (getline(&password, &n, pwf) < 0)
- err(1, "getline");
- fclose(pwf);
- return password;
-}
-
-int main(int argc, char* argv[])
-{
- if (argc < 4)
- err(1, "usage: %s <identity_template> <management_ip> <management_port> [<pw-file>]", argv[0]);
-
- char *cert_prop = argv[1];
- char *s_ip = argv[2];
- char *s_port = argv[3];
- char *password = NULL;
- int man_fd;
-
- if (argc > 4) {
- char *s_pw_file = argv[4];
- password = read_password(s_pw_file);
- }
-
- SecIdentityRef identity = template_to_identity(cert_prop);
- man_fd = connect_to_management_server(s_ip, s_port);
- fprintf(stderr, "Successfully connected to openvpn\n");
-
- management_loop(identity, man_fd, password);
-}