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