7 #import <Foundation/Foundation.h>
9 #include <KeychainCircle/KCDer.h>
10 #import <KeychainCircle/KCError.h>
12 // These should probably be shared with security, but we don't export our der'izing functions yet.
15 static const uint8_t* kcder_decode_data_internal(NSData** data, bool copy,
17 const uint8_t* der, const uint8_t *der_end)
22 size_t payload_size = 0;
23 const uint8_t *payload = ccder_decode_tl(CCDER_OCTET_STRING, &payload_size, der, der_end);
25 if (NULL == payload || payload + payload_size > der_end) {
26 KCJoiningErrorCreate(kDERUnknownEncoding, error, @"Unknown data encoding");
30 *data = copy ? [NSData dataWithBytes: (void*)payload length: payload_size] :
31 [NSData dataWithBytesNoCopy: (void*)payload length:payload_size freeWhenDone:NO];
34 KCJoiningErrorCreate(kAllocationFailure, error, @"Allocation failure!");
38 return payload + payload_size;
42 const uint8_t* kcder_decode_data_nocopy(NSData** data,
44 const uint8_t* der, const uint8_t *der_end)
46 return kcder_decode_data_internal(data, NO, error, der, der_end);
49 const uint8_t* kcder_decode_data(NSData** data,
51 const uint8_t* der, const uint8_t *der_end) {
52 return kcder_decode_data_internal(data, YES, error, der, der_end);
56 size_t kcder_sizeof_data(NSData* data, NSError** error) {
57 return ccder_sizeof_raw_octet_string(data.length);
60 uint8_t* kcder_encode_data_optional(NSData* _Nullable data, NSError**error,
61 const uint8_t *der, uint8_t *der_end)
63 if (data == nil) return der_end;
65 return kcder_encode_data(data, error, der, der_end);
70 uint8_t* kcder_encode_data(NSData* data, NSError**error,
71 const uint8_t *der, uint8_t *der_end)
73 return ccder_encode_tl(CCDER_OCTET_STRING, data.length, der,
74 ccder_encode_body(data.length, data.bytes, der, der_end));
79 const uint8_t* kcder_decode_string(NSString** string, NSError**error,
80 const uint8_t* der, const uint8_t *der_end)
85 size_t payload_size = 0;
86 const uint8_t *payload = ccder_decode_tl(CCDER_UTF8_STRING, &payload_size, der, der_end);
88 if (NULL == payload || payload + payload_size > der_end) {
89 KCJoiningErrorCreate(kDERUnknownEncoding, error, @"Unknown string encoding");
93 *string = [[NSString alloc] initWithBytes:payload length:payload_size encoding:NSUTF8StringEncoding];
96 KCJoiningErrorCreate(kAllocationFailure, error, @"Allocation failure!");
100 return payload + payload_size;
104 size_t kcder_sizeof_string(NSString* string, NSError** error)
106 return ccder_sizeof(CCDER_UTF8_STRING, [string lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
110 uint8_t* kcder_encode_string(NSString* string, NSError** error,
111 const uint8_t *der, uint8_t *der_end)
113 // Obey the NULL allowed rules.
117 NSUInteger max = (der_end - der);
118 void *buffer = der_end - max;
120 if (![string getBytes:buffer
123 encoding:NSUTF8StringEncoding
125 range:NSMakeRange(0, string.length)
126 remainingRange:nil]) {
127 KCJoiningErrorCreate(kDERStringEncodingFailed, error, @"String encoding failed");
131 return ccder_encode_tl(CCDER_UTF8_STRING, used, der,
132 ccder_encode_body(used, buffer, der, der_end));
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)
142 return ccder_encode_tl(CCDER_OCTET_STRING, s_size, der, der_end);