ObjFW  Diff

Differences From Artifact [5e5d1157d6]:

To Artifact [fa73f4a2f7]:


33
34
35
36
37
38
39
40

41
42
43
44
45
46
47
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47







-
+








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

enum {
	ASN1_TAG_CONSTRUCTED_MASK = 0x20
	tagConstructedMask = 0x20
};

int _OFData_ASN1DERParsing_reference;

static size_t parseObject(OFData *self, id *object, size_t depthLimit);

static OFArray *
57
58
59
60
61
62
63
64

65
66
67
68
69
70
71
57
58
59
60
61
62
63

64
65
66
67
68
69
70
71







-
+







		id object;
		size_t objectLength;

		objectLength = parseObject(contents, &object, depthLimit);

		count -= objectLength;
		contents = [contents subdataWithRange:
		    of_range(objectLength, count)];
		    OFRangeMake(objectLength, count)];

		[ret addObject: object];
	}

	[ret makeImmutable];

	return ret;
84
85
86
87
88
89
90
91

92
93
94
95

96
97
98
99
100

101
102
103
104
105
106
107
84
85
86
87
88
89
90

91
92
93
94

95
96
97
98
99

100
101
102
103
104
105
106
107







-
+



-
+




-
+







	while (count > 0) {
		id object;
		size_t objectLength;
		OFData *objectData;

		objectLength = parseObject(contents, &object, depthLimit);
		objectData = [contents subdataWithRange:
		    of_range(0, objectLength)];
		    OFRangeMake(0, objectLength)];

		if (previousObjectData != nil &&
		    [objectData compare: previousObjectData] !=
		    OF_ORDERED_DESCENDING)
		    OFOrderedDescending)
			@throw [OFInvalidFormatException exception];

		count -= objectLength;
		contents = [contents subdataWithRange:
		    of_range(objectLength, count)];
		    OFRangeMake(objectLength, count)];

		[ret addObject: object];

		previousObjectData = objectData;
	}

	[ret makeImmutable];
151
152
153
154
155
156
157
158

159
160
161
162


163
164
165

166
167
168

169
170
171

172
173
174
175


176
177
178
179
180
181
182
183

184
185
186

187
188
189

190
191
192
193


194
195
196
197
198
199


200
201
202
203
204

205
206
207

208
209
210

211
212
213
214
215
216
217
218
219
220
221

222
223
224
225
226
227
228
151
152
153
154
155
156
157

158
159
160


161
162
163
164

165
166
167

168
169
170

171
172
173


174
175
176
177
178
179
180
181
182

183
184
185

186
187
188

189
190
191


192
193
194
195
196
197


198
199
200
201
202
203

204
205
206

207
208
209

210
211
212
213
214
215
216
217
218
219
220

221
222
223
224
225
226
227
228







-
+


-
-
+
+


-
+


-
+


-
+


-
-
+
+







-
+


-
+


-
+


-
-
+
+




-
-
+
+




-
+


-
+


-
+










-
+







			@throw [OFInvalidFormatException exception];
	}

	if (count - bytesConsumed < contentsLength)
		@throw [OFTruncatedDataException exception];

	contents = [self subdataWithRange:
	    of_range(bytesConsumed, contentsLength)];
	    OFRangeMake(bytesConsumed, contentsLength)];
	bytesConsumed += contentsLength;

	switch (tag & ~ASN1_TAG_CONSTRUCTED_MASK) {
	case OF_ASN1_TAG_NUMBER_BOOLEAN:
	switch (tag & ~tagConstructedMask) {
	case OFASN1TagNumberBoolean:
		valueClass = [OFASN1Boolean class];
		break;
	case OF_ASN1_TAG_NUMBER_INTEGER:
	case OFASN1TagNumberInteger:
		valueClass = [OFASN1Integer class];
		break;
	case OF_ASN1_TAG_NUMBER_BIT_STRING:
	case OFASN1TagNumberBitString:
		valueClass = [OFASN1BitString class];
		break;
	case OF_ASN1_TAG_NUMBER_OCTET_STRING:
	case OFASN1TagNumberOctetString:
		valueClass = [OFASN1OctetString class];
		break;
	case OF_ASN1_TAG_NUMBER_NULL:
		if (tag & ASN1_TAG_CONSTRUCTED_MASK)
	case OFASN1TagNumberNull:
		if (tag & tagConstructedMask)
			@throw [OFInvalidFormatException exception];

		if (contents.count != 0)
			@throw [OFInvalidFormatException exception];

		*object = [OFNull null];
		return bytesConsumed;
	case OF_ASN1_TAG_NUMBER_OBJECT_IDENTIFIER:
	case OFASN1TagNumberObjectIdentifier:
		valueClass = [OFASN1ObjectIdentifier class];
		break;
	case OF_ASN1_TAG_NUMBER_ENUMERATED:
	case OFASN1TagNumberEnumerated:
		valueClass = [OFASN1Enumerated class];
		break;
	case OF_ASN1_TAG_NUMBER_UTF8_STRING:
	case OFASN1TagNumberUTF8String:
		valueClass = [OFASN1UTF8String class];
		break;
	case OF_ASN1_TAG_NUMBER_SEQUENCE:
		if (!(tag & ASN1_TAG_CONSTRUCTED_MASK))
	case OFASN1TagNumberSequence:
		if (!(tag & tagConstructedMask))
			@throw [OFInvalidFormatException exception];

		*object = parseSequence(contents, depthLimit - 1);
		return bytesConsumed;
	case OF_ASN1_TAG_NUMBER_SET:
		if (!(tag & ASN1_TAG_CONSTRUCTED_MASK))
	case OFASN1TagNumberSet:
		if (!(tag & tagConstructedMask))
			@throw [OFInvalidFormatException exception];

		*object = parseSet(contents, depthLimit - 1);
		return bytesConsumed;
	case OF_ASN1_TAG_NUMBER_NUMERIC_STRING:
	case OFASN1TagNumberNumericString:
		valueClass = [OFASN1NumericString class];
		break;
	case OF_ASN1_TAG_NUMBER_PRINTABLE_STRING:
	case OFASN1TagNumberPrintableString:
		valueClass = [OFASN1PrintableString class];
		break;
	case OF_ASN1_TAG_NUMBER_IA5_STRING:
	case OFASN1TagNumberIA5String:
		valueClass = [OFASN1IA5String class];
		break;
	default:
		valueClass = [OFASN1Value class];
		break;
	}

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

@implementation OFData (ASN1DERParsing)
- (id)objectByParsingASN1DER
{