MYOID.m
author Jens Alfke <jens@mooseyard.com>
Fri Aug 07 11:24:53 2009 -0700 (2009-08-07)
changeset 28 54b373aa65ab
parent 26 d9c2a06d4e4e
permissions -rw-r--r--
Fixed iPhone OS build. (issue 3)
     1 //
     2 //  MYOID.m
     3 //  MYCrypto
     4 //
     5 //  Created by Jens Alfke on 5/28/09.
     6 //  Copyright 2009 Jens Alfke. All rights reserved.
     7 //
     8 
     9 #import "MYOID.h"
    10 
    11 
    12 @implementation MYOID
    13 
    14 
    15 - (id) initWithComponents: (const UInt32*)components count: (unsigned)count
    16 {
    17     self = [super init];
    18     if (self != nil) {
    19         _data = [[NSData alloc] initWithBytes: components length: count*sizeof(UInt32)];
    20     }
    21     return self;
    22 }
    23 
    24 - (id) initWithBEREncoding: (NSData*)encoding
    25 {
    26     self = [super init];
    27     if (self != nil) {
    28         size_t len = encoding.length;
    29         const UInt8 *src = encoding.bytes;
    30         const UInt8 *end = src+len;
    31         NSMutableData *data = [NSMutableData dataWithLength: (len+1)*sizeof(UInt32)];
    32         UInt32* dst = data.mutableBytes;
    33         
    34         if (len >= 2) {
    35             *dst++ = *src / 40;
    36             *dst++ = *src % 40;
    37             src++; 
    38         }
    39         while (src < end) {
    40             UInt32 component = 0;
    41             UInt8 byte;
    42             do{
    43                 if (src >= end) {
    44                     [self release];
    45                     return nil;
    46                 }
    47                 byte = *src++;
    48                 component = (component << 7) | (byte & 0x7F);
    49             }while (byte & 0x80);
    50             *dst++ = component;
    51         }
    52         data.length = (UInt8*)dst - (UInt8*)data.mutableBytes;
    53         _data = [data copy];
    54     }
    55     return self;
    56 }
    57 
    58 + (MYOID*) OIDWithEncoding: (NSData*)encoding {
    59     return [[[self alloc] initWithBEREncoding: encoding] autorelease];
    60 }
    61 
    62 #if !TARGET_OS_IPHONE
    63 + (MYOID*) OIDFromCSSM: (CSSM_OID)cssmOid
    64 {
    65     NSData *ber = [[NSData alloc] initWithBytesNoCopy: cssmOid.Data length: cssmOid.Length freeWhenDone: NO];
    66     MYOID *oid = [[[self alloc] initWithBEREncoding: ber] autorelease];
    67     [ber release];
    68     return oid;
    69 }
    70 #endif
    71 
    72 
    73 - (id) copyWithZone: (NSZone*)zone {
    74     return [self retain];
    75 }
    76 
    77 - (void) dealloc
    78 {
    79     [_data release];
    80     [super dealloc];
    81 }
    82 
    83 
    84 - (NSString*) description {
    85     NSMutableString *desc = [NSMutableString stringWithString: @"{"];
    86     const UInt32* components = self.components;
    87     unsigned count = self.componentCount;
    88     for (unsigned i=0; i<count; i++) {
    89         if (i>0)
    90             [desc appendString: @" "];
    91         [desc appendFormat: @"%u", components[i]];
    92     }
    93     [desc appendString: @"}"];
    94     return desc;
    95 }
    96 
    97 
    98 - (NSData*) componentData       {return _data;}
    99 - (const UInt32*) components    {return (const UInt32*)_data.bytes;}
   100 - (unsigned) componentCount     {return _data.length / sizeof(UInt32);}
   101 
   102 - (NSUInteger)hash {
   103     return _data.hash;
   104 }
   105 
   106 - (BOOL)isEqual:(id)object {
   107     return [object isKindOfClass: [MYOID class]] && [_data isEqual: [object componentData]];
   108 }
   109 
   110 
   111 - (NSData*) DEREncoding {
   112     unsigned count = self.componentCount;
   113     UInt8 encoding[5*count]; // worst-case size
   114     const UInt32 *src=self.components, *end=src+count;
   115     UInt8 *dst = encoding;
   116     if (count >= 2 && src[0]<=3 && src[1]<40) {
   117         // Weird collapsing of 1st two components into one byte:
   118         *dst++ = src[0]*40 + src[1];
   119         src += 2;
   120     }
   121     while (src<end) {
   122         UInt32 component = *src++;
   123         // Write the component in 7-bit groups, most significant first:
   124         BOOL any = NO;
   125         for (int shift=28; shift>=0; shift -= 7) {
   126             UInt8 byte = (component >> shift) & 0x7F;
   127             if (byte || any) {
   128                 if (any)
   129                     dst[-1] |= 0x80;
   130                 *dst++ = byte;
   131                 any = YES;
   132             }
   133         }
   134     }
   135     return [NSData dataWithBytes: encoding length: dst-encoding];
   136 }
   137 
   138 
   139 @end
   140 
   141 
   142 
   143 #define $data(BYTES...)    ({const uint8_t bytes[] = {BYTES}; [NSData dataWithBytes: bytes length: sizeof(bytes)];})
   144 
   145 #define $components(INTS...)    ({const UInt32 components[] = {INTS}; components;})
   146 
   147 TestCase(OID) {
   148     CAssertEqual([[MYOID OIDWithEncoding: $data(0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01)] description],
   149                  @"{1 2 840 113549 1 1 1}");
   150     CAssertEqual([[MYOID OIDWithEncoding: $data(0x55,0x04,0x04)] description],
   151                  @"{2 5 4 4}");
   152     CAssertEqual([[MYOID OIDWithEncoding: $data(0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x09,0x01)] description],
   153                  @"{1 2 840 113549 1 9 1}");
   154 
   155     CAssertEqual([[[MYOID alloc] initWithComponents: $components(1,2,840,113549,1,1,1) count: 7] description],
   156                  @"{1 2 840 113549 1 1 1}");
   157 
   158     CAssertEqual([[[MYOID alloc] initWithComponents: $components(1,2,840,113549,1,1,1) count: 7] DEREncoding],
   159                  $data(0x2a, 0x86, 0x48, 0x86,  0xf7, 0x0d, 0x01, 0x01,  0x01));
   160     CAssertEqual([[[MYOID alloc] initWithComponents: $components(2,5,4,4) count: 4] DEREncoding],
   161                  $data(0x55,0x04,0x04));
   162 }
   163 
   164 
   165 
   166 /*
   167  Copyright (c) 2009, Jens Alfke <jens@mooseyard.com>. All rights reserved.
   168  
   169  Redistribution and use in source and binary forms, with or without modification, are permitted
   170  provided that the following conditions are met:
   171  
   172  * Redistributions of source code must retain the above copyright notice, this list of conditions
   173  and the following disclaimer.
   174  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
   175  and the following disclaimer in the documentation and/or other materials provided with the
   176  distribution.
   177  
   178  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
   179  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
   180  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI-
   181  BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   182  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
   183   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
   184  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
   185  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   186  */