]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_keychain/lib/Identity.cpp
Security-57336.1.9.tar.gz
[apple/security.git] / OSX / libsecurity_keychain / lib / Identity.cpp
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
33 using namespace KeychainCore;
34
35 Identity::Identity(const SecPointer<KeyItem> &privateKey,
36 const SecPointer<Certificate> &certificate) :
37 mPrivateKey(privateKey),
38 mCertificate(certificate)
39 {
40 }
41
42 Identity::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
57 Identity::~Identity() throw()
58 {
59 }
60
61 SecPointer<KeyItem>
62 Identity::privateKey() const
63 {
64 return mPrivateKey;
65 }
66
67 SecPointer<Certificate>
68 Identity::certificate() const
69 {
70 return mCertificate;
71 }
72
73 bool
74 Identity::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
80 bool
81 Identity::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
89 bool Identity::equal(SecCFObject &other)
90 {
91 CFHashCode this_hash = hash();
92 CFHashCode other_hash = other.hash();
93 return (this_hash == other_hash);
94 }
95
96 CFHashCode 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