1/* 2 * Copyright (c) 2002-2004,2011-2014 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// 25// Identity.cpp - Working with Identities 26// 27#include <security_keychain/Identity.h> 28 29#include <security_cdsa_utilities/KeySchema.h> 30#include <security_keychain/KCCursor.h> 31#include <string.h> 32 33using namespace KeychainCore; 34 35Identity::Identity(const SecPointer<KeyItem> &privateKey, 36 const SecPointer<Certificate> &certificate) : 37 mPrivateKey(privateKey), 38 mCertificate(certificate) 39{ 40} 41 42Identity::Identity(const StorageManager::KeychainList &keychains, const SecPointer<Certificate> &certificate) : 43 mCertificate(certificate) 44{ 45 // Find a key whose label matches the publicKeyHash of the public key in the certificate. 46 KCCursor keyCursor(keychains, CSSM_DL_DB_RECORD_PRIVATE_KEY, NULL); 47 keyCursor->add(CSSM_DB_EQUAL, KeySchema::Label, certificate->publicKeyHash()); 48 49 Item key; 50 if (!keyCursor->next(key)) 51 MacOSError::throwMe(errSecItemNotFound); 52 53 SecPointer<KeyItem> keyItem(static_cast<KeyItem *>(&*key)); 54 mPrivateKey = keyItem; 55} 56 57Identity::~Identity() throw() 58{ 59} 60 61SecPointer<KeyItem> 62Identity::privateKey() const 63{ 64 return mPrivateKey; 65} 66 67SecPointer<Certificate> 68Identity::certificate() const 69{ 70 return mCertificate; 71} 72 73bool 74Identity::operator < (const Identity &other) const 75{ 76 // Certificates in different keychains are considered equal if data is equal 77 return (mCertificate < other.mCertificate); 78} 79 80bool 81Identity::operator == (const Identity &other) const 82{ 83 // Certificates in different keychains are considered equal if data is equal; 84 // however, if their keys are in different keychains, the identities should 85 // not be considered equal (according to mb) 86 return (mCertificate == other.mCertificate && mPrivateKey == other.mPrivateKey); 87} 88 89bool Identity::equal(SecCFObject &other) 90{ 91 CFHashCode this_hash = hash(); 92 CFHashCode other_hash = other.hash(); 93 return (this_hash == other_hash); 94} 95 96CFHashCode Identity::hash() 97{ 98 CFHashCode result = SecCFObject::hash(); 99 100 101 struct keyAndCertHash 102 { 103 CFHashCode keyHash; 104 CFHashCode certHash; 105 }; 106 107 struct keyAndCertHash hashes; 108 memset(&hashes, 0, sizeof(struct keyAndCertHash)); 109 110 KeyItem* pKeyItem = mPrivateKey.get(); 111 if (NULL != pKeyItem) 112 { 113 hashes.keyHash = pKeyItem->hash(); 114 } 115 116 Certificate* pCert = mCertificate.get(); 117 if (NULL != pCert) 118 { 119 hashes.certHash = pCert->hash(); 120 } 121 122 if (hashes.keyHash != 0 || hashes.certHash != 0) 123 { 124 125 CFDataRef temp_data = CFDataCreateWithBytesNoCopy(NULL, (const UInt8 *)&hashes, sizeof(struct keyAndCertHash), kCFAllocatorNull); 126 if (NULL != temp_data) 127 { 128 result = CFHash(temp_data); 129 CFRelease(temp_data); 130 } 131 } 132 133 return result; 134} 135 136