ObjFW  Check-in [b1944fd052]

Overview
Comment:Do not subclass OFASN1Value

The reason for this is that OFASN1Value requires an initializer for DER
encoding, however, it might be beneficial to create an ASN.1 type
without providing DER encoding for it.

Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: b1944fd052a70f757a4c114cb2e769ca3c87b5186dc06c5d4ed52010f58b91e4
User & Date: js on 2018-10-27 13:01:38
Other Links: manifest | tags
Context
2018-10-27
13:12
PLATFORMS.md: Add RISC-V 64 to Linux check-in: d1f1f6c023 user: js tags: trunk
13:01
Do not subclass OFASN1Value check-in: b1944fd052 user: js tags: trunk
2018-10-21
18:54
OFURLHandler: Do not depend on OFFileManager check-in: ad3fc136ba user: js tags: trunk
Changes

Modified src/Makefile from [3928b87dc8] to [2eb6f3cb8d].

11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
11
12
13
14
15
16
17

18
19
20
21
22
23
24







-







LIB_MINOR = ${OBJFW_LIB_MINOR}

SRCS = OFASN1BitString.m		\
       OFASN1Boolean.m			\
       OFASN1Enumerated.m		\
       OFASN1IA5String.m		\
       OFASN1Integer.m			\
       OFASN1Null.m			\
       OFASN1NumericString.m		\
       OFASN1ObjectIdentifier.m		\
       OFASN1OctetString.m		\
       OFASN1PrintableString.m		\
       OFASN1UTF8String.m		\
       OFASN1Value.m			\
       OFApplication.m			\

Modified src/OFASN1BitString.h from [df8e872210] to [1d1b455c34].

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
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







+







-
+

-
+






-
+




-
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



 *
 * 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 bit string.
 * @brief An ASN.1 BitString.
 */
@interface OFASN1BitString: OFASN1Value
@interface OFASN1BitString: OFObject
{
	OFData *_bitStringValue;
	size_t _bitStringLength;
}

/*!
 * @brief The bit string value.
 * @brief The BitString value.
 */
@property (readonly, nonatomic) OFData *bitStringValue;

/*!
 * @brief The length of the bit string in bits.
 * @brief The length of the BitString in bits.
 */
@property (readonly, nonatomic) size_t bitStringLength;

- (instancetype)init OF_UNAVAILABLE;

/*!
 * @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 ASN.1 BitString
 */
- (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

Modified src/OFASN1BitString.m from [a33414023e] to [32f037ffdb].

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
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







+
+
+
+
+






-
+
-
-
-




-
+

-
-
+
+
-


-
+



-
+









-
+

















+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfRangeException.h"

@implementation OFASN1BitString
@synthesize bitStringValue = _bitStringValue;
@synthesize bitStringLength = _bitStringLength;

- (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 initWithTagClass: tagClass
	self = [super init];
			     tagNumber: tagNumber
			   constructed: constructed
		    DEREncodedContents: DEREncodedContents];

	@try {
		void *pool = objc_autoreleasePoolPush();
		unsigned char lastByteBits;
		size_t count = [_DEREncodedContents count];
		size_t count = [DEREncodedContents count];

		if (_tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    _tagNumber != OF_ASN1_TAG_NUMBER_BIT_STRING ||
		if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    tagNumber != OF_ASN1_TAG_NUMBER_BIT_STRING || constructed)
		    _constructed)
			@throw [OFInvalidArgumentException exception];

		if (count == 0)
		if ([DEREncodedContents itemSize] != 1 || count == 0)
			@throw [OFInvalidFormatException exception];

		lastByteBits =
		    *(unsigned char *)[_DEREncodedContents itemAtIndex: 0];
		    *(unsigned char *)[DEREncodedContents itemAtIndex: 0];

		if (count == 1 && lastByteBits != 0)
			@throw [OFInvalidFormatException exception];

		if (SIZE_MAX / 8 < count - 1 ||
		    SIZE_MAX - (count - 1) * 8 < lastByteBits)
			@throw [OFOutOfRangeException exception];

		_bitStringLength = (count - 1) * 8 + lastByteBits;
		_bitStringValue = [[_DEREncodedContents
		_bitStringValue = [[DEREncodedContents
		    subdataWithRange: of_range(1, count - 1)] copy];

		objc_autoreleasePoolPop(pool);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_bitStringValue release];

	[super dealloc];
}

- (bool)isEqual: (id)object
{
	OFASN1BitString *bitString;

	if (![object isKindOfClass: [OFASN1BitString class]])
		return false;

	bitString = object;

	if (![bitString->_bitStringValue isEqual: _bitStringValue])
		return false;
	if (bitString->_bitStringLength != _bitStringLength)
		return false;

	return true;
}

- (uint32_t)hash
{
	return [_bitStringValue hash] + (uint32_t)_bitStringLength;
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"<OFASN1BitString: %@ (%zu bits)>",
					   _bitStringValue, _bitStringLength];
}
@end

Modified src/OFASN1Boolean.h from [9272d43696] to [15b44725cd].

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
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







+





-
+

-
+





-
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



 *
 * 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 boolean.
 * @brief An ASN.1 Boolean.
 */
@interface OFASN1Boolean: OFASN1Value
@interface OFASN1Boolean: OFObject
{
	bool _booleanValue;
}

/*!
 * @brief The boolean value.
 * @brief The Boolean value.
 */
@property (readonly, nonatomic) bool booleanValue;

- (instancetype)init OF_UNAVAILABLE;

/*!
 * @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 ASN.1 Boolean
 */
- (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

Modified src/OFASN1Boolean.m from [c9cf50048c] to [d10f7216af].

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
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







+
+
+
+
+






-
+
-
-
-




-
-
+
+


+
-
+


-
+












+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+








#import "OFString.h"

#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"

@implementation OFASN1Boolean
@synthesize booleanValue = _booleanValue;

- (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 initWithTagClass: tagClass
	self = [super init];
			     tagNumber: tagNumber
			   constructed: constructed
		    DEREncodedContents: DEREncodedContents];

	@try {
		unsigned char value;

		if (_tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    _tagNumber != OF_ASN1_TAG_NUMBER_BOOLEAN || _constructed)
		if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    tagNumber != OF_ASN1_TAG_NUMBER_BOOLEAN || constructed)
			@throw [OFInvalidArgumentException exception];

		if ([DEREncodedContents itemSize] != 1 ||
		if ([_DEREncodedContents count] != 1)
		    [DEREncodedContents count] != 1)
			@throw [OFInvalidFormatException exception];

		value = *(unsigned char *)[_DEREncodedContents itemAtIndex: 0];
		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;
}

- (bool)isEqual: (id)object
{
	OFASN1Boolean *boolean;

	if (![object isKindOfClass: [OFASN1Boolean class]])
		return false;

	boolean = object;

	if (boolean->_booleanValue != _booleanValue)
		return false;

	return true;
}

- (uint32_t)hash
{
	return (uint32_t)_booleanValue;
}

- (OFString *)description
{
	return (_booleanValue
	    ? @"<OFASN1Boolean: true>"
	    : @"<OFASN1Boolean: false>");
}
@end

Modified src/OFASN1Enumerated.h from [cc45518bc1] to [3d6c493463].

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
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







+





-
+

-
+








+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



 *
 * 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.
 * @brief An ASN.1 Enumerated.
 */
@interface OFASN1Enumerated: OFASN1Value
@interface OFASN1Enumerated: OFObject
{
	intmax_t _integerValue;
}

/*!
 * @brief The integer value.
 */
@property (readonly, nonatomic) intmax_t integerValue;

- (instancetype)init OF_UNAVAILABLE;

/*!
 * @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 ASN.1 Enumerated
 */
- (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

Modified src/OFASN1Enumerated.m from [e8fb04db87] to [e9e319365f].

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
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







+
+
+
+
+






-
+
-
-
-


-
-
+
+
+
+
+



-
+







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







#import "OFInvalidArgumentException.h"

extern intmax_t of_asn1_integer_parse(const unsigned char *buffer,
    size_t length);

@implementation OFASN1Enumerated
@synthesize integerValue = _integerValue;

- (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 initWithTagClass: tagClass
	self = [super init];
			     tagNumber: tagNumber
			   constructed: constructed
		    DEREncodedContents: DEREncodedContents];

	@try {
		if (_tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    _tagNumber != OF_ASN1_TAG_NUMBER_ENUMERATED || _constructed)
		if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    tagNumber != OF_ASN1_TAG_NUMBER_ENUMERATED || constructed)
			@throw [OFInvalidArgumentException exception];

		if ([DEREncodedContents itemSize] != 1)
			@throw [OFInvalidArgumentException exception];

		_integerValue = of_asn1_integer_parse(
		    [_DEREncodedContents items], [_DEREncodedContents count]);
		    [DEREncodedContents items], [DEREncodedContents count]);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (bool)isEqual: (id)object
{
	OFASN1Enumerated *enumerated;

	if (![object isKindOfClass: [OFASN1Enumerated class]])
		return false;

	enumerated = object;

	if (enumerated->_integerValue != _integerValue)
		return false;

	return true;
}

- (uint32_t)hash
{
	return (uint32_t)_integerValue;
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"<OFASN1Enumerated: %jd>",
					   _integerValue];
}
@end

Modified src/OFASN1IA5String.h from [979959c6d4] to [7d806e36e1].

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
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







+









-
+













+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



 *
 * 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.
 */
@interface OFASN1IA5String: OFASN1Value
@interface OFASN1IA5String: OFObject
{
	OFString *_IA5StringValue;
}

/*!
 * @brief The IA5String value.
 */
@property (readonly, nonatomic) OFString *IA5StringValue;

/*!
 * @brief The string value.
 */
@property (readonly, nonatomic) OFString *stringValue;

- (instancetype)init OF_UNAVAILABLE;

/*!
 * @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 ASN.1 IA5String
 */
- (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

Modified src/OFASN1IA5String.m from [25dbe148e7] to [7247e3cb9c].

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
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







+
+
+
+
+






-
+
-
-
-


-
-
-
+
+
+
+
+



-
+

-
+



















+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







#import "OFData.h"
#import "OFString.h"

#import "OFInvalidArgumentException.h"

@implementation OFASN1IA5String
@synthesize IA5StringValue = _IA5StringValue;

- (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 initWithTagClass: tagClass
	self = [super init];
			     tagNumber: tagNumber
			   constructed: constructed
		    DEREncodedContents: DEREncodedContents];

	@try {
		if (_tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    _tagNumber != OF_ASN1_TAG_NUMBER_IA5_STRING ||
		    _constructed)
		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];

		_IA5StringValue = [[OFString alloc]
		    initWithCString: [_DEREncodedContents items]
		    initWithCString: [DEREncodedContents items]
			   encoding: OF_STRING_ENCODING_ASCII
			     length: [_DEREncodedContents count]];
			     length: [DEREncodedContents count]];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_IA5StringValue release];

	[super dealloc];
}

- (OFString *)stringValue
{
	return [self IA5StringValue];
}

- (bool)isEqual: (id)object
{
	OFASN1IA5String *IA5String;

	if (![object isKindOfClass: [OFASN1IA5String class]])
		return false;

	IA5String = object;

	if (![IA5String->_IA5StringValue isEqual: _IA5StringValue])
		return false;

	return true;
}

- (uint32_t)hash
{
	return [_IA5StringValue hash];
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"<OFASN1IA5String: %@>",
					   _IA5StringValue];
}
@end

Modified src/OFASN1Integer.h from [076cb23965] to [15d300b002].

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
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







+





-
+

-
+





-
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



 *
 * 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.
 * @brief An ASN.1 Integer.
 */
@interface OFASN1Integer: OFASN1Value
@interface OFASN1Integer: OFObject
{
	intmax_t _integerValue;
}

/*!
 * @brief The integer value.
 * @brief The Integer value.
 */
@property (readonly, nonatomic) intmax_t integerValue;

- (instancetype)init OF_UNAVAILABLE;

/*!
 * @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 ASN.1 Integer
 */
- (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

Modified src/OFASN1Integer.m from [77da974eb5] to [da98b02485].

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
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







+
+
+
+
+






-
+
-
-
-


-
-
+
+
+
+
+



-
+







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







		value = (value << 8) | *buffer++;

	return value;
}

@implementation OFASN1Integer
@synthesize integerValue = _integerValue;

- (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 initWithTagClass: tagClass
	self = [super init];
			     tagNumber: tagNumber
			   constructed: constructed
		    DEREncodedContents: DEREncodedContents];

	@try {
		if (_tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    _tagNumber != OF_ASN1_TAG_NUMBER_INTEGER || _constructed)
		if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    tagNumber != OF_ASN1_TAG_NUMBER_INTEGER || constructed)
			@throw [OFInvalidArgumentException exception];

		if ([DEREncodedContents itemSize] != 1)
			@throw [OFInvalidArgumentException exception];

		_integerValue = of_asn1_integer_parse(
		    [_DEREncodedContents items], [_DEREncodedContents count]);
		    [DEREncodedContents items], [DEREncodedContents count]);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (bool)isEqual: (id)object
{
	OFASN1Integer *integer;

	if (![object isKindOfClass: [OFASN1Integer class]])
		return false;

	integer = object;

	if (integer->_integerValue != _integerValue)
		return false;

	return true;
}

- (uint32_t)hash
{
	return (uint32_t)_integerValue;
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"<OFASN1Integer: %jd>",
					   _integerValue];
}
@end

Deleted 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

Deleted src/OFASN1Null.m version [f37dc7e287].

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

























































-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
/*
 * 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 "OFString.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;
}

- (OFString *)description
{
	return @"<OFASN1Null>";
}
@end

Modified src/OFASN1NumericString.h from [ff4261a7f5] to [fb5d204f84].

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
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







+









-
+













+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



 *
 * 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.
 */
@interface OFASN1NumericString: OFASN1Value
@interface OFASN1NumericString: OFObject
{
	OFString *_numericStringValue;
}

/*!
 * @brief The NumericString value.
 */
@property (readonly, nonatomic) OFString *numericStringValue;

/*!
 * @brief The string value.
 */
@property (readonly, nonatomic) OFString *stringValue;

- (instancetype)init OF_UNAVAILABLE;

/*!
 * @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

Modified src/OFASN1NumericString.m from [0dfe0413cd] to [e15f600266].

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
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







+
+
+
+
+






-
+
-
-
-


-
-
+
+

-
-
-
+
+
+
+
+
+







-
+

-
+



















+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







#import "OFString.h"

#import "OFInvalidArgumentException.h"
#import "OFInvalidEncodingException.h"

@implementation OFASN1NumericString
@synthesize numericStringValue = _numericStringValue;

- (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 initWithTagClass: tagClass
	self = [super init];
			     tagNumber: tagNumber
			   constructed: constructed
		    DEREncodedContents: DEREncodedContents];

	@try {
		const unsigned char *items = [_DEREncodedContents items];
		size_t count = [_DEREncodedContents count];
		const unsigned char *items = [DEREncodedContents items];
		size_t count = [DEREncodedContents count];

		if (_tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    _tagNumber != OF_ASN1_TAG_NUMBER_NUMERIC_STRING ||
		    _constructed)
		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];

		for (size_t i = 0; i < count; i++)
			if (!of_ascii_isdigit(items[i]) && items[i] != ' ')
				@throw [OFInvalidEncodingException exception];

		_numericStringValue = [[OFString alloc]
		    initWithCString: [_DEREncodedContents items]
		    initWithCString: [DEREncodedContents items]
			   encoding: OF_STRING_ENCODING_ASCII
			     length: [_DEREncodedContents count]];
			     length: [DEREncodedContents count]];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_numericStringValue release];

	[super dealloc];
}

- (OFString *)stringValue
{
	return [self numericStringValue];
}

- (bool)isEqual: (id)object
{
	OFASN1NumericString *numericString;

	if (![object isKindOfClass: [OFASN1NumericString class]])
		return false;

	numericString = object;

	if (![numericString->_numericStringValue isEqual: _numericStringValue])
		return false;

	return true;
}

- (uint32_t)hash
{
	return [_numericStringValue hash];
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"<OFASN1NumericString: %@>",
					   _numericStringValue];
}
@end

Modified src/OFASN1ObjectIdentifier.h from [24fd141231] to [ff0a1d2946].

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
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







+








-
+

-
+





-
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



 *
 * 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 Object Identifier.
 * @brief An ASN.1 ObjectIdentifier.
 */
@interface OFASN1ObjectIdentifier: OFASN1Value
@interface OFASN1ObjectIdentifier: OFObject
{
	OFArray OF_GENERIC(OFNumber *) *_subidentifiers;
}

/*!
 * @brief The subidentifiers of the Object Identifier.
 * @brief The subidentifiers of the ObjectIdentifier.
 */
@property (readonly, nonatomic) OFArray OF_GENERIC(OFNumber *) *subidentifiers;

- (instancetype)init OF_UNAVAILABLE;

/*!
 * @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 ASN.1 ObjectIdentifier
 */
- (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

Modified src/OFASN1ObjectIdentifier.m from [94a9ef2a4a] to [84db523991].

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
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







+
+
+
+
+






-
+
-
-
-



-
-
+
+




-
-
-
+
+
+


-
-
+
+








#import "OFInvalidArgumentException.h"
#import "OFInvalidFormatException.h"
#import "OFOutOfRangeException.h"

@implementation OFASN1ObjectIdentifier
@synthesize subidentifiers = _subidentifiers;

- (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 initWithTagClass: tagClass
	self = [super init];
			     tagNumber: tagNumber
			   constructed: constructed
		    DEREncodedContents: DEREncodedContents];

	@try {
		void *pool = objc_autoreleasePoolPush();
		const unsigned char *items = [_DEREncodedContents items];
		size_t count = [_DEREncodedContents count];
		const unsigned char *items = [DEREncodedContents items];
		size_t count = [DEREncodedContents count];
		OFMutableArray *subidentifiers = [OFMutableArray array];
		uintmax_t value = 0;
		uint_fast8_t bits = 0;

		if (_tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    _tagNumber != OF_ASN1_TAG_NUMBER_OBJECT_IDENTIFIER ||
		    _constructed)
		if (tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    tagNumber != OF_ASN1_TAG_NUMBER_OBJECT_IDENTIFIER ||
		    constructed)
			@throw [OFInvalidArgumentException exception];

		if (count == 0)
			@throw [OFInvalidFormatException exception];
		if ([DEREncodedContents itemSize] != 1 || count == 0)
			@throw [OFInvalidArgumentException exception];

		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;
108
109
110
111
112
113
114




















115
116
117
118
119
120
121
122
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







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+









- (void)dealloc
{
	[_subidentifiers release];

	[super dealloc];
}

- (bool)isEqual: (id)object
{
	OFASN1ObjectIdentifier *objectIdentifier;

	if (![object isKindOfClass: [OFASN1ObjectIdentifier class]])
		return false;

	objectIdentifier = object;

	if (![objectIdentifier->_subidentifiers isEqual: _subidentifiers])
		return false;

	return true;
}

- (uint32_t)hash
{
	return [_subidentifiers hash];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"<OFASN1ObjectIdentifier: %@>",
	    [_subidentifiers componentsJoinedByString: @"."]];
}
@end

Modified src/OFASN1OctetString.h from [e75e49a18e] to [bbb7148b03].

11
12
13
14
15
16
17

18
19
20
21
22
23
24
25

26
27





28
29

30
31

















32
33
34
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







+







-
+

-
+
+
+
+
+

-
+


+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



 *
 * 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 octet string.
 * @brief An ASN.1 OctetString.
 */
@interface OFASN1OctetString: OFASN1Value
@interface OFASN1OctetString: OFObject
{
	OFData *_octetStringValue;
}

/*!
 * @brief The octet string value.
 * @brief The OctetString value.
 */
@property (readonly, nonatomic) OFData *octetStringValue;

- (instancetype)init OF_UNAVAILABLE;

/*!
 * @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

Modified src/OFASN1OctetString.m from [899f633e76] to [f80a8b6c4e].

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
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







+
+
+
+
+
+
+





-
+
-
-
-


-
-
-
+
+
+

+
+
+
+
+








+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+





-
+


#import "OFASN1OctetString.h"
#import "OFData.h"
#import "OFString.h"

#import "OFInvalidArgumentException.h"

@implementation OFASN1OctetString
@synthesize octetStringValue = _octetStringValue;

- (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 initWithTagClass: tagClass
	self = [super init];
			     tagNumber: tagNumber
			   constructed: constructed
		    DEREncodedContents: DEREncodedContents];

	@try {
		if (_tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    _tagNumber != OF_ASN1_TAG_NUMBER_OCTET_STRING ||
		    _constructed)
		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];

		_octetStringValue = [DEREncodedContents copy];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
- (OFData *)octetStringValue
{
	return _DEREncodedContents;
	[_octetStringValue release];

	[super dealloc];
}

- (bool)isEqual: (id)object
{
	OFASN1OctetString *octetString;

	if (![object isKindOfClass: [OFASN1OctetString class]])
		return false;

	octetString = object;

	if (![octetString->_octetStringValue isEqual: _octetStringValue])
		return false;

	return true;
}

- (uint32_t)hash
{
	return [_octetStringValue hash];
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"<OFASN1OctetString: %@>",
					   _DEREncodedContents];
					   _octetStringValue];
}
@end

Modified src/OFASN1PrintableString.h from [29166468df] to [dcc9a7f890].

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
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







+









-
+













+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



 *
 * 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.
 */
@interface OFASN1PrintableString: OFASN1Value
@interface OFASN1PrintableString: OFObject
{
	OFString *_printableStringValue;
}

/*!
 * @brief The PrintableString value.
 */
@property (readonly, nonatomic) OFString *printableStringValue;

/*!
 * @brief The string value.
 */
@property (readonly, nonatomic) OFString *stringValue;

- (instancetype)init OF_UNAVAILABLE;

/*!
 * @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 ASN.1 PrintableString
 */
- (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

Modified src/OFASN1PrintableString.m from [c4ad6140d5] to [341cd0aa78].

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
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







+
+
+
+
+






-
+
-
-
-


-
-
+
+

-
-
-
+
+
+
+
+
+







#import "OFString.h"

#import "OFInvalidArgumentException.h"
#import "OFInvalidEncodingException.h"

@implementation OFASN1PrintableString
@synthesize printableStringValue = _printableStringValue;

- (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 initWithTagClass: tagClass
	self = [super init];
			     tagNumber: tagNumber
			   constructed: constructed
		    DEREncodedContents: DEREncodedContents];

	@try {
		const unsigned char *items = [_DEREncodedContents items];
		size_t count = [_DEREncodedContents count];
		const unsigned char *items = [DEREncodedContents items];
		size_t count = [DEREncodedContents count];

		if (_tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    _tagNumber != OF_ASN1_TAG_NUMBER_PRINTABLE_STRING ||
		    _constructed)
		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];

		for (size_t i = 0; i < count; i++) {
			if (of_ascii_isalnum(items[i]))
				continue;

			switch (items[i]) {
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
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







-
+

-
+



















+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







				continue;
			default:
				@throw [OFInvalidEncodingException exception];
			}
		}

		_printableStringValue = [[OFString alloc]
		    initWithCString: [_DEREncodedContents items]
		    initWithCString: [DEREncodedContents items]
			   encoding: OF_STRING_ENCODING_ASCII
			     length: [_DEREncodedContents count]];
			     length: [DEREncodedContents count]];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_printableStringValue release];

	[super dealloc];
}

- (OFString *)stringValue
{
	return [self printableStringValue];
}

- (bool)isEqual: (id)object
{
	OFASN1PrintableString *printableString;

	if (![object isKindOfClass: [OFASN1PrintableString class]])
		return false;

	printableString = object;

	if (![printableString->_printableStringValue isEqual:
	    _printableStringValue])
		return false;

	return true;
}

- (uint32_t)hash
{
	return [_printableStringValue hash];
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"<OFASN1PrintableString: %@>",
					   _printableStringValue];
}
@end

Modified src/OFASN1UTF8String.h from [e216804d88] to [609c5811c7].

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
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







+







-
+

-
+





-
+







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



 *
 * 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 UTF-8 string.
 * @brief An ASN.1 UTF8String.
 */
@interface OFASN1UTF8String: OFASN1Value
@interface OFASN1UTF8String: OFObject
{
	OFString *_UTF8StringValue;
}

/*!
 * @brief The UTF-8 string value.
 * @brief The UTF8String value.
 */
@property (readonly, nonatomic) OFString *UTF8StringValue;

/*!
 * @brief The string value.
 */
@property (readonly, nonatomic) OFString *stringValue;

- (instancetype)init OF_UNAVAILABLE;

/*!
 * @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 ASN.1 UTF8String
 */
- (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

Modified src/OFASN1UTF8String.m from [245e438871] to [0422c0308e].

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
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







+
+
+
+
+






-
+
-
-
-


-
-
-
+
+
+
+
+



-
-
+
+



















+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







#import "OFData.h"
#import "OFString.h"

#import "OFInvalidArgumentException.h"

@implementation OFASN1UTF8String
@synthesize UTF8StringValue = _UTF8StringValue;

- (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 initWithTagClass: tagClass
	self = [super init];
			     tagNumber: tagNumber
			   constructed: constructed
		    DEREncodedContents: DEREncodedContents];

	@try {
		if (_tagClass != OF_ASN1_TAG_CLASS_UNIVERSAL ||
		    _tagNumber != OF_ASN1_TAG_NUMBER_UTF8_STRING ||
		    _constructed)
		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];

		_UTF8StringValue = [[OFString alloc]
		    initWithUTF8String: [_DEREncodedContents items]
				length: [_DEREncodedContents count]];
		    initWithUTF8String: [DEREncodedContents items]
				length: [DEREncodedContents count]];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)dealloc
{
	[_UTF8StringValue release];

	[super dealloc];
}

- (OFString *)stringValue
{
	return [self UTF8StringValue];
}

- (bool)isEqual: (id)object
{
	OFASN1UTF8String *UTF8String;

	if (![object isKindOfClass: [OFASN1UTF8String class]])
		return false;

	UTF8String = object;

	if (![UTF8String->_UTF8StringValue isEqual: _UTF8StringValue])
		return false;

	return true;
}

- (uint32_t)hash
{
	return [_UTF8StringValue hash];
}

- (OFString *)description
{
	return [OFString stringWithFormat: @"<OFASN1UTF8String: %@>",
					   _UTF8StringValue];
}
@end

Modified src/OFASN1Value.h from [3df22b0a2b] to [cc8037de53].

68
69
70
71
72
73
74
75

76
77
78
79
80
81
82
68
69
70
71
72
73
74

75
76
77
78
79
80
81
82







-
+







	/*! IA5String */
	OF_ASN1_TAG_NUMBER_IA5_STRING	     = 0x16
} of_asn1_tag_number_t;

/*!
 * @brief A class representing an ASN.1 value.
 */
@interface OFASN1Value: OFObject <OFCopying>
@interface OFASN1Value: OFObject
{
	of_asn1_tag_class_t _tagClass;
	of_asn1_tag_number_t _tagNumber;
	bool _constructed;
	OFData *_DEREncodedContents;
}

Modified src/OFASN1Value.m from [32a8246549] to [9c63414e2b].

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
108
109
110
111
112
113
114





115
116
117
118
119
120
121
122
123
124
125
126
127







-
-
-
-
-













	OF_HASH_ADD_HASH(hash, [_DEREncodedContents hash]);

	OF_HASH_FINALIZE(hash);

	return hash;
}

- (id)copy
{
	return [self retain];
}

- (OFString *)description
{
	return [OFString stringWithFormat:
	    @"<OFASN1Value:\n"
	    @"\tTag class = %x\n"
	    @"\tTag number = %x\n"
	    @"\tConstructed = %u\n"
	    @"\tDER-encoded contents = %@\n"
	    @">",
	    _tagClass, _tagNumber, _constructed,
	    [_DEREncodedContents description]];
}
@end

Modified src/OFData+ASN1DERValue.m from [84eafb2ba8] to [c2a6a4af74].

19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40







-







+








#import "OFData+ASN1DERValue.h"
#import "OFASN1BitString.h"
#import "OFASN1Boolean.h"
#import "OFASN1Enumerated.h"
#import "OFASN1IA5String.h"
#import "OFASN1Integer.h"
#import "OFASN1Null.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"

170
171
172
173
174
175
176


177
178






179
180
181
182
183
184
185
170
171
172
173
174
175
176
177
178


179
180
181
182
183
184
185
186
187
188
189
190
191







+
+
-
-
+
+
+
+
+
+







	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];
		valueClass = [OFASN1Null class];
		break;

		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:
207
208
209
210
211
212
213

214
215
216
217




218
219
220
221
222
223
224
213
214
215
216
217
218
219
220




221
222
223
224
225
226
227
228
229
230
231







+
-
-
-
-
+
+
+
+







		valueClass = [OFASN1IA5String class];
		break;
	default:
		valueClass = [OFASN1Value class];
		break;
	}

	*object = [[[valueClass alloc]
	*object = [valueClass valueWithTagClass: tag >> 6
				      tagNumber: tag & 0x1F
				    constructed: tag & ASN1_TAG_CONSTRUCTED_MASK
			     DEREncodedContents: contents];
	      initWithTagClass: tag >> 6
		     tagNumber: tag & 0x1F
		   constructed: tag & ASN1_TAG_CONSTRUCTED_MASK
	    DEREncodedContents: contents] autorelease];
	return bytesConsumed;
}

@implementation OFData (ASN1DERValue)
- (id)ASN1DERValue
{
	return [self ASN1DERValueWithDepthLimit: 32];

Modified src/ObjFW.h from [ee89e1ae2e] to [fa03da00eb].

124
125
126
127
128
129
130












131
132
133
134
135
136
137
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







+
+
+
+
+
+
+
+
+
+
+
+







#import "OFTimer.h"
#import "OFRunLoop.h"
#import "OFSandbox.h"

#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"
# import "OFBindFailedException.h"

Modified tests/OFASN1DERValueTests.m from [2a96ab0844] to [589ffdef13].

18
19
20
21
22
23
24
25
26
27
28
29
30
31

32
33
34
35
36
37
38
18
19
20
21
22
23
24

25
26
27
28
29
30
31
32
33
34
35
36
37
38







-






+







#include "config.h"

#import "OFData.h"
#import "OFASN1BitString.h"
#import "OFASN1Boolean.h"
#import "OFASN1IA5String.h"
#import "OFASN1Integer.h"
#import "OFASN1Null.h"
#import "OFASN1NumericString.h"
#import "OFASN1ObjectIdentifier.h"
#import "OFASN1OctetString.h"
#import "OFASN1PrintableString.h"
#import "OFASN1UTF8String.h"
#import "OFArray.h"
#import "OFNull.h"
#import "OFNumber.h"
#import "OFSet.h"
#import "OFString.h"
#import "OFAutoreleasePool.h"

#import "TestsAppDelegate.h"

185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
200
185
186
187
188
189
190
191

192

193
194
195
196
197
198
199







-
+
-







	EXPECT_EXCEPTION(@"Detection of truncated octet string",
	    OFTruncatedDataException, [[OFData dataWithItems: "\x04\x01"
						       count: 2] ASN1DERValue])

	/* Null */
	TEST(@"Parsing of null",
	    [[[OFData dataWithItems: "\x05\x00"
			      count: 2] ASN1DERValue]
			      count: 2] ASN1DERValue] isEqual: [OFNull null]])
	    isKindOfClass: [OFASN1Null class]])

	EXPECT_EXCEPTION(@"Detection of invalid null",
	    OFInvalidFormatException, [[OFData dataWithItems: "\x05\x01\x00"
						       count: 3] ASN1DERValue])

	/* Object Identifier */
	TEST(@"Parsing of Object Identifier",