]> git.saurik.com Git - apple/security.git/blob - KeychainCircle/KCDer.m
Security-58286.270.3.0.1.tar.gz
[apple/security.git] / KeychainCircle / KCDer.m
1 //
2 // KCDer.m
3 // Security
4 //
5 //
6
7 #import <Foundation/Foundation.h>
8
9 #include <KeychainCircle/KCDer.h>
10 #import <KeychainCircle/KCError.h>
11 #import <os/overflow.h>
12
13 // These should probably be shared with security, but we don't export our der'izing functions yet.
14
15
16 static const uint8_t* kcder_decode_data_internal(NSData** data, bool copy,
17 NSError**error,
18 const uint8_t* der, const uint8_t *der_end)
19 {
20 if (NULL == der)
21 return NULL;
22
23 size_t payload_size = 0;
24 const uint8_t *payload = ccder_decode_tl(CCDER_OCTET_STRING, &payload_size, der, der_end);
25
26 uintptr_t payload_end_computed = 0;
27 if(os_add_overflow((uintptr_t)payload, payload_size, &payload_end_computed)) {
28 KCJoiningErrorCreate(kDERUnknownEncoding, error, @"Bad payload size");
29 return NULL;
30 }
31 if (NULL == payload || payload_end_computed > (uintptr_t) der_end) {
32 KCJoiningErrorCreate(kDERUnknownEncoding, error, @"Unknown data encoding");
33 return NULL;
34 }
35
36 *data = copy ? [NSData dataWithBytes: (void*)payload length: payload_size] :
37 [NSData dataWithBytesNoCopy: (void*)payload length:payload_size freeWhenDone:NO];
38
39 if (NULL == *data) {
40 KCJoiningErrorCreate(kAllocationFailure, error, @"Allocation failure!");
41 return NULL;
42 }
43
44 return payload + payload_size;
45 }
46
47
48 const uint8_t* kcder_decode_data_nocopy(NSData** data,
49 NSError**error,
50 const uint8_t* der, const uint8_t *der_end)
51 {
52 return kcder_decode_data_internal(data, NO, error, der, der_end);
53 }
54
55 const uint8_t* kcder_decode_data(NSData** data,
56 NSError**error,
57 const uint8_t* der, const uint8_t *der_end) {
58 return kcder_decode_data_internal(data, YES, error, der, der_end);
59 }
60
61
62 size_t kcder_sizeof_data(NSData* data, NSError** error) {
63 return ccder_sizeof_raw_octet_string(data.length);
64 }
65
66 uint8_t* kcder_encode_data_optional(NSData* _Nullable data, NSError**error,
67 const uint8_t *der, uint8_t *der_end)
68 {
69 if (data == nil) return der_end;
70
71 return kcder_encode_data(data, error, der, der_end);
72
73 }
74
75
76 uint8_t* kcder_encode_data(NSData* data, NSError**error,
77 const uint8_t *der, uint8_t *der_end)
78 {
79 return ccder_encode_tl(CCDER_OCTET_STRING, data.length, der,
80 ccder_encode_body(data.length, data.bytes, der, der_end));
81
82 }
83
84
85 const uint8_t* kcder_decode_string(NSString** string, NSError**error,
86 const uint8_t* der, const uint8_t *der_end)
87 {
88 if (NULL == der)
89 return NULL;
90
91 size_t payload_size = 0;
92 const uint8_t *payload = ccder_decode_tl(CCDER_UTF8_STRING, &payload_size, der, der_end);
93
94 uintptr_t payload_end_computed = 0;
95 if(os_add_overflow((uintptr_t)payload, payload_size, &payload_end_computed)) {
96 KCJoiningErrorCreate(kDERUnknownEncoding, error, @"Bad payload size");
97 return NULL;
98 }
99 if (NULL == payload || payload_end_computed > (uintptr_t) der_end) {
100 KCJoiningErrorCreate(kDERUnknownEncoding, error, @"Unknown string encoding");
101 return NULL;
102 }
103
104 *string = [[NSString alloc] initWithBytes:payload length:payload_size encoding:NSUTF8StringEncoding];
105
106 if (nil == *string) {
107 KCJoiningErrorCreate(kAllocationFailure, error, @"Allocation failure!");
108 return NULL;
109 }
110
111 return payload + payload_size;
112 }
113
114
115 size_t kcder_sizeof_string(NSString* string, NSError** error)
116 {
117 return ccder_sizeof(CCDER_UTF8_STRING, [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
118 }
119
120
121 uint8_t* kcder_encode_string(NSString* string, NSError** error,
122 const uint8_t *der, uint8_t *der_end)
123 {
124 // Obey the NULL allowed rules.
125 if (!der_end)
126 return NULL;
127
128 NSUInteger max = (der_end - der);
129 void *buffer = der_end - max;
130 NSUInteger used = 0;
131 if (![string getBytes:buffer
132 maxLength:max
133 usedLength:&used
134 encoding:NSUTF8StringEncoding
135 options:0
136 range:NSMakeRange(0, string.length)
137 remainingRange:nil]) {
138 KCJoiningErrorCreate(kDERStringEncodingFailed, error, @"String encoding failed");
139 return NULL;
140 }
141
142 return ccder_encode_tl(CCDER_UTF8_STRING, used, der,
143 ccder_encode_body(used, buffer, der, der_end));
144
145 }
146
147 uint8_t *kcder_encode_raw_octet_space(size_t s_size, uint8_t **location,
148 const uint8_t *der, uint8_t *der_end) {
149 der_end = ccder_encode_body_nocopy(s_size, der, der_end);
150 if (der_end && location)
151 *location = der_end;
152
153 return ccder_encode_tl(CCDER_OCTET_STRING, s_size, der, der_end);
154 }
155