MYCertificate-iPhone.m
author Jens Alfke <jens@mooseyard.com>
Sun Jun 07 21:53:56 2009 -0700 (2009-06-07)
changeset 23 39fec79de6e8
parent 21 2c300b15b381
permissions -rw-r--r--
A snapshot taken during the long, agonizing crawl toward getting everything running on iPhone.
snej@0
     1
//
snej@0
     2
//  MYCertificate-iPhone.m
snej@0
     3
//  MYCrypto-iPhone
snej@0
     4
//
snej@0
     5
//  Created by Jens Alfke on 3/30/09.
snej@0
     6
//  Copyright 2009 Jens Alfke. All rights reserved.
snej@0
     7
//
snej@0
     8
snej@0
     9
#import "MYCertificate.h"
jens@21
    10
#import "MYCertificateInfo.h"
snej@0
    11
#import "MYCrypto_Private.h"
snej@0
    12
snej@2
    13
#if MYCRYPTO_USE_IPHONE_API
snej@0
    14
snej@0
    15
snej@0
    16
@implementation MYCertificate
snej@0
    17
snej@0
    18
snej@8
    19
+ (MYCertificate*) certificateWithCertificateRef: (SecCertificateRef)certificateRef {
snej@8
    20
    return [[[self alloc] initWithCertificateRef: certificateRef] autorelease];
snej@8
    21
}
snej@8
    22
snej@0
    23
/** Creates a MYCertificate object for an existing Keychain certificate reference. */
snej@0
    24
- (id) initWithCertificateRef: (SecCertificateRef)certificateRef {
snej@0
    25
    self = [super initWithKeychainItemRef: (SecKeychainItemRef)certificateRef];
snej@0
    26
    if (self) {
snej@0
    27
        _certificateRef = certificateRef;     // superclass has already CFRetained it
snej@0
    28
    }
snej@0
    29
    return self;
snej@0
    30
}
snej@0
    31
snej@0
    32
/** Creates a MYCertificate object from exported key data, but does not add it to any keychain. */
snej@0
    33
- (id) initWithCertificateData: (NSData*)data
snej@0
    34
{
snej@0
    35
    SecCertificateRef certificateRef = SecCertificateCreateWithData(NULL, (CFDataRef)data);
snej@0
    36
    self = [self initWithCertificateRef: certificateRef];
snej@0
    37
    CFRelease(certificateRef);
snej@0
    38
    return self;
snej@0
    39
}
snej@0
    40
jens@21
    41
- (void) dealloc
jens@21
    42
{
jens@21
    43
    [_info release];
jens@21
    44
    [super dealloc];
jens@21
    45
}
jens@21
    46
snej@0
    47
snej@8
    48
- (BOOL)isEqualToCertificate:(MYCertificate*)cert {
snej@8
    49
    return [self isEqual: cert] || [self.certificateData isEqual: cert.certificateData];
snej@8
    50
}
snej@8
    51
snej@0
    52
@synthesize certificateRef=_certificateRef;
snej@0
    53
snej@0
    54
- (NSData*) certificateData {
snej@0
    55
    CFDataRef data = SecCertificateCopyData(_certificateRef);
snej@0
    56
    return data ?[(id)CFMakeCollectable(data) autorelease] :nil;
snej@0
    57
}
snej@0
    58
snej@0
    59
- (MYPublicKey*) publicKey {
snej@0
    60
    SecTrustRef trust = NULL;
snej@0
    61
    SecPolicyRef policy = SecPolicyCreateBasicX509();
snej@0
    62
    OSStatus err = SecTrustCreateWithCertificates((CFArrayRef)$array((id)_certificateRef),
snej@0
    63
                                                  policy,
snej@0
    64
                                                  &trust);
snej@0
    65
    CFRelease(policy);
snej@0
    66
    if (!check(err,@"SecTrustCreateWithCertificates"))
snej@0
    67
        return nil;
snej@0
    68
    
snej@0
    69
    MYPublicKey *key = nil;
snej@0
    70
    SecKeyRef keyRef = SecTrustCopyPublicKey(trust);
snej@0
    71
    if (keyRef) {
snej@0
    72
        key = [[[MYPublicKey alloc] initWithKeyRef: keyRef] autorelease];
snej@0
    73
        CFRelease(keyRef);
snej@0
    74
    }
snej@0
    75
    CFRelease(trust);
snej@0
    76
    return key;
snej@0
    77
}
snej@0
    78
jens@21
    79
- (MYIdentity*) identity {
jens@21
    80
    return [self.keychain identityWithDigest: self.publicKey.publicKeyDigest];
jens@21
    81
}
jens@21
    82
jens@21
    83
jens@21
    84
- (MYCertificateInfo*) info {
jens@21
    85
    if (!_info) {
jens@21
    86
        NSError *error;
jens@21
    87
        _info = [[MYCertificateInfo alloc] initWithCertificateData: self.certificateData
jens@21
    88
                                                             error: &error];
jens@21
    89
        if (!_info)
jens@21
    90
            Warn(@"Couldn't parse certificate %@: %@", self, error);
jens@21
    91
    }
jens@21
    92
    return _info;
jens@21
    93
}
snej@0
    94
snej@0
    95
- (NSString*) commonName {
snej@0
    96
    CFStringRef name = SecCertificateCopySubjectSummary(_certificateRef);
snej@0
    97
    return name ?[(id)CFMakeCollectable(name) autorelease] :nil;
snej@0
    98
}
snej@0
    99
jens@23
   100
- (NSArray*) emailAddresses {
jens@23
   101
    NSString *email = self.info.subject.emailAddress;
jens@23
   102
    return email ?$array(email) :nil;
jens@23
   103
}
snej@0
   104
snej@0
   105
@end
snej@0
   106
snej@2
   107
#endif MYCRYPTO_USE_IPHONE_API