1/* 2 * Copyright (c) 2013-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 "SOSAccountPriv.h" 26 27// 28// DER Encoding utilities 29// 30 31// 32// Encodes data or a zero length data 33// 34size_t der_sizeof_data_or_null(CFDataRef data, CFErrorRef* error) 35{ 36 if (data) { 37 return der_sizeof_data(data, error); 38 } else { 39 return der_sizeof_null(kCFNull, error); 40 } 41} 42 43uint8_t* der_encode_data_or_null(CFDataRef data, CFErrorRef* error, const uint8_t* der, uint8_t* der_end) 44{ 45 if (data) { 46 return der_encode_data(data, error, der, der_end); 47 } else { 48 return der_encode_null(kCFNull, error, der, der_end); 49 } 50} 51 52 53const uint8_t* der_decode_data_or_null(CFAllocatorRef allocator, CFDataRef* data, 54 CFErrorRef* error, 55 const uint8_t* der, const uint8_t* der_end) 56{ 57 CFTypeRef value = NULL; 58 der = der_decode_plist(allocator, 0, &value, error, der, der_end); 59 if (value && CFGetTypeID(value) != CFDataGetTypeID()) { 60 CFReleaseNull(value); 61 } 62 if (data) { 63 *data = value; 64 } 65 return der; 66} 67 68 69// 70// Mark: public_bytes encode/decode 71// 72 73size_t der_sizeof_public_bytes(SecKeyRef publicKey, CFErrorRef* error) 74{ 75 CFDataRef publicData = NULL; 76 77 if (publicKey) 78 SecKeyCopyPublicBytes(publicKey, &publicData); 79 80 size_t size = der_sizeof_data_or_null(publicData, error); 81 82 CFReleaseNull(publicData); 83 84 return size; 85} 86 87uint8_t* der_encode_public_bytes(SecKeyRef publicKey, CFErrorRef* error, const uint8_t* der, uint8_t* der_end) 88{ 89 CFDataRef publicData = NULL; 90 91 if (publicKey) 92 SecKeyCopyPublicBytes(publicKey, &publicData); 93 94 uint8_t *result = der_encode_data_or_null(publicData, error, der, der_end); 95 96 CFReleaseNull(publicData); 97 98 return result; 99} 100 101const uint8_t* der_decode_public_bytes(CFAllocatorRef allocator, CFIndex algorithmID, SecKeyRef* publicKey, CFErrorRef* error, const uint8_t* der, const uint8_t* der_end) 102{ 103 CFDataRef dataFound = NULL; 104 der = der_decode_data_or_null(allocator, &dataFound, error, der, der_end); 105 106 if (der && dataFound && publicKey) { 107 *publicKey = SecKeyCreateFromPublicData(allocator, algorithmID, dataFound); 108 } 109 CFReleaseNull(dataFound); 110 111 return der; 112} 113 114 115 116 117// 118// bool encoding/decoding 119// 120 121 122const uint8_t* ccder_decode_bool(bool* boolean, const uint8_t* der, const uint8_t *der_end) 123{ 124 if (NULL == der) 125 return NULL; 126 127 size_t payload_size = 0; 128 const uint8_t *payload = ccder_decode_tl(CCDER_BOOLEAN, &payload_size, der, der_end); 129 130 if (NULL == payload || (der_end - payload) < 1 || payload_size != 1) { 131 return NULL; 132 } 133 134 if (boolean) 135 *boolean = (*payload != 0); 136 137 return payload + payload_size; 138} 139 140 141size_t ccder_sizeof_bool(bool value __unused, CFErrorRef *error) 142{ 143 return ccder_sizeof(CCDER_BOOLEAN, 1); 144} 145 146 147uint8_t* ccder_encode_bool(bool value, const uint8_t *der, uint8_t *der_end) 148{ 149 uint8_t value_byte = value; 150 151 return ccder_encode_tl(CCDER_BOOLEAN, 1, der, 152 ccder_encode_body(1, &value_byte, der, der_end)); 153} 154