Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -12,11 +12,10 @@ LIB_PATCH = ${OBJFW_LIB_PATCH} SRCS = OFASN1BitString.m \ OFASN1Enumerated.m \ OFASN1IA5String.m \ - OFASN1Integer.m \ OFASN1NumericString.m \ OFASN1ObjectIdentifier.m \ OFASN1OctetString.m \ OFASN1PrintableString.m \ OFASN1UTF8String.m \ DELETED src/OFASN1Integer.h Index: src/OFASN1Integer.h ================================================================== --- src/OFASN1Integer.h +++ src/OFASN1Integer.h @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2008-2024 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 "OFObject.h" -#import "OFASN1Value.h" - -OF_ASSUME_NONNULL_BEGIN - -/** - * @brief An ASN.1 Integer. - */ -OF_SUBCLASSING_RESTRICTED -@interface OFASN1Integer: OFObject -{ - long long _longLongValue; -} - -/** - * @brief The Integer value. - */ -@property (readonly, nonatomic) long long longLongValue; - -/** - * @brief Creates an ASN.1 Integer with the specified integer value. - * - * @param value The `long long` value of the Integer - * @return A new, autoreleased OFASN1Integer - */ -+ (instancetype)integerWithLongLong: (long long)value; - -- (instancetype)init OF_UNAVAILABLE; - -/** - * @brief Initializes an already allocated ASN.1 Integer with the specified - * integer value. - * - * @param value The `long long` value of the Integer - * @return An initialized OFASN1Integer - */ -- (instancetype)initWithLongLong: (long long)value OF_DESIGNATED_INITIALIZER; - -/** - * @brief Initializes an already allocated ASN.1 Integer with the specified - * arguments. - * - * @param tagClass The tag class of the value's type - * @param tagNumber The tag number of the value's type - * @param constructed Whether the value if of a constructed type - * @param DEREncodedContents The DER-encoded contents octets of the value. - * @return An initialized OFASN1Integer - */ -- (instancetype)initWithTagClass: (OFASN1TagClass)tagClass - tagNumber: (OFASN1TagNumber)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents; -@end - -OF_ASSUME_NONNULL_END DELETED src/OFASN1Integer.m Index: src/OFASN1Integer.m ================================================================== --- src/OFASN1Integer.m +++ src/OFASN1Integer.m @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2008-2024 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 "OFASN1Integer.h" -#import "OFData.h" -#import "OFString.h" - -#import "OFInvalidArgumentException.h" -#import "OFInvalidFormatException.h" -#import "OFOutOfRangeException.h" - -long long -OFASN1DERIntegerParse(const unsigned char *buffer, size_t length) -{ - unsigned long long value = 0; - - /* TODO: Support for big numbers */ - if (length > sizeof(unsigned long long) && - (length != sizeof(unsigned long long) + 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 = ~0ull; - - while (length--) - value = (value << 8) | *buffer++; - - return value; -} - -@implementation OFASN1Integer -@synthesize longLongValue = _longLongValue; - -+ (instancetype)integerWithLongLong: (long long)value -{ - return [[[self alloc] initWithLongLong: value] autorelease]; -} - -- (instancetype)initWithLongLong: (long long)value -{ - self = [super init]; - - _longLongValue = value; - - return self; -} - -- (instancetype)initWithTagClass: (OFASN1TagClass)tagClass - tagNumber: (OFASN1TagNumber)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents -{ - long long value; - - @try { - if (tagClass != OFASN1TagClassUniversal || - tagNumber != OFASN1TagNumberInteger || constructed) - @throw [OFInvalidArgumentException exception]; - - if (DEREncodedContents.itemSize != 1) - @throw [OFInvalidArgumentException exception]; - - value = OFASN1DERIntegerParse( - DEREncodedContents.items, DEREncodedContents.count); - } @catch (id e) { - [self release]; - @throw e; - } - - return [self initWithLongLong: value]; -} - -- (instancetype)init -{ - OF_INVALID_INIT_METHOD -} - -- (bool)isEqual: (id)object -{ - OFASN1Integer *integer; - - if (object == self) - return true; - - if (![object isKindOfClass: [OFASN1Integer class]]) - return false; - - integer = object; - - if (integer->_longLongValue != _longLongValue) - return false; - - return true; -} - -- (unsigned long)hash -{ - return (unsigned long)_longLongValue; -} - -- (OFString *)description -{ - return [OFString stringWithFormat: @"", - _longLongValue]; -} -@end Index: src/OFData+ASN1DERParsing.m ================================================================== --- src/OFData+ASN1DERParsing.m +++ src/OFData+ASN1DERParsing.m @@ -17,11 +17,10 @@ #import "OFData+ASN1DERParsing.h" #import "OFASN1BitString.h" #import "OFASN1Enumerated.h" #import "OFASN1IA5String.h" -#import "OFASN1Integer.h" #import "OFASN1NumericString.h" #import "OFASN1ObjectIdentifier.h" #import "OFASN1OctetString.h" #import "OFASN1PrintableString.h" #import "OFASN1UTF8String.h" @@ -41,10 +40,33 @@ }; int _OFData_ASN1DERParsing_reference; static size_t parseObject(OFData *self, id *object, size_t depthLimit); + +long long +OFASN1DERIntegerParse(const unsigned char *buffer, size_t length) +{ + unsigned long long value = 0; + + /* TODO: Support for big numbers */ + if (length > sizeof(unsigned long long) && + (length != sizeof(unsigned long long) + 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 = ~0ull; + + while (length--) + value = (value << 8) | *buffer++; + + return value; +} static OFArray * parseSequence(OFData *contents, size_t depthLimit) { OFMutableArray *ret = [OFMutableArray array]; @@ -174,12 +196,16 @@ @throw [OFInvalidFormatException exception]; *object = [OFNumber numberWithBool: boolValue]; return bytesConsumed; case OFASN1TagNumberInteger: - valueClass = [OFASN1Integer class]; - break; + if (tag & tagConstructedMask) + @throw [OFInvalidFormatException exception]; + + *object = [OFNumber numberWithLongLong: + OFASN1DERIntegerParse(contents.items, contents.count)]; + return bytesConsumed; case OFASN1TagNumberBitString: valueClass = [OFASN1BitString class]; break; case OFASN1TagNumberOctetString: valueClass = [OFASN1OctetString class]; Index: src/ObjFW.h ================================================================== --- src/ObjFW.h +++ src/ObjFW.h @@ -145,11 +145,10 @@ #endif #import "OFASN1BitString.h" #import "OFASN1Enumerated.h" #import "OFASN1IA5String.h" -#import "OFASN1Integer.h" #import "OFASN1NumericString.h" #import "OFASN1ObjectIdentifier.h" #import "OFASN1OctetString.h" #import "OFASN1PrintableString.h" #import "OFASN1UTF8String.h"