MYCertificateInfo.m
changeset 26 d9c2a06d4e4e
parent 25 38c3c3923e1f
     1.1 --- a/MYCertificateInfo.m	Wed Jun 10 09:02:18 2009 -0700
     1.2 +++ b/MYCertificateInfo.m	Wed Jul 01 14:19:13 2009 -0700
     1.3 @@ -7,6 +7,7 @@
     1.4  //
     1.5  
     1.6  // References:
     1.7 +// <http://tools.ietf.org/html/rfc3280> "RFC 3280: Internet X.509 Certificate Profile"
     1.8  // <http://www.columbia.edu/~ariel/ssleay/layman.html> "Layman's Guide To ASN.1/BER/DER"
     1.9  // <http://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt> "X.509 Style Guide"
    1.10  // <http://en.wikipedia.org/wiki/X.509> Wikipedia article on X.509
    1.11 @@ -67,7 +68,7 @@
    1.12          kSurnameOID = [[MYOID alloc] initWithComponents: (UInt32[]){2, 5, 4, 4}
    1.13                                                    count: 4];
    1.14          kDescriptionOID = [[MYOID alloc] initWithComponents: (UInt32[]){2, 5, 4, 13}
    1.15 -                                                count: 7];
    1.16 +                                                count: 4];
    1.17          kEmailOID = [[MYOID alloc] initWithComponents: (UInt32[]){1, 2, 840, 113549, 1, 9, 1}
    1.18                                                  count: 7];
    1.19      }
    1.20 @@ -160,14 +161,18 @@
    1.21  }
    1.22  
    1.23  
    1.24 -- (MYPublicKey*) subjectPublicKey {
    1.25 +- (NSData*) subjectPublicKeyData {
    1.26      NSArray *keyInfo = $cast(NSArray, $atIf(self._info, 6));
    1.27      MYOID *keyAlgorithmID = $castIf(MYOID, $atIf($castIf(NSArray,$atIf(keyInfo,0)), 0));
    1.28      if (!$equal(keyAlgorithmID, kRSAAlgorithmID))
    1.29          return nil;
    1.30 -    MYBitString *keyData = $cast(MYBitString, $atIf(keyInfo, 1));
    1.31 +    return $cast(MYBitString, $atIf(keyInfo, 1)).bits;
    1.32 +}
    1.33 +
    1.34 +- (MYPublicKey*) subjectPublicKey {
    1.35 +    NSData *keyData = self.subjectPublicKeyData;
    1.36      if (!keyData) return nil;
    1.37 -    return [[[MYPublicKey alloc] initWithKeyData: keyData.bits] autorelease];
    1.38 +    return [[[MYPublicKey alloc] initWithKeyData: keyData] autorelease];
    1.39  }
    1.40  
    1.41  - (NSData*) signedData {
    1.42 @@ -364,10 +369,15 @@
    1.43  
    1.44  - (void) setString: (NSString*)value forOID: (MYOID*)oid {
    1.45      NSMutableArray *pair = (NSMutableArray*) [self _pairForOID: oid];
    1.46 -    if (pair)
    1.47 -        [pair replaceObjectAtIndex: 1 withObject: value];
    1.48 -    else
    1.49 -        [(NSMutableArray*)_components addObject: [NSSet setWithObject: $marray(oid,value)]];
    1.50 +    if (pair) {
    1.51 +        if (value)
    1.52 +            [pair replaceObjectAtIndex: 1 withObject: value];
    1.53 +        else
    1.54 +            Assert(NO,@"-setString:forOID: removing strings is unimplemented");//FIX
    1.55 +    } else {
    1.56 +        if (value)
    1.57 +            [(NSMutableArray*)_components addObject: [NSSet setWithObject: $marray(oid,value)]];
    1.58 +    }
    1.59  }
    1.60  
    1.61  - (NSString*) commonName    {return [self stringForOID: kCommonNameOID];}
    1.62 @@ -386,152 +396,6 @@
    1.63  @end
    1.64  
    1.65  
    1.66 -
    1.67 -#pragma mark -
    1.68 -#pragma mark TEST CASES:
    1.69 -
    1.70 -#if DEBUG
    1.71 -
    1.72 -
    1.73 -static MYCertificateInfo* testCertData(NSData *certData, BOOL selfSigned) {
    1.74 -    //Log(@"Cert Data =\n%@", certData);
    1.75 -    CAssert(certData!=nil);
    1.76 -    NSError *error = nil;
    1.77 -    MYCertificateInfo *pcert = [[MYCertificateInfo alloc] initWithCertificateData: certData 
    1.78 -                                                                            error: &error];
    1.79 -    CAssertNil(error);
    1.80 -    CAssert(pcert != nil);
    1.81 -    
    1.82 -    CAssertEq(pcert.isRoot, selfSigned);
    1.83 -        
    1.84 -    Log(@"Subject Public Key = %@", pcert.subjectPublicKey);
    1.85 -    CAssert(pcert.subjectPublicKey);
    1.86 -    MYCertificateName *subject = pcert.subject;
    1.87 -    Log(@"Common Name = %@", subject.commonName);
    1.88 -    Log(@"Given Name  = %@", subject.givenName);
    1.89 -    Log(@"Surname     = %@", subject.surname);
    1.90 -    Log(@"Desc        = %@", subject.nameDescription);
    1.91 -    Log(@"Email       = %@", subject.emailAddress);
    1.92 -    CAssert(subject.commonName);
    1.93 -    
    1.94 -    // Now go through MYCertificate:
    1.95 -    Log(@"Creating a MYCertificate from the data...");
    1.96 -    MYCertificate *cert = [[MYCertificate alloc] initWithCertificateData: certData];
    1.97 -    Log(@"MYCertificate = %@", cert);
    1.98 -    CAssert(cert);
    1.99 -    CAssertEqual(cert.info, pcert);
   1.100 -    Log(@"Trust = %@", MYTrustResultDescribe([cert evaluateTrust]));
   1.101 -    
   1.102 -    return pcert;
   1.103 -}
   1.104 -
   1.105 -static NSData* readTestFile(NSString *filename) {
   1.106 -#if TARGET_OS_IPHONE
   1.107 -    filename = [[NSBundle mainBundle] pathForResource: filename ofType: @"cer"];
   1.108 -#else
   1.109 -    filename = [[@"../../Tests/" stringByAppendingPathComponent: filename]
   1.110 -                stringByAppendingPathExtension: @"cer"];
   1.111 -#endif
   1.112 -    Log(@"--- Testing certificate file %@", filename);
   1.113 -    NSData *data = [NSData dataWithContentsOfFile: filename];
   1.114 -    CAssert(data, @"Couldn't read file %@", filename);
   1.115 -    return data;
   1.116 -}
   1.117 -
   1.118 -static MYCertificateInfo* testCert(NSString *filename, BOOL selfSigned) {
   1.119 -    return testCertData(readTestFile(filename), selfSigned);
   1.120 -}
   1.121 -
   1.122 -
   1.123 -TestCase(ParsedCert) {
   1.124 -    testCert(@"selfsigned", YES);
   1.125 -    testCert(@"iphonedev", NO);
   1.126 -    
   1.127 -    // Now test a self-signed cert with a bad signature:
   1.128 -    MYCertificate *cert = [[MYCertificate alloc] initWithCertificateData: readTestFile(@"selfsigned_altered")];
   1.129 -    Log(@"MYCertificate = %@", cert);
   1.130 -    CAssertNil(cert);
   1.131 -
   1.132 -    Log(@"Checking /tmp/generated.cer");
   1.133 -    testCertData([NSData dataWithContentsOfFile: @"/tmp/generated.cer"], YES);//TEMP
   1.134 -}
   1.135 -
   1.136 -
   1.137 -#import "MYCrypto_Private.h"
   1.138 -
   1.139 -TestCase(CreateCert) {
   1.140 -    MYPrivateKey *privateKey = [[MYKeychain defaultKeychain] generateRSAKeyPairOfSize: 512];
   1.141 -    CAssert(privateKey);
   1.142 -    MYIdentity *identity = nil;
   1.143 -    @try{
   1.144 -        MYCertificateRequest *pcert = [[MYCertificateRequest alloc] initWithPublicKey: privateKey.publicKey];
   1.145 -        MYCertificateName *subject = pcert.subject;
   1.146 -        subject.commonName = @"testcase";
   1.147 -        subject.givenName = @"Test";
   1.148 -        subject.surname = @"Case";
   1.149 -        subject.nameDescription = @"Just a test certificate created by MYCrypto";
   1.150 -        subject.emailAddress = @"testcase@example.com";
   1.151 -
   1.152 -        subject = pcert.subject;
   1.153 -        CAssertEqual(subject.commonName, @"testcase");
   1.154 -        CAssertEqual(subject.givenName, @"Test");
   1.155 -        CAssertEqual(subject.surname, @"Case");
   1.156 -        CAssertEqual(subject.nameDescription, @"Just a test certificate created by MYCrypto");
   1.157 -        CAssertEqual(subject.emailAddress, @"testcase@example.com");
   1.158 -        
   1.159 -        Log(@"Signing...");
   1.160 -        NSError *error;
   1.161 -        NSData *certData = [pcert selfSignWithPrivateKey: privateKey error: &error];
   1.162 -        Log(@"Generated cert = \n%@", certData);
   1.163 -        CAssert(certData);
   1.164 -        CAssertNil(error);
   1.165 -        CAssert(certData);
   1.166 -#if TARGET_OS_IPHONE
   1.167 -        NSString *path = [@"/tmp/generated.cer" stringByStandardizingPath]; //TEMP
   1.168 -        CAssert([certData writeToFile: path atomically: YES]);
   1.169 -        Log(@"Wrote generated cert to %@",path);
   1.170 -#else
   1.171 -        [certData writeToFile: @"../../Tests/generated.cer" atomically: YES];
   1.172 -#endif
   1.173 -        MYCertificateInfo *pcert2 = testCertData(certData, YES);
   1.174 -        
   1.175 -        Log(@"Verifying Info...");
   1.176 -        MYCertificateName *subject2 = pcert2.subject;
   1.177 -        CAssertEqual(subject2,subject);
   1.178 -        CAssertEqual(subject2.commonName, @"testcase");
   1.179 -        CAssertEqual(subject2.givenName, @"Test");
   1.180 -        CAssertEqual(subject2.surname, @"Case");
   1.181 -        CAssertEqual(subject2.nameDescription, @"Just a test certificate created by MYCrypto");
   1.182 -        CAssertEqual(subject2.emailAddress, @"testcase@example.com");
   1.183 -                
   1.184 -        Log(@"Creating MYCertificate object...");
   1.185 -        MYCertificate *cert = [[MYCertificate alloc] initWithCertificateData: certData];
   1.186 -        Log(@"Loaded %@", cert);
   1.187 -        CAssert(cert);
   1.188 -        MYPublicKey *certKey = cert.publicKey;
   1.189 -        Log(@"Its public key = %@", certKey);
   1.190 -        CAssertEqual(certKey.keyData, privateKey.publicKey.keyData);
   1.191 -        
   1.192 -        Log(@"Creating Identity...");
   1.193 -        identity = [pcert createSelfSignedIdentityWithPrivateKey: privateKey error: &error];
   1.194 -        Log(@"Identity = %@", identity);
   1.195 -        CAssert(identity);
   1.196 -        CAssertNil(error);
   1.197 -        CAssertEqual(identity.keychain, [MYKeychain defaultKeychain]);
   1.198 -        CAssertEqual(identity.privateKey, privateKey);
   1.199 -        CAssert([identity isEqualToCertificate: cert]);
   1.200 -        
   1.201 -        [pcert release];
   1.202 -        
   1.203 -    } @finally {
   1.204 -        [privateKey removeFromKeychain];
   1.205 -        [identity removeFromKeychain];
   1.206 -    }
   1.207 -}
   1.208 -
   1.209 -#endif
   1.210 -
   1.211 -
   1.212  /*
   1.213   Copyright (c) 2009, Jens Alfke <jens@mooseyard.com>. All rights reserved.
   1.214