X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/Security/libsecurity_keychain/lib/Identity.cpp?ds=inline diff --git a/Security/libsecurity_keychain/lib/Identity.cpp b/Security/libsecurity_keychain/lib/Identity.cpp new file mode 100644 index 00000000..826ed985 --- /dev/null +++ b/Security/libsecurity_keychain/lib/Identity.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2002-2004,2011-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@ + */ + +// +// Identity.cpp - Working with Identities +// +#include + +#include +#include +#include + +using namespace KeychainCore; + +Identity::Identity(const SecPointer &privateKey, + const SecPointer &certificate) : + mPrivateKey(privateKey), + mCertificate(certificate) +{ +} + +Identity::Identity(const StorageManager::KeychainList &keychains, const SecPointer &certificate) : + mCertificate(certificate) +{ + // Find a key whose label matches the publicKeyHash of the public key in the certificate. + KCCursor keyCursor(keychains, CSSM_DL_DB_RECORD_PRIVATE_KEY, NULL); + keyCursor->add(CSSM_DB_EQUAL, KeySchema::Label, certificate->publicKeyHash()); + + Item key; + if (!keyCursor->next(key)) + MacOSError::throwMe(errSecItemNotFound); + + SecPointer keyItem(static_cast(&*key)); + mPrivateKey = keyItem; +} + +Identity::~Identity() throw() +{ +} + +SecPointer +Identity::privateKey() const +{ + return mPrivateKey; +} + +SecPointer +Identity::certificate() const +{ + return mCertificate; +} + +bool +Identity::operator < (const Identity &other) const +{ + // Certificates in different keychains are considered equal if data is equal + return (mCertificate < other.mCertificate); +} + +bool +Identity::operator == (const Identity &other) const +{ + // Certificates in different keychains are considered equal if data is equal; + // however, if their keys are in different keychains, the identities should + // not be considered equal (according to mb) + return (mCertificate == other.mCertificate && mPrivateKey == other.mPrivateKey); +} + +bool Identity::equal(SecCFObject &other) +{ + CFHashCode this_hash = hash(); + CFHashCode other_hash = other.hash(); + return (this_hash == other_hash); +} + +CFHashCode Identity::hash() +{ + CFHashCode result = SecCFObject::hash(); + + + struct keyAndCertHash + { + CFHashCode keyHash; + CFHashCode certHash; + }; + + struct keyAndCertHash hashes; + memset(&hashes, 0, sizeof(struct keyAndCertHash)); + + KeyItem* pKeyItem = mPrivateKey.get(); + if (NULL != pKeyItem) + { + hashes.keyHash = pKeyItem->hash(); + } + + Certificate* pCert = mCertificate.get(); + if (NULL != pCert) + { + hashes.certHash = pCert->hash(); + } + + if (hashes.keyHash != 0 || hashes.certHash != 0) + { + + CFDataRef temp_data = CFDataCreateWithBytesNoCopy(NULL, (const UInt8 *)&hashes, sizeof(struct keyAndCertHash), kCFAllocatorNull); + if (NULL != temp_data) + { + result = CFHash(temp_data); + CFRelease(temp_data); + } + } + + return result; +} +