* The build process runs Doxygen only if it's installed (i.e. on the shell search path).
* Added instructions to the README on setting up a named Source Tree for MYUtilities.
* Changed the RSA key size in MYCryptoTest to 2048 and made it a named constant.
5 // Created by Jens Alfke on 3/26/09.
6 // Copyright 2009 Jens Alfke. All rights reserved.
9 #import "MYCertificate.h"
10 #import "MYCrypto_Private.h"
12 #import "MYErrorUtils.h"
14 #if !MYCRYPTO_USE_IPHONE_API
17 @implementation MYCertificate
20 /** Creates a MYCertificate object for an existing Keychain certificate reference. */
21 - (id) initWithCertificateRef: (SecCertificateRef)certificateRef {
22 self = [super initWithKeychainItemRef: (SecKeychainItemRef)certificateRef];
24 _certificateRef = certificateRef; // superclass has already CFRetained it
29 + (MYCertificate*) certificateWithCertificateRef: (SecCertificateRef)certificateRef {
30 return [[[self alloc] initWithCertificateRef: certificateRef] autorelease];
33 /** Creates a MYCertificate object from exported key data, but does not add it to any keychain. */
34 - (id) initWithCertificateData: (NSData*)data
35 type: (CSSM_CERT_TYPE) type
36 encoding: (CSSM_CERT_ENCODING) encoding
39 CSSM_DATA cssmData = {.Data=(void*)data.bytes, .Length=data.length};
40 SecCertificateRef certificateRef = NULL;
41 if (!check(SecCertificateCreateFromData(&cssmData, type, encoding, &certificateRef),
42 @"SecCertificateCreateFromData")) {
46 self = [self initWithCertificateRef: certificateRef];
47 CFRelease(certificateRef);
51 - (id) initWithCertificateData: (NSData*)data {
52 return [self initWithCertificateData: data
53 type: CSSM_CERT_X_509v3
54 encoding: CSSM_CERT_ENCODING_BER];
58 - (NSString*) description {
59 return $sprintf(@"%@[%@ %@/%p]",
62 self.certificateData.my_SHA1Digest.abbreviatedHexString,
67 - (BOOL)isEqualToCertificate:(MYCertificate*)cert {
68 return [self isEqual: cert] || [self.certificateData isEqual: cert.certificateData];
72 + (MYCertificate*) preferredCertificateForName: (NSString*)name {
73 SecCertificateRef certRef = NULL;
74 if (!check(SecCertificateCopyPreference((CFStringRef)name, 0, &certRef),
75 @"SecCertificateCopyPreference"))
77 return [[[MYCertificate alloc] initWithCertificateRef: certRef] autorelease];
80 - (BOOL) setPreferredCertificateForName: (NSString*)name {
81 return check(SecCertificateSetPreference(_certificateRef, (CFStringRef)name, 0, NULL),
82 @"SecCertificateSetPreference");
86 @synthesize certificateRef=_certificateRef;
88 - (NSData*) certificateData {
90 if (!check(SecCertificateGetData(_certificateRef, &cssmData),
91 @"SecCertificateGetData"))
93 return [NSData dataWithBytes: cssmData.Data length: cssmData.Length];
96 - (MYPublicKey*) publicKey {
97 SecKeyRef keyRef = NULL;
98 if (!check(SecCertificateCopyPublicKey(_certificateRef, &keyRef),
99 @"SecCertificateCopyPublicKey") || !keyRef)
101 MYPublicKey *key = [[[MYPublicKey alloc] initWithKeyRef: keyRef] autorelease];
106 - (NSString*) commonName {
107 CFStringRef name = NULL;
108 if (!check(SecCertificateCopyCommonName(_certificateRef, &name),
109 @"SecCertificateCopyCommonName") || !name)
111 return [(id)CFMakeCollectable(name) autorelease];
114 - (NSArray*) emailAddresses {
115 CFArrayRef addrs = NULL;
116 if (!check(SecCertificateCopyEmailAddresses(_certificateRef, &addrs),
117 @"SecCertificateCopyEmailAddresses") || !addrs)
119 return [(id)CFMakeCollectable(addrs) autorelease];
124 #pragma mark TRUST/POLICY STUFF:
127 + (SecPolicyRef) policyForOID: (CSSM_OID) policyOID {
128 SecPolicySearchRef search;
129 if (!check(SecPolicySearchCreate(CSSM_CERT_X_509v3, &policyOID, NULL, &search),
130 @"SecPolicySearchCreate"))
132 SecPolicyRef policy = NULL;
133 if (!check(SecPolicySearchCopyNext(search, &policy), @"SecPolicySearchCopyNext"))
139 + (SecPolicyRef) X509Policy {
140 static SecPolicyRef sX509Policy = NULL;
142 sX509Policy = [self policyForOID: CSSMOID_APPLE_X509_BASIC];
146 + (SecPolicyRef) SSLPolicy {
147 static SecPolicyRef sSSLPolicy = NULL;
149 sSSLPolicy = [self policyForOID: CSSMOID_APPLE_TP_SSL];
153 + (SecPolicyRef) SMIMEPolicy {
154 static SecPolicyRef sSMIMEPolicy = NULL;
156 sSMIMEPolicy = [self policyForOID: CSSMOID_APPLE_TP_SMIME];
161 - (CSSM_CERT_TYPE) certificateType {
162 CSSM_CERT_TYPE type = CSSM_CERT_UNKNOWN;
163 if (!check(SecCertificateGetType(_certificateRef, &type), @"SecCertificateGetType"))
164 type = CSSM_CERT_UNKNOWN;
168 - (NSArray*) trustSettings {
169 CFArrayRef settings = NULL;
170 OSStatus err = SecTrustSettingsCopyTrustSettings(_certificateRef, kSecTrustSettingsDomainUser,
172 if (err == errSecItemNotFound || !check(err,@"SecTrustSettingsCopyTrustSettings") || !settings)
174 return [(id)CFMakeCollectable(settings) autorelease];
178 - (BOOL) setUserTrust: (SecTrustUserSetting)trustSetting
180 if (trustSetting == kSecTrustResultProceed) {
181 return check(SecTrustSettingsSetTrustSettings(_certificateRef,
182 kSecTrustSettingsDomainUser, nil),
183 @"SecTrustSettingsSetTrustSettings");
184 } else if (trustSetting == kSecTrustResultDeny) {
185 OSStatus err = SecTrustSettingsRemoveTrustSettings(_certificateRef,
186 kSecTrustSettingsDomainUser);
187 return err == errSecItemNotFound || check(err, @"SecTrustSettingsRemoveTrustSettings");
196 NSString* MYPolicyGetName( SecPolicyRef policy ) {
200 SecPolicyGetOID(policy, &oid);
201 return $sprintf(@"SecPolicy[%@]", OIDAsString(oid));
204 NSString* MYTrustResultDescribe( SecTrustResultType result ) {
205 static NSString* const kTrustResultNames[kSecTrustResultOtherError+1] = {
211 @"RecoverableTrustFailure",
212 @"FatalTrustFailure",
215 if (result>=0 && result <=kSecTrustResultOtherError)
216 return kTrustResultNames[result];
218 return $sprintf(@"(Unknown trust result %i)", result);
222 NSString* MYTrustDescribe( SecTrustRef trust ) {
223 SecTrustResultType result;
224 CFArrayRef certChain=NULL;
225 CSSM_TP_APPLE_EVIDENCE_INFO* statusChain;
226 OSStatus err = SecTrustGetResult(trust, &result, &certChain, &statusChain);
229 desc = $sprintf(@"SecTrust[%p, err=%@]", trust, MYErrorName(NSOSStatusErrorDomain, err));
231 desc = $sprintf(@"SecTrust[%@, %u in chain]",
232 MYTrustResultDescribe(result),
233 CFArrayGetCount(certChain));
234 if (certChain) CFRelease(certChain);
241 Log(@"X.509 policy = %@", MYPolicyGetName([MYCertificate X509Policy]));
242 Log(@" SSL policy = %@", MYPolicyGetName([MYCertificate SSLPolicy]));
243 Log(@"SMIME policy = %@", MYPolicyGetName([MYCertificate SMIMEPolicy]));
244 for (MYCertificate *cert in [[MYKeychain defaultKeychain] enumerateCertificates]) {
245 NSArray *settings = cert.trustSettings;
247 Log(@"---- %@ = %@", cert, settings);
252 #endif !MYCRYPTO_USE_IPHONE_API