1// 2// der_plist.c 3// utilities 4// 5// Created by Mitch Adler on 7/2/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// 19// der..CFPropertyList 20// 21// We support: 22// 23// CFBoolean 24// CFData 25// CFDate 26// CFString 27// CFNumber 28// CFNull 29// 30// CFArray 31// CFDictionary 32// 33// 34 35const uint8_t* der_decode_plist(CFAllocatorRef allocator, CFOptionFlags mutability, 36 CFPropertyListRef* pl, CFErrorRef *error, 37 const uint8_t* der, const uint8_t *der_end) 38{ if (NULL == der) 39 return NULL; 40 41 ccder_tag tag; 42 if (NULL == ccder_decode_tag(&tag, der, der_end)) 43 return NULL; 44 45 switch (tag) { 46 case CCDER_NULL: 47 return der_decode_null(allocator, mutability, (CFNullRef*)pl, error, der, der_end); 48 case CCDER_BOOLEAN: 49 return der_decode_boolean(allocator, mutability, (CFBooleanRef*)pl, error, der, der_end); 50 case CCDER_OCTET_STRING: 51 return der_decode_data(allocator, mutability, (CFDataRef*)pl, error, der, der_end); 52 case CCDER_GENERALIZED_TIME: 53 return der_decode_date(allocator, mutability, (CFDateRef*)pl, error, der, der_end); 54 case CCDER_CONSTRUCTED_SEQUENCE: 55 return der_decode_array(allocator, mutability, (CFArrayRef*)pl, error, der, der_end); 56 case CCDER_UTF8_STRING: 57 return der_decode_string(allocator, mutability, (CFStringRef*)pl, error, der, der_end); 58 case CCDER_INTEGER: 59 return der_decode_number(allocator, mutability, (CFNumberRef*)pl, error, der, der_end); 60 case CCDER_CONSTRUCTED_SET: 61 return der_decode_dictionary(allocator, mutability, (CFDictionaryRef*)pl, error, der, der_end); 62 default: 63 SecCFDERCreateError(kSecDERErrorUnsupportedDERType, CFSTR("Unsupported DER Type"), NULL, error); 64 return NULL; 65 } 66} 67 68 69size_t der_sizeof_plist(CFPropertyListRef pl, CFErrorRef *error) 70{ 71 if (!pl) { 72 SecCFDERCreateError(kSecDERErrorUnsupportedCFObject, CFSTR("Null CFType"), NULL, error); 73 return 0; 74 } 75 76 CFTypeID dataType = CFGetTypeID(pl); 77 78 if (CFArrayGetTypeID() == dataType) 79 return der_sizeof_array((CFArrayRef) pl, error); 80 else if (CFBooleanGetTypeID() == dataType) 81 return der_sizeof_boolean((CFBooleanRef) pl, error); 82 else if (CFDataGetTypeID() == dataType) 83 return der_sizeof_data((CFDataRef) pl, error); 84 else if (CFDateGetTypeID() == dataType) 85 return der_sizeof_date((CFDateRef) pl, error); 86 else if (CFDictionaryGetTypeID() == dataType) 87 return der_sizeof_dictionary((CFDictionaryRef) pl, error); 88 else if (CFStringGetTypeID() == dataType) 89 return der_sizeof_string((CFStringRef) pl, error); 90 else if (CFNumberGetTypeID() == dataType) 91 return der_sizeof_number((CFNumberRef) pl, error); 92 if (CFNullGetTypeID() == dataType) 93 return der_sizeof_null((CFNullRef) pl, error); 94 else { 95 SecCFDERCreateError(kSecDERErrorUnsupportedCFObject, CFSTR("Unsupported CFType"), NULL, error); 96 return 0; 97 } 98} 99 100 101uint8_t* der_encode_plist(CFPropertyListRef pl, CFErrorRef *error, 102 const uint8_t *der, uint8_t *der_end) 103{ 104 if (!pl) { 105 SecCFDERCreateError(kSecDERErrorUnsupportedCFObject, CFSTR("Null CFType"), NULL, error); 106 return NULL; 107 } 108 109 CFTypeID dataType = CFGetTypeID(pl); 110 111 if (CFArrayGetTypeID() == dataType) 112 return der_encode_array((CFArrayRef) pl, error, der, der_end); 113 else if (CFBooleanGetTypeID() == dataType) 114 return der_encode_boolean((CFBooleanRef) pl, error, der, der_end); 115 else if (CFDataGetTypeID() == dataType) 116 return der_encode_data((CFDataRef) pl, error, der, der_end); 117 else if (CFDateGetTypeID() == dataType) 118 return der_encode_date((CFDateRef) pl, error, der, der_end); 119 else if (CFDictionaryGetTypeID() == dataType) 120 return der_encode_dictionary((CFDictionaryRef) pl, error, der, der_end); 121 else if (CFStringGetTypeID() == dataType) 122 return der_encode_string((CFStringRef) pl, error, der, der_end); 123 else if (CFNumberGetTypeID() == dataType) 124 return der_encode_number((CFNumberRef) pl, error, der, der_end); 125 else if (CFNullGetTypeID() == dataType) 126 return der_encode_null((CFNullRef) pl, error, der, der_end); 127 else { 128 SecCFDERCreateError(kSecDERErrorUnsupportedCFObject, CFSTR("Unsupported CFType"), NULL, error); 129 return NULL; 130 } 131} 132