1/* 2 * Copyright (c) 2004 Apple Computer, 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#include "transit.h" 24 25 26namespace Security { 27namespace Tokend { 28 29 30// 31// Relocation support 32// 33void relocate(Context &context, void *base, Context::Attr *attrs, uint32 attrSize) 34{ 35 ReconstituteWalker relocator(attrs, base); 36 context.ContextAttributes = attrs; // fix context->attr vector link 37 for (uint32 n = 0; n < context.attributesInUse(); n++) 38 walk(relocator, context[n]); 39} 40 41 42// 43// Data search and retrieval interface 44// 45DataRetrieval::DataRetrieval(CssmDbRecordAttributeData *inAttributes, bool getData) 46{ 47 this->attributes = inAttributes; 48 this->data = getData ? &mData : NULL; 49 this->record = CSSM_INVALID_HANDLE; 50 this->keyhandle = CSSM_INVALID_HANDLE; 51} 52 53 54DataRetrieval::~DataRetrieval() 55{ 56} 57 58 59void DataRetrieval::returnData(KeyHandle &hKey, RecordHandle &hRecord, 60 void *&outData, mach_msg_type_number_t &outDataLength, 61 CssmDbRecordAttributeData *&outAttributes, mach_msg_type_number_t &outAttributesLength, 62 CssmDbRecordAttributeData *&outAttributesBase) 63{ 64 Copier<CssmDbRecordAttributeData> outCopy(CssmDbRecordAttributeData::overlay(this->attributes)); 65 outAttributesLength = outCopy.length(); 66 outAttributes = outAttributesBase = outCopy.keep(); 67 if (this->data) { 68 outData = this->data->Data; 69 outDataLength = this->data->Length; 70 } else { 71 outData = NULL; 72 outDataLength = 0; 73 } 74 75 /* 76 "record" and "keyhandle" below come from the underlying TOKEND_RETURN_DATA, 77 and are native-sized quantities. These need to be converted to a client 78 handle (32 bit) 79 */ 80 81 hKey = (this->keyhandle)?TokendHandleObject::make(this->keyhandle)->ipcHandle():0; 82 hRecord = (this->record)?TokendHandleObject::make(this->record)->ipcHandle():0; 83 84 server->freeRetrievedData(this); 85 //@@@ deferred-release outAttributes == Copier 86} 87 88/* 89 Cheat sheet 90 91 CSSM_HANDLE 92 - native size, 64 bit or 32 bit 93 - passed along to Tokend e.g. Tokend::Token::_findRecordHandle 94 - passed e.g. as CALL(findNext, ...) 95 96 RecordHandle & SearchHandle 97 - always 32 bit 98 - returned to callers through SecurityTokend interface 99*/ 100 101TokendHandleObject::TokendHandleObject(CSSM_HANDLE cssmh) : mTokendHandle(cssmh) 102{ 103 thmstate().add(ipcHandle(), this); 104} 105 106TokendHandleObject::~TokendHandleObject() 107{ 108 thmstate().erase(ipcHandle()); 109} 110 111 112ModuleNexus<TokendHandleObject::TokendHandleMapState> TokendHandleObject::thmstate; 113 114TokendHandleObject::TokendHandleMapState::TokendHandleMapState() 115{ 116} 117 118// static factory method 119TokendHandleObject *TokendHandleObject::make(CSSM_HANDLE cssmh) 120{ 121 // This will create a new TokendHandleObject, add it to the map, and return 122 // the value of the newly created object 123 if (!cssmh) 124 CssmError::throwMe(CSSMERR_CSSM_INVALID_ADDIN_HANDLE); 125 return new TokendHandleObject(cssmh); 126} 127 128// static method 129CSSM_HANDLE TokendHandleObject::findTDHandle(TokendHandleObject::TransitHandle thdl) 130{ 131 /* 132 Find a handle that we can pass along to tokend. We do this so that Tokend 133 can return different errors for different calls -- even if we don't find 134 it in our map, we will still call out to Tokend. It might be better to 135 use a distinctive non-zero value for the bad handle for tracking 136 */ 137 const CSSM_HANDLE knownBadHandle = 0; // for now 138 139 if (!thdl) 140 return knownBadHandle; 141 142 TokendHandleMap::const_iterator it = thmstate().find(thdl); 143 return (it == thmstate().end()) ? knownBadHandle : it->second->tokendHandle(); 144} 145 146void TokendHandleObject::TokendHandleMapState::add(TransitHandle thdl, TokendHandleObject *tho) 147{ 148 StLock<Mutex> _(*this); 149 thmstate().insert(thmstate().end(), make_pair(thdl,tho)); 150} 151 152void TokendHandleObject::TokendHandleMapState::erase(TransitHandle thdl) 153{ 154 StLock<Mutex> _(*this); 155 // @@@ check cssmh, don't erase if not valid 156 TokendHandleMap::erase(thdl); 157} 158 159} // namespace Tokend 160} // namespace Security 161 162