X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/80e2389990082500d76eb566d4946be3e786c3ef..d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb:/Security/libsecurity_cdsa_client/lib/cspclient.h diff --git a/Security/libsecurity_cdsa_client/lib/cspclient.h b/Security/libsecurity_cdsa_client/lib/cspclient.h new file mode 100644 index 00000000..67c35d70 --- /dev/null +++ b/Security/libsecurity_cdsa_client/lib/cspclient.h @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2000-2002,2011-2012,2014 Apple Inc. All Rights Reserved. + * + * The contents of this file constitute Original Code as defined in and are + * subject to the Apple Public Source License Version 1.2 (the 'License'). + * You may not use this file except in compliance with the License. Please obtain + * a copy of the License at http://www.apple.com/publicsource and read it before + * using this file. + * + * This Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS + * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT + * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the + * specific language governing rights and limitations under the License. + */ + + +// +// cspclient - client interface to CSSM CSPs and their operations +// +#ifndef _H_CDSA_CLIENT_CSPCLIENT +#define _H_CDSA_CLIENT_CSPCLIENT 1 + +#include +#include +#include + +namespace Security { +namespace CssmClient { + + +// +// A CSP attachment +// +class CSPImpl : public AttachmentImpl +{ +public: + CSPImpl(const Guid &guid); + CSPImpl(const Module &module); + virtual ~CSPImpl(); + + // the least inappropriate place for this one + void freeKey(CssmKey &key, const AccessCredentials *cred = NULL, bool permanent = false); +}; + +class CSP : public Attachment +{ +public: + typedef CSPImpl Impl; + + explicit CSP(Impl *impl) : Attachment(impl) {} + CSP(const Guid &guid) : Attachment(new Impl(guid)) {} + CSP(const Module &module) : Attachment(new Impl(module)) {} + + Impl *operator ->() const { return &impl(); } + Impl &operator *() const { return impl(); } +}; + +// +// A cryptographic context. +// Contexts always belong to CSPs (CSP attachments). +// +class Context : public ObjectImpl +{ +public: + Context(const CSP &csp, CSSM_ALGORITHMS alg = CSSM_ALGID_NONE); + ~Context(); + + CSP attachment() const { return parent(); } + Module module() const { return attachment()->module(); } + + CSSM_ALGORITHMS algorithm() const { return mAlgorithm; } + void algorithm(CSSM_ALGORITHMS alg); + + const AccessCredentials *cred() const { return mCred; } + void cred(const CSSM_ACCESS_CREDENTIALS *cred); + void cred(const CSSM_ACCESS_CREDENTIALS &cred) { this->cred(&cred); } + +public: + CSSM_CC_HANDLE handle() { activate(); return mHandle; } + + uint32 getOutputSize(uint32 inputSize, bool encrypt = true); + void getOutputSize(CSSM_QUERY_SIZE_DATA &sizes, uint32 count, bool encrypt = true); + +public: + // don't use this section unless you know what you're doing! + void override(const ::Context &ctx); + + template + void set(CSSM_ATTRIBUTE_TYPE type, const T &value) + { + if (isActive()) { + ::Context::Attr attr(type, value); + check(CSSM_UpdateContextAttributes(mHandle, 1, &attr)); + } + } + + void set(CSSM_ATTRIBUTE_TYPE type, uint32 value) + { + if (isActive()) { + ::Context::Attr attr(type, value); + check(CSSM_UpdateContextAttributes(mHandle, 1, &attr)); + } + } + + template + void add(CSSM_ATTRIBUTE_TYPE type, const T &value) + { activate(); set(type, value); } + + void add(CSSM_ATTRIBUTE_TYPE type, uint32 value) + { activate(); set(type, value); } + +protected: + void deactivate(); + + virtual void init(); // Subclasses must implement if they support staged operations. + + void unstaged() + { activate(); if (mStaged) CssmError::throwMe(CSSMERR_CSP_STAGED_OPERATION_IN_PROGRESS); } + + void staged() + { if (!mStaged) init(); } + + const AccessCredentials *neededCred() + { return AccessCredentials::needed(mCred); } + +protected: + CSSM_ALGORITHMS mAlgorithm; // intended algorithm + CSSM_CC_HANDLE mHandle; // CSSM CC handle + bool mStaged; // staged in progress + const AccessCredentials *mCred; // if explicitly set + RecursiveMutex mActivateMutex; +}; + + +// +// An RccBearer holds a ResourceControlContext. Note that this is a composite +// of an AccessCredentials and an AclEntryInput. We allow setting the whole +// thing, or its two components separately. A complete rcc set (via ::rcc) +// overrides any components. +// @@@ Perhaps we should merge components into a specified rcc? Iffy, though... +// Note: We call the credential components "opCred" to distinguish it from +// the "cred" of a CredBearer; some classes are both. As a rule, the "cred" goes +// into the context, while the "opCred" gets passed as an argument. +// +class RccBearer { +public: + RccBearer() : mOpCred(NULL), mOwner(NULL), mRcc(NULL) { } + + const AccessCredentials *opCred() const { return mOpCred; } + void opCred(const CSSM_ACCESS_CREDENTIALS *cred) { mOpCred = AccessCredentials::overlay(cred); } + void opCred(const CSSM_ACCESS_CREDENTIALS &cred) { this->opCred(&cred); } + const AclEntryInput *owner() const { return mOwner; } + void owner(const CSSM_ACL_ENTRY_INPUT *owner) { mOwner = AclEntryInput::overlay(owner); } + void owner(const CSSM_ACL_ENTRY_INPUT &owner) { this->owner(&owner); } + void owner(const CSSM_ACL_ENTRY_PROTOTYPE *owner); + void owner(const CSSM_ACL_ENTRY_PROTOTYPE &owner) { this->owner(&owner); } + const ResourceControlContext *rcc() const { return mRcc; } + void rcc(const CSSM_RESOURCE_CONTROL_CONTEXT *rcc) + { mRcc = ResourceControlContext::overlay(rcc); } + void rcc(const CSSM_RESOURCE_CONTROL_CONTEXT &rcc) { this->rcc(&rcc); } + +protected: + const ResourceControlContext &compositeRcc() const; + +private: + // an RCC contains both a cred and entryInput + // mCred/mAcl are only considered if mRcc is not set (NULL) + const AccessCredentials *mOpCred; + const AclEntryInput *mOwner; + const ResourceControlContext *mRcc; + + mutable ResourceControlContext mWorkRcc; // work area + mutable AclEntryInput mWorkInput; // work area +}; + + +// +// A PassThough context +// +class PassThrough : public Context +{ +public: + PassThrough(const CSP &csp) : Context(csp) { } + +public: + void operator () (uint32 passThroughId, const void *inData, void **outData); + + template + void operator () (uint32 passThroughId, const TIn *inData, TOut **outData) + { operator () (passThroughId, (const void *)inData, (void **)outData); } + + template + void operator () (uint32 passThroughId, const TIn *inData) + { operator () (passThroughId, (const void *)inData, NULL); } + + const CSSM_KEY *key() const { return mKey; } + void key(const CSSM_KEY *k) { mKey = k; set(CSSM_ATTRIBUTE_KEY, k); } + +protected: + void activate(); + +protected: + const CSSM_KEY *mKey; +}; + + +// +// A Digest context +// +class Digest : public Context +{ +public: + Digest(const CSP &csp, CSSM_ALGORITHMS alg) : Context(csp, alg) { } + +public: + // integrated + void digest(const CssmData &data, CssmData &digest) { this->digest(&data, 1, digest); } + void digest(const CssmData *data, uint32 count, CssmData &digest); + + // staged + void digest(const CssmData &data) { digest(&data, 1); } + void digest(const CssmData *data, uint32 count); + void operator () (CssmData &digest); + CssmData operator () () { CssmData digest; (*this)(digest); return digest; } + +protected: + void activate(); +}; + + +// +// A [P]RNG context +// +class Random : public Context +{ +public: + Random(const CSP &csp, CSSM_ALGORITHMS alg) : Context(csp, alg), mSeed(NULL), mSize(1) { } + Random(const CSP &csp, CSSM_ALGORITHMS alg, const CssmCryptoData &seed) + : Context(csp, alg), mSeed(&seed), mSize(1) { } + Random(const CSP &csp, CSSM_ALGORITHMS alg, uint32 size) + : Context(csp, alg), mSeed(NULL), mSize(size) { } + Random(const CSP &csp, CSSM_ALGORITHMS alg, const CssmCryptoData &seed, uint32 size) + : Context(csp, alg), mSeed(&seed), mSize(size) { } + + void seed(const CssmCryptoData &data); + void size(uint32 size); + +public: + void generate(CssmData &data, uint32 size = 0); + + // alternate function-call form + CssmData operator () (uint32 size = 0) + { CssmData output; generate(output, size); return output; } + +protected: + void activate(); + +private: + const CssmCryptoData *mSeed; + uint32 mSize; +}; + + +} // end namespace CssmClient +} // end namespace Security + +#endif // _H_CDSA_CLIENT_CSPCLIENT