1/* 2 * Copyright (c) 2000-2004,2006,2011,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// 26// cssmwalkers - walkers for standard CSSM datatypes and wrappers 27// 28#ifndef _H_CSSMWALKERS 29#define _H_CSSMWALKERS 30 31#include <security_cdsa_utilities/walkers.h> 32#include <security_cdsa_utilities/cssmdata.h> 33#include <security_cdsa_utilities/cssmpods.h> 34#include <security_cdsa_utilities/cssmkey.h> 35 36 37 38namespace Security { 39namespace DataWalkers { 40 41 42// 43// There are lots of CSSM data structures that are variable-length records 44// of the form { count, pointer-to-array }. If you have a regular PodWrapper 45// for it, we can enumerate the array for you right here. Minimum requirement: 46// size_t size() const; 47// Element &operator [] (uint32 index); 48// // and some Element *&foo() that returns a reference-to-array-pointer 49// and a reference walker for the element type (as returned by operator []). 50// 51template <class Action, class Record, class Element> 52void enumerateArray(Action &operate, Record &record, Element *& (Record::*pointer)()) 53{ 54 if (record.size()) { 55 Element *&root = (record.*pointer)(); 56 operate.blob(root, record.size() * sizeof(Element)); 57 for (uint32 ix = 0; ix < record.size(); ++ix) 58 walk(operate, record[ix]); 59 } 60} 61 62 63// 64// The full set of walkers for CssmData in all its forms. 65// 66template <class Action> 67void walk(Action &operate, CssmData &data) 68{ 69 operate(data); 70 operate.blob(data.Data, data.Length); 71} 72 73template <class Action> 74CssmData *walk(Action &operate, CssmData * &data) 75{ 76 operate(data); 77 operate.blob(data->Data, data->Length); 78 return data; 79} 80 81template <class Action> 82void walk(Action &operate, CSSM_DATA &data) 83{ walk(operate, CssmData::overlay(data)); } 84 85template <class Action> 86CSSM_DATA *walk(Action &operate, CSSM_DATA * &data) 87{ return walk(operate, CssmData::overlayVar(data)); } 88 89 90 91// 92// Walking a C string is almost regular (the size comes from strlen()). 93// Just make sure you honor the needsSize preference of the operator. 94// 95template <class Action> 96char *walk(Action &operate, char * &s) 97{ 98 if (s) 99 operate(s, operate.needsSize ? (strlen(s) + 1) : 0); 100 return s; 101} 102 103 104// 105// Flattener functions for common CSSM data types that have internal structure. 106// 107template <class Action> 108CssmKey *walk(Action &operate, CssmKey * &key) 109{ 110 operate(key); 111 walk(operate, key->keyData()); 112 return key; 113} 114 115template <class Action> 116CSSM_KEY *walk(Action &operate, CSSM_KEY * &data) 117{ return walk(operate, CssmKey::overlayVar(data)); } 118 119template <class Action> 120CssmCryptoData *walk(Action &operate, CssmCryptoData * &data) 121{ 122 operate(data); 123 walk(operate, data->param()); 124 return data; 125} 126 127template <class Action> 128CSSM_CRYPTO_DATA *walk(Action &operate, CSSM_CRYPTO_DATA * &data) 129{ return walk(operate, CssmCryptoData::overlayVar(data)); } 130 131template <class Action> 132void walk(Action &operate, CSSM_PKCS5_PBKDF2_PARAMS &data) 133{ 134 operate(data); 135 walk(operate, data.Passphrase); 136} 137 138// 139// Walkers for flat datatypes 140// 141template <class Action> 142CSSM_DATE_PTR walk(Action &operate, CSSM_DATE_PTR &date) 143{ 144 operate(date); 145 return date; 146} 147 148template <class Action> 149CSSM_RANGE_PTR walk(Action &operate, CSSM_RANGE_PTR &range) 150{ 151 operate(range); 152 return range; 153} 154 155template <class Action> 156CSSM_VERSION_PTR walk(Action &operate, CSSM_VERSION_PTR &version) 157{ 158 operate(version); 159 return version; 160} 161 162template <class Action> 163CSSM_DL_DB_HANDLE_PTR walk(Action &operate, CSSM_DL_DB_HANDLE_PTR &dlDbHandle) 164{ 165 operate(dlDbHandle); 166 return dlDbHandle; 167} 168 169template <class Action> 170CssmSubserviceUid *walk(Action &operate, CssmSubserviceUid * &ssUid) 171{ 172 operate(ssUid); 173 return ssUid; 174} 175 176 177// 178// A synthetic variant of CssmData to model key derivation (input) parameters, 179// which have algorithm dependent structure. This is not likely to be useful 180// for anything else; but here's the common ancestor of all its users. 181// 182class CssmDeriveData { 183public: 184 CssmDeriveData(const CssmData &dat, CSSM_ALGORITHMS alg) 185 : baseData(dat), algorithm(alg) { } 186 187 CssmData baseData; 188 CSSM_ALGORITHMS algorithm; 189 190 template <class Action> 191 void enumerate(Action &operate) 192 { 193 walk(operate, baseData); 194 switch (algorithm) { 195 case CSSM_ALGID_PKCS5_PBKDF2: 196#if BUG_3762664 197 walk(operate, *baseData.interpretedAs<CSSM_PKCS5_PBKDF2_PARAMS> 198 (CSSMERR_CSP_INVALID_ATTR_ALG_PARAMS)); 199#else 200 if (baseData.length() != sizeof(CSSM_PKCS5_PBKDF2_PARAMS)) 201 CssmError::throwMe(CSSMERR_CSP_INVALID_ATTR_ALG_PARAMS); 202 walk(operate, *(CSSM_PKCS5_PBKDF2_PARAMS *)baseData.data()); 203#endif 204 break; 205 default: 206 break; 207 } 208 } 209}; 210 211 212template <class Action> 213void walk(Action &operate, CssmDeriveData &data) 214{ 215 operate(data); 216 data.enumerate(operate); 217} 218 219template <class Action> 220CssmDeriveData *walk(Action &operate, CssmDeriveData * &data) 221{ 222 operate(data); 223 if (data) 224 data->enumerate(operate); 225 return data; 226} 227 228 229 230} // end namespace DataWalkers 231} // end namespace Security 232 233#endif //_H_CSSMWALKERS 234