snej@0: //
snej@0: //  MYCertificate.m
snej@0: //  MYCrypto
snej@0: //
snej@0: //  Created by Jens Alfke on 3/26/09.
snej@0: //  Copyright 2009 Jens Alfke. All rights reserved.
snej@0: //
snej@0: 
snej@0: #import "MYCertificate.h"
snej@0: #import "MYCrypto_Private.h"
snej@0: 
snej@2: #if !MYCRYPTO_USE_IPHONE_API
snej@0: 
snej@0: 
snej@0: @implementation MYCertificate
snej@0: 
snej@0: 
snej@0: /** Creates a MYCertificate object for an existing Keychain certificate reference. */
snej@0: - (id) initWithCertificateRef: (SecCertificateRef)certificateRef {
snej@0:     self = [super initWithKeychainItemRef: (SecKeychainItemRef)certificateRef];
snej@0:     if (self) {
snej@0:         _certificateRef = certificateRef;     // superclass has already CFRetained it
snej@0:     }
snej@0:     return self;
snej@0: }
snej@0: 
snej@0: /** Creates a MYCertificate object from exported key data, but does not add it to any keychain. */
snej@0: - (id) initWithCertificateData: (NSData*)data
snej@0:                           type: (CSSM_CERT_TYPE) type
snej@0:                       encoding: (CSSM_CERT_ENCODING) encoding
snej@0: {
snej@0:     Assert(data);
snej@0:     CSSM_DATA cssmData = {.Data=(void*)data.bytes, .Length=data.length};
snej@0:     SecCertificateRef certificateRef = NULL;
snej@0:     if (!check(SecCertificateCreateFromData(&cssmData, type, encoding, &certificateRef),
snej@0:         @"SecCertificateCreateFromData")) {
snej@0:         [self release];
snej@0:         return nil;
snej@0:     }
snej@0:     self = [self initWithCertificateRef: certificateRef];
snej@0:     CFRelease(certificateRef);
snej@0:     return self;
snej@0: }
snej@0: 
snej@0: - (id) initWithCertificateData: (NSData*)data {
snej@0:     return [self initWithCertificateData: data 
snej@0:                                     type: CSSM_CERT_X_509v3 
snej@0:                                 encoding: CSSM_CERT_ENCODING_BER];
snej@0: }
snej@0: 
snej@0: + (MYCertificate*) preferredCertificateForName: (NSString*)name {
snej@0:     SecCertificateRef certRef = NULL;
snej@0:     if (!check(SecCertificateCopyPreference((CFStringRef)name, 0, &certRef),
snej@0:                @"SecCertificateCopyPreference"))
snej@0:         return nil;
snej@0:     return [[[MYCertificate alloc] initWithCertificateRef: certRef] autorelease];
snej@0: }
snej@0: 
snej@0: - (BOOL) setPreferredCertificateForName: (NSString*)name {
snej@0:     return check(SecCertificateSetPreference(_certificateRef, (CFStringRef)name, 0, NULL),
snej@0:                  @"SecCertificateSetPreference");
snej@0: }
snej@0: 
snej@0: @synthesize certificateRef=_certificateRef;
snej@0: 
snej@0: - (NSData*) certificateData {
snej@0:     CSSM_DATA cssmData;
snej@0:     if (!check(SecCertificateGetData(_certificateRef, &cssmData),
snej@0:                @"SecCertificateGetData"))
snej@0:         return nil;
snej@0:     return [NSData dataWithBytes: cssmData.Data length: cssmData.Length];
snej@0: }
snej@0: 
snej@0: - (MYPublicKey*) publicKey {
snej@0:     SecKeyRef keyRef = NULL;
snej@0:     if (!check(SecCertificateCopyPublicKey(_certificateRef, &keyRef),
snej@0:                @"SecCertificateCopyPublicKey") || !keyRef)
snej@0:         return nil;
snej@0:     MYPublicKey *key = [[[MYPublicKey alloc] initWithKeyRef: keyRef] autorelease];
snej@0:     CFRelease(keyRef);
snej@0:     return key;
snej@0: }
snej@0: 
snej@0: - (NSString*) commonName {
snej@0:     CFStringRef name = NULL;
snej@0:     if (!check(SecCertificateCopyCommonName(_certificateRef, &name),
snej@0:                @"SecCertificateCopyCommonName") || !name)
snej@0:         return nil;
snej@0:     return [(id)CFMakeCollectable(name) autorelease];
snej@0: }
snej@0: 
snej@0: - (NSArray*) emailAddresses {
snej@0:     CFArrayRef addrs = NULL;
snej@0:     if (!check(SecCertificateCopyEmailAddresses(_certificateRef, &addrs),
snej@0:                @"SecCertificateCopyEmailAddresses") || !addrs)
snej@0:         return nil;
snej@0:     return [(id)CFMakeCollectable(addrs) autorelease];
snej@0: }
snej@0: 
snej@0: 
snej@0: @end
snej@0: 
snej@0: 
snej@2: #endif !MYCRYPTO_USE_IPHONE_API