1/* 2 * Copyright (c) 2000-2002,2011-2012,2014 Apple Inc. All Rights Reserved. 3 * 4 * The contents of this file constitute Original Code as defined in and are 5 * subject to the Apple Public Source License Version 1.2 (the 'License'). 6 * You may not use this file except in compliance with the License. Please obtain 7 * a copy of the License at http://www.apple.com/publicsource and read it before 8 * using this file. 9 * 10 * This Original Code and all software distributed under the License are 11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS 12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT 13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the 15 * specific language governing rights and limitations under the License. 16 */ 17 18 19// 20// cspclient - client interface to CSSM CSPs and their operations 21// 22#ifndef _H_CDSA_CLIENT_CSPCLIENT 23#define _H_CDSA_CLIENT_CSPCLIENT 1 24 25#include <security_cdsa_client/cssmclient.h> 26#include <security_cdsa_utilities/context.h> 27#include <security_cdsa_utilities/cssmacl.h> 28 29namespace Security { 30namespace CssmClient { 31 32 33// 34// A CSP attachment 35// 36class CSPImpl : public AttachmentImpl 37{ 38public: 39 CSPImpl(const Guid &guid); 40 CSPImpl(const Module &module); 41 virtual ~CSPImpl(); 42 43 // the least inappropriate place for this one 44 void freeKey(CssmKey &key, const AccessCredentials *cred = NULL, bool permanent = false); 45}; 46 47class CSP : public Attachment 48{ 49public: 50 typedef CSPImpl Impl; 51 52 explicit CSP(Impl *impl) : Attachment(impl) {} 53 CSP(const Guid &guid) : Attachment(new Impl(guid)) {} 54 CSP(const Module &module) : Attachment(new Impl(module)) {} 55 56 Impl *operator ->() const { return &impl<Impl>(); } 57 Impl &operator *() const { return impl<Impl>(); } 58}; 59 60// 61// A cryptographic context. 62// Contexts always belong to CSPs (CSP attachments). 63// 64class Context : public ObjectImpl 65{ 66public: 67 Context(const CSP &csp, CSSM_ALGORITHMS alg = CSSM_ALGID_NONE); 68 ~Context(); 69 70 CSP attachment() const { return parent<CSP>(); } 71 Module module() const { return attachment()->module(); } 72 73 CSSM_ALGORITHMS algorithm() const { return mAlgorithm; } 74 void algorithm(CSSM_ALGORITHMS alg); 75 76 const AccessCredentials *cred() const { return mCred; } 77 void cred(const CSSM_ACCESS_CREDENTIALS *cred); 78 void cred(const CSSM_ACCESS_CREDENTIALS &cred) { this->cred(&cred); } 79 80public: 81 CSSM_CC_HANDLE handle() { activate(); return mHandle; } 82 83 uint32 getOutputSize(uint32 inputSize, bool encrypt = true); 84 void getOutputSize(CSSM_QUERY_SIZE_DATA &sizes, uint32 count, bool encrypt = true); 85 86public: 87 // don't use this section unless you know what you're doing! 88 void override(const ::Context &ctx); 89 90 template <class T> 91 void set(CSSM_ATTRIBUTE_TYPE type, const T &value) 92 { 93 if (isActive()) { 94 ::Context::Attr attr(type, value); 95 check(CSSM_UpdateContextAttributes(mHandle, 1, &attr)); 96 } 97 } 98 99 void set(CSSM_ATTRIBUTE_TYPE type, uint32 value) 100 { 101 if (isActive()) { 102 ::Context::Attr attr(type, value); 103 check(CSSM_UpdateContextAttributes(mHandle, 1, &attr)); 104 } 105 } 106 107 template <class T> 108 void add(CSSM_ATTRIBUTE_TYPE type, const T &value) 109 { activate(); set(type, value); } 110 111 void add(CSSM_ATTRIBUTE_TYPE type, uint32 value) 112 { activate(); set(type, value); } 113 114protected: 115 void deactivate(); 116 117 virtual void init(); // Subclasses must implement if they support staged operations. 118 119 void unstaged() 120 { activate(); if (mStaged) CssmError::throwMe(CSSMERR_CSP_STAGED_OPERATION_IN_PROGRESS); } 121 122 void staged() 123 { if (!mStaged) init(); } 124 125 const AccessCredentials *neededCred() 126 { return AccessCredentials::needed(mCred); } 127 128protected: 129 CSSM_ALGORITHMS mAlgorithm; // intended algorithm 130 CSSM_CC_HANDLE mHandle; // CSSM CC handle 131 bool mStaged; // staged in progress 132 const AccessCredentials *mCred; // if explicitly set 133 RecursiveMutex mActivateMutex; 134}; 135 136 137// 138// An RccBearer holds a ResourceControlContext. Note that this is a composite 139// of an AccessCredentials and an AclEntryInput. We allow setting the whole 140// thing, or its two components separately. A complete rcc set (via ::rcc) 141// overrides any components. 142// @@@ Perhaps we should merge components into a specified rcc? Iffy, though... 143// Note: We call the credential components "opCred" to distinguish it from 144// the "cred" of a CredBearer; some classes are both. As a rule, the "cred" goes 145// into the context, while the "opCred" gets passed as an argument. 146// 147class RccBearer { 148public: 149 RccBearer() : mOpCred(NULL), mOwner(NULL), mRcc(NULL) { } 150 151 const AccessCredentials *opCred() const { return mOpCred; } 152 void opCred(const CSSM_ACCESS_CREDENTIALS *cred) { mOpCred = AccessCredentials::overlay(cred); } 153 void opCred(const CSSM_ACCESS_CREDENTIALS &cred) { this->opCred(&cred); } 154 const AclEntryInput *owner() const { return mOwner; } 155 void owner(const CSSM_ACL_ENTRY_INPUT *owner) { mOwner = AclEntryInput::overlay(owner); } 156 void owner(const CSSM_ACL_ENTRY_INPUT &owner) { this->owner(&owner); } 157 void owner(const CSSM_ACL_ENTRY_PROTOTYPE *owner); 158 void owner(const CSSM_ACL_ENTRY_PROTOTYPE &owner) { this->owner(&owner); } 159 const ResourceControlContext *rcc() const { return mRcc; } 160 void rcc(const CSSM_RESOURCE_CONTROL_CONTEXT *rcc) 161 { mRcc = ResourceControlContext::overlay(rcc); } 162 void rcc(const CSSM_RESOURCE_CONTROL_CONTEXT &rcc) { this->rcc(&rcc); } 163 164protected: 165 const ResourceControlContext &compositeRcc() const; 166 167private: 168 // an RCC contains both a cred and entryInput 169 // mCred/mAcl are only considered if mRcc is not set (NULL) 170 const AccessCredentials *mOpCred; 171 const AclEntryInput *mOwner; 172 const ResourceControlContext *mRcc; 173 174 mutable ResourceControlContext mWorkRcc; // work area 175 mutable AclEntryInput mWorkInput; // work area 176}; 177 178 179// 180// A PassThough context 181// 182class PassThrough : public Context 183{ 184public: 185 PassThrough(const CSP &csp) : Context(csp) { } 186 187public: 188 void operator () (uint32 passThroughId, const void *inData, void **outData); 189 190 template <class TIn, class TOut> 191 void operator () (uint32 passThroughId, const TIn *inData, TOut **outData) 192 { operator () (passThroughId, (const void *)inData, (void **)outData); } 193 194 template <class TIn> 195 void operator () (uint32 passThroughId, const TIn *inData) 196 { operator () (passThroughId, (const void *)inData, NULL); } 197 198 const CSSM_KEY *key() const { return mKey; } 199 void key(const CSSM_KEY *k) { mKey = k; set(CSSM_ATTRIBUTE_KEY, k); } 200 201protected: 202 void activate(); 203 204protected: 205 const CSSM_KEY *mKey; 206}; 207 208 209// 210// A Digest context 211// 212class Digest : public Context 213{ 214public: 215 Digest(const CSP &csp, CSSM_ALGORITHMS alg) : Context(csp, alg) { } 216 217public: 218 // integrated 219 void digest(const CssmData &data, CssmData &digest) { this->digest(&data, 1, digest); } 220 void digest(const CssmData *data, uint32 count, CssmData &digest); 221 222 // staged 223 void digest(const CssmData &data) { digest(&data, 1); } 224 void digest(const CssmData *data, uint32 count); 225 void operator () (CssmData &digest); 226 CssmData operator () () { CssmData digest; (*this)(digest); return digest; } 227 228protected: 229 void activate(); 230}; 231 232 233// 234// A [P]RNG context 235// 236class Random : public Context 237{ 238public: 239 Random(const CSP &csp, CSSM_ALGORITHMS alg) : Context(csp, alg), mSeed(NULL), mSize(1) { } 240 Random(const CSP &csp, CSSM_ALGORITHMS alg, const CssmCryptoData &seed) 241 : Context(csp, alg), mSeed(&seed), mSize(1) { } 242 Random(const CSP &csp, CSSM_ALGORITHMS alg, uint32 size) 243 : Context(csp, alg), mSeed(NULL), mSize(size) { } 244 Random(const CSP &csp, CSSM_ALGORITHMS alg, const CssmCryptoData &seed, uint32 size) 245 : Context(csp, alg), mSeed(&seed), mSize(size) { } 246 247 void seed(const CssmCryptoData &data); 248 void size(uint32 size); 249 250public: 251 void generate(CssmData &data, uint32 size = 0); 252 253 // alternate function-call form 254 CssmData operator () (uint32 size = 0) 255 { CssmData output; generate(output, size); return output; } 256 257protected: 258 void activate(); 259 260private: 261 const CssmCryptoData *mSeed; 262 uint32 mSize; 263}; 264 265 266} // end namespace CssmClient 267} // end namespace Security 268 269#endif // _H_CDSA_CLIENT_CSPCLIENT 270