Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -13,11 +13,10 @@ SRCS = OFASN1BitString.m \ OFASN1Boolean.m \ OFASN1Enumerated.m \ OFASN1IA5String.m \ OFASN1Integer.m \ - OFASN1IntegerOrEnumerated.m \ OFASN1Null.m \ OFASN1NumericString.m \ OFASN1ObjectIdentifier.m \ OFASN1OctetString.m \ OFASN1PrintableString.m \ Index: src/OFASN1Enumerated.h ================================================================== --- src/OFASN1Enumerated.h +++ src/OFASN1Enumerated.h @@ -13,16 +13,24 @@ * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ -#import "OFASN1IntegerOrEnumerated.h" +#import "OFASN1Value.h" OF_ASSUME_NONNULL_BEGIN /*! * @brief An ASN.1 enumerated. */ -@interface OFASN1Enumerated: OFASN1IntegerOrEnumerated +@interface OFASN1Enumerated: OFASN1Value +{ + intmax_t _integerValue; +} + +/*! + * @brief The integer value. + */ +@property (readonly, nonatomic) intmax_t integerValue; @end OF_ASSUME_NONNULL_END Index: src/OFASN1Enumerated.m ================================================================== --- src/OFASN1Enumerated.m +++ src/OFASN1Enumerated.m @@ -16,14 +16,21 @@ */ #include "config.h" #import "OFASN1Enumerated.h" +#import "OFData.h" +#import "OFString.h" #import "OFInvalidArgumentException.h" + +extern intmax_t of_asn1_integer_parse(const unsigned char *buffer, + size_t length); @implementation OFASN1Enumerated +@synthesize integerValue = _integerValue; + - (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass tagNumber: (of_asn1_tag_number_t)tagNumber constructed: (bool)constructed DEREncodedContents: (OFData *)DEREncodedContents { @@ -34,13 +41,22 @@ @try { if (_tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || _tagNumber != OF_ASN1_TAG_NUMBER_ENUMERATED || _constructed) @throw [OFInvalidArgumentException exception]; + + _integerValue = of_asn1_integer_parse( + [_DEREncodedContents items], [_DEREncodedContents count]); } @catch (id e) { [self release]; @throw e; } return self; } + +- (OFString *)description +{ + return [OFString stringWithFormat: @"", + _integerValue]; +} @end Index: src/OFASN1Integer.h ================================================================== --- src/OFASN1Integer.h +++ src/OFASN1Integer.h @@ -13,16 +13,24 @@ * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ -#import "OFASN1IntegerOrEnumerated.h" +#import "OFASN1Value.h" OF_ASSUME_NONNULL_BEGIN /*! * @brief An ASN.1 integer. */ -@interface OFASN1Integer: OFASN1IntegerOrEnumerated +@interface OFASN1Integer: OFASN1Value +{ + intmax_t _integerValue; +} + +/*! + * @brief The integer value. + */ +@property (readonly, nonatomic) intmax_t integerValue; @end OF_ASSUME_NONNULL_END Index: src/OFASN1Integer.m ================================================================== --- src/OFASN1Integer.m +++ src/OFASN1Integer.m @@ -16,14 +16,43 @@ */ #include "config.h" #import "OFASN1Integer.h" +#import "OFData.h" +#import "OFString.h" #import "OFInvalidArgumentException.h" +#import "OFInvalidFormatException.h" +#import "OFOutOfRangeException.h" + +intmax_t +of_asn1_integer_parse(const unsigned char *buffer, size_t length) +{ + uintmax_t value = 0; + + /* TODO: Support for big numbers */ + if (length > sizeof(uintmax_t) && + (length != sizeof(uintmax_t) + 1 || buffer[0] != 0)) + @throw [OFOutOfRangeException exception]; + + if (length >= 2 && ((buffer[0] == 0 && !(buffer[1] & 0x80)) || + (buffer[0] == 0xFF && buffer[1] & 0x80))) + @throw [OFInvalidFormatException exception]; + + if (length >= 1 && buffer[0] & 0x80) + value = ~(uintmax_t)0; + + while (length--) + value = (value << 8) | *buffer++; + + return value; +} @implementation OFASN1Integer +@synthesize integerValue = _integerValue; + - (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass tagNumber: (of_asn1_tag_number_t)tagNumber constructed: (bool)constructed DEREncodedContents: (OFData *)DEREncodedContents { @@ -34,13 +63,22 @@ @try { if (_tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || _tagNumber != OF_ASN1_TAG_NUMBER_INTEGER || _constructed) @throw [OFInvalidArgumentException exception]; + + _integerValue = of_asn1_integer_parse( + [_DEREncodedContents items], [_DEREncodedContents count]); } @catch (id e) { [self release]; @throw e; } return self; } + +- (OFString *)description +{ + return [OFString stringWithFormat: @"", + _integerValue]; +} @end DELETED src/OFASN1IntegerOrEnumerated.h Index: src/OFASN1IntegerOrEnumerated.h ================================================================== --- src/OFASN1IntegerOrEnumerated.h +++ src/OFASN1IntegerOrEnumerated.h @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, - * 2018 - * Jonathan Schleifer - * - * All rights reserved. - * - * This file is part of ObjFW. It may be distributed under the terms of the - * Q Public License 1.0, which can be found in the file LICENSE.QPL included in - * the packaging of this file. - * - * Alternatively, it may be distributed under the terms of the GNU General - * Public License, either version 2 or 3, which can be found in the file - * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this - * file. - */ - -#import "OFASN1Value.h" - -OF_ASSUME_NONNULL_BEGIN - -/*! - * @brief An ASN.1 integer or enumerated. - */ -@interface OFASN1IntegerOrEnumerated: OFASN1Value -{ - intmax_t _integerValue; -} - -/*! - * @brief The integer value. - */ -@property (readonly, nonatomic) intmax_t integerValue; -@end - -OF_ASSUME_NONNULL_END DELETED src/OFASN1IntegerOrEnumerated.m Index: src/OFASN1IntegerOrEnumerated.m ================================================================== --- src/OFASN1IntegerOrEnumerated.m +++ src/OFASN1IntegerOrEnumerated.m @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, - * 2018 - * Jonathan Schleifer - * - * All rights reserved. - * - * This file is part of ObjFW. It may be distributed under the terms of the - * Q Public License 1.0, which can be found in the file LICENSE.QPL included in - * the packaging of this file. - * - * Alternatively, it may be distributed under the terms of the GNU General - * Public License, either version 2 or 3, which can be found in the file - * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this - * file. - */ - -#include "config.h" - -#import "OFASN1IntegerOrEnumerated.h" -#import "OFData.h" -#import "OFString.h" - -#import "OFInvalidFormatException.h" -#import "OFNotImplementedException.h" -#import "OFOutOfRangeException.h" - -@implementation OFASN1IntegerOrEnumerated -@synthesize integerValue = _integerValue; - -+ (instancetype)alloc -{ - if (self == [OFASN1IntegerOrEnumerated class]) - @throw [OFNotImplementedException exceptionWithSelector: _cmd - object: self]; - - return [super alloc]; -} - -- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents -{ - self = [super initWithTagClass: tagClass - tagNumber: tagNumber - constructed: constructed - DEREncodedContents: DEREncodedContents]; - - @try { - const unsigned char *items = [_DEREncodedContents items]; - size_t count = [_DEREncodedContents count]; - uintmax_t value = 0; - - /* TODO: Support for big numbers */ - if (count > sizeof(uintmax_t) && - (count != sizeof(uintmax_t) + 1 || items[0] != 0)) - @throw [OFOutOfRangeException exception]; - - if (count >= 2 && ((items[0] == 0 && !(items[1] & 0x80)) || - (items[0] == 0xFF && items[1] & 0x80))) - @throw [OFInvalidFormatException exception]; - - if (count >= 1 && items[0] & 0x80) - value = ~(uintmax_t)0; - - while (count--) - value = (value << 8) | *items++; - - _integerValue = value; - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- (OFString *)description -{ - return [OFString stringWithFormat: @"<%@: %jd>", - [self class], _integerValue]; -} -@end