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