]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/dotMacArchive/identSearch.cpp
Security-57031.30.12.tar.gz
[apple/security.git] / SecurityTests / clxutils / dotMacArchive / identSearch.cpp
1 /*
2 * Copyright (c) 2004-2005 Apple Computer, 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 * identSearch.cpp - search for identity whose cert has specified email address
26 */
27
28 #include "identSearch.h"
29 #include <Security/SecKeychainItemPriv.h> /* for kSecAlias */
30
31 /*
32 * Does the specified identity's cert have the specified email address? Returns
33 * true if so.
34 */
35 bool idHasEmail(
36 SecIdentityRef idRef,
37 const void *emailAddress, // UTF8 encoded email address
38 unsigned emailAddressLen)
39 {
40 SecCertificateRef certRef;
41 OSStatus ortn;
42 bool ourRtn = false;
43
44 ortn = SecIdentityCopyCertificate(idRef, &certRef);
45 if(ortn) {
46 /* should never happen */
47 cssmPerror("SecIdentityCopyCertificate", ortn);
48 return ortn;
49 }
50
51 /*
52 * Fetch one attribute - the alias (which is always the "best attempt" at
53 * finding an email address within a cert).
54 */
55 UInt32 oneTag = kSecAlias;
56 SecKeychainAttributeInfo attrInfo;
57 attrInfo.count = 1;
58 attrInfo.tag = &oneTag;
59 attrInfo.format = NULL;
60 SecKeychainAttributeList *attrList = NULL;
61 SecKeychainAttribute *attr = NULL;
62
63 ortn = SecKeychainItemCopyAttributesAndData((SecKeychainItemRef)certRef,
64 &attrInfo,
65 NULL, // itemClass
66 &attrList,
67 NULL, // length - don't need the data
68 NULL); // outData
69 if(ortn || (attrList == NULL) || (attrList->count != 1)) {
70 /* I don't *think* this should ever happen... */
71 cssmPerror("SecKeychainItemCopyAttributesAndData", ortn);
72 goto errOut;
73 }
74 attr = attrList->attr;
75 if(attr->length == emailAddressLen) {
76 if(!memcmp(attr->data, emailAddress, emailAddressLen)) {
77 ourRtn = true;
78 }
79 }
80 errOut:
81 SecKeychainItemFreeAttributesAndData(attrList, NULL);
82 CFRelease(certRef);
83 return ourRtn;
84 }
85
86 /* public function */
87 OSStatus findIdentity(
88 const void *emailAddress, // UTF8 encoded email address
89 unsigned emailAddressLen,
90 SecKeychainRef kcRef, // keychain to search, or NULL to search all
91 SecIdentityRef *idRef) // RETURNED
92 {
93 OSStatus ortn;
94
95 /* Search for all identities */
96 SecIdentitySearchRef srchRef = nil;
97 ortn = SecIdentitySearchCreate(kcRef,
98 0, // keyUsage - any
99 &srchRef);
100 if(ortn) {
101 /* should never happen */
102 cssmPerror("SecIdentitySearchCreate", ortn);
103 return ortn;
104 }
105
106 SecIdentityRef foundId = NULL;
107 do {
108 SecIdentityRef thisId;
109 ortn = SecIdentitySearchCopyNext(srchRef, &thisId);
110 if(ortn != noErr) {
111 break;
112 }
113 /* email addres match? */
114 if(idHasEmail(thisId, emailAddress, emailAddressLen)) {
115 foundId = thisId;
116 break;
117 }
118 else {
119 /* we're done with thie identity */
120 CFRelease(thisId);
121 }
122 } while(ortn == noErr);
123 CFRelease(srchRef);
124 if(foundId) {
125 *idRef = foundId;
126 return noErr;
127 }
128 else {
129 return errSecItemNotFound;
130 }
131 }
132