]> git.saurik.com Git - apple/security.git/blob - KeychainCircle/KCJoiningMessages.m
Security-57740.1.18.tar.gz
[apple/security.git] / KeychainCircle / KCJoiningMessages.m
1 //
2 // KCJoiningMessages.m
3 // Security
4 //
5 // Created by Mitch Adler on 2/17/16.
6 //
7 //
8
9 #import <Foundation/Foundation.h>
10
11 #import <KeychainCircle/KCDer.h>
12 #import <KeychainCircle/KCError.h>
13 #import <KeychainCircle/KCJoiningMessages.h>
14
15 #include <corecrypto/ccder.h>
16
17
18 @implementation KCJoiningMessage
19
20 + (nullable instancetype) messageWithDER: (NSData*) message
21 error: (NSError**) error {
22 return [[KCJoiningMessage alloc] initWithDER: message error: nil];
23 }
24
25 + (nullable instancetype) messageWithType: (KCJoiningMessageType) type
26 data: (NSData*) firstData
27 error: (NSError**) error {
28 return [[KCJoiningMessage alloc] initWithType:type data:firstData payload:nil error:error];
29 }
30
31 + (nullable instancetype) messageWithType: (KCJoiningMessageType) type
32 data: (NSData*) firstData
33 payload: (NSData*) secondData
34 error: (NSError**) error {
35 return [[KCJoiningMessage alloc] initWithType:type data:firstData payload:secondData error:error];
36
37 }
38
39 - (bool) inflatePartsOfEncoding: (NSError**) error {
40 const uint8_t *der = self.der.bytes;
41 const uint8_t *der_end = der + self.der.length;
42
43 const uint8_t *sequence_end = 0;
44
45 der = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &sequence_end, der, der_end);
46
47 if (der == 0) {
48 KCJoiningErrorCreate(kDERUnknownEncoding, error, @"Not sequence");
49 return false;
50 }
51
52 if (sequence_end != der_end) {
53 KCJoiningErrorCreate(kDERUnknownEncoding, error, @"Extra data at end of message");
54 return false;
55 }
56
57 uint64_t type;
58 der = ccder_decode_uint64(&type, der, der_end);
59
60 self->_type = (type > kLargestMessageType) ? kUnknown : (KCJoiningMessageType) type;
61
62 NSData* firstData;
63 NSData* secondData;
64
65 der = kcder_decode_data_nocopy(&firstData, error, der, der_end);
66
67 if (der != der_end) {
68 der = kcder_decode_data_nocopy(&secondData, error, der, der_end);
69 }
70
71 self->_firstData = firstData;
72 self->_secondData = secondData;
73
74 if (der != der_end) {
75 KCJoiningErrorCreate(kDERUnknownEncoding, error, @"Extra in sequence");
76 return false;
77 }
78
79 return true;
80 }
81
82 + (size_t) encodedSizeType: (KCJoiningMessageType) type
83 data: (NSData*) firstData
84 payload: (nullable NSData*) secondData
85 error: (NSError**) error {
86 size_t type_size = ccder_sizeof_uint64(type);
87
88 size_t srp_data_size = kcder_sizeof_data(firstData, error);
89 if (srp_data_size == 0) return 0;
90
91 size_t encrypted_payload_size = 0;
92
93 if (secondData != nil) {
94 encrypted_payload_size = kcder_sizeof_data(secondData, error);
95 if (srp_data_size == 0) return 0;
96 }
97
98
99 return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, type_size + srp_data_size + encrypted_payload_size);
100 }
101
102 + (nullable NSData*) encodeToDERType: (KCJoiningMessageType) type
103 data: (NSData*) firstData
104 payload: (nullable NSData*) secondData
105 error: (NSError**) error {
106
107 size_t length = [KCJoiningMessage encodedSizeType:type
108 data:firstData
109 payload:secondData
110 error: error];
111 if (length == 0) return nil;
112
113 NSMutableData* encoded = [NSMutableData dataWithLength: length];
114
115 uint8_t* der = encoded.mutableBytes;
116 uint8_t* der_end = der + encoded.length;
117
118 uint8_t* encode_end = ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
119 ccder_encode_uint64(type, der,
120 kcder_encode_data(firstData, error, der,
121 kcder_encode_data_optional(secondData, error, der, der_end))));
122
123 if (encode_end == NULL) return nil;
124 if (encode_end != der) {
125 KCJoiningErrorCreate(kDEREncodingFailed, error, @"Size didn't match encoding");
126 return nil;
127 }
128
129 return encoded;
130 }
131
132 - (nullable instancetype) initWithDER: (NSData*) message
133 error: (NSError**) error {
134 self = [super init];
135
136 self->_der = [NSData dataWithData: message];
137
138 return [self inflatePartsOfEncoding: error] ? self : nil;
139 }
140
141 - (nullable instancetype) initWithType: (KCJoiningMessageType) type
142 data: (NSData*) firstData
143 payload: (nullable NSData*) secondData
144 error: (NSError**) error {
145 self = [super init];
146
147 self->_der = [KCJoiningMessage encodeToDERType:type
148 data:firstData
149 payload:secondData
150 error:error];
151 if (self->_der == nil) return nil;
152
153 return [self inflatePartsOfEncoding: error] ? self : nil;
154 }
155
156 @end
157
158
159 @implementation NSData(KCJoiningMessages)
160
161 + (nullable instancetype) dataWithEncodedString: (NSString*) string
162 error: (NSError**) error {
163 size_t result_size = kcder_sizeof_string(string, error);
164 if (result_size == 0) return nil;
165
166 NSMutableData *result = [NSMutableData dataWithLength: result_size];
167
168 uint8_t *der = result.mutableBytes;
169 uint8_t *der_end = der + result.length;
170
171 uint8_t *encode_done = kcder_encode_string(string, error,
172 der, der_end);
173
174 if (encode_done != der) {
175 KCJoiningErrorCreate(kDEREncodingFailed, error, @"extra data");
176 return nil;
177 }
178
179 return result;
180 }
181
182 + (nullable instancetype) dataWithEncodedSequenceData: (NSData*) data1
183 data: (NSData*) data2
184 error: (NSError**) error {
185 size_t result_size = sizeof_seq_data_data(data1, data2, error);
186 if (result_size == 0) return nil;
187
188 NSMutableData *result = [NSMutableData dataWithLength: result_size];
189
190 uint8_t *der = result.mutableBytes;
191 uint8_t *der_end = der + result.length;
192
193 uint8_t *encode_done = encode_seq_data_data(data1, data2, error,
194 der, der_end);
195
196 if (encode_done != der) {
197 KCJoiningErrorCreate(kDEREncodingFailed, error, @"extra data");
198 return nil;
199 }
200
201 return result;
202 }
203
204 - (bool) decodeSequenceData: (NSData* _Nullable * _Nonnull) data1
205 data: (NSData* _Nullable * _Nonnull) data2
206 error: (NSError** _Nullable) error {
207
208 return NULL != decode_seq_data_data(data1, data2, error, self.bytes, self.bytes + self.length);
209 }
210
211 + (nullable instancetype) dataWithEncodedSequenceString: (NSString*) string
212 data: (NSData*) data
213 error: (NSError**) error {
214 size_t result_size = sizeof_seq_string_data(string, data, error);
215 if (result_size == 0) return nil;
216
217 NSMutableData *result = [NSMutableData dataWithLength: result_size];
218
219 uint8_t *der = result.mutableBytes;
220 uint8_t *der_end = der + result.length;
221
222 uint8_t *encode_done = encode_seq_string_data(string, data, error,
223 der, der_end);
224
225 if (encode_done != der) {
226 KCJoiningErrorCreate(kDEREncodingFailed, error, @"extra data");
227 return nil;
228 }
229
230 return result;
231 }
232
233 - (bool) decodeSequenceString: (NSString* _Nullable * _Nonnull) string
234 data: (NSData* _Nullable * _Nonnull) data
235 error: (NSError** _Nullable) error {
236 return NULL != decode_seq_string_data(string, data, error, self.bytes, self.bytes + self.length);
237 }
238
239 @end
240
241 @implementation NSString(KCJoiningMessages)
242 + (nullable instancetype) decodeFromDER: (NSData*)der error: (NSError** _Nullable) error {
243 NSString* result = nil;
244 const uint8_t* decode_result = kcder_decode_string(&result, error, der.bytes, der.bytes+der.length);
245 if (decode_result == nil) return nil;
246 if (decode_result != der.bytes + der.length) {
247 KCJoiningErrorCreate(kDERUnknownEncoding, error, @"extra data in string");
248 return nil;
249 }
250
251 return result;
252 }
253 @end
254
255
256 NSData* extractStartFromInitialMessage(NSData* initialMessage, NSError** error) {
257 NSData* result = nil;
258 const uint8_t *der = [initialMessage bytes];
259 const uint8_t *der_end = der + [initialMessage length];
260 const uint8_t *parse_end = decode_initialmessage(&result, error, der, der_end);
261
262 // Allow extra stuff in here for future start messages.
263 if (parse_end == NULL) {
264 return nil;
265 }
266 return result;
267
268 }
269
270 const uint8_t* decode_initialmessage(NSData** data, NSError** error,
271 const uint8_t* der, const uint8_t *der_end)
272 {
273 if (NULL == der)
274 return NULL;
275
276 const uint8_t *sequence_end = 0;
277 der = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &sequence_end, der, der_end);
278
279 if (der == NULL || sequence_end != der_end) {
280 KCJoiningErrorCreate(kDERUnknownEncoding, error, @"decode failed");
281 return nil;
282 }
283
284 uint64_t version = 0;
285 der = ccder_decode_uint64(&version, der, der_end);
286
287 if (der == NULL) {
288 KCJoiningErrorCreate(kDERUnknownEncoding, error, @"Version mising");
289 return nil;
290 }
291
292 if (version != 0) {
293 KCJoiningErrorCreate(kDERUnknownEncoding, error, @"Bad version: %d", version);
294 return nil;
295 }
296
297 return kcder_decode_data(data, error, der, der_end);
298 }
299
300 size_t sizeof_initialmessage(NSData*data) {
301 size_t version_size = ccder_sizeof_uint64(0);
302 if (version_size == 0) {
303 return 0;
304 }
305 size_t message_size = kcder_sizeof_data(data, nil);
306 if (message_size == 0) {
307 return 0;
308 }
309 return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, version_size + message_size);
310 }
311
312 uint8_t* encode_initialmessage(NSData* data, NSError**error,
313 const uint8_t *der, uint8_t *der_end)
314 {
315 return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
316 ccder_encode_uint64(0, der,
317 kcder_encode_data(data, error, der, der_end)));
318
319 }
320
321
322 size_t sizeof_seq_data_data(NSData*data1, NSData*data2, NSError**error) {
323 size_t data1_size = kcder_sizeof_data(data1, error);
324 if (data1_size == 0) {
325 return 0;
326 }
327 size_t data2_size = kcder_sizeof_data(data2, error);
328 if (data2_size == 0) {
329 return 0;
330 }
331 return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, data1_size + data2_size);
332 }
333
334 uint8_t* encode_seq_data_data(NSData* data1, NSData*data2, NSError**error,
335 const uint8_t *der, uint8_t *der_end) {
336 return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
337 kcder_encode_data(data1, error, der,
338 kcder_encode_data(data2, error, der, der_end)));
339 }
340
341 const uint8_t* decode_seq_data_data(NSData** data1, NSData** data2, NSError** error,
342 const uint8_t* der, const uint8_t *der_end) {
343 if (NULL == der)
344 return NULL;
345
346 const uint8_t *sequence_end = 0;
347 der = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &sequence_end, der, der_end);
348
349 if (der == NULL || sequence_end != der_end) {
350 KCJoiningErrorCreate(kDERUnknownEncoding, error, @"decode failed");
351 return nil;
352 }
353
354 der = kcder_decode_data(data1, error, der, der_end);
355 return kcder_decode_data(data2, error, der, der_end);
356 }
357
358 size_t sizeof_seq_string_data(NSString*string, NSData*data, NSError** error) {
359 size_t string_size = kcder_sizeof_string(string, error);
360 if (string_size == 0) {
361 return 0;
362 }
363 size_t data_size = kcder_sizeof_data(data, error);
364 if (data_size == 0) {
365 return 0;
366 }
367 return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, string_size + data_size);
368 }
369
370 uint8_t* _Nullable encode_seq_string_data(NSString* string, NSData*data, NSError**error,
371 const uint8_t *der, uint8_t *der_end) {
372 return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
373 kcder_encode_string(string, error, der,
374 kcder_encode_data(data, error, der, der_end)));
375 }
376
377 const uint8_t* _Nullable decode_seq_string_data(NSString* _Nonnull * _Nonnull string, NSData* _Nonnull * _Nonnull data,
378 NSError** error,
379 const uint8_t* der, const uint8_t *der_end) {
380 if (NULL == der)
381 return NULL;
382
383 const uint8_t *sequence_end = 0;
384 der = ccder_decode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, &sequence_end, der, der_end);
385
386 if (der == NULL || sequence_end != der_end) {
387 KCJoiningErrorCreate(kDERUnknownEncoding, error, @"decode failed");
388 return nil;
389 }
390
391 der = kcder_decode_string(string, error, der, der_end);
392 return kcder_decode_data(data, error, der, der_end);
393 }