X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/SecurityTool/trusted_cert_utils.c?ds=inline diff --git a/SecurityTool/trusted_cert_utils.c b/SecurityTool/trusted_cert_utils.c new file mode 100644 index 00000000..808ab47b --- /dev/null +++ b/SecurityTool/trusted_cert_utils.c @@ -0,0 +1,446 @@ +/* + * Copyright (c) 2003-2004,2006,2009-2010,2012,2014 Apple Inc. All Rights Reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. + * + * @APPLE_LICENSE_HEADER_END@ + * + * trusted_cert_utils.c + */ + +#include "trusted_cert_utils.h" +#include +#include +#include +#include +#include +#include +#include +#include + +static int indentSize = 0; +void indentIncr(void) { indentSize += 3; } +void indentDecr(void) { indentSize -= 3; } + +void indent(void) +{ + int dex; + if(indentSize < 0) { + /* bug */ + indentSize = 0; + } + for (dex=0; dex maxLen) { + len = maxLen; + doEllipsis = true; + } + for(dex=0; dex maxLen) { + len = maxLen; + doEllipsis = true; + } + for(dex=0; dex>"); + return; + } + const char *cp = (const char *)CFDataGetBytePtr(strData); + CFIndex len = CFDataGetLength(strData); + for(dex=0; dex>\n"); + return; + } + CFGregorianDate gregDate = CFAbsoluteTimeGetGregorianDate(absTime, NULL); + const char *month = "Unknown"; + if((gregDate.month > 12) || (gregDate.month <= 0)) { + printf("Huh? GregDate.month > 11. These amps only GO to 11.\n"); + } + else { + month = months[gregDate.month - 1]; + } + printf("%s %d, %d %02d:%02d", + month, gregDate.day, (int)gregDate.year, gregDate.hour, gregDate.minute); +} + +/* print a CFNumber */ +void printCfNumber( + CFNumberRef cfNum) +{ + SInt32 s; + if(!CFNumberGetValue(cfNum, kCFNumberSInt32Type, &s)) { + printf("***CFNumber overflow***"); + return; + } + printf("%d", (int)s); +} + +/* print a CFNumber as a SecTrustSettingsResult */ +void printResultType( + CFNumberRef cfNum) +{ + SInt32 n; + if(!CFNumberGetValue(cfNum, kCFNumberSInt32Type, &n)) { + printf("***CFNumber overflow***"); + return; + } + const char *s; + char bogus[100]; + switch(n) { + case kSecTrustSettingsResultInvalid: s = "kSecTrustSettingsResultInvalid"; break; + case kSecTrustSettingsResultTrustRoot: s = "kSecTrustSettingsResultTrustRoot"; break; + case kSecTrustSettingsResultTrustAsRoot: s = "kSecTrustSettingsResultTrustAsRoot"; break; + case kSecTrustSettingsResultDeny: s = "kSecTrustSettingsResultDeny"; break; + case kSecTrustSettingsResultUnspecified: s = "kSecTrustSettingsResultUnspecified"; break; + default: + sprintf(bogus, "Unknown SecTrustSettingsResult (%d)", (int)n); + s = bogus; + break; + } + printf("%s", s); +} + +/* print a CFNumber as SecTrustSettingsKeyUsage */ +void printKeyUsage( + CFNumberRef cfNum) +{ + SInt32 s; + if(!CFNumberGetValue(cfNum, kCFNumberSInt32Type, &s)) { + printf("***CFNumber overflow***"); + return; + } + uint32 n = (uint32)s; + if(n == kSecTrustSettingsKeyUseAny) { + printf(""); + return; + } + else if(n == 0) { + printf(""); + return; + } + printf("< "); + if(n & kSecTrustSettingsKeyUseSignature) { + printf("Signature "); + } + if(n & kSecTrustSettingsKeyUseEnDecryptData) { + printf("EnDecryptData "); + } + if(n & kSecTrustSettingsKeyUseEnDecryptKey) { + printf("EnDecryptKey "); + } + if(n & kSecTrustSettingsKeyUseSignCert) { + printf("SignCert "); + } + if(n & kSecTrustSettingsKeyUseSignRevocation) { + printf("SignRevocation "); + } + if(n & kSecTrustSettingsKeyUseKeyExchange) { + printf("KeyExchange "); + } + printf(" >"); +} + +/* print a CFNumber as CSSM_RETURN string */ +void printCssmErr( + CFNumberRef cfNum) +{ + SInt32 s; + if(!CFNumberGetValue(cfNum, kCFNumberSInt32Type, &s)) { + printf("***CFNumber overflow***"); + return; + } + printf("%s", cssmErrorString((CSSM_RETURN)s)); +} + +/* convert an OID to a SecPolicyRef */ +SecPolicyRef oidToPolicy( + const CSSM_OID *oid) +{ + OSStatus ortn; + SecPolicyRef policyRef = NULL; + + ortn = SecPolicyCopy(CSSM_CERT_X_509v3, oid, &policyRef); + if(ortn) { + cssmPerror("SecPolicyCopy", ortn); + return NULL; + } + return policyRef; +} + +typedef struct { + const CSSM_OID *oid; + const char *oidStr; +} OidString; + +static OidString oidStrings[] = +{ + { &CSSMOID_APPLE_ISIGN, "iSign" }, + { &CSSMOID_APPLE_X509_BASIC, "Apple X509 Basic" }, + { &CSSMOID_APPLE_TP_SSL, "SSL" }, + { &CSSMOID_APPLE_TP_SMIME, "SMIME" }, + { &CSSMOID_APPLE_TP_EAP, "EAP" }, + { &CSSMOID_APPLE_TP_SW_UPDATE_SIGNING, "SW Update Signing" }, + { &CSSMOID_APPLE_TP_IP_SEC, "IPSec" }, + { &CSSMOID_APPLE_TP_ICHAT, "iChat" }, + { &CSSMOID_APPLE_TP_RESOURCE_SIGN, "Resource Signing" }, + { &CSSMOID_APPLE_TP_PKINIT_CLIENT, "PKINIT Client" }, + { &CSSMOID_APPLE_TP_PKINIT_SERVER, "PKINIT Server" }, + { &CSSMOID_APPLE_TP_CODE_SIGNING, "Code Signing" }, + { &CSSMOID_APPLE_TP_PACKAGE_SIGNING, "Package Signing" }, + { &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT, "Mac App Store" }, + { &CSSMOID_APPLE_TP_APPLEID_SHARING, "AppleID Sharing" } +}; +#define NUM_OID_STRINGS (sizeof(oidStrings) / sizeof(oidStrings[0])) + +/* convert a policy string to a SecPolicyRef */ +SecPolicyRef oidStringToPolicy( + const char *oidStr) +{ + /* OID string to an OID pointer */ + const CSSM_OID *oid = NULL; + unsigned dex; + + for(dex=0; dexoidStr)) { + oid = os->oid; + break; + } + } + if(oid == NULL) { + return NULL; + } + + /* OID to SecPolicyRef */ + return oidToPolicy(oid); +} + +/* CSSM_OID --> OID string */ +const char *oidToOidString( + const CSSM_OID *oid) +{ + unsigned dex; + static char unknownOidString[200]; + + for(dex=0; dexoid)) { + return os->oidStr; + } + } + sprintf(unknownOidString, "Unknown OID length %ld, value { ", oid->Length); + for(dex=0; dexLength; dex++) { + char tmp[6]; + sprintf(tmp, "%02X ", oid->Data[dex]); + strcat(unknownOidString, tmp); + } + strcat(unknownOidString, " }"); + return unknownOidString; +} + +/* compare OIDs; returns 1 if identical, else returns 0 */ +int compareOids( + const CSSM_OID *oid1, + const CSSM_OID *oid2) +{ + if((oid1 == NULL) || (oid2 == NULL)) { + return 0; + } + if(oid1->Length != oid2->Length) { + return 0; + } + if(memcmp(oid1->Data, oid2->Data, oid1->Length)) { + return 0; + } + return 1; +} + +/* app path string to SecTrustedApplicationRef */ +SecTrustedApplicationRef appPathToAppRef( + const char *appPath) +{ + SecTrustedApplicationRef appRef = NULL; + OSStatus ortn; + + if(appPath == NULL) { + return NULL; + } + ortn = SecTrustedApplicationCreateFromPath(appPath, &appRef); + if(ortn) { + cssmPerror("SecTrustedApplicationCreateFromPath", ortn); + return NULL; + } + return appRef; +} + +int readCertFile( + const char *fileName, + SecCertificateRef *certRef) +{ + unsigned char *cp = NULL; + unsigned len = 0; + CSSM_DATA certData; + OSStatus ortn; + unsigned char *decoded = NULL; + unsigned decodedLen = 0; + + if(readFile(fileName, &cp, &len)) { + printf("***Error reading file %s\n", fileName); + return -1; + } + if(isPem(cp, len)) { + if(pemDecode(cp, len, &decoded, &decodedLen)) { + fprintf(stderr, "Error decoding cert file %s\n", fileName); + return -1; + } + certData.Length = decodedLen; + certData.Data = decoded; + } + else { + certData.Length = len; + certData.Data = cp; + } + ortn = SecCertificateCreateFromData(&certData, + CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER, certRef); + free(cp); + if(decoded) { + free(decoded); + } + if(ortn) { + cssmPerror("SecCertificateCreateFromData", ortn); + return -1; + } + return 0; +} + +/* policy string --> CSSM_OID */ +const CSSM_OID *policyStringToOid( + const char *policy) +{ + if(policy == NULL) { + return NULL; + } + if(!strcmp(policy, "ssl")) { + return &CSSMOID_APPLE_TP_SSL; + } + else if(!strcmp(policy, "smime")) { + return &CSSMOID_APPLE_TP_SMIME; + } + else if(!strcmp(policy, "codeSign")) { + return &CSSMOID_APPLE_TP_CODE_SIGNING; + } + else if(!strcmp(policy, "IPSec")) { + return &CSSMOID_APPLE_TP_IP_SEC; + } + else if(!strcmp(policy, "iChat")) { + return &CSSMOID_APPLE_TP_ICHAT; + } + else if(!strcmp(policy, "basic")) { + return &CSSMOID_APPLE_X509_BASIC; + } + else if(!strcmp(policy, "swUpdate")) { + return &CSSMOID_APPLE_TP_SW_UPDATE_SIGNING; + } + else if(!strcmp(policy, "pkgSign")) { + return &CSSMOID_APPLE_TP_PACKAGE_SIGNING; + } + else if(!strcmp(policy, "pkinitClient")) { + return &CSSMOID_APPLE_TP_PKINIT_CLIENT; + } + else if(!strcmp(policy, "pkinitServer")) { + return &CSSMOID_APPLE_TP_PKINIT_SERVER; + } + else if(!strcmp(policy, "eap")) { + return &CSSMOID_APPLE_TP_EAP; + } + else if(!strcmp(policy, "macappstore")) { + return &CSSMOID_APPLE_TP_MACAPPSTORE_RECEIPT; + } + else if(!strcmp(policy, "appleID")) { + return &CSSMOID_APPLE_TP_APPLEID_SHARING; + } + else if(!strcmp(policy, "timestamping")) { + return &CSSMOID_APPLE_TP_TIMESTAMPING; + } + else { + fprintf(stderr, "***unknown policy spec (%s)\n", policy); + return NULL; + } +}