Index: .fossil-settings/clean-glob ================================================================== --- .fossil-settings/clean-glob +++ .fossil-settings/clean-glob @@ -46,6 +46,5 @@ utils/objfw-config utils/ofarc/ofarc utils/ofdns/ofdns utils/ofhash/ofhash utils/ofhttp/ofhttp -utils/ofsock/ofsock Index: .fossil-settings/ignore-glob ================================================================== --- .fossil-settings/ignore-glob +++ .fossil-settings/ignore-glob @@ -51,6 +51,5 @@ utils/objfw-config utils/ofarc/ofarc utils/ofdns/ofdns utils/ofhash/ofhash utils/ofhttp/ofhttp -utils/ofsock/ofsock Index: .gitignore ================================================================== --- .gitignore +++ .gitignore @@ -51,6 +51,5 @@ utils/objfw-config utils/ofarc/ofarc utils/ofdns/ofdns utils/ofhash/ofhash utils/ofhttp/ofhttp -utils/ofsock/ofsock Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -1335,16 +1335,10 @@ ]) AC_CHECK_HEADER(netinet/tcp.h, [ AC_DEFINE(OF_HAVE_NETINET_TCP_H, 1, [Whether we have netinet/tcp.h]) ]) - AC_CHECK_HEADER(netinet/sctp.h, [ - AC_DEFINE(OF_HAVE_SCTP, 1, [Whether we have SCTP]) - AC_DEFINE(OF_HAVE_NETINET_SCTP_H, 1, - [Whether we have netinet/sctp.h]) - AC_SUBST(USE_SRCS_SCTP, '${SRCS_SCTP}') - ]) AC_CHECK_HEADERS([arpa/inet.h netdb.h]) AC_CHECK_HEADER(netipx/ipx.h, [ AC_DEFINE(OF_HAVE_NETIPX_IPX_H, 1, [Whether we have netipx/ipx.h]) ]) @@ -1521,11 +1515,10 @@ AC_SUBST(OFDNS, "ofdns") AS_IF([test x"$enable_files" != x"no"], [ AC_SUBST(OFHTTP, "ofhttp") ]) - AC_SUBST(OFSOCK, "ofsock") ]) AC_DEFUN([CHECK_BUILTIN_BSWAP], [ AC_MSG_CHECKING(for __builtin_bswap$1) AC_LINK_IFELSE([ Index: extra.mk.in ================================================================== --- extra.mk.in +++ extra.mk.in @@ -42,17 +42,15 @@ MAP_LDFLAGS = @MAP_LDFLAGS@ OFARC = @OFARC@ OFDNS = @OFDNS@ OFHASH = @OFHASH@ OFHTTP = @OFHTTP@ -OFSOCK = @OFSOCK@ OF_BLOCK_TESTS_M = @OF_BLOCK_TESTS_M@ OF_EPOLL_KERNEL_EVENT_OBSERVER_M = @OF_EPOLL_KERNEL_EVENT_OBSERVER_M@ OF_HTTP_CLIENT_TESTS_M = @OF_HTTP_CLIENT_TESTS_M@ OF_KQUEUE_KERNEL_EVENT_OBSERVER_M = @OF_KQUEUE_KERNEL_EVENT_OBSERVER_M@ OF_POLL_KERNEL_EVENT_OBSERVER_M = @OF_POLL_KERNEL_EVENT_OBSERVER_M@ -OF_SCTP_SOCKET_M = @OF_SCTP_SOCKET_M@ OF_SELECT_KERNEL_EVENT_OBSERVER_M = @OF_SELECT_KERNEL_EVENT_OBSERVER_M@ OF_SUBPROCESS_M = @OF_SUBPROCESS_M@ REEXPORT_RUNTIME = @REEXPORT_RUNTIME@ REEXPORT_RUNTIME_FRAMEWORK = @REEXPORT_RUNTIME_FRAMEWORK@ RUNTIME = @RUNTIME@ @@ -72,10 +70,9 @@ UNICODE_M = @UNICODE_M@ USE_INCLUDES_ATOMIC = @USE_INCLUDES_ATOMIC@ USE_SRCS_FILES = @USE_SRCS_FILES@ USE_SRCS_IPX = @USE_SRCS_IPX@ USE_SRCS_PLUGINS = @USE_SRCS_PLUGINS@ -USE_SRCS_SCTP = @USE_SRCS_SCTP@ USE_SRCS_SOCKETS = @USE_SRCS_SOCKETS@ USE_SRCS_THREADS = @USE_SRCS_THREADS@ USE_SRCS_WINDOWS = @USE_SRCS_WINDOWS@ WRAPPER = @WRAPPER@ Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -8,30 +8,18 @@ STATIC_LIB = ${OBJFW_STATIC_LIB} FRAMEWORK = ${OBJFW_FRAMEWORK} LIB_MAJOR = ${OBJFW_LIB_MAJOR} LIB_MINOR = ${OBJFW_LIB_MINOR} -SRCS = OFASN1BitString.m \ - OFASN1Boolean.m \ - OFASN1Enumerated.m \ - OFASN1IA5String.m \ - OFASN1Integer.m \ - OFASN1NumericString.m \ - OFASN1ObjectIdentifier.m \ - OFASN1OctetString.m \ - OFASN1PrintableString.m \ - OFASN1UTF8String.m \ - OFASN1Value.m \ - OFApplication.m \ +SRCS = OFApplication.m \ OFArray.m \ OFBlock.m \ OFCharacterSet.m \ OFColor.m \ OFConstantString.m \ OFCountedSet.m \ OFData.m \ - OFData+ASN1DERParsing.m \ OFData+CryptographicHashing.m \ OFData+MessagePackParsing.m \ OFDate.m \ OFDictionary.m \ OFEnumerator.m \ @@ -135,11 +123,10 @@ OFString+PathAdditions.m SRCS_IPX = OFIPXSocket.m \ OFSPXSocket.m \ OFSPXStreamSocket.m SRCS_PLUGINS = OFPlugin.m -SRCS_SCTP = OFSCTPSocket.m SRCS_SOCKETS = OFDNSQuery.m \ OFDNSResolver.m \ OFDNSResourceRecord.m \ OFDNSResponse.m \ OFDatagramSocket.m \ @@ -152,12 +139,11 @@ OFSequencedPacketSocket.m \ OFStreamSocket.m \ OFTCPSocket.m \ OFUDPSocket.m \ socket.m \ - ${USE_SRCS_IPX} \ - ${USE_SRCS_SCTP} + ${USE_SRCS_IPX} SRCS_THREADS = OFCondition.m \ OFMutex.m \ OFRecursiveMutex.m \ OFThreadPool.m \ condition.m \ @@ -173,11 +159,10 @@ atomic_osatomic.h \ atomic_powerpc.h \ atomic_sync_builtins.h \ atomic_x86.h INCLUDES := ${SRCS:.m=.h} \ - OFASN1DERRepresentation.h \ OFCollection.h \ OFCryptographicHash.h \ OFJSONRepresentation.h \ OFKernelEventObserver.h \ OFKeyValueCoding.h \ DELETED src/OFASN1BitString.h Index: src/OFASN1BitString.h ================================================================== --- src/OFASN1BitString.h +++ src/OFASN1BitString.h @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 "OFASN1DERRepresentation.h" -#import "OFASN1Value.h" - -OF_ASSUME_NONNULL_BEGIN - -@class OFData; - -/** - * @brief An ASN.1 BitString. - */ -OF_SUBCLASSING_RESTRICTED -@interface OFASN1BitString: OFObject -{ - OFData *_bitStringValue; - size_t _bitStringLength; -} - -/** - * @brief The BitString value. - */ -@property (readonly, nonatomic) OFData *bitStringValue; - -/** - * @brief The length of the BitString in bits. - */ -@property (readonly, nonatomic) size_t bitStringLength; - -/** - * @brief Creates an ASN.1 BitString with the specified BitString value and - * length. - * - * @param bitString The value of the BitString - * @param length The length of the BitString in bits - * @return A new, autoreleased OFASN1BitString - */ -+ (instancetype)bitStringWithBitString: (OFData *)bitString - length: (size_t)length; - -- (instancetype)init OF_UNAVAILABLE; - -/** - * @brief Initializes an already allocated ASN.1 BitString with the specified - * BitString value and length. - * - * @param bitString The value of the BitString - * @param length The length of the BitString in bits - * @return An initialized OFASN1BitString - */ -- (instancetype)initWithBitString: (OFData *)bitString - length: (size_t)length OF_DESIGNATED_INITIALIZER; - -/** - * @brief Initializes an already allocated ASN.1 BitString 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 OFASN1BitString - */ -- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents; -@end - -OF_ASSUME_NONNULL_END DELETED src/OFASN1BitString.m Index: src/OFASN1BitString.m ================================================================== --- src/OFASN1BitString.m +++ src/OFASN1BitString.m @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 "OFASN1BitString.h" -#import "OFData.h" -#import "OFString.h" - -#import "OFInvalidArgumentException.h" -#import "OFInvalidFormatException.h" -#import "OFOutOfRangeException.h" - -@implementation OFASN1BitString -@synthesize bitStringValue = _bitStringValue; -@synthesize bitStringLength = _bitStringLength; - -+ (instancetype)bitStringWithBitString: (OFData *)bitString - length: (size_t)length -{ - return [[[self alloc] initWithBitString: bitString - length: length] autorelease]; -} - -- (instancetype)initWithBitString: (OFData *)bitString length: (size_t)length -{ - self = [super init]; - - @try { - if (bitString.count * bitString.itemSize != - OF_ROUND_UP_POW2(8, length) / 8) - @throw [OFInvalidFormatException exception]; - - _bitStringValue = [bitString copy]; - _bitStringLength = length; - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents -{ - void *pool = objc_autoreleasePoolPush(); - OFData *bitString; - size_t length; - - @try { - unsigned char unusedBits; - size_t count = DEREncodedContents.count; - - if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || - tagNumber != OF_ASN1_TAG_NUMBER_BIT_STRING || constructed) - @throw [OFInvalidArgumentException exception]; - - if (DEREncodedContents.itemSize != 1 || count == 0) - @throw [OFInvalidFormatException exception]; - - unusedBits = - *(unsigned char *)[DEREncodedContents itemAtIndex: 0]; - - if (unusedBits > 7) - @throw [OFInvalidFormatException exception]; - - /* - * Can't have any bits of the last byte unused if we have no - * byte. - */ - if (count == 1 && unusedBits != 0) - @throw [OFInvalidFormatException exception]; - - if (SIZE_MAX / 8 < count - 1) - @throw [OFOutOfRangeException exception]; - - length = (count - 1) * 8; - bitString = [DEREncodedContents subdataWithRange: - of_range(1, count - 1)]; - - if (unusedBits != 0) - length -= unusedBits; - } @catch (id e) { - [self release]; - @throw e; - } - - self = [self initWithBitString: bitString length: length]; - - objc_autoreleasePoolPop(pool); - - return self; -} - -- (instancetype)init -{ - OF_INVALID_INIT_METHOD -} - -- (void)dealloc -{ - [_bitStringValue release]; - - [super dealloc]; -} - -- (OFData *)ASN1DERRepresentation -{ - size_t bitStringValueCount = _bitStringValue.count; - size_t roundedUpLength = OF_ROUND_UP_POW2(8, _bitStringLength); - unsigned char unusedBits = roundedUpLength - _bitStringLength; - unsigned char header[] = { - OF_ASN1_TAG_NUMBER_BIT_STRING, - bitStringValueCount + 1, - unusedBits - }; - OFMutableData *data; - - if (bitStringValueCount + 1 > UINT8_MAX || - bitStringValueCount != roundedUpLength / 8) - @throw [OFInvalidFormatException exception]; - - data = [OFMutableData - dataWithCapacity: sizeof(header) + bitStringValueCount]; - [data addItems: header count: sizeof(header)]; - [data addItems: _bitStringValue.items count: bitStringValueCount]; - - [data makeImmutable]; - - return data; -} - -- (bool)isEqual: (id)object -{ - OFASN1BitString *bitString; - - if (object == self) - return true; - - if (![object isKindOfClass: [OFASN1BitString class]]) - return false; - - bitString = object; - - if (![bitString->_bitStringValue isEqual: _bitStringValue]) - return false; - if (bitString->_bitStringLength != _bitStringLength) - return false; - - return true; -} - -- (unsigned long)hash -{ - return _bitStringValue.hash + (unsigned long)_bitStringLength; -} - -- (OFString *)description -{ - return [OFString stringWithFormat: @"", - _bitStringValue, _bitStringLength]; -} -@end DELETED src/OFASN1Boolean.h Index: src/OFASN1Boolean.h ================================================================== --- src/OFASN1Boolean.h +++ src/OFASN1Boolean.h @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 "OFASN1DERRepresentation.h" -#import "OFASN1Value.h" - -OF_ASSUME_NONNULL_BEGIN - -/** - * @brief An ASN.1 Boolean. - */ -OF_SUBCLASSING_RESTRICTED -@interface OFASN1Boolean: OFObject -{ - bool _boolValue; -} - -/** - * @brief The value of the Boolean. - */ -@property (readonly, nonatomic) bool boolValue; - -/** - * @brief Creates an ASN.1 Boolean with the specified Boolean value. - * - * @param bool_ The value of the Boolean - * @return A new, autoreleased OFASN1Boolean - */ -+ (instancetype)booleanWithBool: (bool)bool_; - -- (instancetype)init OF_UNAVAILABLE; - -/** - * @brief Initializes an already allocated ASN.1 Boolean with the specified - * Boolean value. - * - * @param bool_ The value of the Boolean - * @return An initialized OFASN1Boolean - */ -- (instancetype)initWithBool: (bool)bool_ OF_DESIGNATED_INITIALIZER; - -/** - * @brief Initializes an already allocated ASN.1 Boolean 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 OFASN1Boolean - */ -- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents; -@end - -OF_ASSUME_NONNULL_END DELETED src/OFASN1Boolean.m Index: src/OFASN1Boolean.m ================================================================== --- src/OFASN1Boolean.m +++ src/OFASN1Boolean.m @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 "OFASN1Boolean.h" -#import "OFData.h" -#import "OFString.h" - -#import "OFInvalidArgumentException.h" -#import "OFInvalidFormatException.h" - -@implementation OFASN1Boolean -@synthesize boolValue = _boolValue; - -+ (instancetype)booleanWithBool: (bool)bool_ -{ - return [[[self alloc] initWithBool: bool_] autorelease]; -} - -- (instancetype)initWithBool: (bool)bool_ -{ - self = [super init]; - - _boolValue = bool_; - - return self; -} - -- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents -{ - unsigned char value; - - @try { - if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || - tagNumber != OF_ASN1_TAG_NUMBER_BOOLEAN || constructed) - @throw [OFInvalidArgumentException exception]; - - if (DEREncodedContents.itemSize != 1 || - DEREncodedContents.count != 1) - @throw [OFInvalidFormatException exception]; - - value = *(unsigned char *)[DEREncodedContents itemAtIndex: 0]; - - if (value != 0 && value != 0xFF) - @throw [OFInvalidFormatException exception]; - } @catch (id e) { - [self release]; - @throw e; - } - - return [self initWithBool: !!value]; -} - -- (instancetype)init -{ - OF_INVALID_INIT_METHOD -} - -- (OFData *)ASN1DERRepresentation -{ - char buffer[] = { - OF_ASN1_TAG_NUMBER_BOOLEAN, - 1, - (_boolValue ? 0xFF : 0x00) - }; - - return [OFData dataWithItems: buffer count: sizeof(buffer)]; -} - -- (bool)isEqual: (id)object -{ - OFASN1Boolean *boolean; - - if (object == self) - return true; - - if (![object isKindOfClass: [OFASN1Boolean class]]) - return false; - - boolean = object; - - if (boolean->_boolValue != _boolValue) - return false; - - return true; -} - -- (unsigned long)hash -{ - return _boolValue; -} - -- (OFString *)description -{ - return (_boolValue - ? @"" - : @""); -} -@end DELETED src/OFASN1DERRepresentation.h Index: src/OFASN1DERRepresentation.h ================================================================== --- src/OFASN1DERRepresentation.h +++ src/OFASN1DERRepresentation.h @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 DELETED src/OFASN1Enumerated.h Index: src/OFASN1Enumerated.h ================================================================== --- src/OFASN1Enumerated.h +++ src/OFASN1Enumerated.h @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 Enumerated. - */ -OF_SUBCLASSING_RESTRICTED -@interface OFASN1Enumerated: OFObject -{ - long long _longLongValue; -} - -/** - * @brief The integer value. - */ -@property (readonly, nonatomic) long long longLongValue; - -/** - * @brief Creates an ASN.1 Enumerated with the specified integer value. - * - * @param value The `long long` value of the Enumerated - * @return A new, autoreleased OFASN1Enumerated - */ -+ (instancetype)enumeratedWithLongLong: (long long)value; - -- (instancetype)init OF_UNAVAILABLE; - -/** - * @brief Initializes an already allocated ASN.1 Enumerated with the specified - * integer value. - * - * @param value The `long long` value of the Enumerated - * @return An initialized OFASN1Enumerated - */ -- (instancetype)initWithLongLong: (long long)value OF_DESIGNATED_INITIALIZER; - -/** - * @brief Initializes an already allocated ASN.1 Enumerated 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 OFASN1Enumerated - */ -- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents; -@end - -OF_ASSUME_NONNULL_END DELETED src/OFASN1Enumerated.m Index: src/OFASN1Enumerated.m ================================================================== --- src/OFASN1Enumerated.m +++ src/OFASN1Enumerated.m @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 "OFASN1Enumerated.h" -#import "OFData.h" -#import "OFString.h" - -#import "OFInvalidArgumentException.h" - -extern long long of_asn1_der_integer_parse(const unsigned char *buffer, - size_t length); - -@implementation OFASN1Enumerated -@synthesize longLongValue = _longLongValue; - -+ (instancetype)enumeratedWithLongLong: (long long)value -{ - return [[[self alloc] initWithLongLong: value] autorelease]; -} - -- (instancetype)initWithLongLong: (long long)value -{ - self = [super init]; - - _longLongValue = value; - - return self; -} - -- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents -{ - long long value; - - @try { - if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || - tagNumber != OF_ASN1_TAG_NUMBER_ENUMERATED || constructed) - @throw [OFInvalidArgumentException exception]; - - if (DEREncodedContents.itemSize != 1) - @throw [OFInvalidArgumentException exception]; - - value = of_asn1_der_integer_parse( - 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 -{ - OFASN1Enumerated *enumerated; - - if (object == self) - return true; - - if (![object isKindOfClass: [OFASN1Enumerated class]]) - return false; - - enumerated = object; - - if (enumerated->_longLongValue != _longLongValue) - return false; - - return true; -} - -- (unsigned long)hash -{ - return (unsigned long)_longLongValue; -} - -- (OFString *)description -{ - return [OFString stringWithFormat: @"", - _longLongValue]; -} -@end DELETED src/OFASN1IA5String.h Index: src/OFASN1IA5String.h ================================================================== --- src/OFASN1IA5String.h +++ src/OFASN1IA5String.h @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 - -@class OFString; - -/** - * @brief An ASN.1 IA5String. - */ -OF_SUBCLASSING_RESTRICTED -@interface OFASN1IA5String: OFObject -{ - OFString *_IA5StringValue; -} - -/** - * @brief The IA5String value. - */ -@property (readonly, nonatomic) OFString *IA5StringValue; - -/** - * @brief The string value. - */ -@property (readonly, nonatomic) OFString *stringValue; - -/** - * @brief Creates an IA5String with the specified string value. - * - * @param string The string value of the IA5String - * @return A new, autoreleased OFASN1IA5String - */ -+ (instancetype)stringWithString: (OFString *)string; - -- (instancetype)init OF_UNAVAILABLE; - -/** - * @brief Initializes an already allocated IA5String with the specified string - * value. - * - * @param string The string value of the IA5String - * @return An initialized OFASN1IA5String - */ -- (instancetype)initWithString: (OFString *)string OF_DESIGNATED_INITIALIZER; - -/** - * @brief Initializes an already allocated ASN.1 IA5String 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 OFASN1IA5String - */ -- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents; -@end - -OF_ASSUME_NONNULL_END DELETED src/OFASN1IA5String.m Index: src/OFASN1IA5String.m ================================================================== --- src/OFASN1IA5String.m +++ src/OFASN1IA5String.m @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 "OFASN1IA5String.h" -#import "OFData.h" -#import "OFString.h" - -#import "OFInvalidArgumentException.h" - -@implementation OFASN1IA5String -@synthesize IA5StringValue = _IA5StringValue; - -+ (instancetype)stringWithString: (OFString *)string -{ - return [[[self alloc] initWithString: string] autorelease]; -} - -- (instancetype)initWithString: (OFString *)string -{ - self = [super init]; - - @try { - _IA5StringValue = [string copy]; - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents -{ - void *pool = objc_autoreleasePoolPush(); - OFString *IA5String; - - @try { - if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || - tagNumber != OF_ASN1_TAG_NUMBER_IA5_STRING || constructed) - @throw [OFInvalidArgumentException exception]; - - if (DEREncodedContents.itemSize != 1) - @throw [OFInvalidArgumentException exception]; - - IA5String= [OFString - stringWithCString: DEREncodedContents.items - encoding: OF_STRING_ENCODING_ASCII - length: DEREncodedContents.count]; - } @catch (id e) { - [self release]; - @throw e; - } - - self = [self initWithString: IA5String]; - - objc_autoreleasePoolPop(pool); - - return self; -} - -- (instancetype)init -{ - OF_INVALID_INIT_METHOD -} - -- (void)dealloc -{ - [_IA5StringValue release]; - - [super dealloc]; -} - -- (OFString *)stringValue -{ - return self.IA5StringValue; -} - -- (bool)isEqual: (id)object -{ - OFASN1IA5String *IA5String; - - if (object == self) - return true; - - if (![object isKindOfClass: [OFASN1IA5String class]]) - return false; - - IA5String = object; - - if (![IA5String->_IA5StringValue isEqual: _IA5StringValue]) - return false; - - return true; -} - -- (unsigned long)hash -{ - return _IA5StringValue.hash; -} - -- (OFString *)description -{ - return [OFString stringWithFormat: @"", - _IA5StringValue]; -} -@end DELETED src/OFASN1Integer.h Index: src/OFASN1Integer.h ================================================================== --- src/OFASN1Integer.h +++ src/OFASN1Integer.h @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2008-2021 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: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)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-2021 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 -of_asn1_der_integer_parse(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: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents -{ - long long value; - - @try { - if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || - tagNumber != OF_ASN1_TAG_NUMBER_INTEGER || constructed) - @throw [OFInvalidArgumentException exception]; - - if (DEREncodedContents.itemSize != 1) - @throw [OFInvalidArgumentException exception]; - - value = of_asn1_der_integer_parse( - 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 DELETED src/OFASN1NumericString.h Index: src/OFASN1NumericString.h ================================================================== --- src/OFASN1NumericString.h +++ src/OFASN1NumericString.h @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 - -@class OFString; - -/** - * @brief An ASN.1 NumericString. - */ -OF_SUBCLASSING_RESTRICTED -@interface OFASN1NumericString: OFObject -{ - OFString *_numericStringValue; -} - -/** - * @brief The NumericString value. - */ -@property (readonly, nonatomic) OFString *numericStringValue; - -/** - * @brief The string value. - */ -@property (readonly, nonatomic) OFString *stringValue; - -/** - * @brief Creates an NumericString with the specified string value. - * - * @param string The string value of the NumericString - * @return A new, autoreleased OFASN1NumericString - */ -+ (instancetype)stringWithString: (OFString *)string; - -- (instancetype)init OF_UNAVAILABLE; - -/** - * @brief Initializes an already allocated NumericString with the specified - * string value. - * - * @param string The string value of the NumericString - * @return An initialized OFASN1NumericString - */ -- (instancetype)initWithString: (OFString *)string OF_DESIGNATED_INITIALIZER; - -/** - * @brief Initializes an already allocated ASN.1 NumericString 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 ASN.1 NumericString - */ -- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents; -@end - -OF_ASSUME_NONNULL_END DELETED src/OFASN1NumericString.m Index: src/OFASN1NumericString.m ================================================================== --- src/OFASN1NumericString.m +++ src/OFASN1NumericString.m @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 "OFASN1NumericString.h" -#import "OFData.h" -#import "OFString.h" - -#import "OFInvalidArgumentException.h" -#import "OFInvalidEncodingException.h" - -@implementation OFASN1NumericString -@synthesize numericStringValue = _numericStringValue; - -+ (instancetype)stringWithString: (OFString *)string -{ - return [[[self alloc] initWithString: string] autorelease]; -} - -- (instancetype)initWithString: (OFString *)string -{ - self = [super init]; - - @try { - void *pool = objc_autoreleasePoolPush(); - const char *cString = string.UTF8String; - size_t length = string.UTF8StringLength; - - for (size_t i = 0; i < length; i++) - if (!of_ascii_isdigit(cString[i]) && cString[i] != ' ') - @throw [OFInvalidEncodingException exception]; - - _numericStringValue = [string copy]; - - objc_autoreleasePoolPop(pool); - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents -{ - void *pool = objc_autoreleasePoolPush(); - OFString *numericString; - - @try { - if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || - tagNumber != OF_ASN1_TAG_NUMBER_NUMERIC_STRING || - constructed) - @throw [OFInvalidArgumentException exception]; - - if (DEREncodedContents.itemSize != 1) - @throw [OFInvalidArgumentException exception]; - - numericString = [OFString - stringWithCString: DEREncodedContents.items - encoding: OF_STRING_ENCODING_ASCII - length: DEREncodedContents.count]; - } @catch (id e) { - [self release]; - @throw e; - } - - self = [self initWithString: numericString]; - - objc_autoreleasePoolPop(pool); - - return self; -} - -- (instancetype)init -{ - OF_INVALID_INIT_METHOD -} - -- (void)dealloc -{ - [_numericStringValue release]; - - [super dealloc]; -} - -- (OFString *)stringValue -{ - return self.numericStringValue; -} - -- (bool)isEqual: (id)object -{ - OFASN1NumericString *numericString; - - if (object == self) - return true; - - if (![object isKindOfClass: [OFASN1NumericString class]]) - return false; - - numericString = object; - - if (![numericString->_numericStringValue isEqual: _numericStringValue]) - return false; - - return true; -} - -- (unsigned long)hash -{ - return _numericStringValue.hash; -} - -- (OFString *)description -{ - return [OFString stringWithFormat: @"", - _numericStringValue]; -} -@end DELETED src/OFASN1ObjectIdentifier.h Index: src/OFASN1ObjectIdentifier.h ================================================================== --- src/OFASN1ObjectIdentifier.h +++ src/OFASN1ObjectIdentifier.h @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 - -@class OFArray OF_GENERIC(ObjetType); -@class OFNumber; - -/** - * @brief An ASN.1 ObjectIdentifier. - */ -OF_SUBCLASSING_RESTRICTED -@interface OFASN1ObjectIdentifier: OFObject -{ - OFArray OF_GENERIC(OFNumber *) *_subidentifiers; -} - -/** - * @brief The subidentifiers of the ObjectIdentifier. - */ -@property (readonly, nonatomic) OFArray OF_GENERIC(OFNumber *) *subidentifiers; - -/** - * @brief Creates an ASN.1 ObjectIdentifier with the specified subidentifiers. - * - * @param subidentifiers The subidentifiers of the ASN.1 ObjectIdentifier - * @return A new, autoreleased OFASN1ObjectIdentifier - */ -+ (instancetype)objectIdentifierWithSubidentifiers: - (OFArray OF_GENERIC(OFNumber *) *)subidentifiers; - -- (instancetype)init OF_UNAVAILABLE; - -/** - * @brief Initializes an already allocated ASN.1 ObjectIdentifier with the - * specified subidentifiers. - * - * @param subidentifiers The subidentifiers of the ASN.1 ObjectIdentifier - * @return An initialized OFASN1ObjectIdentifier - */ -- (instancetype)initWithSubidentifiers: - (OFArray OF_GENERIC(OFNumber *) *)subidentifiers OF_DESIGNATED_INITIALIZER; - -/** - * @brief Initializes an already allocated ASN.1 ObjectIdentifier 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 OFASN1ObjectIdentifier - */ -- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents; -@end - -OF_ASSUME_NONNULL_END DELETED src/OFASN1ObjectIdentifier.m Index: src/OFASN1ObjectIdentifier.m ================================================================== --- src/OFASN1ObjectIdentifier.m +++ src/OFASN1ObjectIdentifier.m @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 "OFASN1ObjectIdentifier.h" -#import "OFArray.h" -#import "OFData.h" -#import "OFNumber.h" -#import "OFString.h" - -#import "OFInvalidArgumentException.h" -#import "OFInvalidFormatException.h" -#import "OFOutOfRangeException.h" - -@implementation OFASN1ObjectIdentifier -@synthesize subidentifiers = _subidentifiers; - -+ (instancetype)objectIdentifierWithSubidentifiers: - (OFArray OF_GENERIC(OFNumber *) *)subidentifiers -{ - return [[[self alloc] - initWithSubidentifiers: subidentifiers] autorelease]; -} - -- (instancetype)initWithSubidentifiers: - (OFArray OF_GENERIC(OFNumber *) *)subidentifiers -{ - self = [super init]; - - @try { - if (subidentifiers.count < 1) - @throw [OFInvalidFormatException exception]; - - switch ([[subidentifiers objectAtIndex: 0] longLongValue]) { - case 0: - case 1: - case 2: - break; - default: - @throw [OFInvalidFormatException exception]; - } - - _subidentifiers = [subidentifiers copy]; - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents -{ - void *pool = objc_autoreleasePoolPush(); - OFMutableArray OF_GENERIC(OFNumber *) *subidentifiers; - - @try { - const unsigned char *items = DEREncodedContents.items; - size_t count = DEREncodedContents.count; - unsigned long long value = 0; - uint_fast8_t bits = 0; - - if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || - tagNumber != OF_ASN1_TAG_NUMBER_OBJECT_IDENTIFIER || - constructed) - @throw [OFInvalidArgumentException exception]; - - if (DEREncodedContents.itemSize != 1 || count == 0) - @throw [OFInvalidArgumentException exception]; - - subidentifiers = [OFMutableArray array]; - - for (size_t i = 0; i < count; i++) { - if (bits == 0 && items[i] == 0x80) - @throw [OFInvalidFormatException exception]; - - value = (value << 7) | (items[i] & 0x7F); - bits += 7; - - if (bits > sizeof(unsigned long long) * 8) - @throw [OFOutOfRangeException exception]; - - if (items[i] & 0x80) - continue; - - if (subidentifiers.count == 0) { - if (value < 40) - [subidentifiers addObject: - [OFNumber numberWithInt: 0]]; - else if (value < 80) { - [subidentifiers addObject: - [OFNumber numberWithInt: 1]]; - value -= 40; - } else { - [subidentifiers addObject: - [OFNumber numberWithInt: 2]]; - value -= 80; - } - } - - [subidentifiers addObject: - [OFNumber numberWithUnsignedLongLong: value]]; - - value = 0; - bits = 0; - } - - if (items[count - 1] & 0x80) - @throw [OFInvalidFormatException exception]; - - [subidentifiers makeImmutable]; - } @catch (id e) { - [self release]; - @throw e; - } - - self = [self initWithSubidentifiers: subidentifiers]; - - objc_autoreleasePoolPop(pool); - - return self; -} - -- (instancetype)init -{ - OF_INVALID_INIT_METHOD -} - -- (void)dealloc -{ - [_subidentifiers release]; - - [super dealloc]; -} - -- (bool)isEqual: (id)object -{ - OFASN1ObjectIdentifier *objectIdentifier; - - if (object == self) - return true; - - if (![object isKindOfClass: [OFASN1ObjectIdentifier class]]) - return false; - - objectIdentifier = object; - - if (![objectIdentifier->_subidentifiers isEqual: _subidentifiers]) - return false; - - return true; -} - -- (unsigned long)hash -{ - return _subidentifiers.hash; -} - -- (OFString *)description -{ - return [OFString stringWithFormat: - @"", - [_subidentifiers componentsJoinedByString: @"."]]; -} -@end DELETED src/OFASN1OctetString.h Index: src/OFASN1OctetString.h ================================================================== --- src/OFASN1OctetString.h +++ src/OFASN1OctetString.h @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 - -@class OFData; - -/** - * @brief An ASN.1 OctetString. - */ -OF_SUBCLASSING_RESTRICTED -@interface OFASN1OctetString: OFObject -{ - OFData *_octetStringValue; -} - -/** - * @brief The OctetString value. - */ -@property (readonly, nonatomic) OFData *octetStringValue; - -/** - * @brief Creates an OctetString with the specified value. - * - * @param octetString The OctetString value - * @return A new, autoreleased OFASN1OctetString - */ -+ (instancetype)octetStringWithOctetString: (OFData *)octetString; - -- (instancetype)init OF_UNAVAILABLE; - -/** - * @brief Initializes an already allocated OctetString with the specified - * value. - * - * @param octetString The OctetString value - * @return An initialized OFASN1OctetString - */ -- (instancetype)initWithOctetString: (OFData *)octetString - OF_DESIGNATED_INITIALIZER; - -/** - * @brief Initializes an already allocated ASN.1 OctetString 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 ASN.1 OctetString - */ -- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents; -@end - -OF_ASSUME_NONNULL_END DELETED src/OFASN1OctetString.m Index: src/OFASN1OctetString.m ================================================================== --- src/OFASN1OctetString.m +++ src/OFASN1OctetString.m @@ -1,107 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 "OFASN1OctetString.h" -#import "OFData.h" -#import "OFString.h" - -#import "OFInvalidArgumentException.h" - -@implementation OFASN1OctetString -@synthesize octetStringValue = _octetStringValue; - -+ (instancetype)octetStringWithOctetString: (OFData *)octetString -{ - return [[[self alloc] initWithOctetString: octetString] autorelease]; -} - -- (instancetype)initWithOctetString: (OFData *)octetString -{ - self = [super init]; - - @try { - _octetStringValue = [octetString copy]; - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents -{ - @try { - if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || - tagNumber != OF_ASN1_TAG_NUMBER_OCTET_STRING || - constructed) - @throw [OFInvalidArgumentException exception]; - - if (DEREncodedContents.itemSize != 1) - @throw [OFInvalidArgumentException exception]; - } @catch (id e) { - [self release]; - @throw e; - } - - return [self initWithOctetString: DEREncodedContents]; -} - -- (instancetype)init -{ - OF_INVALID_INIT_METHOD -} - -- (void)dealloc -{ - [_octetStringValue release]; - - [super dealloc]; -} - -- (bool)isEqual: (id)object -{ - OFASN1OctetString *octetString; - - if (object == self) - return true; - - if (![object isKindOfClass: [OFASN1OctetString class]]) - return false; - - octetString = object; - - if (![octetString->_octetStringValue isEqual: _octetStringValue]) - return false; - - return true; -} - -- (unsigned long)hash -{ - return _octetStringValue.hash; -} - -- (OFString *)description -{ - return [OFString stringWithFormat: @"", - _octetStringValue]; -} -@end DELETED src/OFASN1PrintableString.h Index: src/OFASN1PrintableString.h ================================================================== --- src/OFASN1PrintableString.h +++ src/OFASN1PrintableString.h @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 - -@class OFString; - -/** - * @brief An ASN.1 PrintableString. - */ -OF_SUBCLASSING_RESTRICTED -@interface OFASN1PrintableString: OFObject -{ - OFString *_printableStringValue; -} - -/** - * @brief The PrintableString value. - */ -@property (readonly, nonatomic) OFString *printableStringValue; - -/** - * @brief The string value. - */ -@property (readonly, nonatomic) OFString *stringValue; - -/** - * @brief Creates a PrintableString with the specified string value. - * - * @param string The string value of the PrintableString - * @return A new, autoreleased OFASN1PrintableString - */ -+ (instancetype)stringWithString: (OFString *)string; - -- (instancetype)init OF_UNAVAILABLE; - -/** - * @brief Initializes an already allocated PrintableString with the specified - * string value. - * - * @param string The string value of the PrintableString - * @return An initialized OFASN1PrintableString - */ -- (instancetype)initWithString: (OFString *)string OF_DESIGNATED_INITIALIZER; - -/** - * @brief Initializes an already allocated ASN.1 PrintableString 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 OFASN1PrintableString - */ -- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents; -@end - -OF_ASSUME_NONNULL_END DELETED src/OFASN1PrintableString.m Index: src/OFASN1PrintableString.m ================================================================== --- src/OFASN1PrintableString.m +++ src/OFASN1PrintableString.m @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 "OFASN1PrintableString.h" -#import "OFData.h" -#import "OFString.h" - -#import "OFInvalidArgumentException.h" -#import "OFInvalidEncodingException.h" - -@implementation OFASN1PrintableString -@synthesize printableStringValue = _printableStringValue; - -+ (instancetype)stringWithString: (OFString *)string -{ - return [[[self alloc] initWithString: string] autorelease]; -} - -- (instancetype)initWithString: (OFString *)string -{ - self = [super init]; - - @try { - void *pool = objc_autoreleasePoolPush(); - const char *cString = string.UTF8String; - size_t length = string.UTF8StringLength; - - for (size_t i = 0; i < length; i++) { - if (of_ascii_isalnum(cString[i])) - continue; - - switch (cString[i]) { - case ' ': - case '\'': - case '(': - case ')': - case '+': - case ',': - case '-': - case '.': - case '/': - case ':': - case '=': - case '?': - continue; - default: - @throw [OFInvalidEncodingException exception]; - } - } - - _printableStringValue = [string copy]; - - objc_autoreleasePoolPop(pool); - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents -{ - void *pool = objc_autoreleasePoolPush(); - OFString *printableString; - - @try { - if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || - tagNumber != OF_ASN1_TAG_NUMBER_PRINTABLE_STRING || - constructed) - @throw [OFInvalidArgumentException exception]; - - if (DEREncodedContents.itemSize != 1) - @throw [OFInvalidArgumentException exception]; - - printableString = [OFString - stringWithCString: DEREncodedContents.items - encoding: OF_STRING_ENCODING_ASCII - length: DEREncodedContents.count]; - } @catch (id e) { - [self release]; - @throw e; - } - - self = [self initWithString: printableString]; - - objc_autoreleasePoolPop(pool); - - return self; -} - -- (instancetype)init -{ - OF_INVALID_INIT_METHOD -} - -- (void)dealloc -{ - [_printableStringValue release]; - - [super dealloc]; -} - -- (OFString *)stringValue -{ - return self.printableStringValue; -} - -- (bool)isEqual: (id)object -{ - OFASN1PrintableString *printableString; - - if (object == self) - return true; - - if (![object isKindOfClass: [OFASN1PrintableString class]]) - return false; - - printableString = object; - - if (![printableString->_printableStringValue isEqual: - _printableStringValue]) - return false; - - return true; -} - -- (unsigned long)hash -{ - return _printableStringValue.hash; -} - -- (OFString *)description -{ - return [OFString stringWithFormat: @"", - _printableStringValue]; -} -@end DELETED src/OFASN1UTF8String.h Index: src/OFASN1UTF8String.h ================================================================== --- src/OFASN1UTF8String.h +++ src/OFASN1UTF8String.h @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 - -@class OFString; - -/** - * @brief An ASN.1 UTF8String. - */ -OF_SUBCLASSING_RESTRICTED -@interface OFASN1UTF8String: OFObject -{ - OFString *_UTF8StringValue; -} - -/** - * @brief The UTF8String value. - */ -@property (readonly, nonatomic) OFString *UTF8StringValue; - -/** - * @brief The string value. - */ -@property (readonly, nonatomic) OFString *stringValue; - -/** - * @brief Creates a UTF8String with the specified string value. - * - * @param string The string value of the UTF8String - * @return A new, autoreleased OFASN1UTF8String - */ -+ (instancetype)stringWithString: (OFString *)string; - -- (instancetype)init OF_UNAVAILABLE; - -/** - * @brief Initializes an already allocated UTF8String with the specified - * string value. - * - * @param string The string value of the UTF8String - * @return An initialized OFASN1UTF8String - */ -- (instancetype)initWithString: (OFString *)string OF_DESIGNATED_INITIALIZER; - -/** - * @brief Initializes an already allocated ASN.1 UTF8String 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 OFASN1UTF8String - */ -- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents; -@end - -OF_ASSUME_NONNULL_END DELETED src/OFASN1UTF8String.m Index: src/OFASN1UTF8String.m ================================================================== --- src/OFASN1UTF8String.m +++ src/OFASN1UTF8String.m @@ -1,122 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 "OFASN1UTF8String.h" -#import "OFData.h" -#import "OFString.h" - -#import "OFInvalidArgumentException.h" - -@implementation OFASN1UTF8String -@synthesize UTF8StringValue = _UTF8StringValue; - -+ (instancetype)stringWithString: (OFString *)string -{ - return [[[self alloc] initWithString: string] autorelease]; -} - -- (instancetype)initWithString: (OFString *)string -{ - self = [super init]; - - @try { - _UTF8StringValue = [string copy]; - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents -{ - void *pool = objc_autoreleasePoolPush(); - OFString *UTF8String; - - @try { - if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || - tagNumber != OF_ASN1_TAG_NUMBER_UTF8_STRING || constructed) - @throw [OFInvalidArgumentException exception]; - - if (DEREncodedContents.itemSize != 1) - @throw [OFInvalidArgumentException exception]; - - UTF8String = [OFString - stringWithUTF8String: DEREncodedContents.items - length: DEREncodedContents.count]; - } @catch (id e) { - [self release]; - @throw e; - } - - self = [self initWithString: UTF8String]; - - objc_autoreleasePoolPop(pool); - - return self; -} - -- (instancetype)init -{ - OF_INVALID_INIT_METHOD -} - -- (void)dealloc -{ - [_UTF8StringValue release]; - - [super dealloc]; -} - -- (OFString *)stringValue -{ - return self.UTF8StringValue; -} - -- (bool)isEqual: (id)object -{ - OFASN1UTF8String *UTF8String; - - if (object == self) - return true; - - if (![object isKindOfClass: [OFASN1UTF8String class]]) - return false; - - UTF8String = object; - - if (![UTF8String->_UTF8StringValue isEqual: _UTF8StringValue]) - return false; - - return true; -} - -- (unsigned long)hash -{ - return _UTF8StringValue.hash; -} - -- (OFString *)description -{ - return [OFString stringWithFormat: @"", - _UTF8StringValue]; -} -@end DELETED src/OFASN1Value.h Index: src/OFASN1Value.h ================================================================== --- src/OFASN1Value.h +++ src/OFASN1Value.h @@ -1,135 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 - -/** @file */ - -@class OFData; - -/** - * @brief ASN.1 tag class. - */ -typedef enum { - /** Universal */ - OF_ASN1_TAG_CLASS_UNIVERSAL = 0x0, - /** Application */ - OF_ASN1_TAG_CLASS_APPLICATION = 0x1, - /** Context specific */ - OF_ASN1_TAG_CLASS_CONTEXT_SPECIFIC = 0x2, - /** Private */ - OF_ASN1_TAG_CLASS_PRIVATE = 0x3 -} of_asn1_tag_class_t; - -/** - * @brief ASN.1 tag number. - */ -typedef enum { - /** Boolean */ - OF_ASN1_TAG_NUMBER_BOOLEAN = 0x01, - /** Integer */ - OF_ASN1_TAG_NUMBER_INTEGER = 0x02, - /** Bit string */ - OF_ASN1_TAG_NUMBER_BIT_STRING = 0x03, - /** Octet string */ - OF_ASN1_TAG_NUMBER_OCTET_STRING = 0x04, - /** Null */ - OF_ASN1_TAG_NUMBER_NULL = 0x05, - /** Object Identifier */ - OF_ASN1_TAG_NUMBER_OBJECT_IDENTIFIER = 0x06, - /** Enumerated */ - OF_ASN1_TAG_NUMBER_ENUMERATED = 0x0A, - /** UTF-8 string */ - OF_ASN1_TAG_NUMBER_UTF8_STRING = 0x0C, - /** Sequence */ - OF_ASN1_TAG_NUMBER_SEQUENCE = 0x10, - /** Set */ - OF_ASN1_TAG_NUMBER_SET = 0x11, - /** NumericString */ - OF_ASN1_TAG_NUMBER_NUMERIC_STRING = 0x12, - /** PrintableString */ - OF_ASN1_TAG_NUMBER_PRINTABLE_STRING = 0x13, - /** IA5String */ - OF_ASN1_TAG_NUMBER_IA5_STRING = 0x16 -} of_asn1_tag_number_t; - -/** - * @brief A class representing an ASN.1 value. - */ -OF_SUBCLASSING_RESTRICTED -@interface OFASN1Value: OFObject -{ - of_asn1_tag_class_t _tagClass; - of_asn1_tag_number_t _tagNumber; - bool _constructed; - OFData *_DEREncodedContents; -} - -/** - * @brief The tag class of the value's type. - */ -@property (readonly, nonatomic) of_asn1_tag_class_t tagClass; - -/** - * @brief The tag number of the value's type. - */ -@property (readonly, nonatomic) of_asn1_tag_number_t tagNumber; - -/** - * @brief Whether the value if of a constructed type. - */ -@property (readonly, nonatomic, getter=isConstructed) bool constructed; - -/** - * @brief The DER-encoded contents octets of the value. - */ -@property (readonly, nonatomic) OFData *DEREncodedContents; - -/** - * @brief Creates a new ASN.1 value 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 A new ASN.1 value - */ -+ (instancetype)valueWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents; - -- (instancetype)init OF_UNAVAILABLE; - -/** - * @brief Initializes an already allocated ASN.1 value 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 ASN.1 value - */ -- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents - OF_DESIGNATED_INITIALIZER; -@end - -OF_ASSUME_NONNULL_END DELETED src/OFASN1Value.m Index: src/OFASN1Value.m ================================================================== --- src/OFASN1Value.m +++ src/OFASN1Value.m @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 "OFASN1Value.h" -#import "OFData.h" -#import "OFString.h" - -#import "OFInvalidFormatException.h" - -@implementation OFASN1Value -@synthesize tagClass = _tagClass, tagNumber = _tagNumber; -@synthesize constructed = _constructed; -@synthesize DEREncodedContents = _DEREncodedContents; - -+ (instancetype)valueWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents -{ - return [[[self alloc] - initWithTagClass: tagClass - tagNumber: tagNumber - constructed: constructed - DEREncodedContents: DEREncodedContents] autorelease]; -} - -- (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass - tagNumber: (of_asn1_tag_number_t)tagNumber - constructed: (bool)constructed - DEREncodedContents: (OFData *)DEREncodedContents -{ - self = [super init]; - - @try { - if (DEREncodedContents.itemSize != 1) - @throw [OFInvalidFormatException exception]; - - _tagClass = tagClass; - _tagNumber = tagNumber; - _constructed = constructed; - _DEREncodedContents = [DEREncodedContents copy]; - } @catch (id e) { - [self release]; - @throw e; - } - - return self; -} - -- (instancetype)init -{ - OF_INVALID_INIT_METHOD -} - -- (void)dealloc -{ - [_DEREncodedContents release]; - - [super dealloc]; -} - -- (bool)isEqual: (id)object -{ - OFASN1Value *value; - - if (object == self) - return true; - - if (![object isKindOfClass: [OFASN1Value class]]) - return false; - - value = object; - - if (value->_tagClass != _tagClass) - return false; - if (value->_tagNumber != _tagNumber) - return false; - if (value->_constructed != _constructed) - return false; - if (![value->_DEREncodedContents isEqual: _DEREncodedContents]) - return false; - - return true; -} - -- (unsigned long)hash -{ - uint32_t hash; - - OF_HASH_INIT(hash); - - OF_HASH_ADD(hash, _tagClass & 0xFF); - OF_HASH_ADD(hash, _tagNumber & 0xFF); - OF_HASH_ADD(hash, _constructed); - OF_HASH_ADD_HASH(hash, _DEREncodedContents.hash); - - OF_HASH_FINALIZE(hash); - - return hash; -} - -- (OFString *)description -{ - return [OFString stringWithFormat: - @"", - _tagClass, _tagNumber, _constructed, - _DEREncodedContents.description]; -} -@end Index: src/OFConstantString.m ================================================================== --- src/OFConstantString.m +++ src/OFConstantString.m @@ -177,14 +177,14 @@ [self finishInitialization]; return [self mutableCopy]; } /* From protocol OFComparing, but overridden in OFString */ -- (of_comparison_result_t)compare: (OFString *)object +- (of_comparison_result_t)compare: (OFString *)string { [self finishInitialization]; - return [self compare: object]; + return [self compare: string]; } /* From OFObject, but reimplemented in OFString */ - (bool)isEqual: (id)object { @@ -243,14 +243,14 @@ { [self finishInitialization]; return [self cStringLengthWithEncoding: encoding]; } -- (of_comparison_result_t)caseInsensitiveCompare: (OFString *)otherString +- (of_comparison_result_t)caseInsensitiveCompare: (OFString *)string { [self finishInitialization]; - return [self caseInsensitiveCompare: otherString]; + return [self caseInsensitiveCompare: string]; } - (of_unichar_t)characterAtIndex: (size_t)idx { [self finishInitialization]; DELETED src/OFData+ASN1DERParsing.h Index: src/OFData+ASN1DERParsing.h ================================================================== --- src/OFData+ASN1DERParsing.h +++ src/OFData+ASN1DERParsing.h @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 "OFData.h" -#import "OFASN1Value.h" - -OF_ASSUME_NONNULL_BEGIN - -#ifdef __cplusplus -extern "C" { -#endif -extern int _OFData_ASN1DERParsing_reference; -#ifdef __cplusplus -} -#endif - -@interface OFData (ASN1DERParsing) -/** - * @brief The data interpreted as ASN.1 in DER representation and parsed as an - * object. - * - * This is either an OFArray (for a sequence), an OFSet (for a set) or an - * OFASN1Value. - */ -@property (readonly, nonatomic) id objectByParsingASN1DER; - -/** - * @brief Parses the ASN.1 DER representation and returns it as an object. - * - * This is either an OFArray (for a sequence), an OFSet (for a set) or an - * OFASN1Value. - * - * @param depthLimit The maximum depth the parser should accept (defaults to 32 - * if not specified, 0 means no limit (insecure!)) - * @return The ASN.1 DER representation as an object - */ -- (id)objectByParsingASN1DERWithDepthLimit: (size_t)depthLimit; -@end - -OF_ASSUME_NONNULL_END DELETED src/OFData+ASN1DERParsing.m Index: src/OFData+ASN1DERParsing.m ================================================================== --- src/OFData+ASN1DERParsing.m +++ src/OFData+ASN1DERParsing.m @@ -1,249 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 "OFData+ASN1DERParsing.h" -#import "OFASN1BitString.h" -#import "OFASN1Boolean.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" -#import "OFASN1Value.h" -#import "OFArray.h" -#import "OFNull.h" -#import "OFSet.h" - -#import "OFInvalidArgumentException.h" -#import "OFInvalidFormatException.h" -#import "OFOutOfRangeException.h" -#import "OFTruncatedDataException.h" - -enum { - ASN1_TAG_CONSTRUCTED_MASK = 0x20 -}; - -int _OFData_ASN1DERParsing_reference; - -static size_t parseObject(OFData *self, id *object, size_t depthLimit); - -static OFArray * -parseSequence(OFData *contents, size_t depthLimit) -{ - OFMutableArray *ret = [OFMutableArray array]; - size_t count = contents.count; - - if (depthLimit == 0) - @throw [OFOutOfRangeException exception]; - - while (count > 0) { - id object; - size_t objectLength; - - objectLength = parseObject(contents, &object, depthLimit); - - count -= objectLength; - contents = [contents subdataWithRange: - of_range(objectLength, count)]; - - [ret addObject: object]; - } - - [ret makeImmutable]; - - return ret; -} - -static OFSet * -parseSet(OFData *contents, size_t depthLimit) -{ - OFMutableSet *ret = [OFMutableSet set]; - size_t count = contents.count; - OFData *previousObjectData = nil; - - if (depthLimit == 0) - @throw [OFOutOfRangeException exception]; - - while (count > 0) { - id object; - size_t objectLength; - OFData *objectData; - - objectLength = parseObject(contents, &object, depthLimit); - objectData = [contents subdataWithRange: - of_range(0, objectLength)]; - - if (previousObjectData != nil && - [objectData compare: previousObjectData] != - OF_ORDERED_DESCENDING) - @throw [OFInvalidFormatException exception]; - - count -= objectLength; - contents = [contents subdataWithRange: - of_range(objectLength, count)]; - - [ret addObject: object]; - - previousObjectData = objectData; - } - - [ret makeImmutable]; - - return ret; -} - -static size_t -parseObject(OFData *self, id *object, size_t depthLimit) -{ - const unsigned char *items = self.items; - size_t count = self.count; - unsigned char tag; - size_t contentsLength, bytesConsumed = 0; - Class valueClass; - OFData *contents; - - if (count < 2) - @throw [OFTruncatedDataException exception]; - - tag = *items++; - contentsLength = *items++; - bytesConsumed += 2; - - if (contentsLength > 127) { - uint_fast8_t lengthLength = contentsLength & 0x7F; - - if (lengthLength > sizeof(size_t)) - @throw [OFOutOfRangeException exception]; - - if (count - bytesConsumed < lengthLength) - @throw [OFTruncatedDataException exception]; - - if (lengthLength == 0 || - (lengthLength == 1 && items[0] < 0x80) || - (lengthLength >= 2 && items[0] == 0)) - @throw [OFInvalidFormatException exception]; - - contentsLength = 0; - - for (uint_fast8_t i = 0; i < lengthLength; i++) - contentsLength = (contentsLength << 8) | *items++; - - bytesConsumed += lengthLength; - - if (contentsLength <= 127) - @throw [OFInvalidFormatException exception]; - } - - if (count - bytesConsumed < contentsLength) - @throw [OFTruncatedDataException exception]; - - contents = [self subdataWithRange: - of_range(bytesConsumed, contentsLength)]; - bytesConsumed += contentsLength; - - switch (tag & ~ASN1_TAG_CONSTRUCTED_MASK) { - case OF_ASN1_TAG_NUMBER_BOOLEAN: - valueClass = [OFASN1Boolean class]; - break; - case OF_ASN1_TAG_NUMBER_INTEGER: - valueClass = [OFASN1Integer class]; - break; - case OF_ASN1_TAG_NUMBER_BIT_STRING: - valueClass = [OFASN1BitString class]; - break; - case OF_ASN1_TAG_NUMBER_OCTET_STRING: - valueClass = [OFASN1OctetString class]; - break; - case OF_ASN1_TAG_NUMBER_NULL: - if (tag & ASN1_TAG_CONSTRUCTED_MASK) - @throw [OFInvalidFormatException exception]; - - if (contents.count != 0) - @throw [OFInvalidFormatException exception]; - - *object = [OFNull null]; - return bytesConsumed; - case OF_ASN1_TAG_NUMBER_OBJECT_IDENTIFIER: - valueClass = [OFASN1ObjectIdentifier class]; - break; - case OF_ASN1_TAG_NUMBER_ENUMERATED: - valueClass = [OFASN1Enumerated class]; - break; - case OF_ASN1_TAG_NUMBER_UTF8_STRING: - valueClass = [OFASN1UTF8String class]; - break; - case OF_ASN1_TAG_NUMBER_SEQUENCE: - if (!(tag & ASN1_TAG_CONSTRUCTED_MASK)) - @throw [OFInvalidFormatException exception]; - - *object = parseSequence(contents, depthLimit - 1); - return bytesConsumed; - case OF_ASN1_TAG_NUMBER_SET: - if (!(tag & ASN1_TAG_CONSTRUCTED_MASK)) - @throw [OFInvalidFormatException exception]; - - *object = parseSet(contents, depthLimit - 1); - return bytesConsumed; - case OF_ASN1_TAG_NUMBER_NUMERIC_STRING: - valueClass = [OFASN1NumericString class]; - break; - case OF_ASN1_TAG_NUMBER_PRINTABLE_STRING: - valueClass = [OFASN1PrintableString class]; - break; - case OF_ASN1_TAG_NUMBER_IA5_STRING: - valueClass = [OFASN1IA5String class]; - break; - default: - valueClass = [OFASN1Value class]; - break; - } - - *object = [[[valueClass alloc] - initWithTagClass: tag >> 6 - tagNumber: tag & 0x1F - constructed: tag & ASN1_TAG_CONSTRUCTED_MASK - DEREncodedContents: contents] autorelease]; - return bytesConsumed; -} - -@implementation OFData (ASN1DERParsing) -- (id)objectByParsingASN1DER -{ - return [self objectByParsingASN1DERWithDepthLimit: 32]; -} - -- (id)objectByParsingASN1DERWithDepthLimit: (size_t)depthLimit -{ - void *pool = objc_autoreleasePoolPush(); - id object; - - if (self.itemSize != 1) - @throw [OFInvalidArgumentException exception]; - - if (parseObject(self, &object, depthLimit) != self.count) - @throw [OFInvalidFormatException exception]; - - [object retain]; - - objc_autoreleasePoolPop(pool); - - return [object autorelease]; -} -@end Index: src/OFData.h ================================================================== --- src/OFData.h +++ src/OFData.h @@ -329,8 +329,7 @@ @end OF_ASSUME_NONNULL_END #import "OFMutableData.h" -#import "OFData+ASN1DERParsing.h" #import "OFData+CryptographicHashing.h" #import "OFData+MessagePackParsing.h" Index: src/OFData.m ================================================================== --- src/OFData.m +++ src/OFData.m @@ -44,11 +44,10 @@ /* References for static linking */ void _references_to_categories_of_OFData(void) { - _OFData_ASN1DERParsing_reference = 1; _OFData_CryptographicHashing_reference = 1; _OFData_MessagePackParsing_reference = 1; } @implementation OFData @@ -448,21 +447,18 @@ return false; return true; } -- (of_comparison_result_t)compare: (id )object +- (of_comparison_result_t)compare: (OFData *)data { - OFData *data; int comparison; size_t count, minCount; - if (![(id)object isKindOfClass: [OFData class]]) + if (![data isKindOfClass: [OFData class]]) @throw [OFInvalidArgumentException exception]; - data = (OFData *)object; - if (data.itemSize != _itemSize) @throw [OFInvalidArgumentException exception]; count = data.count; minCount = (_count > count ? count : _count); Index: src/OFDate.m ================================================================== --- src/OFDate.m +++ src/OFDate.m @@ -563,22 +563,18 @@ - (id)copy { return [self retain]; } -- (of_comparison_result_t)compare: (id )object +- (of_comparison_result_t)compare: (OFDate *)date { - OFDate *otherDate; - - if (![(id)object isKindOfClass: [OFDate class]]) + if (![date isKindOfClass: [OFDate class]]) @throw [OFInvalidArgumentException exception]; - otherDate = (OFDate *)object; - - if (self.timeIntervalSince1970 < otherDate.timeIntervalSince1970) + if (self.timeIntervalSince1970 < date.timeIntervalSince1970) return OF_ORDERED_ASCENDING; - if (self.timeIntervalSince1970 > otherDate.timeIntervalSince1970) + if (self.timeIntervalSince1970 > date.timeIntervalSince1970) return OF_ORDERED_DESCENDING; return OF_ORDERED_SAME; } Index: src/OFIPSocketAsyncConnector.m ================================================================== --- src/OFIPSocketAsyncConnector.m +++ src/OFIPSocketAsyncConnector.m @@ -17,13 +17,10 @@ #include #import "OFIPSocketAsyncConnector.h" #import "OFData.h" -#ifdef OF_HAVE_SCTP -# import "OFSCTPSocket.h" -#endif #import "OFTCPSocket.h" #import "OFThread.h" #import "OFTimer.h" #import "OFConnectionFailedException.h" @@ -72,15 +69,10 @@ #ifdef OF_HAVE_BLOCKS if (_block != NULL) { if ([_socket isKindOfClass: [OFTCPSocket class]]) ((of_tcp_socket_async_connect_block_t)_block)( _exception); -# ifdef OF_HAVE_SCTP - else if ([_socket isKindOfClass: [OFSCTPSocket class]]) - ((of_sctp_socket_async_connect_block_t)_block)( - _exception); -# endif else OF_ENSURE(0); } else { #endif if ([_delegate respondsToSelector: Index: src/OFNull.h ================================================================== --- src/OFNull.h +++ src/OFNull.h @@ -12,11 +12,10 @@ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" -#import "OFASN1DERRepresentation.h" #import "OFJSONRepresentation.h" #import "OFMessagePackRepresentation.h" #import "OFSerialization.h" OF_ASSUME_NONNULL_BEGIN @@ -26,15 +25,15 @@ * * @brief A class for representing null values in collections. */ OF_SUBCLASSING_RESTRICTED @interface OFNull: OFObject + OFMessagePackRepresentation> /** * @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 @@ -102,16 +102,10 @@ { 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: src/OFNumber.m ================================================================== --- src/OFNumber.m +++ src/OFNumber.m @@ -940,18 +940,14 @@ return (number.longLongValue == self.longLongValue); return (number.unsignedLongLongValue == self.unsignedLongLongValue); } -- (of_comparison_result_t)compare: (id )object -{ - OFNumber *number; - - if (![(id)object isKindOfClass: [OFNumber class]]) - @throw [OFInvalidArgumentException exception]; - - number = (OFNumber *)object; +- (of_comparison_result_t)compare: (OFNumber *)number +{ + if (![number isKindOfClass: [OFNumber class]]) + @throw [OFInvalidArgumentException exception]; if (isFloat(self) || isFloat(number)) { double double1 = self.doubleValue; double double2 = number.doubleValue; DELETED src/OFSCTPSocket.h Index: src/OFSCTPSocket.h ================================================================== --- src/OFSCTPSocket.h +++ src/OFSCTPSocket.h @@ -1,152 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 "OFSequencedPacketSocket.h" -#import "OFRunLoop.h" - -OF_ASSUME_NONNULL_BEGIN - -/** @file */ - -@class OFSCTPSocket; -@class OFString; - -#ifdef OF_HAVE_BLOCKS -/** - * @brief A block which is called when the socket connected. - * - * @param exception An exception which occurred while connecting the socket or - * `nil` on success - */ -typedef void (^of_sctp_socket_async_connect_block_t)(id _Nullable exception); -#endif - -/** - * @protocol OFSCTPSocketDelegate OFSCTPSocket.h ObjFW/OFSCTPSocket.h - * - * A delegate for OFSCTPSocket. - */ -@protocol OFSCTPSocketDelegate -@optional -/** - * @brief A method which is called when a socket connected. - * - * @param socket The socket which connected - * @param host The host connected to - * @param port The port on the host connected to - * @param exception An exception that occurred while connecting, or nil on - * success - */ -- (void)socket: (OFSCTPSocket *)socket - didConnectToHost: (OFString *)host - port: (uint16_t)port - exception: (nullable id)exception; -@end - -/** - * @class OFSCTPSocket OFSCTPSocket.h ObjFW/OFSCTPSocket.h - * - * @brief A class which provides methods to create and use SCTP sockets in - * one-to-one mode. - * - * To connect to a server, create a socket and connect it. - * To create a server, create a socket, bind it and listen on it. - */ -@interface OFSCTPSocket: OFSequencedPacketSocket -{ - OF_RESERVE_IVARS(OFSCTPSocket, 4) -} - -/** - * @brief Whether sending packets can be delayed. Setting this to NO sets - * SCTP_NODELAY on the socket. - */ -@property (nonatomic) bool canDelaySendingPackets; - -/** - * @brief The delegate for asynchronous operations on the socket. - * - * @note The delegate is retained for as long as asynchronous operations are - * still ongoing. - */ -@property OF_NULLABLE_PROPERTY (assign, nonatomic) - id delegate; - -/** - * @brief Connect the OFSCTPSocket to the specified destination. - * - * @param host The host to connect to - * @param port The port on the host to connect to - */ -- (void)connectToHost: (OFString *)host port: (uint16_t)port; - -/** - * @brief Asynchronously connect the OFSCTPSocket to the specified destination. - * - * @param host The host to connect to - * @param port The port on the host to connect to - */ -- (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port; - -/** - * @brief Asynchronously connect the OFSCTPSocket to the specified destination. - * - * @param host The host to connect to - * @param port The port on the host to connect to - * @param runLoopMode The run loop mode in which to perform the async connect - */ -- (void)asyncConnectToHost: (OFString *)host - port: (uint16_t)port - runLoopMode: (of_run_loop_mode_t)runLoopMode; - -#ifdef OF_HAVE_BLOCKS -/** - * @brief Asynchronously connect the OFSCTPSocket to the specified destination. - * - * @param host The host to connect to - * @param port The port on the host to connect to - * @param block The block to execute once the connection has been established - */ -- (void)asyncConnectToHost: (OFString *)host - port: (uint16_t)port - block: (of_sctp_socket_async_connect_block_t)block; - -/** - * @brief Asynchronously connect the OFSCTPSocket to the specified destination. - * - * @param host The host to connect to - * @param port The port on the host to connect to - * @param runLoopMode The run loop mode in which to perform the async connect - * @param block The block to execute once the connection has been established - */ -- (void)asyncConnectToHost: (OFString *)host - port: (uint16_t)port - runLoopMode: (of_run_loop_mode_t)runLoopMode - block: (of_sctp_socket_async_connect_block_t)block; -#endif - -/** - * @brief Bind the socket to the specified host and port. - * - * @param host The host to bind to. Use `@"0.0.0.0"` for IPv4 or `@"::"` for - * IPv6 to bind to all. - * @param port The port to bind to. If the port is 0, an unused port will be - * chosen, which can be obtained using the return value. - * @return The port the socket was bound to - */ -- (uint16_t)bindToHost: (OFString *)host port: (uint16_t)port; -@end - -OF_ASSUME_NONNULL_END DELETED src/OFSCTPSocket.m Index: src/OFSCTPSocket.m ================================================================== --- src/OFSCTPSocket.m +++ src/OFSCTPSocket.m @@ -1,325 +0,0 @@ -/* - * Copyright (c) 2008-2021 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" - -#include -#include -#include -#include - -#ifdef HAVE_FCNTL_H -# include -#endif - -#import "OFSCTPSocket.h" -#import "OFDNSResolver.h" -#import "OFData.h" -#import "OFDate.h" -#import "OFIPSocketAsyncConnector.h" -#import "OFRunLoop.h" -#import "OFRunLoop+Private.h" -#import "OFString.h" -#import "OFThread.h" - -#import "OFAlreadyConnectedException.h" -#import "OFBindFailedException.h" -#import "OFGetOptionFailedException.h" -#import "OFNotOpenException.h" -#import "OFSetOptionFailedException.h" - -#import "socket.h" -#import "socket_helpers.h" - -static const of_run_loop_mode_t connectRunLoopMode = - @"of_sctp_socket_connect_mode"; - -@interface OFSCTPSocket () -@end - -@interface OFSCTPSocketConnectDelegate: OFObject -{ -@public - bool _done; - id _exception; -} -@end - -@implementation OFSCTPSocketConnectDelegate -- (void)dealloc -{ - [_exception release]; - - [super dealloc]; -} - -- (void)socket: (OFSCTPSocket *)sock - didConnectToHost: (OFString *)host - port: (uint16_t)port - exception: (id)exception -{ - _done = true; - _exception = [exception retain]; -} -@end - -@implementation OFSCTPSocket -@dynamic delegate; - -- (bool)of_createSocketForAddress: (const of_socket_address_t *)address - errNo: (int *)errNo -{ -#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) - int flags; -#endif - - if (_socket != INVALID_SOCKET) - @throw [OFAlreadyConnectedException exceptionWithSocket: self]; - - if ((_socket = socket(address->sockaddr.sockaddr.sa_family, - SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_SCTP)) == INVALID_SOCKET) { - *errNo = of_socket_errno(); - return false; - } - -#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) - if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) - fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); -#endif - - return true; -} - -- (bool)of_connectSocketToAddress: (const of_socket_address_t *)address - errNo: (int *)errNo -{ - if (_socket == INVALID_SOCKET) - @throw [OFNotOpenException exceptionWithObject: self]; - - if (connect(_socket, &address->sockaddr.sockaddr, - address->length) != 0) { - *errNo = of_socket_errno(); - return false; - } - - return true; -} - -- (void)of_closeSocket -{ - closesocket(_socket); - _socket = INVALID_SOCKET; -} - -- (void)connectToHost: (OFString *)host port: (uint16_t)port -{ - void *pool = objc_autoreleasePoolPush(); - id delegate = _delegate; - OFSCTPSocketConnectDelegate *connectDelegate = - [[[OFSCTPSocketConnectDelegate alloc] init] autorelease]; - OFRunLoop *runLoop = [OFRunLoop currentRunLoop]; - - self.delegate = connectDelegate; - [self asyncConnectToHost: host - port: port - runLoopMode: connectRunLoopMode]; - - while (!connectDelegate->_done) - [runLoop runMode: connectRunLoopMode beforeDate: nil]; - - /* Cleanup */ - [runLoop runMode: connectRunLoopMode beforeDate: [OFDate date]]; - - if (connectDelegate->_exception != nil) - @throw connectDelegate->_exception; - - self.delegate = delegate; - - objc_autoreleasePoolPop(pool); -} - -- (void)asyncConnectToHost: (OFString *)host port: (uint16_t)port -{ - [self asyncConnectToHost: host - port: port - runLoopMode: of_run_loop_mode_default]; -} - -- (void)asyncConnectToHost: (OFString *)host - port: (uint16_t)port - runLoopMode: (of_run_loop_mode_t)runLoopMode -{ - void *pool = objc_autoreleasePoolPush(); - - if (_socket != INVALID_SOCKET) - @throw [OFAlreadyConnectedException exceptionWithSocket: self]; - - [[[[OFIPSocketAsyncConnector alloc] - initWithSocket: self - host: host - port: port - delegate: _delegate - block: NULL - ] autorelease] startWithRunLoopMode: runLoopMode]; - - objc_autoreleasePoolPop(pool); -} - -#ifdef OF_HAVE_BLOCKS -- (void)asyncConnectToHost: (OFString *)host - port: (uint16_t)port - block: (of_sctp_socket_async_connect_block_t)block -{ - [self asyncConnectToHost: host - port: port - runLoopMode: of_run_loop_mode_default - block: block]; -} - -- (void)asyncConnectToHost: (OFString *)host - port: (uint16_t)port - runLoopMode: (of_run_loop_mode_t)runLoopMode - block: (of_sctp_socket_async_connect_block_t)block -{ - void *pool = objc_autoreleasePoolPush(); - - if (_socket != INVALID_SOCKET) - @throw [OFAlreadyConnectedException exceptionWithSocket: self]; - - [[[[OFIPSocketAsyncConnector alloc] - initWithSocket: self - host: host - port: port - delegate: nil - block: block] autorelease] - startWithRunLoopMode: runLoopMode]; - - objc_autoreleasePoolPop(pool); -} -#endif - -- (uint16_t)bindToHost: (OFString *)host port: (uint16_t)port -{ - const int one = 1; - void *pool = objc_autoreleasePoolPush(); - OFData *socketAddresses; - of_socket_address_t address; -#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) - int flags; -#endif - - if (_socket != INVALID_SOCKET) - @throw [OFAlreadyConnectedException exceptionWithSocket: self]; - - socketAddresses = [[OFThread DNSResolver] - resolveAddressesForHost: host - addressFamily: OF_SOCKET_ADDRESS_FAMILY_ANY]; - - address = *(of_socket_address_t *)[socketAddresses itemAtIndex: 0]; - of_socket_address_set_port(&address, port); - - if ((_socket = socket(address.sockaddr.sockaddr.sa_family, - SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_SCTP)) == INVALID_SOCKET) - @throw [OFBindFailedException - exceptionWithHost: host - port: port - socket: self - errNo: of_socket_errno()]; - - _canBlock = true; - -#if SOCK_CLOEXEC == 0 && defined(HAVE_FCNTL) && defined(FD_CLOEXEC) - if ((flags = fcntl(_socket, F_GETFD, 0)) != -1) - fcntl(_socket, F_SETFD, flags | FD_CLOEXEC); -#endif - - setsockopt(_socket, SOL_SOCKET, SO_REUSEADDR, - (char *)&one, (socklen_t)sizeof(one)); - - if (bind(_socket, &address.sockaddr.sockaddr, address.length) != 0) { - int errNo = of_socket_errno(); - - closesocket(_socket); - _socket = INVALID_SOCKET; - - @throw [OFBindFailedException exceptionWithHost: host - port: port - socket: self - errNo: errNo]; - } - - objc_autoreleasePoolPop(pool); - - if (port > 0) - return port; - - memset(&address, 0, sizeof(address)); - - address.length = (socklen_t)sizeof(address.sockaddr); - if (of_getsockname(_socket, &address.sockaddr.sockaddr, - &address.length) != 0) { - int errNo = of_socket_errno(); - - closesocket(_socket); - _socket = INVALID_SOCKET; - - @throw [OFBindFailedException exceptionWithHost: host - port: port - socket: self - errNo: errNo]; - } - - if (address.sockaddr.sockaddr.sa_family == AF_INET) - return OF_BSWAP16_IF_LE(address.sockaddr.in.sin_port); -# ifdef OF_HAVE_IPV6 - else if (address.sockaddr.sockaddr.sa_family == AF_INET6) - return OF_BSWAP16_IF_LE(address.sockaddr.in6.sin6_port); -# endif - else { - closesocket(_socket); - _socket = INVALID_SOCKET; - - @throw [OFBindFailedException exceptionWithHost: host - port: port - socket: self - errNo: EAFNOSUPPORT]; - } -} - -- (void)setCanDelaySendingPackets: (bool)canDelaySendingPackets -{ - int v = !canDelaySendingPackets; - - if (setsockopt(_socket, IPPROTO_SCTP, SCTP_NODELAY, - (char *)&v, (socklen_t)sizeof(v)) != 0) - @throw [OFSetOptionFailedException - exceptionWithObject: self - errNo: of_socket_errno()]; -} - -- (bool)canDelaySendingPackets -{ - int v; - socklen_t len = sizeof(v); - - if (getsockopt(_socket, IPPROTO_SCTP, SCTP_NODELAY, - (char *)&v, &len) != 0 || len != sizeof(v)) - @throw [OFGetOptionFailedException - exceptionWithObject: self - errNo: of_socket_errno()]; - - return !v; -} -@end Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -1512,30 +1512,30 @@ } - (bool)isEqual: (id)object { void *pool; - OFString *otherString; + OFString *string; const of_unichar_t *characters, *otherCharacters; size_t length; if (object == self) return true; if (![object isKindOfClass: [OFString class]]) return false; - otherString = object; + string = object; length = self.length; - if (otherString.length != length) + if (string.length != length) return false; pool = objc_autoreleasePoolPush(); characters = self.characters; - otherCharacters = otherString.characters; + otherCharacters = string.characters; if (memcmp(characters, otherCharacters, length * sizeof(of_unichar_t)) != 0) { objc_autoreleasePoolPop(pool); return false; @@ -1554,31 +1554,29 @@ - (id)mutableCopy { return [[OFMutableString alloc] initWithString: self]; } -- (of_comparison_result_t)compare: (id )object +- (of_comparison_result_t)compare: (OFString *)string { void *pool; - OFString *otherString; const of_unichar_t *characters, *otherCharacters; size_t minimumLength; - if (object == self) + if (string == self) return OF_ORDERED_SAME; - if (![(id)object isKindOfClass: [OFString class]]) + if (![string isKindOfClass: [OFString class]]) @throw [OFInvalidArgumentException exception]; - otherString = (OFString *)object; - minimumLength = (self.length > otherString.length - ? otherString.length : self.length); + minimumLength = (self.length > string.length + ? string.length : self.length); pool = objc_autoreleasePoolPush(); characters = self.characters; - otherCharacters = otherString.characters; + otherCharacters = string.characters; for (size_t i = 0; i < minimumLength; i++) { if (characters[i] > otherCharacters[i]) { objc_autoreleasePoolPop(pool); return OF_ORDERED_DESCENDING; @@ -1590,31 +1588,31 @@ } } objc_autoreleasePoolPop(pool); - if (self.length > otherString.length) + if (self.length > string.length) return OF_ORDERED_DESCENDING; - if (self.length < otherString.length) + if (self.length < string.length) return OF_ORDERED_ASCENDING; return OF_ORDERED_SAME; } -- (of_comparison_result_t)caseInsensitiveCompare: (OFString *)otherString +- (of_comparison_result_t)caseInsensitiveCompare: (OFString *)string { void *pool = objc_autoreleasePoolPush(); const of_unichar_t *characters, *otherCharacters; size_t length, otherLength, minimumLength; - if (otherString == self) + if (string == self) return OF_ORDERED_SAME; characters = self.characters; - otherCharacters = otherString.characters; + otherCharacters = string.characters; length = self.length; - otherLength = otherString.length; + otherLength = string.length; minimumLength = (length > otherLength ? otherLength : length); for (size_t i = 0; i < minimumLength; i++) { of_unichar_t c = characters[i]; Index: src/OFTimer.m ================================================================== --- src/OFTimer.m +++ src/OFTimer.m @@ -504,18 +504,14 @@ #endif [super dealloc]; } -- (of_comparison_result_t)compare: (id )object -{ - OFTimer *timer; - - if (![(id)object isKindOfClass: [OFTimer class]]) - @throw [OFInvalidArgumentException exception]; - - timer = (OFTimer *)object; +- (of_comparison_result_t)compare: (OFTimer *)timer +{ + if (![timer isKindOfClass: [OFTimer class]]) + @throw [OFInvalidArgumentException exception]; return [_fireDate compare: timer->_fireDate]; } - (void)of_setInRunLoop: (OFRunLoop *)runLoop mode: (of_run_loop_mode_t)mode Index: src/OFUTF8String.m ================================================================== --- src/OFUTF8String.m +++ src/OFUTF8String.m @@ -772,54 +772,51 @@ return _s->cStringLength; } - (bool)isEqual: (id)object { - OFUTF8String *otherString; + OFUTF8String *string; if (object == self) return true; if (![object isKindOfClass: [OFString class]]) return false; - otherString = object; + string = object; - if (otherString.UTF8StringLength != _s->cStringLength || - otherString.length != _s->length) + if (string.UTF8StringLength != _s->cStringLength || + string.length != _s->length) + return false; + + if (([string isKindOfClass: [OFUTF8String class]] || + [string isKindOfClass: [OFMutableUTF8String class]]) && + _s->hashed && string->_s->hashed && _s->hash != string->_s->hash) return false; - if (([otherString isKindOfClass: [OFUTF8String class]] || - [otherString isKindOfClass: [OFMutableUTF8String class]]) && - _s->hashed && otherString->_s->hashed && - _s->hash != otherString->_s->hash) - return false; - - if (strcmp(_s->cString, otherString.UTF8String) != 0) + if (strcmp(_s->cString, string.UTF8String) != 0) return false; return true; } -- (of_comparison_result_t)compare: (id )object +- (of_comparison_result_t)compare: (OFString *)string { - OFString *otherString; size_t otherCStringLength, minimumCStringLength; int compare; - if (object == self) + if (string == self) return OF_ORDERED_SAME; - if (![(id)object isKindOfClass: [OFString class]]) + if (![string isKindOfClass: [OFString class]]) @throw [OFInvalidArgumentException exception]; - otherString = (OFString *)object; - otherCStringLength = otherString.UTF8StringLength; + otherCStringLength = string.UTF8StringLength; minimumCStringLength = (_s->cStringLength > otherCStringLength ? otherCStringLength : _s->cStringLength); - if ((compare = memcmp(_s->cString, otherString.UTF8String, + if ((compare = memcmp(_s->cString, string.UTF8String, minimumCStringLength)) == 0) { if (_s->cStringLength > otherCStringLength) return OF_ORDERED_DESCENDING; if (_s->cStringLength < otherCStringLength) return OF_ORDERED_ASCENDING; @@ -830,27 +827,24 @@ return OF_ORDERED_DESCENDING; else return OF_ORDERED_ASCENDING; } -- (of_comparison_result_t)caseInsensitiveCompare: (OFString *)otherString +- (of_comparison_result_t)caseInsensitiveCompare: (OFString *)string { const char *otherCString; size_t otherCStringLength, minimumCStringLength; #ifdef OF_HAVE_UNICODE_TABLES size_t i, j; #endif int compare; - if (otherString == self) + if (string == self) return OF_ORDERED_SAME; - if (![otherString isKindOfClass: [OFString class]]) - @throw [OFInvalidArgumentException exception]; - - otherCString = otherString.UTF8String; - otherCStringLength = otherString.UTF8StringLength; + otherCString = string.UTF8String; + otherCStringLength = string.UTF8StringLength; #ifdef OF_HAVE_UNICODE_TABLES if (!_s->isUTF8) { #endif minimumCStringLength = (_s->cStringLength > otherCStringLength Index: src/ObjFW.h ================================================================== --- src/ObjFW.h +++ src/ObjFW.h @@ -81,13 +81,10 @@ # ifdef OF_HAVE_IPX # import "OFIPXSocket.h" # import "OFSPXSocket.h" # import "OFSPXStreamSocket.h" # endif -# ifdef OF_HAVE_SCTP -# import "OFSCTPSocket.h" -# endif #endif #ifdef OF_HAVE_SOCKETS # ifdef OF_HAVE_THREADS # import "OFHTTPClient.h" # endif @@ -135,22 +132,10 @@ #ifdef OF_WINDOWS # import "OFWindowsRegistryKey.h" #endif -#import "OFASN1BitString.h" -#import "OFASN1Boolean.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" -#import "OFASN1Value.h" - #import "OFAllocFailedException.h" #import "OFException.h" #ifdef OF_HAVE_SOCKETS # import "OFAcceptFailedException.h" # import "OFAlreadyConnectedException.h" Index: src/objfw-defs.h.in ================================================================== --- src/objfw-defs.h.in +++ src/objfw-defs.h.in @@ -14,11 +14,10 @@ #undef OF_HAVE_IPX #undef OF_HAVE_LIMITS_H #undef OF_HAVE_LINK #undef OF_HAVE_MAX_ALIGN_T #undef OF_HAVE_NETINET_IN_H -#undef OF_HAVE_NETINET_SCTP_H #undef OF_HAVE_NETINET_TCP_H #undef OF_HAVE_NETIPX_IPX_H #undef OF_HAVE_OSATOMIC #undef OF_HAVE_OSATOMIC_64 #undef OF_HAVE_PIPE Index: src/socket.h ================================================================== --- src/socket.h +++ src/socket.h @@ -30,13 +30,10 @@ # include #endif #ifdef OF_HAVE_NETINET_TCP_H # include #endif -#ifdef OF_HAVE_NETINET_SCTP_H -# include -#endif #ifdef OF_HAVE_NETIPX_IPX_H # include #endif #include "platform.h" Index: tests/Makefile ================================================================== --- tests/Makefile +++ tests/Makefile @@ -9,12 +9,10 @@ DISTCLEAN = Info.plist PROG_NOINST = tests${PROG_SUFFIX} STATIC_LIB_NOINST = ${TESTS_STATIC_LIB} SRCS = ForwardingTests.m \ - OFASN1DERParsingTests.m \ - OFASN1DERRepresentationTests.m \ OFArrayTests.m \ ${OF_BLOCK_TESTS_M} \ OFCharacterSetTests.m \ OFDataTests.m \ OFDateTests.m \ @@ -58,21 +56,19 @@ OFSHA512HashTests.m SRCS_IPX = OFIPXSocketTests.m \ OFSPXSocketTests.m \ OFSPXStreamSocketTests.m SRCS_PLUGINS = OFPluginTests.m -SRCS_SCTP = OFSCTPSocketTests.m SRCS_SOCKETS = OFDNSResolverTests.m \ ${OF_HTTP_CLIENT_TESTS_M} \ OFHTTPCookieTests.m \ OFHTTPCookieManagerTests.m \ OFKernelEventObserverTests.m \ OFTCPSocketTests.m \ OFUDPSocketTests.m \ SocketTests.m \ - ${USE_SRCS_IPX} \ - ${USE_SRCS_SCTP} + ${USE_SRCS_IPX} SRCS_THREADS = OFThreadTests.m SRCS_WINDOWS = OFWindowsRegistryKeyTests.m IOS_USER ?= mobile IOS_TMP ?= /tmp/objfw-test DELETED tests/OFASN1DERParsingTests.m Index: tests/OFASN1DERParsingTests.m ================================================================== --- tests/OFASN1DERParsingTests.m +++ tests/OFASN1DERParsingTests.m @@ -1,480 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 = @"OFData+ASN1DERParsing"; - -@implementation TestsAppDelegate (OFASN1DERParsingTests) -- (void)ASN1DERParsingTests -{ - void *pool = objc_autoreleasePoolPush(); - OFASN1BitString *bitString; - OFArray *array; - OFSet *set; - OFEnumerator *enumerator; - - /* Boolean */ - TEST(@"Parsing of boolean", - ![[[OFData dataWithItems: "\x01\x01\x00" - count: 3] objectByParsingASN1DER] boolValue] && - [[[OFData dataWithItems: "\x01\x01\xFF" - count: 3] objectByParsingASN1DER] boolValue]) - - EXPECT_EXCEPTION(@"Detection of invalid boolean #1", - OFInvalidFormatException, - [[OFData dataWithItems: "\x01\x01\x01" - count: 3] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of invalid boolean #2", - OFInvalidFormatException, - [[OFData dataWithItems: "\x01\x02\x00\x00" - count: 4] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of invalid boolean #3", - OFInvalidFormatException, - [[OFData dataWithItems: "\x01\x00" - count: 2] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of truncated boolean", - OFTruncatedDataException, - [[OFData dataWithItems: "\x01\x01" - count: 2] objectByParsingASN1DER]) - - /* Integer */ - TEST(@"Parsing of integer", - [[[OFData dataWithItems: "\x02\x00" - count: 2] objectByParsingASN1DER] - longLongValue] == 0 && - [[[OFData dataWithItems: "\x02\x01\x01" - count: 3] objectByParsingASN1DER] - longLongValue] == 1 && - [[[OFData dataWithItems: "\x02\x02\x01\x04" - count: 4] objectByParsingASN1DER] - longLongValue] == 260 && - [[[OFData dataWithItems: "\x02\x01\xFF" - count: 3] objectByParsingASN1DER] - longLongValue] == -1 && - [[[OFData dataWithItems: "\x02\x03\xFF\x00\x00" - count: 5] objectByParsingASN1DER] - longLongValue] == -65536 && - (unsigned long long)[[[OFData dataWithItems: "\x02\x09\x00\xFF\xFF" - "\xFF\xFF\xFF\xFF\xFF" - "\xFF" - count: 11] - objectByParsingASN1DER] longLongValue] == ULLONG_MAX) - - EXPECT_EXCEPTION(@"Detection of invalid integer #1", - OFInvalidFormatException, - [[OFData dataWithItems: "\x02\x02\x00\x00" - count: 4] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of invalid integer #2", - OFInvalidFormatException, - [[OFData dataWithItems: "\x02\x02\x00\x7F" - count: 4] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of invalid integer #3", - OFInvalidFormatException, - [[OFData dataWithItems: "\x02\x02\xFF\x80" - count: 4] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of out of range integer", - OFOutOfRangeException, - [[OFData dataWithItems: "\x02\x09\x01" - "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" - count: 11] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of truncated integer", - OFTruncatedDataException, - [[OFData dataWithItems: "\x02\x02\x00" - count: 3] objectByParsingASN1DER]) - - /* Bit string */ - TEST(@"Parsing of bit string", - (bitString = [[OFData dataWithItems: "\x03\x01\x00" - count: 3] objectByParsingASN1DER]) && - [bitString.bitStringValue isEqual: [OFData dataWithItems: "" - count: 0]] && - bitString.bitStringLength == 0 && - (bitString = [[OFData dataWithItems: "\x03\x0D\x01Hello World\x80" - count: 15] objectByParsingASN1DER]) && - [bitString.bitStringValue - isEqual: [OFData dataWithItems: "Hello World\x80" - count: 12]] && - bitString.bitStringLength == 95 && - (bitString = [[OFData dataWithItems: "\x03\x81\x80\x00xxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxx" - count: 131] objectByParsingASN1DER]) && - [bitString.bitStringValue - isEqual: [OFData dataWithItems: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxx" - count: 127]] && - bitString.bitStringLength == 127 * 8) - - EXPECT_EXCEPTION(@"Detection of invalid bit string #1", - OFInvalidFormatException, - [[OFData dataWithItems: "\x03\x00" - count: 2] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of invalid bit string #2", - OFInvalidFormatException, - [[OFData dataWithItems: "\x03\x01\x01" - count: 3] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of out of range bit string", - OFOutOfRangeException, - [[OFData dataWithItems: "\x03\x89" - "\x01\x01\x01\x01\x01\x01\x01\x01\x01" - count: 11] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of truncated bit string", - OFTruncatedDataException, - [[OFData dataWithItems: "\x03\x01" - count: 2] objectByParsingASN1DER]) - - /* Octet string */ - TEST(@"Parsing of octet string", - [[[[OFData dataWithItems: "\x04\x0CHello World!" - count: 14] objectByParsingASN1DER] - octetStringValue] isEqual: [OFData dataWithItems: "Hello World!" - count: 12]] && - [[[[OFData dataWithItems: "\x04\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxx" - count: 131] objectByParsingASN1DER] - octetStringValue] isEqual: - [OFData dataWithItems: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - count: 128]]) - - EXPECT_EXCEPTION(@"Detection of out of range octet string", - OFOutOfRangeException, - [[OFData dataWithItems: "\x04\x89" - "\x01\x01\x01\x01\x01\x01\x01\x01\x01" - count: 11] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of truncated octet string", - OFTruncatedDataException, - [[OFData dataWithItems: "\x04\x01" - count: 2] objectByParsingASN1DER]) - - /* Null */ - TEST(@"Parsing of null", - [[[OFData dataWithItems: "\x05\x00" - count: 2] objectByParsingASN1DER] - isEqual: [OFNull null]]) - - EXPECT_EXCEPTION(@"Detection of invalid null", - OFInvalidFormatException, - [[OFData dataWithItems: "\x05\x01\x00" - count: 3] objectByParsingASN1DER]) - - /* Object Identifier */ - TEST(@"Parsing of Object Identifier", - (array = [[[OFData dataWithItems: "\x06\x01\x27" - count: 3] objectByParsingASN1DER] - subidentifiers]) && array.count == 2 && - [[array objectAtIndex: 0] unsignedLongLongValue] == 0 && - [[array objectAtIndex: 1] unsignedLongLongValue] == 39 && - (array = [[[OFData dataWithItems: "\x06\x01\x4F" - count: 3] objectByParsingASN1DER] - subidentifiers]) && array.count == 2 && - [[array objectAtIndex: 0] unsignedLongLongValue] == 1 && - [[array objectAtIndex: 1] unsignedLongLongValue] == 39 && - (array = [[[OFData dataWithItems: "\x06\x02\x88\x37" - count: 4] objectByParsingASN1DER] - subidentifiers]) && array.count == 2 && - [[array objectAtIndex: 0] unsignedLongLongValue] == 2 && - [[array objectAtIndex: 1] unsignedLongLongValue] == 999 && - (array = [[[OFData dataWithItems: "\x06\x09\x2A\x86\x48\x86\xF7\x0D" - "\x01\x01\x0B" - count: 11] objectByParsingASN1DER] - subidentifiers]) && array.count == 7 && - [[array objectAtIndex: 0] unsignedLongLongValue] == 1 && - [[array objectAtIndex: 1] unsignedLongLongValue] == 2 && - [[array objectAtIndex: 2] unsignedLongLongValue] == 840 && - [[array objectAtIndex: 3] unsignedLongLongValue] == 113549 && - [[array objectAtIndex: 4] unsignedLongLongValue] == 1 && - [[array objectAtIndex: 5] unsignedLongLongValue] == 1 && - [[array objectAtIndex: 6] unsignedLongLongValue] == 11) - - EXPECT_EXCEPTION(@"Detection of invalid Object Identifier #1", - OFInvalidFormatException, - [[OFData dataWithItems: "\x06\x01\x81" - count: 3] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of invalid Object Identifier #2", - OFInvalidFormatException, - [[OFData dataWithItems: "\x06\x02\x80\x01" - count: 4] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of out of range Object Identifier", - OFOutOfRangeException, - [[OFData dataWithItems: "\x06\x0A\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" - "\xFF\x7F" - count: 12] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of truncated Object Identifier", - OFTruncatedDataException, - [[OFData dataWithItems: "\x06\x02\x00" - count: 3] objectByParsingASN1DER]) - - /* Enumerated */ - TEST(@"Parsing of enumerated", - [[[OFData dataWithItems: "\x0A\x00" - count: 2] objectByParsingASN1DER] longLongValue] == - 0 && - [[[OFData dataWithItems: "\x0A\x01\x01" - count: 3] objectByParsingASN1DER] longLongValue] == - 1 && - [[[OFData dataWithItems: "\x0A\x02\x01\x04" - count: 4] objectByParsingASN1DER] longLongValue] == - 260 && - [[[OFData dataWithItems: "\x0A\x01\xFF" - count: 3] objectByParsingASN1DER] longLongValue] == - -1 && - [[[OFData dataWithItems: "\x0A\x03\xFF\x00\x00" - count: 5] objectByParsingASN1DER] longLongValue] == - -65536 && - (unsigned long long)[[[OFData dataWithItems: "\x0A\x09\x00\xFF\xFF" - "\xFF\xFF\xFF\xFF\xFF" - "\xFF" - count: 11] - objectByParsingASN1DER] longLongValue] == ULLONG_MAX) - - EXPECT_EXCEPTION(@"Detection of invalid enumerated #1", - OFInvalidFormatException, - [[OFData dataWithItems: "\x0A\x02\x00\x00" - count: 4] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of invalid enumerated #2", - OFInvalidFormatException, - [[OFData dataWithItems: "\x0A\x02\x00\x7F" - count: 4] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of invalid enumerated #3", - OFInvalidFormatException, - [[OFData dataWithItems: "\x0A\x02\xFF\x80" - count: 4] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of out of range enumerated", - OFOutOfRangeException, - [[OFData dataWithItems: "\x0A\x09\x01" - "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" - count: 11] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of truncated enumerated", - OFTruncatedDataException, - [[OFData dataWithItems: "\x0A\x02\x00" - count: 3] objectByParsingASN1DER]) - - /* UTF-8 string */ - TEST(@"Parsing of UTF-8 string", - [[[[OFData dataWithItems: "\x0C\x0EHällo Wörld!" - count: 16] objectByParsingASN1DER] - UTF8StringValue] isEqual: @"Hällo Wörld!"] && - [[[[OFData dataWithItems: "\x0C\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxx" - count: 131] objectByParsingASN1DER] - UTF8StringValue] isEqual: @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - @"xxxxxxxxxxx"]) - - EXPECT_EXCEPTION(@"Detection of out of range UTF-8 string", - OFOutOfRangeException, - [[OFData dataWithItems: "\x0C\x89" - "\x01\x01\x01\x01\x01\x01\x01\x01\x01" - count: 11] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of truncated UTF-8 string", - OFTruncatedDataException, - [[OFData dataWithItems: "\x0C\x01" - count: 2] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of truncated length", - OFTruncatedDataException, - [[OFData dataWithItems: "\x0C\x83\x01\x01" - count: 4] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of invalid / inefficient length #1", - OFInvalidFormatException, - [[OFData dataWithItems: "\x0C\x81\x7F" - count: 3] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of invalid / inefficient length #2", - OFInvalidFormatException, - [[OFData dataWithItems: "\x0C\x82\x00\x80xxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxx" - count: 132] objectByParsingASN1DER]) - - /* Sequence */ - TEST(@"Parsing of sequence", - (array = [[OFData dataWithItems: "\x30\x00" - count: 2] objectByParsingASN1DER]) && - [array isKindOfClass: [OFArray class]] && array.count == 0 && - (array = [[OFData dataWithItems: "\x30\x09\x02\x01\x7B\x0C\x04Test" - count: 11] objectByParsingASN1DER]) && - [array isKindOfClass: [OFArray class]] && array.count == 2 && - [[array objectAtIndex: 0] longLongValue] == 123 && - [[[array objectAtIndex: 1] stringValue] isEqual: @"Test"]) - - EXPECT_EXCEPTION(@"Detection of truncated sequence #1", - OFTruncatedDataException, - [[OFData dataWithItems: "\x30\x01" - count: 2] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of truncated sequence #2", - OFTruncatedDataException, - [[OFData dataWithItems: "\x30\x04\x02\x01\x01\x00\x00" - count: 7] objectByParsingASN1DER]) - - /* Set */ - TEST(@"Parsing of set", - (set = [[OFData dataWithItems: "\x31\x00" - count: 2] objectByParsingASN1DER]) && - [set isKindOfClass: [OFSet class]] && set.count == 0 && - (set = [[OFData dataWithItems: "\x31\x09\x02\x01\x7B\x0C\x04Test" - count: 11] objectByParsingASN1DER]) && - [set isKindOfClass: [OFSet class]] && set.count == 2 && - (enumerator = [set objectEnumerator]) && - [[enumerator nextObject] longLongValue] == 123 && - [[[enumerator nextObject] stringValue] isEqual: @"Test"]) - - EXPECT_EXCEPTION(@"Detection of invalid set", - OFInvalidFormatException, - [[OFData dataWithItems: "\x31\x06\x02\x01\x02\x02\x01\x01" - count: 8] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of truncated set #1", - OFTruncatedDataException, - [[OFData dataWithItems: "\x31\x01" - count: 2] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of truncated set #2", - OFTruncatedDataException, - [[OFData dataWithItems: "\x31\x04\x02\x01\x01\x00\x00" - count: 7] objectByParsingASN1DER]) - - /* NumericString */ - TEST(@"Parsing of NumericString", - [[[[OFData dataWithItems: "\x12\x0B" "12345 67890" - count: 13] objectByParsingASN1DER] - numericStringValue] isEqual: @"12345 67890"] && - [[[[OFData dataWithItems: "\x12\x81\x80" "0000000000000000000000000" - "0000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000" - "00000000000000000000000" - count: 131] objectByParsingASN1DER] - numericStringValue] isEqual: @"000000000000000000000000000000000000" - @"000000000000000000000000000000000000" - @"000000000000000000000000000000000000" - @"00000000000000000000"]) - - EXPECT_EXCEPTION(@"Detection of invalid NumericString", - OFInvalidEncodingException, - [[OFData dataWithItems: "\x12\x02." - count: 4] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of out of range NumericString", - OFOutOfRangeException, - [[OFData dataWithItems: "\x12\x89" - "\x01\x01\x01\x01\x01\x01\x01\x01\x01" - count: 11] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of truncated NumericString", - OFTruncatedDataException, - [[OFData dataWithItems: "\x12\x01" - count: 2] objectByParsingASN1DER]) - - /* PrintableString */ - TEST(@"Parsing of PrintableString", - [[[[OFData dataWithItems: "\x13\x0CHello World." - count: 14] objectByParsingASN1DER] - printableStringValue] isEqual: @"Hello World."] && - [[[[OFData dataWithItems: "\x13\x81\x80 '()+,-./:=?abcdefghijklmnop" - "qrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ '()" - "+,-./:=?abcdefghijklmnopqrstuvwxyzABCDEF" - "GHIJKLMNOPQRSTUVWXYZ" - count: 131] objectByParsingASN1DER] - printableStringValue] isEqual: @" '()+,-./:=?abcdefghijklmnopqrstuv" - @"wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ '()" - @"+,-./:=?abcdefghijklmnopqrstuvwxyz" - @"ABCDEFGHIJKLMNOPQRSTUVWXYZ"]) - - EXPECT_EXCEPTION(@"Detection of invalid PrintableString", - OFInvalidEncodingException, - [[OFData dataWithItems: "\x13\x02;" - count: 4] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of out of range PrintableString", - OFOutOfRangeException, - [[OFData dataWithItems: "\x13\x89" - "\x01\x01\x01\x01\x01\x01\x01\x01\x01" - count: 11] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of truncated PrintableString", - OFTruncatedDataException, - [[OFData dataWithItems: "\x13\x01" - count: 2] objectByParsingASN1DER]) - - /* IA5String */ - TEST(@"Parsing of IA5String", - [[[[OFData dataWithItems: "\x16\x0CHello World!" - count: 14] objectByParsingASN1DER] - IA5StringValue] isEqual: @"Hello World!"] && - [[[[OFData dataWithItems: "\x16\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - "xxxxxxxxxxxxxxxxxxxx" - count: 131] objectByParsingASN1DER] - IA5StringValue] isEqual: @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" - @"xxxxxxxx"]) - - EXPECT_EXCEPTION(@"Detection of invalid IA5String", - OFInvalidEncodingException, - [[OFData dataWithItems: "\x16\x02ä" - count: 4] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of out of range IA5String", - OFOutOfRangeException, - [[OFData dataWithItems: "\x16\x89" - "\x01\x01\x01\x01\x01\x01\x01\x01\x01" - count: 11] objectByParsingASN1DER]) - - EXPECT_EXCEPTION(@"Detection of truncated IA5String", - OFTruncatedDataException, - [[OFData dataWithItems: "\x16\x01" - count: 2] objectByParsingASN1DER]) - - objc_autoreleasePoolPop(pool); -} -@end DELETED tests/OFASN1DERRepresentationTests.m Index: tests/OFASN1DERRepresentationTests.m ================================================================== --- tests/OFASN1DERRepresentationTests.m +++ tests/OFASN1DERRepresentationTests.m @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 -{ - void *pool = objc_autoreleasePoolPush(); - OFData *data; - - module = @"OFASN1BitString"; - TEST(@"-[ASN1DERRepresentation]", - (data = [OFData dataWithItems: "\xFF\x00\xF8" count: 3]) && - [[[OFASN1BitString bitStringWithBitString: data length: 21] - ASN1DERRepresentation] isEqual: - [OFData dataWithItems: "\x03\x04\x03\xFF\x00\xF8" count: 6]] && - (data = [OFData dataWithItems: "abcdefäöü" count: 12]) && - [[[OFASN1BitString bitStringWithBitString: data length: 12 * 8] - ASN1DERRepresentation] isEqual: - [OFData dataWithItems: "\x03\x0D\x00" "abcdefäöü" count: 15]] && - (data = [OFData dataWithItems: "" count: 0]) && - [[[OFASN1BitString bitStringWithBitString: data length: 0] - ASN1DERRepresentation] isEqual: - [OFData dataWithItems: "\x03\x01\x00" count: 3]]) - - module = @"OFASN1Boolean"; - TEST(@"-[ASN1DERRepresentation]", - [[[OFASN1Boolean booleanWithBool: false] ASN1DERRepresentation] - isEqual: [OFData dataWithItems: "\x01\x01\x00" count: 3]] && - [[[OFASN1Boolean booleanWithBool: true] ASN1DERRepresentation] - isEqual: [OFData dataWithItems: "\x01\x01\xFF" count: 3]]) - - module = @"OFNull"; - TEST(@"-[OFASN1DERRepresentation]", - [[[OFNull null] ASN1DERRepresentation] isEqual: - [OFData dataWithItems: "\x05\x00" count: 2]]) - - objc_autoreleasePoolPop(pool); -} -@end DELETED tests/OFSCTPSocketTests.m Index: tests/OFSCTPSocketTests.m ================================================================== --- tests/OFSCTPSocketTests.m +++ tests/OFSCTPSocketTests.m @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2008-2021 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" - -#include -#include - -#import "TestsAppDelegate.h" - -static OFString *module = @"OFSCTPSocket"; - -@implementation TestsAppDelegate (OFSCTPSocketTests) -- (void)SCTPSocketTests -{ - void *pool = objc_autoreleasePoolPush(); - OFSCTPSocket *server, *client = nil, *accepted; - uint16_t port; - char buf[6]; - - TEST(@"+[socket]", (server = [OFSCTPSocket socket]) && - (client = [OFSCTPSocket socket])) - - @try { - TEST(@"-[bindToHost:port:]", - (port = [server bindToHost: @"127.0.0.1" port: 0])) - } @catch (OFBindFailedException *e) { - switch (e.errNo) { - case EPROTONOSUPPORT: - [of_stdout setForegroundColor: [OFColor lime]]; - [of_stdout writeLine: - @"[OFSCTPSocket] -[bindToHost:port:]: " - @"SCTP unsupported, skipping tests"]; - break; - default: - @throw e; - } - - objc_autoreleasePoolPop(pool); - return; - } - - TEST(@"-[listen]", R([server listen])) - - TEST(@"-[connectToHost:port:]", - R([client connectToHost: @"127.0.0.1" port: port])) - - TEST(@"-[accept]", (accepted = [server accept])) - - TEST(@"-[remoteAddress]", - [of_socket_address_ip_string(accepted.remoteAddress, NULL) - isEqual: @"127.0.0.1"]) - - TEST(@"-[sendBuffer:length:]", - R([client sendBuffer: "Hello!" length: 6])) - - TEST(@"-[receiveIntoBuffer:length:]", - [accepted receiveIntoBuffer: buf length: 6] && - !memcmp(buf, "Hello!", 6)) - - objc_autoreleasePoolPop(pool); -} -@end Index: tests/TestsAppDelegate.h ================================================================== --- tests/TestsAppDelegate.h +++ tests/TestsAppDelegate.h @@ -57,18 +57,10 @@ - (void)outputTesting: (OFString *)test inModule: (OFString *)module; - (void)outputSuccess: (OFString *)test inModule: (OFString *)module; - (void)outputFailure: (OFString *)test inModule: (OFString *)module; @end -@interface TestsAppDelegate (OFASN1DERParsingTests) -- (void)ASN1DERParsingTests; -@end - -@interface TestsAppDelegate (OFASN1DERRepresentationTests) -- (void)ASN1DERRepresentationTests; -@end - @interface TestsAppDelegate (OFArrayTests) - (void)arrayTests; @end @interface TestsAppDelegate (OFBlockTests) @@ -197,14 +189,10 @@ @interface TestsAppDelegate (OFSHA512HashTests) - (void)SHA512HashTests; @end -@interface TestsAppDelegate (OFSCTPSocketTests) -- (void)SCTPSocketTests; -@end - @interface TestsAppDelegate (OFSPXSocketTests) - (void)SPXSocketTests; @end @interface TestsAppDelegate (OFSPXStreamSocketTests) Index: tests/TestsAppDelegate.m ================================================================== --- tests/TestsAppDelegate.m +++ tests/TestsAppDelegate.m @@ -350,13 +350,10 @@ #endif #ifdef OF_HAVE_SOCKETS [self socketTests]; [self TCPSocketTests]; [self UDPSocketTests]; -# ifdef OF_HAVE_SCTP - [self SCTPSocketTests]; -# endif # ifdef OF_HAVE_IPX [self IPXSocketTests]; [self SPXSocketTests]; [self SPXStreamSocketTests]; # endif @@ -379,12 +376,10 @@ #ifdef OF_HAVE_FILES [self serializationTests]; #endif [self JSONTests]; [self propertyListTests]; - [self ASN1DERParsingTests]; - [self ASN1DERRepresentationTests]; #if defined(OF_HAVE_PLUGINS) [self pluginTests]; #endif #ifdef OF_WINDOWS [self windowsRegistryKeyTests]; Index: utils/Makefile ================================================================== --- utils/Makefile +++ utils/Makefile @@ -2,11 +2,10 @@ SUBDIRS += ${OFARC} \ ${OFDNS} \ ${OFHASH} \ ${OFHTTP} \ - ${OFSOCK} \ completions include ../buildsys.mk DISTCLEAN = objfw-config DELETED utils/ofsock/Makefile Index: utils/ofsock/Makefile ================================================================== --- utils/ofsock/Makefile +++ utils/ofsock/Makefile @@ -1,20 +0,0 @@ -include ../../extra.mk - -PROG = ofsock${PROG_SUFFIX} -SRCS = OFSock.m - -include ../../buildsys.mk - -PACKAGE_NAME = ofsock - -${PROG}: ${LIBOBJFW_DEP_LVL2} ${LIBOBJFWRT_DEP_LVL2} - -CPPFLAGS += -I../../src \ - -I../../src/runtime \ - -I../../src/exceptions \ - -I../.. -LIBS := -L../../src -lobjfw \ - -L../../src/runtime -L../../src/runtime/linklib ${RUNTIME_LIBS} \ - ${LIBS} -LD = ${OBJC} -LDFLAGS += ${LDFLAGS_RPATH} DELETED utils/ofsock/OFSock.m Index: utils/ofsock/OFSock.m ================================================================== --- utils/ofsock/OFSock.m +++ utils/ofsock/OFSock.m @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2008-2021 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 "OFApplication.h" -#import "OFArray.h" -#import "OFNumber.h" -#import "OFPair.h" -#import "OFStdIOStream.h" -#import "OFStream.h" -#import "OFString.h" -#import "OFTCPSocket.h" -#import "OFURL.h" - -#define BUFFER_LEN 4096 - -@interface OFSock: OFObject -{ - char _buffer[BUFFER_LEN]; - OFMutableArray OF_GENERIC(OFPair OF_GENERIC(OFStream *, OFStream *) *) - *_streams; - int _errors; -} -@end - -OF_APPLICATION_DELEGATE(OFSock) - -static OFPair OF_GENERIC(OFStream *, OFStream *) * -streamFromString(OFString *string) -{ - OFURL *URL; - OFString *scheme; - - if ([string isEqual: @"-"]) - return [OFPair pairWithFirstObject: of_stdin - secondObject: of_stdout]; - - URL = [OFURL URLWithString: string]; - scheme = URL.scheme; - - if ([scheme isEqual: @"tcp"]) { - OFTCPSocket *sock = [OFTCPSocket socket]; - - if (URL.port == nil) { - [of_stderr writeLine: @"Need a port!"]; - [OFApplication terminateWithStatus: 1]; - } - - [sock connectToHost: URL.host port: URL.port.shortValue]; - return [OFPair pairWithFirstObject: sock secondObject: sock]; - } - - [of_stderr writeFormat: @"Invalid protocol: %@\n", scheme]; - [OFApplication terminateWithStatus: 1]; - abort(); -} - -@implementation OFSock -- (void)applicationDidFinishLaunching -{ - OFArray OF_GENERIC(OFString *) *arguments = [OFApplication arguments]; - - if (arguments.count < 1) { - [of_stderr writeLine: @"Need at least one argument!"]; - [OFApplication terminateWithStatus: 1]; - } - - _streams = [[OFMutableArray alloc] init]; - - for (OFString *argument in arguments) { - OFPair *pair = streamFromString(argument); - - [pair.firstObject setDelegate: self]; - - [_streams addObject: pair]; - } - - if (arguments.count == 1) { - of_stdin.delegate = self; - - [_streams addObject: - [OFPair pairWithFirstObject: of_stdin - secondObject: of_stdout]]; - } - - for (OFPair *pair in _streams) - [pair.firstObject asyncReadIntoBuffer: _buffer - length: BUFFER_LEN]; -} - -- (void)removeDeadStream: (OFStream *)stream -{ - size_t count = _streams.count; - - for (size_t i = 0; i < count; i++) { - if ([[_streams objectAtIndex: i] firstObject] == stream) { - [_streams removeObjectAtIndex: i]; - break; - } - } - - if (_streams.count < 2) - [OFApplication terminateWithStatus: _errors]; -} - -- (bool)stream: (OFStream *)stream - didReadIntoBuffer: (void *)buffer - length: (size_t)length - exception: (id)exception -{ - if (exception != nil) { - [of_stderr writeFormat: @"Exception on stream %@: %@\n", - stream, exception]; - _errors++; - [self removeDeadStream: stream]; - return false; - } - - if (stream.atEndOfStream) { - [self removeDeadStream: stream]; - return false; - } - - for (OFPair *pair in _streams) { - if (pair.firstObject == stream) - continue; - - [pair.secondObject writeBuffer: buffer length: length]; - } - - return true; -} -@end