Comment: | Initial ASN.1 DER parsing support |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
d276166f701cfaf11048d926c5067755 |
User & Date: | js on 2018-10-13 21:40:15 |
Other Links: | manifest | tags |
2018-10-13
| ||
22:43 | Add more ASN.1 string types (IA5 and octet string) check-in: 6410235ae3 user: js tags: trunk | |
21:40 | Initial ASN.1 DER parsing support check-in: d276166f70 user: js tags: trunk | |
21:39 | Add -[OFData subdataWithRange:] check-in: 4075c3beaf user: js tags: trunk | |
Modified src/Makefile from [25efe5c01f] to [80f64e4680].
1 2 3 4 5 6 7 8 9 10 11 12 | include ../extra.mk SUBDIRS = ${RUNTIME} exceptions ${ENCODINGS} forwarding invocation SUBDIRS_AFTER = ${BRIDGE} DISTCLEAN = objfw-defs.h SHARED_LIB = ${OBJFW_SHARED_LIB} STATIC_LIB = ${OBJFW_STATIC_LIB} FRAMEWORK = ${OBJFW_FRAMEWORK} LIB_MAJOR = ${OBJFW_LIB_MAJOR} LIB_MINOR = ${OBJFW_LIB_MINOR} | > > > > > | > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | include ../extra.mk SUBDIRS = ${RUNTIME} exceptions ${ENCODINGS} forwarding invocation SUBDIRS_AFTER = ${BRIDGE} DISTCLEAN = objfw-defs.h SHARED_LIB = ${OBJFW_SHARED_LIB} STATIC_LIB = ${OBJFW_STATIC_LIB} FRAMEWORK = ${OBJFW_FRAMEWORK} LIB_MAJOR = ${OBJFW_LIB_MAJOR} LIB_MINOR = ${OBJFW_LIB_MINOR} SRCS = OFASN1Boolean.m \ OFASN1Integer.m \ OFASN1Null.m \ OFASN1UTF8String.m \ OFASN1Value.m \ OFApplication.m \ OFArray.m \ OFAutoreleasePool.m \ OFBlock.m \ OFCharacterSet.m \ OFColor.m \ OFConstantString.m \ OFCountedSet.m \ OFData.m \ OFData+ASN1DERValue.m \ OFData+CryptoHashing.m \ OFData+MessagePackValue.m \ OFDate.m \ OFDictionary.m \ OFEnumerator.m \ OFGZIPStream.m \ OFHMAC.m \ |
︙ | ︙ |
Added src/OFASN1Boolean.h version [9272d43696].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFASN1Value.h" OF_ASSUME_NONNULL_BEGIN /*! * @brief An ASN.1 boolean. */ @interface OFASN1Boolean: OFASN1Value { bool _booleanValue; } /*! * @brief The boolean value. */ @property (readonly, nonatomic) bool booleanValue; @end OF_ASSUME_NONNULL_END |
Added src/OFASN1Boolean.m version [32df9da0af].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018 * Jonathan Schleifer <js@heap.zone> * * 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 "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" @implementation OFASN1Boolean @synthesize booleanValue = _booleanValue; - (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass tagNumber: (of_asn1_tag_number_t)tagNumber constructed: (bool)constructed DEREncodedContents: (OFData *)DEREncodedContents { self = [super initWithTagClass: tagClass tagNumber: tagNumber constructed: constructed DEREncodedContents: DEREncodedContents]; @try { unsigned char value; if (_tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || _tagNumber != OF_ASN1_TAG_NUMBER_BOOLEAN || _constructed) @throw [OFInvalidArgumentException exception]; if ([_DEREncodedContents count] != 1) @throw [OFInvalidFormatException exception]; value = *(unsigned char *)[_DEREncodedContents itemAtIndex: 0]; if (value != 0 && value != 0xFF) @throw [OFInvalidFormatException exception]; _booleanValue = value; } @catch (id e) { [self release]; @throw e; } return self; } @end |
Added src/OFASN1Integer.h version [076cb23965].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFASN1Value.h" OF_ASSUME_NONNULL_BEGIN /*! * @brief An ASN.1 integer. */ @interface OFASN1Integer: OFASN1Value { intmax_t _integerValue; } /*! * @brief The integer value. */ @property (readonly, nonatomic) intmax_t integerValue; @end OF_ASSUME_NONNULL_END |
Added src/OFASN1Integer.m version [17624dc32d].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018 * Jonathan Schleifer <js@heap.zone> * * 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 "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" @implementation OFASN1Integer @synthesize integerValue = _integerValue; - (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass tagNumber: (of_asn1_tag_number_t)tagNumber constructed: (bool)constructed DEREncodedContents: (OFData *)DEREncodedContents { self = [super initWithTagClass: tagClass tagNumber: tagNumber constructed: constructed DEREncodedContents: DEREncodedContents]; @try { const unsigned char *items; size_t count; uintmax_t value; if (_tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || _tagNumber != OF_ASN1_TAG_NUMBER_INTEGER || _constructed) @throw [OFInvalidArgumentException exception]; /* TODO: Support for big numbers */ items = [_DEREncodedContents items]; count = [_DEREncodedContents count]; value = 0; if (count > sizeof(uintmax_t) && (count != sizeof(uintmax_t) + 1 || items[0] != 0)) @throw [OFOutOfRangeException exception]; if (count >= 2 && ((items[0] == 0 && !(items[1] & 0x80)) || (items[0] == 0xFF && items[1] & 0x80))) @throw [OFInvalidFormatException exception]; if (count >= 1 && items[0] & 0x80) value = ~(uintmax_t)0; while (count--) value = (value << 8) | *items++; _integerValue = value; } @catch (id e) { [self release]; @throw e; } return self; } @end |
Added src/OFASN1Null.h version [98f997dcb0].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFASN1Value.h" OF_ASSUME_NONNULL_BEGIN /*! * @brief An ASN.1 null value. */ @interface OFASN1Null: OFASN1Value @end OF_ASSUME_NONNULL_END |
Added src/OFASN1Null.m version [94777af6ac].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018 * Jonathan Schleifer <js@heap.zone> * * 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 "OFASN1Null.h" #import "OFData.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" @implementation OFASN1Null - (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass tagNumber: (of_asn1_tag_number_t)tagNumber constructed: (bool)constructed DEREncodedContents: (OFData *)DEREncodedContents { self = [super initWithTagClass: tagClass tagNumber: tagNumber constructed: constructed DEREncodedContents: DEREncodedContents]; @try { if (_tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || _tagNumber != OF_ASN1_TAG_NUMBER_NULL || _constructed) @throw [OFInvalidArgumentException exception]; if ([_DEREncodedContents count] != 0) @throw [OFInvalidFormatException exception]; } @catch (id e) { [self release]; @throw e; } return self; } @end |
Added src/OFASN1UTF8String.h version [5546a22768].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018 * Jonathan Schleifer <js@heap.zone> * * All rights reserved. * * This file is part of ObjFW. It may be distributed under the terms of the * Q Public License 1.0, which can be found in the file LICENSE.QPL included in * the packaging of this file. * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFASN1Value.h" OF_ASSUME_NONNULL_BEGIN @class OFString; /*! * @brief An ASN.1 UTF-8 string. */ @interface OFASN1UTF8String: OFASN1Value { OFString *_stringValue; } /*! * @brief The string value. */ @property (readonly, nonatomic) OFString *stringValue; @end OF_ASSUME_NONNULL_END |
Added src/OFASN1UTF8String.m version [73edad1684].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018 * Jonathan Schleifer <js@heap.zone> * * 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 stringValue = _stringValue; - (instancetype)initWithTagClass: (of_asn1_tag_class_t)tagClass tagNumber: (of_asn1_tag_number_t)tagNumber constructed: (bool)constructed DEREncodedContents: (OFData *)DEREncodedContents { self = [super initWithTagClass: tagClass tagNumber: tagNumber constructed: constructed DEREncodedContents: DEREncodedContents]; @try { if (_tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL || _tagNumber != OF_ASN1_TAG_NUMBER_UTF8_STRING || _constructed) @throw [OFInvalidArgumentException exception]; _stringValue = [[OFString alloc] initWithUTF8String: [_DEREncodedContents items] length: [_DEREncodedContents count]]; } @catch (id e) { [self release]; @throw e; } return self; } - (void)dealloc { [_stringValue release]; [super dealloc]; } @end |
Added src/OFASN1Value.h version [5fc1ae337b].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018 * Jonathan Schleifer <js@heap.zone> * * 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, /*! Null */ OF_ASN1_TAG_NUMBER_NULL = 0x05, /*! UTF-8 string */ OF_ASN1_TAG_NUMBER_UTF8_STRING = 0x0C, /*! Sequence */ OF_ASN1_TAG_NUMBER_SEQUENCE = 0x10 } of_asn1_tag_number_t; /*! * @brief A class representing an ASN.1 value. */ @interface OFASN1Value: OFObject <OFCopying> { 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 |
Added src/OFASN1Value.m version [3f613b5ac9].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018 * Jonathan Schleifer <js@heap.zone> * * 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 "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)init { OF_INVALID_INIT_METHOD } - (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; } - (void)dealloc { [_DEREncodedContents release]; [super dealloc]; } - (bool)isEqual: (id)object { OFASN1Value *value; 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; } - (uint32_t)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; } - (id)copy { return [self retain]; } @end |
Added src/OFData+ASN1DERValue.h version [8417761880].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018 * Jonathan Schleifer <js@heap.zone> * * 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_ASN1DERValue_reference; #ifdef __cplusplus } #endif @interface OFData (ASN1DERValue) /*! * @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 ASN1DERValue; /*! * @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)ASN1DERValueWithDepthLimit: (size_t)depthLimit; @end OF_ASSUME_NONNULL_END |
Added src/OFData+ASN1DERValue.m version [a444610f3e].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018 * Jonathan Schleifer <js@heap.zone> * * 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+ASN1DERValue.h" #import "OFASN1Boolean.h" #import "OFASN1Integer.h" #import "OFASN1Null.h" #import "OFASN1UTF8String.h" #import "OFASN1Value.h" #import "OFArray.h" #import "OFInvalidArgumentException.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" enum { ASN1_TAG_CONSTRUCTED_MASK = 0x20 }; int _OFData_ASN1DERValue_reference; static size_t parseObject(OFData *self, id *object, size_t depthLimit); static OFArray * parseSequence(OFData *contents, size_t depthLimit) { size_t count = [contents count]; OFMutableArray *ret; if (depthLimit == 0) @throw [OFOutOfRangeException exception]; ret = [OFMutableArray array]; 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 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) { 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_NULL: valueClass = [OFASN1Null class]; break; case OF_ASN1_TAG_NUMBER_UTF8_STRING: valueClass = [OFASN1UTF8String class]; break; case OF_ASN1_TAG_NUMBER_SEQUENCE | ASN1_TAG_CONSTRUCTED_MASK: *object = parseSequence(contents, depthLimit - 1); return bytesConsumed; default: valueClass = [OFASN1Value class]; break; } *object = [valueClass valueWithTagClass: tag >> 6 tagNumber: tag & 0x1F constructed: tag & ASN1_TAG_CONSTRUCTED_MASK DEREncodedContents: contents]; return bytesConsumed; } @implementation OFData (ASN1DERValue) - (id)ASN1DERValue { return [self ASN1DERValueWithDepthLimit: 32]; } - (id)ASN1DERValueWithDepthLimit: (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 |
Modified src/OFData+MessagePackValue.m from [0ca3c45556] to [0dc708bfc9].
︙ | ︙ | |||
567 568 569 570 571 572 573 | if (parseObject([self items], count, &object, depthLimit) != count) @throw [OFInvalidFormatException exception]; [object retain]; objc_autoreleasePoolPop(pool); | | | 567 568 569 570 571 572 573 574 575 576 | if (parseObject([self items], count, &object, depthLimit) != count) @throw [OFInvalidFormatException exception]; [object retain]; objc_autoreleasePoolPop(pool); return [object autorelease]; } @end |
Modified src/OFData.h from [666bc4047e] to [4bcaa7696d].
︙ | ︙ | |||
321 322 323 324 325 326 327 328 329 | */ - (void)writeToURL: (OFURL *)URL; @end OF_ASSUME_NONNULL_END #import "OFMutableData.h" #import "OFData+CryptoHashing.h" #import "OFData+MessagePackValue.h" | > | 321 322 323 324 325 326 327 328 329 330 | */ - (void)writeToURL: (OFURL *)URL; @end OF_ASSUME_NONNULL_END #import "OFMutableData.h" #import "OFData+ASN1DERValue.h" #import "OFData+CryptoHashing.h" #import "OFData+MessagePackValue.h" |
Modified src/OFData.m from [183d3ab057] to [64ff22bfd0].
︙ | ︙ | |||
44 45 46 47 48 49 50 51 52 53 54 55 56 57 | #import "base64.h" /* References for static linking */ void _references_to_categories_of_OFData(void) { _OFData_CryptoHashing_reference = 1; _OFData_MessagePackValue_reference = 1; } @implementation OFData @synthesize itemSize = _itemSize; | > | 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | #import "base64.h" /* References for static linking */ void _references_to_categories_of_OFData(void) { _OFData_ASN1DERValue_reference = 1; _OFData_CryptoHashing_reference = 1; _OFData_MessagePackValue_reference = 1; } @implementation OFData @synthesize itemSize = _itemSize; |
︙ | ︙ |
Modified tests/Makefile from [aed8a5335f] to [08f313381d].
︙ | ︙ | |||
10 11 12 13 14 15 16 17 18 19 20 21 22 23 | PROG_NOINST = tests${PROG_SUFFIX} STATIC_LIB_NOINST = ${TESTS_STATIC_LIB} SRCS = ForwardingTests.m \ OFArrayTests.m \ ${OFBLOCKTESTS_M} \ OFCharacterSetTests.m \ OFDataTests.m \ OFDateTests.m \ OFDictionaryTests.m \ OFInvocationTests.m \ OFJSONTests.m \ OFListTests.m \ OFLocaleTests.m \ OFMethodSignatureTests.m \ | > | 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | PROG_NOINST = tests${PROG_SUFFIX} STATIC_LIB_NOINST = ${TESTS_STATIC_LIB} SRCS = ForwardingTests.m \ OFArrayTests.m \ ${OFBLOCKTESTS_M} \ OFCharacterSetTests.m \ OFDataTests.m \ OFDataASN1DERValueTests.m \ OFDateTests.m \ OFDictionaryTests.m \ OFInvocationTests.m \ OFJSONTests.m \ OFListTests.m \ OFLocaleTests.m \ OFMethodSignatureTests.m \ |
︙ | ︙ |
Added tests/OFDataASN1DERValueTests.m version [b66444c495].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | /* * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, * 2018 * Jonathan Schleifer <js@heap.zone> * * 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.h" #import "OFASN1Boolean.h" #import "OFASN1Integer.h" #import "OFASN1Null.h" #import "OFASN1UTF8String.h" #import "OFArray.h" #import "OFString.h" #import "OFAutoreleasePool.h" #import "TestsAppDelegate.h" #import "OFInvalidFormatException.h" #import "OFOutOfRangeException.h" #import "OFTruncatedDataException.h" static OFString *module = @"OFData+ASN1DERValue"; @implementation TestsAppDelegate (OFDataASN1DERValueTests) - (void)dataASN1DERValueTests { OFAutoreleasePool *pool = [[OFAutoreleasePool alloc] init]; OFArray *array; TEST(@"Parsing of boolean", ![[[OFData dataWithItems: "\x01\x01\x00" count: 3] ASN1DERValue] booleanValue] && [[[OFData dataWithItems: "\x01\x01\xFF" count: 3] ASN1DERValue] booleanValue]) EXPECT_EXCEPTION(@"Detection of invalid boolean #1", OFInvalidFormatException, [[OFData dataWithItems: "\x01\x01\x01" count: 3] ASN1DERValue]) EXPECT_EXCEPTION(@"Detection of invalid boolean #2", OFInvalidFormatException, [[OFData dataWithItems: "\x01\x02\x00\x00" count: 4] ASN1DERValue]) EXPECT_EXCEPTION(@"Detection of invalid boolean #3", OFInvalidFormatException, [[OFData dataWithItems: "\x01\x00" count: 2] ASN1DERValue]) EXPECT_EXCEPTION(@"Detection of truncated boolean", OFTruncatedDataException, [[OFData dataWithItems: "\x01\x01" count: 2] ASN1DERValue]) TEST(@"Parsing of integer", [[[OFData dataWithItems: "\x02\x00" count: 2] ASN1DERValue] integerValue] == 0 && [[[OFData dataWithItems: "\x02\x01\x01" count: 3] ASN1DERValue] integerValue] == 1 && [[[OFData dataWithItems: "\x02\x02\x01\x04" count: 4] ASN1DERValue] integerValue] == 260 && [[[OFData dataWithItems: "\x02\x01\xFF" count: 3] ASN1DERValue] integerValue] == -1 && [[[OFData dataWithItems: "\x02\x03\xFF\x00\x00" count: 5] ASN1DERValue] integerValue] == -65536 && (uintmax_t)[[[OFData dataWithItems: "\x02\x09\x00\xFF\xFF\xFF\xFF" "\xFF\xFF\xFF\xFF" count: 11] ASN1DERValue] integerValue] == UINTMAX_MAX) EXPECT_EXCEPTION(@"Detecting of invalid integer #1", OFInvalidFormatException, [[OFData dataWithItems: "\x02\x02\x00\x00" count: 4] ASN1DERValue]) EXPECT_EXCEPTION(@"Detecting of invalid integer #2", OFInvalidFormatException, [[OFData dataWithItems: "\x02\x02\x00\x7F" count: 4] ASN1DERValue]) EXPECT_EXCEPTION(@"Detecting of invalid integer #3", OFInvalidFormatException, [[OFData dataWithItems: "\x02\x02\xFF\x80" count: 4] ASN1DERValue]) EXPECT_EXCEPTION(@"Detection of out of range integer", OFOutOfRangeException, [[OFData dataWithItems: "\x02\x09\x01" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" count: 11] ASN1DERValue]) EXPECT_EXCEPTION(@"Detection of truncated integer", OFTruncatedDataException, [[OFData dataWithItems: "\x02\x02\x00" count: 3] ASN1DERValue]) TEST(@"Parsing of NULL", [[[OFData dataWithItems: "\x05\x00" count: 2] ASN1DERValue] isKindOfClass: [OFASN1Null class]]) EXPECT_EXCEPTION(@"Detection of invalid NULL", OFInvalidFormatException, [[OFData dataWithItems: "\x05\x01\x00" count: 3] ASN1DERValue]) TEST(@"Parsing of UTF-8 string", [[[[OFData dataWithItems: "\x0C\x0EHällo Wörld!" count: 16] ASN1DERValue] stringValue] isEqual: @"Hällo Wörld!"] && [[[[OFData dataWithItems: "\x0C\x81\x80xxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxx" count: 131] ASN1DERValue] stringValue] isEqual: @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" @"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" @"xxxxxxxxxxxxxxxx"]) 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] ASN1DERValue]) EXPECT_EXCEPTION(@"Detection of truncated UTF-8 string", OFTruncatedDataException, [[OFData dataWithItems: "\x0C\x01" count: 2] ASN1DERValue]) EXPECT_EXCEPTION(@"Detection of truncated length", OFTruncatedDataException, [[OFData dataWithItems: "\x0C\x83\x01\x01" count: 4] ASN1DERValue]) EXPECT_EXCEPTION(@"Detection of invalid / inefficient length #1", OFInvalidFormatException, [[OFData dataWithItems: "\x0C\x81\x7F" count: 3] ASN1DERValue]) EXPECT_EXCEPTION(@"Detection of invalid / inefficient length #2", OFInvalidFormatException, [[OFData dataWithItems: "\x0C\x82\x00\x80xxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" "xxxxxxxxxxxxxxxxxx" count: 132] ASN1DERValue]) TEST(@"Parsing of sequence", (array = [[OFData dataWithItems: "\x30\x00" count: 2] ASN1DERValue]) && [array isKindOfClass: [OFArray class]] && [array count] == 0 && (array = [[OFData dataWithItems: "\x30\x09\x02\x01\x7B\x0C\x04Test" count: 11] ASN1DERValue]) && [array isKindOfClass: [OFArray class]] && [array count] == 2 && [[array objectAtIndex: 0] integerValue] == 123 && [[[array objectAtIndex: 1] stringValue] isEqual: @"Test"]) EXPECT_EXCEPTION(@"Parsing of truncated sequence #1", OFTruncatedDataException, [[OFData dataWithItems: "\x30\x01" count: 2] ASN1DERValue]) EXPECT_EXCEPTION(@"Parsing of truncated sequence #2", OFTruncatedDataException, [[OFData dataWithItems: "\x30\x04\x02\x01\x01\x00\x00" count: 7] ASN1DERValue]) [pool drain]; } @end |
Modified tests/TestsAppDelegate.h from [3fe9f6c770] to [fc4fed5331].
︙ | ︙ | |||
102 103 104 105 106 107 108 109 110 111 112 113 114 115 | @interface TestsAppDelegate (OFDNSResolverTests) - (void)DNSResolverTests; @end @interface TestsAppDelegate (OFDataTests) - (void)dataTests; @end @interface TestsAppDelegate (OFDateTests) - (void)dateTests; @end @interface TestsAppDelegate (OFDictionaryTests) - (void)dictionaryTests; | > > > > | 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | @interface TestsAppDelegate (OFDNSResolverTests) - (void)DNSResolverTests; @end @interface TestsAppDelegate (OFDataTests) - (void)dataTests; @end @interface TestsAppDelegate (OFDataASN1DERValueTests) - (void)dataASN1DERValueTests; @end @interface TestsAppDelegate (OFDateTests) - (void)dateTests; @end @interface TestsAppDelegate (OFDictionaryTests) - (void)dictionaryTests; |
︙ | ︙ |
Modified tests/TestsAppDelegate.m from [83bb4f0759] to [8a48813bd5].
︙ | ︙ | |||
386 387 388 389 390 391 392 393 394 395 396 397 398 399 | [self forwardingTests]; #ifdef OF_HAVE_BLOCKS [self blockTests]; #endif [self stringTests]; [self characterSetTests]; [self dataTests]; [self arrayTests]; [self dictionaryTests]; [self listTests]; [self setTests]; [self dateTests]; [self valueTests]; [self numberTests]; | > | 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 | [self forwardingTests]; #ifdef OF_HAVE_BLOCKS [self blockTests]; #endif [self stringTests]; [self characterSetTests]; [self dataTests]; [self dataASN1DERValueTests]; [self arrayTests]; [self dictionaryTests]; [self listTests]; [self setTests]; [self dateTests]; [self valueTests]; [self numberTests]; |
︙ | ︙ |