Factored out the name accessors of MYParsedCertificate into a new class MYCertificateName, so that both subject and issuer can be accessed. A bit of other cleanup too.
5 // Created by Jens Alfke on 3/31/09.
6 // Copyright 2009 Jens Alfke. All rights reserved.
9 #import "MYCrypto_Private.h"
11 #import "MYIdentity.h"
14 #if MYCRYPTO_USE_IPHONE_API
17 @interface MYKeyEnumerator : NSEnumerator
24 - (id) initWithQuery: (NSMutableDictionary*)query;
25 + (id) firstItemWithQuery: (NSMutableDictionary*)query;
30 @implementation MYKeychain
33 + (MYKeychain*) allKeychains
35 // iPhone only has a single keychain.
36 return [self defaultKeychain];
39 + (MYKeychain*) defaultKeychain
41 static MYKeychain *sDefaultKeychain;
43 if (!sDefaultKeychain) {
44 sDefaultKeychain = [[self alloc] init];
47 return sDefaultKeychain;
51 - (id) copyWithZone: (NSZone*)zone {
52 // It's not necessary to make copies of Keychain objects. This makes it more efficient
53 // to use instances as NSDictionary keys or store them in NSSets.
60 #pragma mark SEARCHING:
63 - (MYPublicKey*) publicKeyWithDigest: (MYSHA1Digest*)pubKeyDigest {
64 return [MYKeyEnumerator firstItemWithQuery:
65 $mdict({(id)kSecClass, (id)kSecClassKey},
66 {(id)kSecAttrPublicKeyHash, pubKeyDigest.asData},
67 {(id)kSecReturnRef, $true})];
70 - (NSEnumerator*) enumeratePublicKeys {
71 NSMutableDictionary *query = $mdict({(id)kSecClass, (id)kSecClassKey},
72 {(id)kSecAttrKeyClass, (id)kSecAttrKeyClassPublic},
73 {(id)kSecMatchLimit, (id)kSecMatchLimitAll},
74 {(id)kSecReturnRef, $true});
75 return [[[MYKeyEnumerator alloc] initWithQuery: query] autorelease];
79 - (MYPrivateKey*) privateKeyWithDigest: (MYSHA1Digest*)pubKeyDigest {
80 return [MYKeyEnumerator firstItemWithQuery:
81 $mdict({(id)kSecClass, (id)kSecClassKey},
82 {(id)kSecAttrKeyClass, (id)kSecAttrKeyClassPrivate},
83 {(id)kSecAttrPublicKeyHash, pubKeyDigest.asData},
84 {(id)kSecReturnRef, $true})];
87 - (NSEnumerator*) enumeratePrivateKeys {
88 NSMutableDictionary *query = $mdict({(id)kSecClass, (id)kSecClassKey},
89 {(id)kSecAttrKeyClass, (id)kSecAttrKeyClassPrivate},
90 {(id)kSecMatchLimit, (id)kSecMatchLimitAll},
91 {(id)kSecReturnRef, $true});
92 return [[[MYKeyEnumerator alloc] initWithQuery: query] autorelease];
95 - (MYCertificate*) certificateWithDigest: (MYSHA1Digest*)pubKeyDigest {
96 return [MYKeyEnumerator firstItemWithQuery:
97 $mdict({(id)kSecClass, (id)kSecClassCertificate},
98 {(id)kSecAttrPublicKeyHash, pubKeyDigest.asData},
99 {(id)kSecReturnRef, $true})];
102 - (NSEnumerator*) enumerateCertificates {
103 NSMutableDictionary *query = $mdict({(id)kSecClass, (id)kSecClassCertificate},
104 {(id)kSecMatchLimit, (id)kSecMatchLimitAll},
105 {(id)kSecReturnRef, $true});
106 return [[[MYKeyEnumerator alloc] initWithQuery: query] autorelease];
109 - (NSEnumerator*) enumerateIdentities {
110 NSMutableDictionary *query = $mdict({(id)kSecClass, (id)kSecClassIdentity},
111 {(id)kSecMatchLimit, (id)kSecMatchLimitAll},
112 {(id)kSecReturnRef, $true});
113 return [[[MYKeyEnumerator alloc] initWithQuery: query] autorelease];
116 - (NSEnumerator*) enumerateSymmetricKeys {
117 NSMutableDictionary *query = $mdict({(id)kSecClass, (id)kSecClassKey},
118 {(id)kSecAttrKeyClass, (id)kSecAttrKeyClassSymmetric},
119 {(id)kSecMatchLimit, (id)kSecMatchLimitAll},
120 {(id)kSecReturnRef, $true});
121 return [[[MYKeyEnumerator alloc] initWithQuery: query] autorelease];
124 - (NSEnumerator*) symmetricKeysWithAlias: (NSString*)alias {
125 NSMutableDictionary *query = $mdict({(id)kSecClass, (id)kSecClassKey},
126 {(id)kSecAttrKeyClass, (id)kSecAttrKeyClassSymmetric},
127 {(id)kSecAttrApplicationTag, alias},
128 {(id)kSecMatchLimit, (id)kSecMatchLimitAll},
129 {(id)kSecReturnRef, $true});
130 return [[[MYKeyEnumerator alloc] initWithQuery: query] autorelease];
138 - (MYPublicKey*) importPublicKey: (NSData*)keyData {
139 return [[[MYPublicKey alloc] _initWithKeyData: keyData
144 - (MYCertificate*) importCertificate: (NSData*)data
147 NSDictionary *info = $dict( {(id)kSecClass, (id)kSecClassCertificate},
148 {(id)kSecValueData, data},
149 {(id)kSecReturnRef, $true} );
150 SecCertificateRef cert;
151 if (!check(SecItemAdd((CFDictionaryRef)info, (CFTypeRef*)&cert), @"SecItemAdd"))
153 return [[[MYCertificate alloc] initWithCertificateRef: cert] autorelease];
158 #pragma mark GENERATION:
161 - (MYSymmetricKey*) generateSymmetricKeyOfSize: (unsigned)keySizeInBits
162 algorithm: (CCAlgorithm)algorithm
164 return [MYSymmetricKey _generateSymmetricKeyOfSize: keySizeInBits
165 algorithm: algorithm inKeychain: self];
168 - (MYPrivateKey*) generateRSAKeyPairOfSize: (unsigned)keySize {
169 return [MYPrivateKey _generateRSAKeyPairOfSize: keySize inKeychain: self];
178 @implementation MYKeyEnumerator
180 - (id) initWithQuery: (NSMutableDictionary*)query {
183 if (![query objectForKey: (id)kSecMatchLimit])
184 [query setObject: (id)kSecMatchLimitAll forKey: (id)kSecMatchLimit];
185 OSStatus err = SecItemCopyMatching((CFDictionaryRef)query, (CFTypeRef*)&_results);
186 if (err && err != errSecItemNotFound) {
187 check(err,@"SecItemCopyMatching");
191 if (_results) CFRetain(_results);
192 _itemClass = (CFTypeRef)[query objectForKey: (id)kSecClass];
193 if (_itemClass == kSecClassKey)
194 _itemClass = (CFTypeRef)[query objectForKey: (id)kSecAttrKeyClass];
195 if (_itemClass) CFRetain(_itemClass);
200 + (id) firstItemWithQuery: (NSMutableDictionary*)query {
201 MYKeyEnumerator *e = [[self alloc] initWithQuery: query];
202 MYKeychainItem *item = e.nextObject;
209 if (_itemClass) CFRelease(_itemClass);
210 if (_results) CFRelease(_results);
218 MYKeychainItem *next = nil;
219 while (next==nil && _index < CFArrayGetCount(_results)) {
220 CFTypeRef found = CFArrayGetValueAtIndex(_results, _index++);
221 if (_itemClass == kSecAttrKeyClassPrivate) {
222 next = [[MYPrivateKey alloc] initWithKeyRef: (SecKeyRef)found];
223 } else if (_itemClass == kSecAttrKeyClassPublic) {
224 next = [[[MYPublicKey alloc] initWithKeyRef: (SecKeyRef)found] autorelease];
225 } else if (_itemClass == kSecAttrKeyClassSymmetric) {
226 next = [[[MYSymmetricKey alloc] initWithKeyRef: (SecKeyRef)found] autorelease];
227 } else if (_itemClass == kSecClassCertificate) {
228 next = [[[MYCertificate alloc] initWithCertificateRef: (SecCertificateRef)found] autorelease];
229 } else if (_itemClass == kSecClassIdentity) {
230 next = [[[MYIdentity alloc] initWithIdentityRef: (SecIdentityRef)found] autorelease];
240 #endif MYCRYPTO_USE_IPHONE_API
244 Copyright (c) 2009, Jens Alfke <jens@mooseyard.com>. All rights reserved.
246 Redistribution and use in source and binary forms, with or without modification, are permitted
247 provided that the following conditions are met:
249 * Redistributions of source code must retain the above copyright notice, this list of conditions
250 and the following disclaimer.
251 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
252 and the following disclaimer in the documentation and/or other materials provided with the
255 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
256 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
257 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI-
258 BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
259 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
260 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
261 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
262 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.