1/* 2 * Copyright (c) 2002-2013 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#include <Security/SecCertificate.h> 25#include <Security/SecCertificatePriv.h> 26#include <security_keychain/Certificate.h> 27#include <security_keychain/Item.h> 28#include <security_keychain/KCCursor.h> 29#include <Security/cssmapi.h> 30#include <Security/cssmapple.h> 31#include <security_cdsa_client/cspclient.h> 32#include <security_cdsa_client/clclient.h> 33#include <security_cdsa_client/tpclient.h> 34#include <Security/cssmtype.h> 35 36#include "SecBridge.h" 37 38// %%% used by SecCertificate{Copy,Set}Preference 39#include <Security/SecKeychainItemPriv.h> 40#include <Security/SecIdentityPriv.h> 41#include <security_keychain/KCCursor.h> 42#include <security_cdsa_utilities/Schema.h> 43#include <sys/param.h> 44#include "CertificateValues.h" 45#include "SecCertificateP.h" 46#include "SecCertificatePrivP.h" 47// 48//#include "AppleBaselineEscrowCertificates.h" 49// 50//###################################################################### 51//%%% start workaround: rdar://14292830 52//###################################################################### 53 54#ifndef sec_AppleBaselineEscrowCertificates_h 55#define sec_AppleBaselineEscrowCertificates_h 56 57struct RootRecord 58{ 59 size_t _length; 60 UInt8* _bytes; 61}; 62 63/* ========================================================================== 64 Production Escrow Certificates 65 ========================================================================== */ 66 67static const UInt8 kProductionEscrowRootGM[] = { 68 0x30,0x82,0x03,0xD0,0x30,0x82,0x02,0xB8,0xA0,0x03,0x02,0x01,0x02,0x02,0x01,0x64, 69 0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x30, 70 0x79,0x31,0x0C,0x30,0x0A,0x06,0x03,0x55,0x04,0x05,0x13,0x03,0x31,0x30,0x30,0x31, 71 0x0B,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11, 72 0x06,0x03,0x55,0x04,0x0A,0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63, 73 0x2E,0x31,0x26,0x30,0x24,0x06,0x03,0x55,0x04,0x0B,0x13,0x1D,0x41,0x70,0x70,0x6C, 74 0x65,0x20,0x43,0x65,0x72,0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20, 75 0x41,0x75,0x74,0x68,0x6F,0x72,0x69,0x74,0x79,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55, 76 0x04,0x03,0x13,0x16,0x45,0x73,0x63,0x72,0x6F,0x77,0x20,0x53,0x65,0x72,0x76,0x69, 77 0x63,0x65,0x20,0x52,0x6F,0x6F,0x74,0x20,0x43,0x41,0x30,0x1E,0x17,0x0D,0x31,0x33, 78 0x30,0x38,0x30,0x32,0x32,0x33,0x32,0x34,0x34,0x34,0x5A,0x17,0x0D,0x32,0x33,0x30, 79 0x38,0x30,0x32,0x32,0x33,0x32,0x34,0x34,0x34,0x5A,0x30,0x79,0x31,0x0C,0x30,0x0A, 80 0x06,0x03,0x55,0x04,0x05,0x13,0x03,0x31,0x30,0x30,0x31,0x0B,0x30,0x09,0x06,0x03, 81 0x55,0x04,0x06,0x13,0x02,0x55,0x53,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x0A, 82 0x13,0x0A,0x41,0x70,0x70,0x6C,0x65,0x20,0x49,0x6E,0x63,0x2E,0x31,0x26,0x30,0x24, 83 0x06,0x03,0x55,0x04,0x0B,0x13,0x1D,0x41,0x70,0x70,0x6C,0x65,0x20,0x43,0x65,0x72, 84 0x74,0x69,0x66,0x69,0x63,0x61,0x74,0x69,0x6F,0x6E,0x20,0x41,0x75,0x74,0x68,0x6F, 85 0x72,0x69,0x74,0x79,0x31,0x1F,0x30,0x1D,0x06,0x03,0x55,0x04,0x03,0x13,0x16,0x45, 86 0x73,0x63,0x72,0x6F,0x77,0x20,0x53,0x65,0x72,0x76,0x69,0x63,0x65,0x20,0x52,0x6F, 87 0x6F,0x74,0x20,0x43,0x41,0x30,0x82,0x01,0x22,0x30,0x0D,0x06,0x09,0x2A,0x86,0x48, 88 0x86,0xF7,0x0D,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0F,0x00,0x30,0x82,0x01, 89 0x0A,0x02,0x82,0x01,0x01,0x00,0xD0,0xA3,0xF4,0x56,0x7D,0x3F,0x46,0x31,0xD2,0x56, 90 0xA0,0xDF,0x42,0xA0,0x29,0x83,0x1E,0xB9,0x82,0xB5,0xA5,0xFF,0x3E,0xDE,0xB5,0x0F, 91 0x4A,0x8A,0x28,0x60,0xCF,0x75,0xB4,0xA0,0x70,0x7C,0xF5,0xE2,0x94,0xF3,0x22,0x02, 92 0xC8,0x81,0xCE,0x34,0xC7,0x66,0x6A,0x18,0xAA,0xB4,0xFD,0x6D,0xB0,0x0B,0xDD,0x4A, 93 0xDD,0xCF,0xE0,0x08,0x1B,0x1C,0xA6,0xDB,0xBA,0xB2,0xC1,0xA4,0x10,0x5F,0x35,0x4F, 94 0x8B,0x8B,0x7A,0xA3,0xDB,0x3C,0xF6,0x54,0x95,0x42,0xAD,0x2A,0x3B,0xFE,0x06,0x8C, 95 0xE1,0x92,0xF1,0x60,0x97,0x58,0x1B,0xD9,0x8F,0xBE,0xFB,0x46,0x4C,0x29,0x5C,0x1C, 96 0xF0,0x20,0xB6,0x2B,0xA5,0x12,0x09,0x9B,0x28,0x41,0x34,0x97,0x9F,0xF3,0x88,0x4B, 97 0x69,0x72,0xEA,0x3A,0x27,0xB0,0x50,0x1D,0x88,0x29,0x0D,0xBB,0xED,0x04,0xA2,0x11, 98 0xCF,0x0C,0x5B,0x65,0x61,0x35,0xBD,0xF2,0x0D,0xFC,0xE2,0xB9,0x20,0xD3,0xB7,0x03, 99 0x70,0x39,0xD5,0xE0,0x86,0x7C,0x04,0xCC,0xC9,0xA1,0x85,0xB4,0x9B,0xBC,0x88,0x4E, 100 0xD7,0xAD,0x5C,0xFF,0x2C,0x0D,0x80,0x8E,0x51,0x39,0x20,0x8B,0xAF,0x1E,0x46,0x95, 101 0xFA,0x0D,0x1B,0xD2,0xBF,0x80,0xE0,0x9F,0x6D,0x4A,0xF5,0x31,0x67,0x18,0x11,0xA5, 102 0x63,0x27,0x08,0xEE,0xD9,0x07,0x29,0xD0,0xD4,0x36,0x91,0x5B,0xFB,0x4A,0x0B,0x07, 103 0xD1,0x0D,0x79,0x16,0x6E,0x16,0x02,0x23,0x80,0xC6,0x15,0x07,0x6D,0xA0,0x06,0xB6, 104 0x45,0x90,0xB0,0xAE,0xA4,0xAD,0x0E,0x75,0x04,0x2B,0x2B,0x78,0xF1,0x57,0x84,0x23, 105 0x87,0x24,0xEC,0x58,0xC4,0xF1,0x02,0x03,0x01,0x00,0x01,0xA3,0x63,0x30,0x61,0x30, 106 0x0F,0x06,0x03,0x55,0x1D,0x13,0x01,0x01,0xFF,0x04,0x05,0x30,0x03,0x01,0x01,0xFF, 107 0x30,0x0E,0x06,0x03,0x55,0x1D,0x0F,0x01,0x01,0xFF,0x04,0x04,0x03,0x02,0x01,0x06, 108 0x30,0x1D,0x06,0x03,0x55,0x1D,0x0E,0x04,0x16,0x04,0x14,0xFD,0x78,0x96,0x53,0x80, 109 0xD6,0xF6,0xDC,0xA6,0xC3,0x59,0x06,0x38,0xED,0x79,0x3E,0x8F,0x50,0x1B,0x50,0x30, 110 0x1F,0x06,0x03,0x55,0x1D,0x23,0x04,0x18,0x30,0x16,0x80,0x14,0xFD,0x78,0x96,0x53, 111 0x80,0xD6,0xF6,0xDC,0xA6,0xC3,0x59,0x06,0x38,0xED,0x79,0x3E,0x8F,0x50,0x1B,0x50, 112 0x30,0x0D,0x06,0x09,0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,0x05,0x00,0x03, 113 0x82,0x01,0x01,0x00,0x71,0x15,0xCA,0x87,0xD0,0x2D,0xB5,0x18,0xD5,0x35,0x7A,0xCD, 114 0xDF,0x62,0x28,0xF0,0x0B,0x63,0x4D,0x4E,0x02,0xBA,0x3D,0xB8,0xB4,0x37,0xEA,0xB0, 115 0x93,0x93,0xAB,0x1C,0xFD,0x9F,0xE8,0x72,0xBF,0xF3,0xDB,0xE6,0xAD,0x16,0xFE,0x71, 116 0x61,0xA8,0x5A,0xD0,0x58,0x0F,0x65,0x7A,0x57,0x7A,0xE0,0x34,0x80,0x8E,0xBB,0x41, 117 0x01,0xE7,0xB0,0x3B,0xF7,0x2B,0x3A,0x6D,0x44,0x2A,0x3A,0x04,0x52,0xFA,0x2B,0x7B, 118 0x3B,0x21,0xDD,0x0C,0x70,0x3D,0xFB,0x45,0xC6,0x79,0x68,0x62,0xE2,0x89,0xB8,0x25, 119 0xEE,0x63,0x76,0x02,0xB2,0x22,0xE9,0x53,0x85,0x68,0x3E,0x75,0xB6,0x0B,0x65,0xE9, 120 0x1C,0xBA,0x84,0x93,0xB0,0x8A,0xEF,0xB5,0x1A,0x12,0xE4,0x8F,0xAE,0xD5,0x5C,0xA1, 121 0x05,0x4A,0x01,0xBC,0x6F,0xF9,0x58,0x5E,0xF7,0x04,0x61,0xEE,0xF5,0xC6,0xA0,0x1B, 122 0x44,0x2E,0x5A,0x3A,0x59,0xA1,0xB3,0xB0,0xF4,0xB6,0xCB,0xE0,0x6C,0x2B,0x59,0x8A, 123 0xFB,0x6A,0xE0,0xA2,0x57,0x09,0x79,0xC1,0xDD,0xFB,0x84,0x86,0xEB,0x66,0x29,0x73, 124 0xAE,0xBF,0x58,0xAE,0x47,0x4D,0x48,0x37,0xD6,0xB1,0x8C,0x5F,0x26,0x5F,0xB5,0x26, 125 0x07,0x0B,0x85,0xB7,0x36,0x37,0x14,0xCF,0x5E,0x55,0xA5,0x3C,0xF3,0x1E,0x79,0x50, 126 0xBB,0x85,0x3B,0xB2,0x94,0x68,0xB0,0x25,0x4F,0x75,0xEC,0xF0,0xF9,0xC0,0x5A,0x2D, 127 0xE5,0xED,0x67,0xCD,0x88,0x55,0xA0,0x42,0xDE,0x78,0xBC,0xFE,0x30,0xB1,0x62,0x2D, 128 0xE1,0xFD,0xEC,0x75,0x03,0xA6,0x1F,0x7C,0xC4,0x3A,0x4A,0x59,0xFE,0x77,0xC3,0x99, 129 0x96,0x87,0x44,0xC3, 130}; 131 132static struct RootRecord kProductionEscrowRootRecord = {sizeof(kProductionEscrowRootGM), (UInt8*)kProductionEscrowRootGM}; 133static struct RootRecord* kProductionEscrowRoots[] = {&kProductionEscrowRootRecord}; 134static const int kNumberOfProductionEscrowRoots = (int)(sizeof(kProductionEscrowRoots)/sizeof(kProductionEscrowRoots[0])); 135 136static struct RootRecord kBaseLineEscrowRootRecord = {sizeof(kProductionEscrowRootGM), (UInt8*)kProductionEscrowRootGM}; 137static struct RootRecord* kBaseLineEscrowRoots[] = {&kBaseLineEscrowRootRecord}; 138static const int kNumberOfBaseLineEscrowRoots = (int)(sizeof(kBaseLineEscrowRoots)/sizeof(kBaseLineEscrowRoots[0])); 139 140 141#endif 142//###################################################################### 143//%%% end workaround: rdar://14292830 144////###################################################################### 145 146 147extern CSSM_KEYUSE ConvertArrayToKeyUsage(CFArrayRef usage); 148 149#define SEC_CONST_DECL(k,v) CFTypeRef k = (CFTypeRef)(CFSTR(v)); 150 151SEC_CONST_DECL (kSecCertificateProductionEscrowKey, "ProductionEscrowKey"); 152SEC_CONST_DECL (kSecCertificateEscrowFileName, "AppleESCertificates"); 153 154 155using namespace CssmClient; 156 157CFTypeID 158SecCertificateGetTypeID(void) 159{ 160 BEGIN_SECAPI 161 162 return gTypes().Certificate.typeID; 163 164 END_SECAPI1(_kCFRuntimeNotATypeID) 165} 166 167 168OSStatus 169SecCertificateCreateFromData(const CSSM_DATA *data, CSSM_CERT_TYPE type, CSSM_CERT_ENCODING encoding, SecCertificateRef *certificate) 170{ 171 BEGIN_SECAPI 172 173 SecPointer<Certificate> certificatePtr(new Certificate(Required(data), type, encoding)); 174 Required(certificate) = certificatePtr->handle(); 175 176 END_SECAPI 177} 178 179/* new in 10.6 */ 180SecCertificateRef 181SecCertificateCreateWithData(CFAllocatorRef allocator, CFDataRef data) 182{ 183 SecCertificateRef certificate = NULL; 184 OSStatus __secapiresult; 185 try { 186 CSSM_DATA cssmCertData; 187 cssmCertData.Length = (data) ? (CSSM_SIZE)CFDataGetLength(data) : 0; 188 cssmCertData.Data = (data) ? (uint8 *)CFDataGetBytePtr(data) : NULL; 189 190 //NOTE: there isn't yet a Certificate constructor which accepts a CFAllocatorRef 191 SecPointer<Certificate> certificatePtr(new Certificate(cssmCertData, CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER)); 192 certificate = certificatePtr->handle(); 193 194 __secapiresult=errSecSuccess; 195 } 196 catch (const MacOSError &err) { __secapiresult=err.osStatus(); } 197 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); } 198 catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; } 199 catch (...) { __secapiresult=errSecInternalComponent; } 200 return certificate; 201} 202 203OSStatus 204SecCertificateAddToKeychain(SecCertificateRef certificate, SecKeychainRef keychain) 205{ 206 BEGIN_SECAPI 207 208 Item item(Certificate::required(certificate)); 209 Keychain::optional(keychain)->add(item); 210 211 END_SECAPI 212} 213 214OSStatus 215SecCertificateGetData(SecCertificateRef certificate, CSSM_DATA_PTR data) 216{ 217 BEGIN_SECAPI 218 219 Required(data) = Certificate::required(certificate)->data(); 220 221 END_SECAPI 222} 223 224/* new in 10.6 */ 225CFDataRef 226SecCertificateCopyData(SecCertificateRef certificate) 227{ 228 CFDataRef data = NULL; 229 OSStatus __secapiresult = errSecSuccess; 230 try { 231 CssmData output = Certificate::required(certificate)->data(); 232 CFIndex length = (CFIndex)output.length(); 233 const UInt8 *bytes = (const UInt8 *)output.data(); 234 if (length && bytes) { 235 data = CFDataCreate(NULL, bytes, length); 236 } 237 } 238 catch (const MacOSError &err) { __secapiresult=err.osStatus(); } 239 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); } 240 catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; } 241 catch (...) { __secapiresult=errSecInternalComponent; } 242 return data; 243} 244 245CFDataRef 246SecCertificateGetSHA1Digest(SecCertificateRef certificate) 247{ 248 CFDataRef data = NULL; 249 OSStatus __secapiresult = errSecSuccess; 250 try { 251 data = Certificate::required(certificate)->sha1Hash(); 252 } 253 catch (const MacOSError &err) { __secapiresult=err.osStatus(); } 254 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); } 255 catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; } 256 catch (...) { __secapiresult=errSecInternalComponent; } 257 return data; 258} 259 260CFArrayRef 261SecCertificateCopyDNSNames(SecCertificateRef certificate) 262{ 263 CFArrayRef names = NULL; 264 OSStatus __secapiresult = errSecSuccess; 265 try { 266 names = Certificate::required(certificate)->copyDNSNames(); 267 } 268 catch (const MacOSError &err) { __secapiresult=err.osStatus(); } 269 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); } 270 catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; } 271 catch (...) { __secapiresult=errSecInternalComponent; } 272 return names; 273} 274 275OSStatus 276SecCertificateGetType(SecCertificateRef certificate, CSSM_CERT_TYPE *certificateType) 277{ 278 BEGIN_SECAPI 279 280 Required(certificateType) = Certificate::required(certificate)->type(); 281 282 END_SECAPI 283} 284 285 286OSStatus 287SecCertificateGetSubject(SecCertificateRef certificate, const CSSM_X509_NAME **subject) 288{ 289 BEGIN_SECAPI 290 291 Required(subject) = Certificate::required(certificate)->subjectName(); 292 293 END_SECAPI 294} 295 296 297OSStatus 298SecCertificateGetIssuer(SecCertificateRef certificate, const CSSM_X509_NAME **issuer) 299{ 300 BEGIN_SECAPI 301 302 Required(issuer) = Certificate::required(certificate)->issuerName(); 303 304 END_SECAPI 305} 306 307 308OSStatus 309SecCertificateGetCLHandle(SecCertificateRef certificate, CSSM_CL_HANDLE *clHandle) 310{ 311 BEGIN_SECAPI 312 313 Required(clHandle) = Certificate::required(certificate)->clHandle(); 314 315 END_SECAPI 316} 317 318/* 319 * Private API to infer a display name for a SecCertificateRef which 320 * may or may not be in a keychain. 321 */ 322OSStatus 323SecCertificateInferLabel(SecCertificateRef certificate, CFStringRef *label) 324{ 325 BEGIN_SECAPI 326 327 Certificate::required(certificate)->inferLabel(false, 328 &Required(label)); 329 330 END_SECAPI 331} 332 333OSStatus 334SecCertificateCopyPublicKey(SecCertificateRef certificate, SecKeyRef *key) 335{ 336 BEGIN_SECAPI 337 338 Required(key) = Certificate::required(certificate)->publicKey()->handle(); 339 340 END_SECAPI 341} 342 343OSStatus 344SecCertificateGetAlgorithmID(SecCertificateRef certificate, const CSSM_X509_ALGORITHM_IDENTIFIER **algid) 345{ 346 BEGIN_SECAPI 347 348 Required(algid) = Certificate::required(certificate)->algorithmID(); 349 350 END_SECAPI 351} 352 353OSStatus 354SecCertificateCopyCommonName(SecCertificateRef certificate, CFStringRef *commonName) 355{ 356 BEGIN_SECAPI 357 358 Required(commonName) = Certificate::required(certificate)->commonName(); 359 360 END_SECAPI 361} 362 363/* new in 10.6 */ 364CFStringRef 365SecCertificateCopySubjectSummary(SecCertificateRef certificate) 366{ 367 CFStringRef summary = NULL; 368 OSStatus __secapiresult; 369 try { 370 Certificate::required(certificate)->inferLabel(false, &summary); 371 372 __secapiresult=errSecSuccess; 373 } 374 catch (const MacOSError &err) { __secapiresult=err.osStatus(); } 375 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); } 376 catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; } 377 catch (...) { __secapiresult=errSecInternalComponent; } 378 return summary; 379} 380 381CFStringRef 382SecCertificateCopyIssuerSummary(SecCertificateRef certificate) 383{ 384 CFStringRef issuerStr = NULL; 385 SecCertificateRefP certP = NULL; 386 CFDataRef certData = SecCertificateCopyData(certificate); 387 if (certData) { 388 certP = SecCertificateCreateWithDataP(NULL, certData); 389 CFRelease(certData); 390 } 391 if (certP) { 392 issuerStr = SecCertificateCopyIssuerSummaryP(certP); 393 CFRelease(certP); 394 } 395 return issuerStr; 396} 397 398OSStatus 399SecCertificateCopySubjectComponent(SecCertificateRef certificate, const CSSM_OID *component, CFStringRef *result) 400{ 401 BEGIN_SECAPI 402 403 Required(result) = Certificate::required(certificate)->distinguishedName(&CSSMOID_X509V1SubjectNameCStruct, component); 404 405 END_SECAPI 406} 407 408OSStatus 409SecCertificateGetCommonName(SecCertificateRef certificate, CFStringRef *commonName) 410{ 411 // deprecated SPI signature; replaced by SecCertificateCopyCommonName 412 return SecCertificateCopyCommonName(certificate, commonName); 413} 414 415OSStatus 416SecCertificateGetEmailAddress(SecCertificateRef certificate, CFStringRef *emailAddress) 417{ 418 BEGIN_SECAPI 419 420 Required(emailAddress) = Certificate::required(certificate)->copyFirstEmailAddress(); 421 422 END_SECAPI 423} 424 425OSStatus 426SecCertificateCopyEmailAddresses(SecCertificateRef certificate, CFArrayRef *emailAddresses) 427{ 428 BEGIN_SECAPI 429 430 Required(emailAddresses) = Certificate::required(certificate)->copyEmailAddresses(); 431 432 END_SECAPI 433} 434 435OSStatus 436SecCertificateCopyFieldValues(SecCertificateRef certificate, const CSSM_OID *field, CSSM_DATA_PTR **fieldValues) 437{ 438/* Return a zero terminated list of CSSM_DATA_PTR's with the values of the field specified by field. Caller must call releaseFieldValues to free the storage allocated by this call. */ 439 BEGIN_SECAPI 440 441 Required(fieldValues) = Certificate::required(certificate)->copyFieldValues(Required(field)); 442 443 END_SECAPI 444} 445 446OSStatus 447SecCertificateReleaseFieldValues(SecCertificateRef certificate, const CSSM_OID *field, CSSM_DATA_PTR *fieldValues) 448{ 449 BEGIN_SECAPI 450 451 Certificate::required(certificate)->releaseFieldValues(Required(field), fieldValues); 452 453 END_SECAPI 454} 455 456OSStatus 457SecCertificateCopyFirstFieldValue(SecCertificateRef certificate, const CSSM_OID *field, CSSM_DATA_PTR *fieldValue) 458{ 459 BEGIN_SECAPI 460 461 Required(fieldValue) = Certificate::required(certificate)->copyFirstFieldValue(Required(field)); 462 463 END_SECAPI 464} 465 466OSStatus 467SecCertificateReleaseFirstFieldValue(SecCertificateRef certificate, const CSSM_OID *field, CSSM_DATA_PTR fieldValue) 468{ 469 BEGIN_SECAPI 470 471 Certificate::required(certificate)->releaseFieldValue(Required(field), fieldValue); 472 473 END_SECAPI 474} 475 476OSStatus 477SecCertificateFindByIssuerAndSN(CFTypeRef keychainOrArray,const CSSM_DATA *issuer, 478 const CSSM_DATA *serialNumber, SecCertificateRef *certificate) 479{ 480 BEGIN_SECAPI 481 482 StorageManager::KeychainList keychains; 483 globals().storageManager.optionalSearchList(keychainOrArray, keychains); 484 Required(certificate) = Certificate::findByIssuerAndSN(keychains, CssmData::required(issuer), CssmData::required(serialNumber))->handle(); 485 486 END_SECAPI 487} 488 489OSStatus 490SecCertificateFindBySubjectKeyID(CFTypeRef keychainOrArray, const CSSM_DATA *subjectKeyID, 491 SecCertificateRef *certificate) 492{ 493 BEGIN_SECAPI 494 495 StorageManager::KeychainList keychains; 496 globals().storageManager.optionalSearchList(keychainOrArray, keychains); 497 Required(certificate) = Certificate::findBySubjectKeyID(keychains, CssmData::required(subjectKeyID))->handle(); 498 499 END_SECAPI 500} 501 502OSStatus 503SecCertificateFindByEmail(CFTypeRef keychainOrArray, const char *emailAddress, SecCertificateRef *certificate) 504{ 505 BEGIN_SECAPI 506 507 StorageManager::KeychainList keychains; 508 globals().storageManager.optionalSearchList(keychainOrArray, keychains); 509 Required(certificate) = Certificate::findByEmail(keychains, emailAddress)->handle(); 510 511 END_SECAPI 512} 513 514OSStatus 515SecKeychainSearchCreateForCertificateByIssuerAndSN(CFTypeRef keychainOrArray, const CSSM_DATA *issuer, 516 const CSSM_DATA *serialNumber, SecKeychainSearchRef *searchRef) 517{ 518 BEGIN_SECAPI 519 520 Required(searchRef); 521 522 StorageManager::KeychainList keychains; 523 globals().storageManager.optionalSearchList(keychainOrArray, keychains); 524 KCCursor cursor(Certificate::cursorForIssuerAndSN(keychains, CssmData::required(issuer), CssmData::required(serialNumber))); 525 *searchRef = cursor->handle(); 526 527 END_SECAPI 528} 529 530OSStatus 531SecKeychainSearchCreateForCertificateByIssuerAndSN_CF(CFTypeRef keychainOrArray, CFDataRef issuer, 532 CFDataRef serialNumber, SecKeychainSearchRef *searchRef) 533{ 534 BEGIN_SECAPI 535 536 Required(searchRef); 537 538 StorageManager::KeychainList keychains; 539 globals().storageManager.optionalSearchList(keychainOrArray, keychains); 540 Required(issuer); 541 Required(serialNumber); 542 KCCursor cursor(Certificate::cursorForIssuerAndSN_CF(keychains, issuer, serialNumber)); 543 *searchRef = cursor->handle(); 544 545 END_SECAPI 546} 547 548OSStatus 549SecKeychainSearchCreateForCertificateBySubjectKeyID(CFTypeRef keychainOrArray, const CSSM_DATA *subjectKeyID, 550 SecKeychainSearchRef *searchRef) 551{ 552 BEGIN_SECAPI 553 554 Required(searchRef); 555 556 StorageManager::KeychainList keychains; 557 globals().storageManager.optionalSearchList(keychainOrArray, keychains); 558 KCCursor cursor(Certificate::cursorForSubjectKeyID(keychains, CssmData::required(subjectKeyID))); 559 *searchRef = cursor->handle(); 560 561 END_SECAPI 562} 563 564OSStatus 565SecKeychainSearchCreateForCertificateByEmail(CFTypeRef keychainOrArray, const char *emailAddress, 566 SecKeychainSearchRef *searchRef) 567{ 568 BEGIN_SECAPI 569 570 Required(searchRef); 571 572 StorageManager::KeychainList keychains; 573 globals().storageManager.optionalSearchList(keychainOrArray, keychains); 574 KCCursor cursor(Certificate::cursorForEmail(keychains, emailAddress)); 575 *searchRef = cursor->handle(); 576 577 END_SECAPI 578} 579 580/* NOT EXPORTED YET; copied from SecurityInterface but could be useful in the future. 581CSSM_CSP_HANDLE 582SecGetAppleCSPHandle() 583{ 584 BEGIN_SECAPI 585 return CSP(gGuidAppleCSP)->handle(); 586 END_SECAPI1(NULL); 587} 588 589CSSM_CL_HANDLE 590SecGetAppleCLHandle() 591{ 592 BEGIN_SECAPI 593 return CL(gGuidAppleX509CL)->handle(); 594 END_SECAPI1(NULL); 595} 596*/ 597 598CSSM_RETURN 599SecDigestGetData (CSSM_ALGORITHMS alg, CSSM_DATA* digest, const CSSM_DATA* data) 600{ 601 BEGIN_SECAPI 602 // sanity checking 603 if (!digest || !digest->Data || !digest->Length || !data || !data->Data || !data->Length) 604 return errSecParam; 605 606 CSP csp(gGuidAppleCSP); 607 Digest context(csp, alg); 608 CssmData input(data->Data, data->Length); 609 CssmData output(digest->Data, digest->Length); 610 611 context.digest(input, output); 612 digest->Length = output.length(); 613 614 return CSSM_OK; 615 END_SECAPI1(1); 616} 617 618/* determine whether a cert is self-signed */ 619OSStatus SecCertificateIsSelfSigned( 620 SecCertificateRef certificate, 621 Boolean *isSelfSigned) /* RETURNED */ 622{ 623 BEGIN_SECAPI 624 625 *isSelfSigned = Certificate::required(certificate)->isSelfSigned(); 626 627 END_SECAPI 628} 629 630OSStatus 631SecCertificateCopyPreference( 632 CFStringRef name, 633 CSSM_KEYUSE keyUsage, 634 SecCertificateRef *certificate) 635{ 636 BEGIN_SECAPI 637 638 Required(name); 639 Required(certificate); 640 StorageManager::KeychainList keychains; 641 globals().storageManager.getSearchList(keychains); 642 KCCursor cursor(keychains, kSecGenericPasswordItemClass, NULL); 643 644 char idUTF8[MAXPATHLEN]; 645 if (!CFStringGetCString(name, idUTF8, sizeof(idUTF8)-1, kCFStringEncodingUTF8)) 646 idUTF8[0] = (char)'\0'; 647 CssmData service(const_cast<char *>(idUTF8), strlen(idUTF8)); 648 FourCharCode itemType = 'cprf'; 649 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecServiceItemAttr), service); 650 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecTypeItemAttr), itemType); 651 if (keyUsage) 652 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecScriptCodeItemAttr), (sint32)keyUsage); 653 654 Item prefItem; 655 if (!cursor->next(prefItem)) 656 MacOSError::throwMe(errSecItemNotFound); 657 658 // get persistent certificate reference 659 SecKeychainAttribute itemAttrs[] = { { kSecGenericItemAttr, 0, NULL } }; 660 SecKeychainAttributeList itemAttrList = { sizeof(itemAttrs) / sizeof(itemAttrs[0]), itemAttrs }; 661 prefItem->getContent(NULL, &itemAttrList, NULL, NULL); 662 663 // find certificate, given persistent reference data 664 CFDataRef pItemRef = CFDataCreateWithBytesNoCopy(NULL, (const UInt8 *)itemAttrs[0].data, itemAttrs[0].length, kCFAllocatorNull); 665 SecKeychainItemRef certItemRef = nil; 666 OSStatus status = SecKeychainItemCopyFromPersistentReference(pItemRef, &certItemRef); //%%% need to make this a method of ItemImpl 667 prefItem->freeContent(&itemAttrList, NULL); 668 if (pItemRef) 669 CFRelease(pItemRef); 670 if (status) 671 return status; 672 673 *certificate = (SecCertificateRef)certItemRef; 674 675 END_SECAPI 676} 677 678SecCertificateRef 679SecCertificateCopyPreferred( 680 CFStringRef name, 681 CFArrayRef keyUsage) 682{ 683 // This function will look for a matching preference in the following order: 684 // - matches the name and the supplied key use 685 // - matches the name and the special 'ANY' key use 686 // - matches the name with no key usage constraint 687 688 SecCertificateRef certRef = NULL; 689 CSSM_KEYUSE keyUse = ConvertArrayToKeyUsage(keyUsage); 690 OSStatus status = SecCertificateCopyPreference(name, keyUse, &certRef); 691 if (status != errSecSuccess && keyUse != CSSM_KEYUSE_ANY) 692 status = SecCertificateCopyPreference(name, CSSM_KEYUSE_ANY, &certRef); 693 if (status != errSecSuccess && keyUse != 0) 694 status = SecCertificateCopyPreference(name, 0, &certRef); 695 696 return certRef; 697} 698 699static OSStatus 700SecCertificateFindPreferenceItemWithNameAndKeyUsage( 701 CFTypeRef keychainOrArray, 702 CFStringRef name, 703 int32_t keyUsage, 704 SecKeychainItemRef *itemRef) 705{ 706 BEGIN_SECAPI 707 708 StorageManager::KeychainList keychains; 709 globals().storageManager.optionalSearchList(keychainOrArray, keychains); 710 KCCursor cursor(keychains, kSecGenericPasswordItemClass, NULL); 711 712 char idUTF8[MAXPATHLEN]; 713 idUTF8[0] = (char)'\0'; 714 if (name) 715 { 716 if (!CFStringGetCString(name, idUTF8, sizeof(idUTF8)-1, kCFStringEncodingUTF8)) 717 idUTF8[0] = (char)'\0'; 718 } 719 size_t idUTF8Len = strlen(idUTF8); 720 if (!idUTF8Len) 721 MacOSError::throwMe(errSecParam); 722 723 CssmData service(const_cast<char *>(idUTF8), idUTF8Len); 724 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecServiceItemAttr), service); 725 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecTypeItemAttr), (FourCharCode)'cprf'); 726 if (keyUsage) 727 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecScriptCodeItemAttr), (sint32)keyUsage); 728 729 Item item; 730 if (!cursor->next(item)) 731 MacOSError::throwMe(errSecItemNotFound); 732 733 if (itemRef) 734 *itemRef=item->handle(); 735 736 END_SECAPI 737} 738 739static 740OSStatus SecCertificateDeletePreferenceItemWithNameAndKeyUsage( 741 CFTypeRef keychainOrArray, 742 CFStringRef name, 743 int32_t keyUsage) 744{ 745 // when a specific key usage is passed, we'll only match & delete that pref; 746 // when a key usage of 0 is passed, all matching prefs should be deleted. 747 // maxUsages represents the most matches there could theoretically be, so 748 // cut things off at that point if we're still finding items (if they can't 749 // be deleted for some reason, we'd never break out of the loop.) 750 751 OSStatus status; 752 SecKeychainItemRef item = NULL; 753 int count = 0, maxUsages = 12; 754 while (++count <= maxUsages && 755 (status = SecCertificateFindPreferenceItemWithNameAndKeyUsage(keychainOrArray, name, keyUsage, &item)) == errSecSuccess) { 756 status = SecKeychainItemDelete(item); 757 CFRelease(item); 758 item = NULL; 759 } 760 761 // it's not an error if the item isn't found 762 return (status == errSecItemNotFound) ? errSecSuccess : status; 763} 764 765OSStatus SecCertificateSetPreference( 766 SecCertificateRef certificate, 767 CFStringRef name, 768 CSSM_KEYUSE keyUsage, 769 CFDateRef date) 770{ 771 if (!name) { 772 return errSecParam; 773 } 774 if (!certificate) { 775 // treat NULL certificate as a request to clear the preference 776 // (note: if keyUsage is 0, this clears all key usage prefs for name) 777 return SecCertificateDeletePreferenceItemWithNameAndKeyUsage(NULL, name, keyUsage); 778 } 779 780 BEGIN_SECAPI 781 782 // determine the account attribute 783 // 784 // This attribute must be synthesized from certificate label + pref item type + key usage, 785 // as only the account and service attributes can make a generic keychain item unique. 786 // For 'iprf' type items (but not 'cprf'), we append a trailing space. This insures that 787 // we can save a certificate preference if an identity preference already exists for the 788 // given service name, and vice-versa. 789 // If the key usage is 0 (i.e. the normal case), we omit the appended key usage string. 790 // 791 CFStringRef labelStr = nil; 792 Certificate::required(certificate)->inferLabel(false, &labelStr); 793 if (!labelStr) { 794 MacOSError::throwMe(errSecDataTooLarge); // data is "in a format which cannot be displayed" 795 } 796 CFIndex accountUTF8Len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(labelStr), kCFStringEncodingUTF8) + 1; 797 const char *templateStr = "%s [key usage 0x%X]"; 798 const int keyUsageMaxStrLen = 8; 799 accountUTF8Len += strlen(templateStr) + keyUsageMaxStrLen; 800 char accountUTF8[accountUTF8Len]; 801 if (!CFStringGetCString(labelStr, accountUTF8, accountUTF8Len-1, kCFStringEncodingUTF8)) 802 accountUTF8[0] = (char)'\0'; 803 if (keyUsage) 804 snprintf(accountUTF8, accountUTF8Len-1, templateStr, accountUTF8, keyUsage); 805 CssmData account(const_cast<char *>(accountUTF8), strlen(accountUTF8)); 806 CFRelease(labelStr); 807 808 // service attribute (name provided by the caller) 809 CFIndex serviceUTF8Len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(name), kCFStringEncodingUTF8) + 1;; 810 char serviceUTF8[serviceUTF8Len]; 811 if (!CFStringGetCString(name, serviceUTF8, serviceUTF8Len-1, kCFStringEncodingUTF8)) 812 serviceUTF8[0] = (char)'\0'; 813 CssmData service(const_cast<char *>(serviceUTF8), strlen(serviceUTF8)); 814 815 // look for existing preference item, in case this is an update 816 StorageManager::KeychainList keychains; 817 globals().storageManager.getSearchList(keychains); 818 KCCursor cursor(keychains, kSecGenericPasswordItemClass, NULL); 819 FourCharCode itemType = 'cprf'; 820 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecServiceItemAttr), service); 821 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecTypeItemAttr), itemType); 822 if (keyUsage) 823 cursor->add(CSSM_DB_EQUAL, Schema::attributeInfo(kSecScriptCodeItemAttr), (sint32)keyUsage); 824 if (date) 825 ; // %%%TBI 826 827 Item item(kSecGenericPasswordItemClass, 'aapl', 0, NULL, false); 828 bool add = (!cursor->next(item)); 829 // at this point, we either have a new item to add or an existing item to update 830 831 // set item attribute values 832 item->setAttribute(Schema::attributeInfo(kSecServiceItemAttr), service); 833 item->setAttribute(Schema::attributeInfo(kSecTypeItemAttr), itemType); 834 item->setAttribute(Schema::attributeInfo(kSecAccountItemAttr), account); 835 item->setAttribute(Schema::attributeInfo(kSecScriptCodeItemAttr), (sint32)keyUsage); 836 item->setAttribute(Schema::attributeInfo(kSecLabelItemAttr), service); 837 838 // date 839 if (date) 840 ; // %%%TBI 841 842 // generic attribute (store persistent certificate reference) 843 CFDataRef pItemRef = nil; 844 Certificate::required(certificate)->copyPersistentReference(pItemRef); 845 if (!pItemRef) { 846 MacOSError::throwMe(errSecInvalidItemRef); 847 } 848 const UInt8 *dataPtr = CFDataGetBytePtr(pItemRef); 849 CFIndex dataLen = CFDataGetLength(pItemRef); 850 CssmData pref(const_cast<void *>(reinterpret_cast<const void *>(dataPtr)), dataLen); 851 item->setAttribute(Schema::attributeInfo(kSecGenericItemAttr), pref); 852 CFRelease(pItemRef); 853 854 if (add) { 855 Keychain keychain = nil; 856 try { 857 keychain = globals().storageManager.defaultKeychain(); 858 if (!keychain->exists()) 859 MacOSError::throwMe(errSecNoSuchKeychain); // Might be deleted or not available at this time. 860 } 861 catch(...) { 862 keychain = globals().storageManager.defaultKeychainUI(item); 863 } 864 865 try { 866 keychain->add(item); 867 } 868 catch (const MacOSError &err) { 869 if (err.osStatus() != errSecDuplicateItem) 870 throw; // if item already exists, fall through to update 871 } 872 } 873 item->update(); 874 875 END_SECAPI 876} 877 878OSStatus SecCertificateSetPreferred( 879 SecCertificateRef certificate, 880 CFStringRef name, 881 CFArrayRef keyUsage) 882{ 883 CSSM_KEYUSE keyUse = ConvertArrayToKeyUsage(keyUsage); 884 return SecCertificateSetPreference(certificate, name, keyUse, NULL); 885} 886 887CFDictionaryRef SecCertificateCopyValues(SecCertificateRef certificate, CFArrayRef keys, CFErrorRef *error) 888{ 889 CFDictionaryRef result = NULL; 890 OSStatus __secapiresult; 891 try 892 { 893 CertificateValues cv(certificate); 894 result = cv.copyFieldValues(keys,error); 895 __secapiresult=0; 896 } 897 catch (const MacOSError &err) { __secapiresult=err.osStatus(); } 898 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); } 899 catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; } 900 catch (...) { __secapiresult=errSecInternalComponent; } 901 return result; 902} 903 904CFStringRef SecCertificateCopyLongDescription(CFAllocatorRef alloc, SecCertificateRef certificate, CFErrorRef *error) 905{ 906 return SecCertificateCopyShortDescription(alloc, certificate, error); 907} 908 909CFStringRef SecCertificateCopyShortDescription(CFAllocatorRef alloc, SecCertificateRef certificate, CFErrorRef *error) 910{ 911 CFStringRef result = NULL; 912 OSStatus __secapiresult; 913 try 914 { 915 __secapiresult = SecCertificateInferLabel(certificate, &result); 916 } 917 catch (const MacOSError &err) { __secapiresult=err.osStatus(); } 918 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); } 919 catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; } 920 catch (...) { __secapiresult=errSecInternalComponent; } 921 if (error!=NULL && __secapiresult!=errSecSuccess) 922 { 923 *error = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainOSStatus, 924 __secapiresult ? __secapiresult : CSSM_ERRCODE_INTERNAL_ERROR, NULL); 925 } 926 return result; 927} 928 929CFDataRef SecCertificateCopySerialNumber(SecCertificateRef certificate, CFErrorRef *error) 930{ 931 CFDataRef result = NULL; 932 OSStatus __secapiresult; 933 try 934 { 935 CertificateValues cv(certificate); 936 result = cv.copySerialNumber(error); 937 __secapiresult=0; 938 } 939 catch (const MacOSError &err) { __secapiresult=err.osStatus(); } 940 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); } 941 catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; } 942 catch (...) { __secapiresult=errSecInternalComponent; } 943 return result; 944} 945 946CFDataRef SecCertificateCopyNormalizedIssuerContent(SecCertificateRef certificate, CFErrorRef *error) 947{ 948 CFDataRef result = NULL; 949 OSStatus __secapiresult; 950 try 951 { 952 CertificateValues cv(certificate); 953 result = cv.copyNormalizedIssuerContent(error); 954 __secapiresult=0; 955 } 956 catch (const MacOSError &err) { __secapiresult=err.osStatus(); } 957 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); } 958 catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; } 959 catch (...) { __secapiresult=errSecInternalComponent; } 960 return result; 961} 962 963CFDataRef SecCertificateCopyNormalizedSubjectContent(SecCertificateRef certificate, CFErrorRef *error) 964{ 965 CFDataRef result = NULL; 966 OSStatus __secapiresult; 967 try 968 { 969 CertificateValues cv(certificate); 970 result = cv.copyNormalizedSubjectContent(error); 971 __secapiresult=0; 972 } 973 catch (const MacOSError &err) { __secapiresult=err.osStatus(); } 974 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); } 975 catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; } 976 catch (...) { __secapiresult=errSecInternalComponent; } 977 return result; 978} 979 980CFDataRef SecCertificateCopyIssuerSequence(SecCertificateRef certificate) 981{ 982 CFDataRef result = NULL; 983 OSStatus __secapiresult; 984 try 985 { 986 CertificateValues cv(certificate); 987 result = cv.copyIssuerSequence(NULL); 988 __secapiresult=0; 989 } 990 catch (const MacOSError &err) { __secapiresult=err.osStatus(); } 991 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); } 992 catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; } 993 catch (...) { __secapiresult=errSecInternalComponent; } 994 return result; 995} 996 997CFDataRef SecCertificateCopySubjectSequence(SecCertificateRef certificate) 998{ 999 CFDataRef result = NULL; 1000 OSStatus __secapiresult; 1001 try 1002 { 1003 CertificateValues cv(certificate); 1004 result = cv.copySubjectSequence(NULL); 1005 __secapiresult=0; 1006 } 1007 catch (const MacOSError &err) { __secapiresult=err.osStatus(); } 1008 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); } 1009 catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; } 1010 catch (...) { __secapiresult=errSecInternalComponent; } 1011 return result; 1012} 1013 1014bool SecCertificateIsValid(SecCertificateRef certificate, CFAbsoluteTime verifyTime) 1015{ 1016 bool result = NULL; 1017 OSStatus __secapiresult; 1018 try 1019 { 1020 CFErrorRef error = NULL; 1021 CertificateValues cv(certificate); 1022 result = cv.isValid(verifyTime, &error); 1023 if (error) CFRelease(error); 1024 __secapiresult=0; 1025 } 1026 catch (const MacOSError &err) { __secapiresult=err.osStatus(); } 1027 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); } 1028 catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; } 1029 catch (...) { __secapiresult=errSecInternalComponent; } 1030 return result; 1031} 1032 1033/* 1034 * deprecated function name 1035 */ 1036bool SecCertificateIsValidX(SecCertificateRef certificate, CFAbsoluteTime verifyTime) 1037{ 1038 return SecCertificateIsValid(certificate, verifyTime); 1039} 1040 1041 1042CFAbsoluteTime SecCertificateNotValidBefore(SecCertificateRef certificate) 1043{ 1044 CFAbsoluteTime result = 0; 1045 OSStatus __secapiresult; 1046 try 1047 { 1048 CFErrorRef error = NULL; 1049 CertificateValues cv(certificate); 1050 result = cv.notValidBefore(&error); 1051 if (error) CFRelease(error); 1052 __secapiresult=0; 1053 } 1054 catch (const MacOSError &err) { __secapiresult=err.osStatus(); } 1055 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); } 1056 catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; } 1057 catch (...) { __secapiresult=errSecInternalComponent; } 1058 return result; 1059} 1060 1061CFAbsoluteTime SecCertificateNotValidAfter(SecCertificateRef certificate) 1062{ 1063 CFAbsoluteTime result = 0; 1064 OSStatus __secapiresult; 1065 try 1066 { 1067 CFErrorRef error = NULL; 1068 CertificateValues cv(certificate); 1069 result = cv.notValidAfter(&error); 1070 if (error) CFRelease(error); 1071 __secapiresult=0; 1072 } 1073 catch (const MacOSError &err) { __secapiresult=err.osStatus(); } 1074 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); } 1075 catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; } 1076 catch (...) { __secapiresult=errSecInternalComponent; } 1077 return result; 1078} 1079 1080/* new in 10.8 */ 1081SecCertificateRef SecCertificateCreateWithBytes(CFAllocatorRef allocator, 1082 const UInt8 *bytes, CFIndex length) 1083{ 1084 SecCertificateRef certificate = NULL; 1085 OSStatus __secapiresult; 1086 try { 1087 CSSM_DATA cssmCertData = { (CSSM_SIZE)length, (uint8 *)bytes }; 1088 1089 //NOTE: there isn't yet a Certificate constructor which accepts a CFAllocatorRef 1090 SecPointer<Certificate> certificatePtr(new Certificate(cssmCertData, CSSM_CERT_X_509v3, CSSM_CERT_ENCODING_DER)); 1091 certificate = certificatePtr->handle(); 1092 1093 __secapiresult=errSecSuccess; 1094 } 1095 catch (const MacOSError &err) { __secapiresult=err.osStatus(); } 1096 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); } 1097 catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; } 1098 catch (...) { __secapiresult=errSecInternalComponent; } 1099 return certificate; 1100} 1101 1102/* new in 10.8 */ 1103CFIndex SecCertificateGetLength(SecCertificateRef certificate) 1104{ 1105 CFIndex length = 0; 1106 OSStatus __secapiresult; 1107 try { 1108 CssmData output = Certificate::required(certificate)->data(); 1109 length = (CFIndex)output.length(); 1110 __secapiresult=errSecSuccess; 1111 } 1112 catch (const MacOSError &err) { __secapiresult=err.osStatus(); } 1113 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); } 1114 catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; } 1115 catch (...) { __secapiresult=errSecInternalComponent; } 1116 return length; 1117} 1118 1119/* new in 10.8 */ 1120const UInt8 *SecCertificateGetBytePtr(SecCertificateRef certificate) 1121{ 1122 const UInt8 *bytes = NULL; 1123 OSStatus __secapiresult; 1124 try { 1125 CssmData output = Certificate::required(certificate)->data(); 1126 bytes = (const UInt8 *)output.data(); 1127 __secapiresult=errSecSuccess; 1128 } 1129 catch (const MacOSError &err) { __secapiresult=err.osStatus(); } 1130 catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); } 1131 catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; } 1132 catch (...) { __secapiresult=errSecInternalComponent; } 1133 return bytes; 1134} 1135 1136static CFArrayRef CopyEscrowCertificates(CFErrorRef *error) 1137{ 1138 // Return array of CFDataRef certificates. 1139 CFArrayRef result = NULL; 1140 int iCnt; 1141 int numRoots = 0; 1142 1143 // Get the hard coded set of production roots 1144 // static struct RootRecord* kProductionEscrowRoots[] = {&kOldEscrowRootRecord, &kProductionEscrowRootRecord}; 1145 1146 numRoots = kNumberOfProductionEscrowRoots; 1147 CFDataRef productionCerts[numRoots]; 1148 struct RootRecord* pRootRecord = NULL; 1149 1150 for (iCnt = 0; iCnt < numRoots; iCnt++) 1151 { 1152 pRootRecord = kProductionEscrowRoots[iCnt]; 1153 if (NULL != pRootRecord && pRootRecord->_length > 0 && NULL != pRootRecord->_bytes) 1154 { 1155 productionCerts[iCnt] = CFDataCreate(kCFAllocatorDefault, pRootRecord->_bytes, pRootRecord->_length); 1156 } 1157 } 1158 result = CFArrayCreate(kCFAllocatorDefault, (const void **)productionCerts, numRoots, &kCFTypeArrayCallBacks); 1159 for (iCnt = 0; iCnt < numRoots; iCnt++) 1160 { 1161 if (NULL != productionCerts[iCnt]) 1162 { 1163 CFRelease(productionCerts[iCnt]); 1164 } 1165 } 1166 1167 return result; 1168} 1169 1170/* new in 10.9 */ 1171CFArrayRef SecCertificateCopyEscrowRoots(SecCertificateEscrowRootType escrowRootType) 1172{ 1173 CFArrayRef result = NULL; 1174 int iCnt; 1175 int numRoots = 0; 1176 CFDataRef certData = NULL; 1177 1178 // The request is for the base line certificates. 1179 // Use the hard coded data to generate the return array 1180 if (kSecCertificateBaselineEscrowRoot == escrowRootType) 1181 { 1182 // Get the hard coded set of roots 1183 numRoots = kNumberOfBaseLineEscrowRoots; 1184 SecCertificateRef baseLineCerts[numRoots]; 1185 struct RootRecord* pRootRecord = NULL; 1186 1187 for (iCnt = 0; iCnt < numRoots; iCnt++) 1188 { 1189 pRootRecord = kBaseLineEscrowRoots[iCnt]; 1190 if (NULL != pRootRecord && pRootRecord->_length > 0 && NULL != pRootRecord->_bytes) 1191 { 1192 certData = CFDataCreate(kCFAllocatorDefault, pRootRecord->_bytes, pRootRecord->_length); 1193 if (NULL != certData) 1194 { 1195 baseLineCerts[iCnt] = SecCertificateCreateWithData(kCFAllocatorDefault, certData); 1196 CFRelease(certData); 1197 } 1198 } 1199 } 1200 result = CFArrayCreate(kCFAllocatorDefault, (const void **)baseLineCerts, numRoots, &kCFTypeArrayCallBacks); 1201 for (iCnt = 0; iCnt < numRoots; iCnt++) 1202 { 1203 if (NULL != baseLineCerts[iCnt]) 1204 { 1205 CFRelease(baseLineCerts[iCnt]); 1206 } 1207 } 1208 } 1209 // The request is for the current certificates. 1210 else if (kSecCertificateProductionEscrowRoot == escrowRootType) 1211 { 1212 CFErrorRef error = NULL; 1213 CFArrayRef cert_datas = CopyEscrowCertificates(&error); 1214 if (NULL != error || NULL == cert_datas || 0 == (numRoots = (int)CFArrayGetCount(cert_datas))) 1215 { 1216 if (NULL != error) 1217 { 1218 CFRelease(error); 1219 } 1220 1221 if (NULL != cert_datas) 1222 { 1223 CFRelease(cert_datas); 1224 } 1225 return result; 1226 } 1227 1228 SecCertificateRef assetCerts[numRoots]; 1229 for (iCnt = 0; iCnt < numRoots; iCnt++) 1230 { 1231 certData = (CFDataRef)CFArrayGetValueAtIndex(cert_datas, iCnt); 1232 if (NULL != certData) 1233 { 1234 SecCertificateRef aCertRef = SecCertificateCreateWithData(kCFAllocatorDefault, certData); 1235 assetCerts[iCnt] = aCertRef; 1236 } 1237 else 1238 { 1239 assetCerts[iCnt] = NULL; 1240 } 1241 } 1242 1243 if (numRoots > 0) 1244 { 1245 result = CFArrayCreate(kCFAllocatorDefault, (const void **)assetCerts, numRoots, &kCFTypeArrayCallBacks); 1246 for (iCnt = 0; iCnt < numRoots; iCnt++) 1247 { 1248 if (NULL != assetCerts[iCnt]) 1249 { 1250 CFRelease(assetCerts[iCnt]); 1251 } 1252 } 1253 } 1254 CFRelease(cert_datas); 1255 } 1256 return result; 1257} 1258 1259