1// 2// der_data.c 3// utilities 4// 5// Created by Mitch Adler on 6/18/12. 6// Copyright (c) 2012 Apple Inc. All rights reserved. 7// 8 9#include <stdio.h> 10 11#include "utilities/SecCFRelease.h" 12#include "utilities/der_plist.h" 13#include "utilities/der_plist_internal.h" 14 15#include <corecrypto/ccder.h> 16#include <CoreFoundation/CoreFoundation.h> 17 18 19const uint8_t* der_decode_data_mutable(CFAllocatorRef allocator, CFOptionFlags mutability, 20 CFMutableDataRef* data, CFErrorRef *error, 21 const uint8_t* der, const uint8_t *der_end) 22{ 23 if (NULL == der) 24 return NULL; 25 26 size_t payload_size = 0; 27 const uint8_t *payload = ccder_decode_tl(CCDER_OCTET_STRING, &payload_size, der, der_end); 28 29 if (NULL == payload || (der_end - payload) < payload_size) { 30 SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown data encoding"), NULL, error); 31 return NULL; 32 } 33 34 *data = CFDataCreateMutable(allocator, 0); 35 36 if (NULL == *data) { 37 SecCFDERCreateError(kSecDERErrorUnderlyingError, CFSTR("Failed to create data"), NULL, error); 38 return NULL; 39 } 40 41 CFDataAppendBytes(*data, payload, payload_size); 42 43 return payload + payload_size; 44} 45 46 47const uint8_t* der_decode_data(CFAllocatorRef allocator, CFOptionFlags mutability, 48 CFDataRef* data, CFErrorRef *error, 49 const uint8_t* der, const uint8_t *der_end) 50{ 51 if (NULL == der) 52 return NULL; 53 54 size_t payload_size = 0; 55 const uint8_t *payload = ccder_decode_tl(CCDER_OCTET_STRING, &payload_size, der, der_end); 56 57 if (NULL == payload || (der_end - payload) < payload_size) { 58 SecCFDERCreateError(kSecDERErrorUnknownEncoding, CFSTR("Unknown data encoding"), NULL, error); 59 return NULL; 60 } 61 62 *data = CFDataCreate(allocator, payload, payload_size); 63 64 if (NULL == *data) { 65 SecCFDERCreateError(kSecDERErrorUnderlyingError, CFSTR("Failed to create data"), NULL, error); 66 return NULL; 67 } 68 69 return payload + payload_size; 70} 71 72 73size_t der_sizeof_data(CFDataRef data, CFErrorRef *error) 74{ 75 return ccder_sizeof_raw_octet_string(CFDataGetLength(data)); 76} 77 78 79uint8_t* der_encode_data(CFDataRef data, CFErrorRef *error, 80 const uint8_t *der, uint8_t *der_end) 81{ 82 const CFIndex data_length = CFDataGetLength(data); 83 84 return ccder_encode_tl(CCDER_OCTET_STRING, data_length, der, 85 ccder_encode_body(data_length, CFDataGetBytePtr(data), der, der_end)); 86 87} 88