Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -161,10 +161,11 @@ atomic_osatomic.h \ atomic_powerpc.h \ atomic_sync_builtins.h \ atomic_x86.h INCLUDES := ${SRCS:.m=.h} \ + OFASN1DERRepresentation.h \ OFCollection.h \ OFCryptoHash.h \ OFJSONRepresentation.h \ OFKernelEventObserver.h \ OFKeyValueCoding.h \ Index: src/OFASN1BitString.h ================================================================== --- src/OFASN1BitString.h +++ src/OFASN1BitString.h @@ -14,20 +14,21 @@ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" +#import "OFASN1DERRepresentation.h" #import "OFASN1Value.h" OF_ASSUME_NONNULL_BEGIN @class OFData; /*! * @brief An ASN.1 BitString. */ -@interface OFASN1BitString: OFObject +@interface OFASN1BitString: OFObject { OFData *_bitStringValue; size_t _bitStringLength; } @@ -39,15 +40,10 @@ /*! * @brief The length of the BitString in bits. */ @property (readonly, nonatomic) size_t bitStringLength; -/*! - * @brief The BitString in DER encoding. - */ -@property (readonly, nonatomic) OFData *DEREncodedValue; - /*! * @brief Creates an ASN.1 BitString with the specified BitString value and * length. * * @param bitStringValue The value of the BitString Index: src/OFASN1BitString.m ================================================================== --- src/OFASN1BitString.m +++ src/OFASN1BitString.m @@ -122,24 +122,28 @@ [_bitStringValue release]; [super dealloc]; } -- (OFData *)DEREncodedValue +- (OFData *)ASN1DERRepresentation { size_t bitStringValueCount = [_bitStringValue count]; unsigned char lastByteBits = _bitStringLength % 8; - unsigned char header[] = { 3, bitStringValueCount + 1, lastByteBits }; + unsigned char header[] = { + OF_ASN1_TAG_NUMBER_BIT_STRING, + bitStringValueCount + 1, + lastByteBits + }; OFMutableData *data; if (bitStringValueCount + 1 > UINT8_MAX || bitStringValueCount != OF_ROUND_UP_POW2(8, _bitStringLength) / 8) @throw [OFInvalidFormatException exception]; data = [OFMutableData dataWithCapacity: 3 + bitStringValueCount]; [data addItems: header - count: 3]; + count: sizeof(header)]; [data addItems: [_bitStringValue items] count: bitStringValueCount]; [data makeImmutable]; Index: src/OFASN1Boolean.h ================================================================== --- src/OFASN1Boolean.h +++ src/OFASN1Boolean.h @@ -14,32 +14,28 @@ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" +#import "OFASN1DERRepresentation.h" #import "OFASN1Value.h" OF_ASSUME_NONNULL_BEGIN /*! * @brief An ASN.1 Boolean. */ -@interface OFASN1Boolean: OFObject +@interface OFASN1Boolean: OFObject { bool _booleanValue; } /*! * @brief The Boolean value. */ @property (readonly, nonatomic) bool booleanValue; -/*! - * @brief The Boolean in DER encoding. - */ -@property (readonly, nonatomic) OFData *DEREncodedValue; - /*! * @brief Creates an ASN.1 Boolean with the specified Boolean value. * * @param booleanValue The value of the Boolean * @return A new, autoreleased OFASN1Boolean Index: src/OFASN1Boolean.m ================================================================== --- src/OFASN1Boolean.m +++ src/OFASN1Boolean.m @@ -72,11 +72,11 @@ - (instancetype)init { OF_INVALID_INIT_METHOD } -- (OFData *)DEREncodedValue +- (OFData *)ASN1DERRepresentation { char buffer[] = { OF_ASN1_TAG_NUMBER_BOOLEAN, 1, (_booleanValue ? 0xFF : 0x00) ADDED src/OFASN1DERRepresentation.h Index: src/OFASN1DERRepresentation.h ================================================================== --- src/OFASN1DERRepresentation.h +++ src/OFASN1DERRepresentation.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018, 2019 + * 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" + +OF_ASSUME_NONNULL_BEGIN + +@class OFData; + +/*! + * @protocol OFASN1DERRepresentation \ + * OFASN1DERRepresentation.h ObjFW/OFASN1DERRepresentation.h + * + * @brief A protocol implemented by classes that support encoding to ASN.1 DER + * representation. + */ +@protocol OFASN1DERRepresentation +/*! + * @brief The object in ASN.1 DER representation. + */ +@property (readonly, nonatomic) OFData *ASN1DERRepresentation; +@end + +OF_ASSUME_NONNULL_END Index: src/OFMessagePackRepresentation.h ================================================================== --- src/OFMessagePackRepresentation.h +++ src/OFMessagePackRepresentation.h @@ -20,11 +20,11 @@ OF_ASSUME_NONNULL_BEGIN @class OFData; /*! - * @protocol OFMessagePackRepresentation + * @protocol OFMessagePackRepresentation \ * OFMessagePackRepresentation.h ObjFW/OFMessagePackRepresentation.h * * @brief A protocol implemented by classes that support encoding to a * MessagePack representation. */ Index: src/OFNull.h ================================================================== --- src/OFNull.h +++ src/OFNull.h @@ -14,13 +14,14 @@ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" -#import "OFSerialization.h" +#import "OFASN1DERRepresentation.h" #import "OFJSONRepresentation.h" #import "OFMessagePackRepresentation.h" +#import "OFSerialization.h" OF_ASSUME_NONNULL_BEGIN /*! * @class OFNull OFNull.h ObjFW/OFNull.h @@ -27,15 +28,15 @@ * * @brief A class for representing null values in collections. */ OF_SUBCLASSING_RESTRICTED @interface OFNull: OFObject + OFMessagePackRepresentation, OFASN1DERRepresentation> /*! * @brief Returns an OFNull singleton. * * @return An OFNull singleton */ + (OFNull *)null; @end OF_ASSUME_NONNULL_END Index: src/OFNull.m ================================================================== --- src/OFNull.m +++ src/OFNull.m @@ -107,10 +107,18 @@ uint8_t type = 0xC0; return [OFData dataWithItems: &type count: 1]; } + +- (OFData *)ASN1DERRepresentation +{ + const unsigned char bytes[] = { OF_ASN1_TAG_NUMBER_NULL, 0 }; + + return [OFData dataWithItems: bytes + count: sizeof(bytes)]; +} - (instancetype)autorelease { return self; } Index: tests/Makefile ================================================================== --- tests/Makefile +++ tests/Makefile @@ -8,12 +8,12 @@ ${PROG_NOINST}.nds PROG_NOINST = tests${PROG_SUFFIX} STATIC_LIB_NOINST = ${TESTS_STATIC_LIB} SRCS = ForwardingTests.m \ + OFASN1DERRepresentationTests.m \ OFASN1DERValueTests.m \ - OFASN1DEREncodedValueTests.m \ OFArrayTests.m \ ${OFBLOCKTESTS_M} \ OFCharacterSetTests.m \ OFDataTests.m \ OFDateTests.m \ DELETED tests/OFASN1DEREncodedValueTests.m Index: tests/OFASN1DEREncodedValueTests.m ================================================================== --- tests/OFASN1DEREncodedValueTests.m +++ tests/OFASN1DEREncodedValueTests.m @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, - * 2018, 2019 - * 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 "TestsAppDelegate.h" - -static OFString *module; - -@implementation TestsAppDelegate (OFASN1DEREncodedValueTests) -- (void)ASN1DEREncodedValueTests -{ - OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; - OFData *data; - - module = @"OFASN1BitString"; - TEST(@"-[DEREncodedValue]", - (data = [OFData dataWithItems: "\xFF\x00\xF8" - count: 3]) && - [[[OFASN1BitString bitStringWithBitStringValue: data - bitStringLength: 20] DEREncodedValue] - isEqual: [OFData dataWithItems: "\x03\x04\x04\xFF\x00\xF8" - count: 6]] && - (data = [OFData dataWithItems: "abcdefäöü" - count: 12]) && - [[[OFASN1BitString bitStringWithBitStringValue: data - bitStringLength: 12 * 8] - DEREncodedValue] isEqual: - [OFData dataWithItems: "\x03\x0D\x00" "abcdefäöü" - count: 15]] && - (data = [OFData dataWithItems: "" - count: 0]) && - [[[OFASN1BitString bitStringWithBitStringValue: data - bitStringLength: 0] DEREncodedValue] - isEqual: [OFData dataWithItems: "\x03\x01\x00" - count: 3]]) - - module = @"OFASN1Boolean"; - TEST(@"-[DEREncodedValue]", - [[[OFASN1Boolean booleanWithBooleanValue: false] DEREncodedValue] - isEqual: [OFData dataWithItems: "\x01\x01\x00" - count: 3]] && - [[[OFASN1Boolean booleanWithBooleanValue: true] DEREncodedValue] - isEqual: [OFData dataWithItems: "\x01\x01\xFF" - count: 3]]) - - [pool drain]; -} -@end ADDED tests/OFASN1DERRepresentationTests.m Index: tests/OFASN1DERRepresentationTests.m ================================================================== --- tests/OFASN1DERRepresentationTests.m +++ tests/OFASN1DERRepresentationTests.m @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, + * 2018, 2019 + * 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 "TestsAppDelegate.h" + +static OFString *module; + +@implementation TestsAppDelegate (OFASN1DERRepresentationTests) +- (void)ASN1DERRepresentationTests +{ + OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; + OFData *data; + + module = @"OFASN1BitString"; + TEST(@"-[ASN1DERRepresentation]", + (data = [OFData dataWithItems: "\xFF\x00\xF8" + count: 3]) && + [[[OFASN1BitString bitStringWithBitStringValue: data + bitStringLength: 20] + ASN1DERRepresentation] isEqual: + [OFData dataWithItems: "\x03\x04\x04\xFF\x00\xF8" + count: 6]] && + (data = [OFData dataWithItems: "abcdefäöü" + count: 12]) && + [[[OFASN1BitString bitStringWithBitStringValue: data + bitStringLength: 12 * 8] + ASN1DERRepresentation] isEqual: + [OFData dataWithItems: "\x03\x0D\x00" "abcdefäöü" + count: 15]] && + (data = [OFData dataWithItems: "" + count: 0]) && + [[[OFASN1BitString bitStringWithBitStringValue: data + bitStringLength: 0] + ASN1DERRepresentation] isEqual: + [OFData dataWithItems: "\x03\x01\x00" + count: 3]]) + + module = @"OFASN1Boolean"; + TEST(@"-[ASN1DERRepresentation]", + [[[OFASN1Boolean booleanWithBooleanValue: false] + ASN1DERRepresentation] isEqual: + [OFData dataWithItems: "\x01\x01\x00" + count: 3]] && + [[[OFASN1Boolean booleanWithBooleanValue: true] + ASN1DERRepresentation] isEqual: + [OFData dataWithItems: "\x01\x01\xFF" + count: 3]]) + + [pool drain]; +} +@end Index: tests/TestsAppDelegate.h ================================================================== --- tests/TestsAppDelegate.h +++ tests/TestsAppDelegate.h @@ -88,12 +88,12 @@ @interface TestsAppDelegate (OFASN1DERValueTests) - (void)ASN1DERValueTests; @end -@interface TestsAppDelegate (OFASN1DEREncodedValueTests) -- (void)ASN1DEREncodedValueTests; +@interface TestsAppDelegate (OFASN1DERRepresentationTests) +- (void)ASN1DERRepresentationTests; @end @interface TestsAppDelegate (OFArrayTests) - (void)arrayTests; @end Index: tests/TestsAppDelegate.m ================================================================== --- tests/TestsAppDelegate.m +++ tests/TestsAppDelegate.m @@ -435,11 +435,11 @@ [self serializationTests]; #endif [self JSONTests]; [self propertyListTests]; [self ASN1DERValueTests]; - [self ASN1DEREncodedValueTests]; + [self ASN1DERRepresentationTests]; #if defined(OF_HAVE_PLUGINS) [self pluginTests]; #endif #ifdef OF_WINDOWS [self windowsRegistryKeyTests];