2 * Copyright (c) 2015 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
24 #include "kc-helpers.h"
25 #include <Security/Security.h>
27 #ifndef kc_identity_helpers_h
28 #define kc_identity_helpers_h
30 #pragma clang diagnostic push
31 #pragma clang diagnostic ignored "-Wunused-variable"
32 #pragma clang diagnostic ignored "-Wunused-function"
35 copyFirstIdentity(SecKeychainRef kc
)
37 // Returns the first SecIdentityRef we can find.
38 // This should always succeed since we can fall back on the system identity.
39 // Caller must release the reference.
41 CFMutableDictionaryRef query
= CFDictionaryCreateMutable(NULL
, 0,
42 &kCFTypeDictionaryKeyCallBacks
,
43 &kCFTypeDictionaryValueCallBacks
);
45 /* set up the query */
46 CFDictionaryAddValue( query
, kSecClass
, kSecClassIdentity
);
47 CFDictionaryAddValue( query
, kSecMatchLimit
, kSecMatchLimitAll
);
48 CFDictionaryAddValue( query
, kSecReturnRef
, kCFBooleanTrue
);
50 CFMutableArrayRef searchList
= (CFMutableArrayRef
) CFArrayCreateMutable(kCFAllocatorDefault
, 1, &kCFTypeArrayCallBacks
);
51 CFArrayAppendValue((CFMutableArrayRef
)searchList
, kc
);
52 CFDictionarySetValue(query
, kSecMatchSearchList
, searchList
);
54 CFTypeRef results
= NULL
;
55 OSStatus status
= SecItemCopyMatching(query
, &results
);
56 ok_status(status
, "%s: SecItemCopyMatching", testName
);
63 CFArrayRef resultArray
= (CFArrayRef
)results
;
64 SecIdentityRef identity
= (SecIdentityRef
)CFArrayGetValueAtIndex(resultArray
, 0);
65 CFRetain(identity
); // since we will return it
71 #define copyFirstIdentityTests 1
74 // - returns a SecIdentityRef for the first identity in the given keychain
75 // which matches the provided certificate.
78 findIdentity(SecKeychainRef keychain
, SecCertificateRef cert
)
80 OSStatus status
= noErr
;
81 SecIdentitySearchRef searchRef
= NULL
;
82 CSSM_DATA certData
= { 0, NULL
};
84 SecIdentityRef outIdentity
= NULL
;
86 if (!keychain
|| !cert
) {
90 // note: we should be using CFEqual on certificate references instead of
91 // comparing the certificate data, but that is currently broken
92 status
= SecCertificateGetData(cert
, &certData
);
93 ok_status(status
, "%s: findIdentity: SecCertificateGetData", testName
);
98 status
= SecIdentitySearchCreate(keychain
, (CSSM_KEYUSE
)0, &searchRef
);
100 SecIdentityRef identityRef
= NULL
;
101 status
= SecIdentitySearchCopyNext(searchRef
, &identityRef
);
103 SecCertificateRef aCert
= NULL
;
104 status
= SecIdentityCopyCertificate(identityRef
, &aCert
);
106 CSSM_DATA aCertData
= { 0, NULL
};
107 status
= SecCertificateGetData(aCert
, &aCertData
);
109 if (aCertData
.Length
== certData
.Length
&&
110 !memcmp(aCertData
.Data
, certData
.Data
, certData
.Length
)) {
111 // we found the identity
113 outIdentity
= identityRef
;
123 CFRelease(identityRef
);
127 ok(outIdentity
, "%s: findIdentity: found an identity", testName
);
130 CFRelease(searchRef
);
135 #define findIdentityTests 2
137 #pragma clang diagnostic pop
139 #endif /* kc_identity_helpers_h */