MYASN1Object.m
author Jens Alfke <jens@mooseyard.com>
Fri Aug 07 11:24:53 2009 -0700 (2009-08-07)
changeset 28 54b373aa65ab
parent 20 df9da0f6b358
permissions -rw-r--r--
Fixed iPhone OS build. (issue 3)
     1 //
     2 //  MYASN1Object.m
     3 //  MYCrypto-iPhone
     4 //
     5 //  Created by Jens Alfke on 5/28/09.
     6 //  Copyright 2009 Jens Alfke. All rights reserved.
     7 //
     8 
     9 // Reference:
    10 // <http://www.columbia.edu/~ariel/ssleay/layman.html> "Layman's Guide To ASN.1/BER/DER"
    11 
    12 #import "MYASN1Object.h"
    13 
    14 
    15 @implementation MYASN1Object
    16 
    17 
    18 - (id) initWithTag: (uint32_t)tag
    19            ofClass: (uint8_t)tagClass 
    20        constructed: (BOOL)constructed
    21              value: (NSData*)value
    22 {
    23     Assert(value);
    24     self = [super init];
    25     if (self != nil) {
    26         _tag = tag;
    27         _tagClass = tagClass;
    28         _constructed = constructed;
    29         _value = [value copy];
    30     }
    31     return self;
    32 }
    33 
    34 - (id) initWithTag: (uint32_t)tag
    35            ofClass: (uint8_t)tagClass 
    36         components: (NSArray*)components
    37 {
    38     Assert(components);
    39     self = [super init];
    40     if (self != nil) {
    41         _tag = tag;
    42         _tagClass = tagClass;
    43         _constructed = YES;
    44         _components = [components copy];
    45     }
    46     return self;
    47 }
    48 
    49 - (void) dealloc
    50 {
    51     [_value release];
    52     [_components release];
    53     [super dealloc];
    54 }
    55 
    56 
    57 @synthesize tag=_tag, tagClass=_tagClass, constructed=_constructed, value=_value, components=_components;
    58 
    59 
    60 - (NSString*)description {
    61     if (_components)
    62         return $sprintf(@"%@[%hhu/%u/%u]%@", self.class, _tagClass,(unsigned)_constructed,_tag, _components);
    63     else
    64         return $sprintf(@"%@[%hhu/%u/%u, %u bytes]", self.class, _tagClass,(unsigned)_constructed,_tag, _value.length);
    65 }
    66 
    67 - (BOOL) isEqual: (id)object {
    68     return [object isKindOfClass: [MYASN1Object class]] 
    69         && _tag==[object tag] 
    70         && _tagClass==[object tagClass] 
    71         && _constructed==[object constructed] 
    72         && $equal(_value,[object value])
    73         && $equal(_components,[object components]);
    74 }
    75 
    76 static void dump(id object, NSMutableString *output, NSString *indent) {
    77     if ([object isKindOfClass: [MYASN1Object class]]) {
    78         MYASN1Object *asn1Obj = object;
    79         [output appendFormat: @"%@%@[%hhu/%u]", indent, asn1Obj.class, asn1Obj.tagClass,asn1Obj.tag];
    80         if (asn1Obj.components) {
    81             [output appendString: @":\n"];
    82             NSString *subindent = [indent stringByAppendingString: @"    "];
    83             for (id o in asn1Obj.components)
    84                 dump(o,output, subindent);
    85         } else
    86             [output appendFormat: @" %@\n", asn1Obj.value];
    87     } else if([object respondsToSelector: @selector(objectEnumerator)]) {
    88         [output appendString: indent];
    89         if ([object isKindOfClass: [NSArray class]])
    90             [output appendString: @"Sequence:\n"];
    91         else if ([object isKindOfClass: [NSSet class]])
    92             [output appendString: @"Set:\n"];
    93         else
    94             [output appendFormat: @"%@:\n", [object class]];
    95         NSString *subindent = [indent stringByAppendingString: @"    "];
    96         for (id o in object)
    97             dump(o,output, subindent);
    98     } else {
    99         [output appendFormat: @"%@%@\n", indent, object];
   100     }
   101 }
   102 
   103 + (NSString*) dump: (id)object {
   104     NSMutableString *output = [NSMutableString stringWithCapacity: 512];
   105     dump(object,output,@"");
   106     return output;
   107 }
   108 
   109 
   110 @end
   111 
   112 
   113 
   114 @implementation MYASN1BigInteger
   115 
   116 - (id) initWithSignedData: (NSData*)signedData {
   117     // Skip unnecessary leading 00 (if positive) or FF (if negative) bytes:
   118     const SInt8 *start = signedData.bytes, *last = start + signedData.length - 1;
   119     const SInt8 *pos = start;
   120     while (pos<last && ((pos[0]==0 && pos[1]>=0) || (pos[0]==-1 && pos[1]<0)))
   121         pos++;
   122     if (pos > start)
   123         signedData = [NSData dataWithBytes: pos length: last-pos+1];
   124     return [self initWithTag: 2 ofClass: 0 constructed: NO value: signedData];
   125 }
   126 
   127 - (id) initWithUnsignedData: (NSData*) unsignedData {
   128     const UInt8 *start = unsignedData.bytes;
   129     if (*start >= 0x80) {
   130         // Prefix with 00 byte so high bit isn't misinterpreted as a sign bit:
   131         NSMutableData *fixedData = [NSMutableData dataWithCapacity: unsignedData.length + 1];
   132         UInt8 zero = 0;
   133         [fixedData appendBytes: &zero length: 1];
   134         [fixedData appendData: unsignedData];
   135         unsignedData = fixedData;
   136     }
   137     return [self initWithSignedData: unsignedData];
   138 }
   139 
   140 - (NSData*) signedData {
   141     return self.value;
   142 }
   143 
   144 - (NSData*) unsignedData {
   145     // Strip any leading zero bytes that were inserted for sign-bit padding:
   146     NSData *data = self.value;
   147     const UInt8 *start = data.bytes, *last = start + data.length - 1;
   148     const UInt8 *pos = start;
   149     while (pos<last && *pos==0)
   150         pos++;
   151     if (pos > start)
   152         data = [NSData dataWithBytes: pos length: last-pos+1];
   153     return data;
   154 }
   155 
   156 @end
   157 
   158 
   159 
   160 @implementation MYBitString
   161 
   162 
   163 - (id)initWithBits: (NSData*)bits count: (unsigned)bitCount {
   164     Assert(bits);
   165     Assert(bitCount <= 8*bits.length);
   166     self = [super init];
   167     if (self != nil) {
   168         _bits = [bits copy];
   169         _bitCount = bitCount;
   170     }
   171     return self;
   172 }
   173 
   174 + (MYBitString*) bitStringWithData: (NSData*)bits {
   175     return [[[self alloc] initWithBits: bits count: 8*bits.length] autorelease];
   176 }
   177 
   178 - (void) dealloc
   179 {
   180     [_bits release];
   181     [super dealloc];
   182 }
   183 
   184 @synthesize bits=_bits, bitCount=_bitCount;
   185 
   186 - (NSString*) description {
   187     return $sprintf(@"%@%@", [self class], _bits);
   188 }
   189 
   190 - (unsigned) hash {
   191     return _bits.hash ^ _bitCount;
   192 }
   193 
   194 - (BOOL) isEqual: (id)object {
   195     return [object isKindOfClass: [MYBitString class]] 
   196         && _bitCount==[object bitCount] 
   197         && [_bits isEqual: [object bits]];
   198 }
   199 
   200 @end
   201 
   202 
   203 
   204 /*
   205  Copyright (c) 2009, Jens Alfke <jens@mooseyard.com>. All rights reserved.
   206  
   207  Redistribution and use in source and binary forms, with or without modification, are permitted
   208  provided that the following conditions are met:
   209  
   210  * Redistributions of source code must retain the above copyright notice, this list of conditions
   211  and the following disclaimer.
   212  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions
   213  and the following disclaimer in the documentation and/or other materials provided with the
   214  distribution.
   215  
   216  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
   217  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
   218  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRI-
   219  BUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
   220  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
   221   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
   222  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF 
   223  THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   224  */