1/* 2 * Copyright (c) 2012-2014 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25#include <stdio.h> 26 27#include "utilities/SecCFRelease.h" 28#include "utilities/der_plist.h" 29#include "utilities/der_plist_internal.h" 30 31#include <corecrypto/ccder.h> 32#include <CoreFoundation/CoreFoundation.h> 33 34// 35// der..CFPropertyList 36// 37// We support: 38// 39// CFBoolean 40// CFData 41// CFDate 42// CFString 43// CFNumber 44// CFNull 45// 46// CFArray 47// CFDictionary 48// 49// 50 51const uint8_t* der_decode_plist(CFAllocatorRef allocator, CFOptionFlags mutability, 52 CFPropertyListRef* pl, CFErrorRef *error, 53 const uint8_t* der, const uint8_t *der_end) 54{ if (NULL == der) 55 return NULL; 56 57 ccder_tag tag; 58 if (NULL == ccder_decode_tag(&tag, der, der_end)) 59 return NULL; 60 61 switch (tag) { 62 case CCDER_NULL: 63 return der_decode_null(allocator, mutability, (CFNullRef*)pl, error, der, der_end); 64 case CCDER_BOOLEAN: 65 return der_decode_boolean(allocator, mutability, (CFBooleanRef*)pl, error, der, der_end); 66 case CCDER_OCTET_STRING: 67 return der_decode_data(allocator, mutability, (CFDataRef*)pl, error, der, der_end); 68 case CCDER_GENERALIZED_TIME: 69 return der_decode_date(allocator, mutability, (CFDateRef*)pl, error, der, der_end); 70 case CCDER_CONSTRUCTED_SEQUENCE: 71 return der_decode_array(allocator, mutability, (CFArrayRef*)pl, error, der, der_end); 72 case CCDER_UTF8_STRING: 73 return der_decode_string(allocator, mutability, (CFStringRef*)pl, error, der, der_end); 74 case CCDER_INTEGER: 75 return der_decode_number(allocator, mutability, (CFNumberRef*)pl, error, der, der_end); 76 case CCDER_CONSTRUCTED_SET: 77 return der_decode_dictionary(allocator, mutability, (CFDictionaryRef*)pl, error, der, der_end); 78 default: 79 SecCFDERCreateError(kSecDERErrorUnsupportedDERType, CFSTR("Unsupported DER Type"), NULL, error); 80 return NULL; 81 } 82} 83 84 85size_t der_sizeof_plist(CFPropertyListRef pl, CFErrorRef *error) 86{ 87 if (!pl) { 88 SecCFDERCreateError(kSecDERErrorUnsupportedCFObject, CFSTR("Null CFType"), NULL, error); 89 return 0; 90 } 91 92 CFTypeID dataType = CFGetTypeID(pl); 93 94 if (CFArrayGetTypeID() == dataType) 95 return der_sizeof_array((CFArrayRef) pl, error); 96 else if (CFBooleanGetTypeID() == dataType) 97 return der_sizeof_boolean((CFBooleanRef) pl, error); 98 else if (CFDataGetTypeID() == dataType) 99 return der_sizeof_data((CFDataRef) pl, error); 100 else if (CFDateGetTypeID() == dataType) 101 return der_sizeof_date((CFDateRef) pl, error); 102 else if (CFDictionaryGetTypeID() == dataType) 103 return der_sizeof_dictionary((CFDictionaryRef) pl, error); 104 else if (CFStringGetTypeID() == dataType) 105 return der_sizeof_string((CFStringRef) pl, error); 106 else if (CFNumberGetTypeID() == dataType) 107 return der_sizeof_number((CFNumberRef) pl, error); 108 if (CFNullGetTypeID() == dataType) 109 return der_sizeof_null((CFNullRef) pl, error); 110 else { 111 SecCFDERCreateError(kSecDERErrorUnsupportedCFObject, CFSTR("Unsupported CFType"), NULL, error); 112 return 0; 113 } 114} 115 116 117uint8_t* der_encode_plist(CFPropertyListRef pl, CFErrorRef *error, 118 const uint8_t *der, uint8_t *der_end) 119{ 120 if (!pl) { 121 SecCFDERCreateError(kSecDERErrorUnsupportedCFObject, CFSTR("Null CFType"), NULL, error); 122 return NULL; 123 } 124 125 CFTypeID dataType = CFGetTypeID(pl); 126 127 if (CFArrayGetTypeID() == dataType) 128 return der_encode_array((CFArrayRef) pl, error, der, der_end); 129 else if (CFBooleanGetTypeID() == dataType) 130 return der_encode_boolean((CFBooleanRef) pl, error, der, der_end); 131 else if (CFDataGetTypeID() == dataType) 132 return der_encode_data((CFDataRef) pl, error, der, der_end); 133 else if (CFDateGetTypeID() == dataType) 134 return der_encode_date((CFDateRef) pl, error, der, der_end); 135 else if (CFDictionaryGetTypeID() == dataType) 136 return der_encode_dictionary((CFDictionaryRef) pl, error, der, der_end); 137 else if (CFStringGetTypeID() == dataType) 138 return der_encode_string((CFStringRef) pl, error, der, der_end); 139 else if (CFNumberGetTypeID() == dataType) 140 return der_encode_number((CFNumberRef) pl, error, der, der_end); 141 else if (CFNullGetTypeID() == dataType) 142 return der_encode_null((CFNullRef) pl, error, der, der_end); 143 else { 144 SecCFDERCreateError(kSecDERErrorUnsupportedCFObject, CFSTR("Unsupported CFType"), NULL, error); 145 return NULL; 146 } 147} 148