X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/72a12576750f52947eb043106ba5c12c0d07decf..b1ab9ed8d0e0f1c3b66d7daa8fd5564444c56195:/libsecurity_cdsa_client/lib/cssmclient.h diff --git a/libsecurity_cdsa_client/lib/cssmclient.h b/libsecurity_cdsa_client/lib/cssmclient.h new file mode 100644 index 00000000..b6b2f321 --- /dev/null +++ b/libsecurity_cdsa_client/lib/cssmclient.h @@ -0,0 +1,375 @@ +/* + * Copyright (c) 2000-2001 Apple Computer, 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. + */ + + +// +// cssmclient - common client interface to CSSM and MDS +// +#ifndef _H_CDSA_CLIENT_CSSMCLIENT +#define _H_CDSA_CLIENT_CSSMCLIENT 1 + +#include +#include +#include +#include +#include +#include + +namespace Security { +namespace CssmClient { + + +// +// Forward declarations +// +class Cssm; +class Module; +class Attachment; + + +// +// An mixin for objects that have (store) GUIDs. +// The GUID value is meant to be set-once constant, and can be lock-handled accordingly. +// +class HasGuid { +public: + HasGuid(const Guid &guid) { mGuid = guid; } + HasGuid() { } + + const Guid &guid() const { return mGuid; } + +protected: + void setGuid(const Guid &guid) { mGuid = guid; } + +private: + Guid mGuid; +}; + + +// +// Exceptions are based on the CssmError utility class. We add our own class of client-side exceptions. +// +class Error : public CssmError { +public: + Error(CSSM_RETURN err) : CssmError(err) { } + virtual const char *what () const throw(); + + enum { + objectBusy = -1, + }; +}; + + +// +// The CssmObject abstract class models features common to different Cssm objects. +// It handles a tree hierarchy of objects (parent/children) safely. +// +class Object; + +class ObjectImpl : virtual public RefCount +{ +public: + explicit ObjectImpl(); // Constructor for Impl objects without a parent. + explicit ObjectImpl(const Object &parent); + virtual ~ObjectImpl(); + + bool isActive() const { return mActive; } + + virtual Allocator &allocator() const; + virtual void allocator(Allocator &alloc); + + // Pointer comparison by default. Subclasses may override. + virtual bool operator <(const ObjectImpl &other) const; + virtual bool operator ==(const ObjectImpl &other) const; + + static void check(CSSM_RETURN status); + +protected: + bool mActive; // loaded, attached, etc. + mutable Allocator *mAllocator; // allocator hierarchy (NULL => TBD) + + template Obj parent() const + { assert(mParent); return Obj(static_cast(&(*mParent))); } + + void addChild(); + void removeChild(); + bool isIdle() const { return mChildCount == 0; } + + // {de,}activate() assume you have locked *this + virtual void activate() = 0; + virtual void deactivate() = 0; + +private: + RefPointer mParent; // parent object + AtomicCounter mChildCount; +}; + + +class Object +{ + friend class ObjectImpl; +public: + typedef ObjectImpl Impl; + explicit Object(Impl *impl) : mImpl(impl) {} + +protected: + // @@@ CSPDL subclass breaks if the is a static_cast + template _Impl &impl() const + { return dynamic_cast<_Impl &>(*mImpl); } + +public: + Impl *operator ->() const { return &(*mImpl); } + Impl &operator *() const { return *mImpl; } + + // @@@ Why is this needed. DbCursor which inheirits from Object wants to call this. + template _Impl &checkedImpl() const + { return dynamic_cast<_Impl &>(*mImpl); } + + bool operator !() const { return !mImpl; } + operator bool() const { return mImpl; } + + bool isActive() const { return mImpl && mImpl->isActive(); } + Allocator &allocator() const { return mImpl->allocator(); } + void release() { mImpl = NULL; } + + bool operator <(const Object &other) const + { return mImpl && other.mImpl ? *mImpl < *other.mImpl : mImpl < other.mImpl; } + bool operator ==(const Object &other) const + { return mImpl && other.mImpl ? *mImpl == *other.mImpl : mImpl == other.mImpl; } + +private: + RefPointer mImpl; +}; + + +// +// Event callback mix-in class +// +class ModuleImpl; + +class RawModuleEvents { + friend class ModuleImpl; +public: + virtual ~RawModuleEvents(); + + virtual void notify(uint32 subService, + CSSM_SERVICE_TYPE type, CSSM_MODULE_EVENT event) = 0; + +private: + static CSSM_RETURN sendNotify(const CSSM_GUID *, void *context, uint32 subService, + CSSM_SERVICE_TYPE type, CSSM_MODULE_EVENT event); +}; + +class ModuleEvents : public RawModuleEvents { +public: + virtual void insertion(uint32 subService, CSSM_SERVICE_TYPE type); + virtual void removal(uint32 subService, CSSM_SERVICE_TYPE type); + virtual void fault(uint32 subService, CSSM_SERVICE_TYPE type); + +protected: + void notify(uint32 subService, CSSM_SERVICE_TYPE type, CSSM_MODULE_EVENT event); +}; + + +// +// A CSSM loadable module. +// You rarely directly interact with these objects, but if you need to, +// here they are. +// +class ModuleImpl : public ObjectImpl, public HasGuid +{ +public: + ModuleImpl(const Guid &guid); + ModuleImpl(const Guid &guid, const Cssm &session); + virtual ~ModuleImpl(); + + void load() { activate(); } + void unload() { deactivate(); } + bool isLoaded() const { return isActive(); } + + Cssm session() const; + + void appNotifyCallback(CSSM_API_ModuleEventHandler appNotifyCallback, void *appNotifyCallbackCtx); + void appNotifyCallback(RawModuleEvents *handler); + +protected: + void activate(); + void deactivate(); + + CSSM_API_ModuleEventHandler mAppNotifyCallback; + void *mAppNotifyCallbackCtx; +}; + +class Module : public Object +{ +public: + typedef ModuleImpl Impl; + explicit Module(Impl *impl) : Object(impl) {} + Module() : Object(NULL) {} // XXX This might break operator < + Module(const Guid &guid) : Object(new Impl(guid)) {} + Module(const Guid &guid, const Cssm &session) : Object(new Impl(guid, session)) {} + + Impl *operator ->() const { return &impl(); } + Impl &operator *() const { return impl(); } +}; + + +// +// An Attachment object. This is the base class of all typed attachment classes. +// +class AttachmentImpl : public ObjectImpl +{ +public: + AttachmentImpl(const Guid &guid, CSSM_SERVICE_TYPE subserviceType); + AttachmentImpl(const Module &module, CSSM_SERVICE_TYPE subserviceType); + //AttachmentImpl(... mds reference ...); + virtual ~AttachmentImpl(); + + // Virtual so that subclasses can return there true mask. + virtual CSSM_SERVICE_MASK subserviceMask() const; + + CSSM_SERVICE_TYPE subserviceType() const { return mSubserviceType; } + CSSM_VERSION version() const { return mVersion; } + void version(const CSSM_VERSION &v) { mVersion = v; } + uint32 subserviceId() const { return mSubserviceId; } + virtual void subserviceId(uint32 id); + CSSM_ATTACH_FLAGS flags() const { return mAttachFlags; } + void flags(CSSM_ATTACH_FLAGS f) { mAttachFlags = f; } + + void attach() { activate(); } + void detach() { deactivate(); } + bool attached() const { return isActive(); } + + Module module() const; + const Guid &guid() const { return module()->guid(); } + CSSM_MODULE_HANDLE handle() { attach(); return mHandle; } + + CssmSubserviceUid subserviceUid() const; + +protected: + void activate(); + void deactivate(); + +private: + void make(CSSM_SERVICE_TYPE subserviceType); // common constructor + + CSSM_MODULE_HANDLE mHandle; + + CSSM_SERVICE_TYPE mSubserviceType; // set by constructor + CSSM_VERSION mVersion; + uint32 mSubserviceId; + CSSM_ATTACH_FLAGS mAttachFlags; + + CssmAllocatorMemoryFunctions mMemoryFunctions; // set on attach() +}; + +class Attachment : public Object +{ +public: + typedef AttachmentImpl Impl; + explicit Attachment(Impl *impl) : Object(impl) {} + Attachment(const Guid &guid, CSSM_SERVICE_TYPE subserviceType) + : Object(new Impl(guid, subserviceType)) {} + Attachment(const Module &module, CSSM_SERVICE_TYPE subserviceType) + : Object(new Impl(module, subserviceType)) {} + //Attachment(... mds reference ...); + + Impl *operator ->() const { return &impl(); } + Impl &operator *() const { return impl(); } +}; + + +// +// A CSSM session object. +// You usually only have one per program, or library, or what-not. +// +class Cssm; + +class CssmImpl : public ObjectImpl { + class StandardCssm; friend class StandardCssm; +public: + CssmImpl(); + virtual ~CssmImpl(); + + void init() { activate(); } + void terminate() { deactivate(); } + + CSSM_PRIVILEGE_SCOPE scope() const { return mScope; } + void scope(CSSM_PRIVILEGE_SCOPE sc) { mScope = sc; } + const Guid &callerGuid() const { return mCallerGuid; } + void callerGuid(const CSSM_GUID &guid) { mCallerGuid = Guid::overlay(guid); } + + Module autoModule(const Guid &guid); + +protected: + explicit CssmImpl(bool); // internal constructor + + void setup(); // constructor setup + + void activate(); + void deactivate(); + +private: + // CSSM global configuration -- picked up on each Init + CSSM_VERSION mVersion; + CSSM_PRIVILEGE_SCOPE mScope; + Guid mCallerGuid; + + // module repository: modules by guid (protected by self) + typedef map ModuleMap; + ModuleMap moduleMap; + Mutex mapLock; + +public: + static Cssm standard(); + static void catchExit(); + +private: + static void atExitHandler(); + + class StandardCssm : public Mutex { + public: + StandardCssm() : mCssm(NULL) { } + ~StandardCssm(); + void setCssm(CssmImpl *cssm); + void unsetCssm(CssmImpl *cssm); + CssmImpl *get(); + + private: + CssmImpl *mCssm; + }; + static ModuleNexus mStandard; +}; + +class Cssm : public Object +{ +public: + typedef CssmImpl Impl; + explicit Cssm(Impl *impl) : Object(impl) {} + explicit Cssm() : Object(new Impl()) {} + + Impl *operator ->() const { return &impl(); } + Impl &operator *() const { return impl(); } + + static Cssm standard() { return CssmImpl::standard(); } +}; + +} // end namespace CssmClient + +} // end namespace Security + +#endif // _H_CDSA_CLIENT_CSSMCLIENT