/* * 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. */ // // keyclient // #include #include #include #include #include namespace Security { namespace CssmClient { static inline void check(CSSM_RETURN rc) { ObjectImpl::check(rc); } // // AclBearer methods (trivial) // AclBearer::~AclBearer() { } // // Variant forms of AclBearer implemented in terms of its canonical virtual methods // void AclBearer::addAcl(const AclEntryInput &input, const CSSM_ACCESS_CREDENTIALS *cred) { changeAcl(AclEdit(input), cred); } void AclBearer::changeAcl(CSSM_ACL_HANDLE handle, const AclEntryInput &input, const CSSM_ACCESS_CREDENTIALS *cred) { changeAcl(AclEdit(handle, input), cred); } void AclBearer::deleteAcl(CSSM_ACL_HANDLE handle, const CSSM_ACCESS_CREDENTIALS *cred) { changeAcl(AclEdit(handle), cred); } void AclBearer::deleteAcl(const char *tag, const CSSM_ACCESS_CREDENTIALS *cred) { AutoAclEntryInfoList entries; getAcl(entries, tag); for (uint32 n = 0; n < entries.count(); n++) deleteAcl(entries[n].handle(), cred); } // // KeyAclBearer implementation // void KeyAclBearer::getAcl(AutoAclEntryInfoList &aclInfos, const char *selectionTag) const { aclInfos.allocator(allocator); check(CSSM_GetKeyAcl(csp, &key, reinterpret_cast(selectionTag), aclInfos, aclInfos)); } void KeyAclBearer::changeAcl(const CSSM_ACL_EDIT &aclEdit, const CSSM_ACCESS_CREDENTIALS *cred) { check(CSSM_ChangeKeyAcl(csp, AccessCredentials::needed(cred), &aclEdit, &key)); } void KeyAclBearer::getOwner(AutoAclOwnerPrototype &owner) const { owner.allocator(allocator); check(CSSM_GetKeyOwner(csp, &key, owner)); } void KeyAclBearer::changeOwner(const CSSM_ACL_OWNER_PROTOTYPE &newOwner, const CSSM_ACCESS_CREDENTIALS *cred) { check(CSSM_ChangeKeyOwner(csp, AccessCredentials::needed(cred), &key, &newOwner)); } // // A single global structure containing pseudo-static data // struct Statics { Statics(); Allocator &alloc; AutoCredentials nullCred; AutoCredentials promptCred; AutoCredentials unlockCred; AclOwnerPrototype anyOwner; AclEntryInfo anyAcl; }; namespace { ModuleNexus statics; } // // Make pseudo-statics. // Note: This is an eternal object. It is not currently destroyed // if the containing code is unloaded. // Statics::Statics() : alloc(Allocator::standard()), nullCred(alloc, 1), promptCred(alloc, 3), unlockCred(alloc, 1), anyOwner(TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_ANY)), anyAcl(AclEntryPrototype(TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_ANY), 1)) { // nullCred: nothing at all // contains: // an empty THRESHOLD sample to match threshold subjects with "free" subjects nullCred.sample(0) = TypedList(alloc, CSSM_SAMPLE_TYPE_THRESHOLD); // promptCred: a credential permitting user prompt confirmations // contains: // a KEYCHAIN_PROMPT sample, both by itself and in a THRESHOLD // a PROMPTED_PASSWORD sample promptCred.sample(0) = TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT); promptCred.sample(1) = TypedList(alloc, CSSM_SAMPLE_TYPE_THRESHOLD, new(alloc) ListElement(TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT))); promptCred.sample(2) = TypedList(alloc, CSSM_SAMPLE_TYPE_PROMPTED_PASSWORD, new(alloc) ListElement(alloc, CssmData())); // unlockCred: ??? unlockCred.sample(0) = TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK, new(alloc) ListElement(CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT)); } // // Make and break AclFactories // AclFactory::AclFactory() { } AclFactory::~AclFactory() { } // // Return basic pseudo-static values // const AccessCredentials *AclFactory::nullCred() const { return &statics().nullCred; } const AccessCredentials *AclFactory::promptCred() const { return &statics().promptCred; } const AccessCredentials *AclFactory::unlockCred() const { return &statics().unlockCred; } // // Manage the (pseudo) credentials used to explicitly provide a passphrase to a keychain. // Use the eternal unlockCred() for normal (protected prompt) unlocking. // AclFactory::KeychainCredentials::~KeychainCredentials () { DataWalkers::chunkFree(mCredentials, allocator); } AclFactory::PassphraseUnlockCredentials::PassphraseUnlockCredentials (const CssmData& password, Allocator& allocator) : KeychainCredentials(allocator) { mCredentials->sample(0) = TypedList(allocator, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK, new (allocator) ListElement (CSSM_SAMPLE_TYPE_PASSWORD), new (allocator) ListElement (CssmAutoData(allocator, password).release())); } // // Manage the (pseudo) credentials used to explicitly change a keychain's passphrase // AclFactory::PasswordChangeCredentials::PasswordChangeCredentials (const CssmData& password, Allocator& allocator) : KeychainCredentials(allocator) { mCredentials->sample(0) = TypedList(allocator, CSSM_SAMPLE_TYPE_KEYCHAIN_CHANGE_LOCK, new (allocator) ListElement (CSSM_SAMPLE_TYPE_PASSWORD), new (allocator) ListElement (CssmAutoData(allocator, password).release())); } // // Wide open ("ANY") CSSM forms for owner and ACL entry // const AclOwnerPrototype &AclFactory::anyOwner() const { return statics().anyOwner; } const AclEntryInfo &AclFactory::anyAcl() const { return statics().anyAcl; } // // Create an ANY style AclEntryInput. // This can be used to explicitly request wide-open authorization on a new CSSM object. // AclFactory::AnyResourceContext::AnyResourceContext(const CSSM_ACCESS_CREDENTIALS *cred) : mAny(CSSM_ACL_SUBJECT_TYPE_ANY), mTag(CSSM_ACL_AUTHORIZATION_ANY) { // set up an ANY/EVERYTHING AclEntryInput input().proto().subject() += &mAny; AuthorizationGroup &authGroup = input().proto().authorization(); authGroup.NumberOfAuthTags = 1; authGroup.AuthTags = &mTag; // install the cred (not copied) credentials(cred); } // // CSSM ACL makers // AclFactory::Subject::Subject(Allocator &alloc, CSSM_ACL_SUBJECT_TYPE type) : TypedList(alloc, type) { } AclFactory::PWSubject::PWSubject(Allocator &alloc) : Subject(alloc, CSSM_ACL_SUBJECT_TYPE_PASSWORD) { } AclFactory::PWSubject::PWSubject(Allocator &alloc, const CssmData &secret) : Subject(alloc, CSSM_ACL_SUBJECT_TYPE_PASSWORD) { append(new(alloc) ListElement(alloc, secret)); } AclFactory::PromptPWSubject::PromptPWSubject(Allocator &alloc, const CssmData &prompt) : Subject(alloc, CSSM_ACL_SUBJECT_TYPE_PROMPTED_PASSWORD) { append(new(alloc) ListElement(alloc, prompt)); } AclFactory::PromptPWSubject::PromptPWSubject(Allocator &alloc, const CssmData &prompt, const CssmData &secret) : Subject(alloc, CSSM_ACL_SUBJECT_TYPE_PROMPTED_PASSWORD) { append(new(alloc) ListElement(alloc, prompt)); append(new(alloc) ListElement(alloc, secret)); } AclFactory::ProtectedPWSubject::ProtectedPWSubject(Allocator &alloc) : Subject(alloc, CSSM_ACL_SUBJECT_TYPE_PROTECTED_PASSWORD) { } AclFactory::PinSubject::PinSubject(Allocator &alloc, uint32 slot) : Subject(alloc, CSSM_ACL_SUBJECT_TYPE_PREAUTH) { append(new(alloc) ListElement(CSSM_ACL_AUTHORIZATION_PREAUTH(slot))); } AclFactory::PinSourceSubject::PinSourceSubject(Allocator &alloc, const TypedList &form, CSSM_ACL_PREAUTH_TRACKING_STATE state) : Subject(alloc, CSSM_ACL_SUBJECT_TYPE_PREAUTH_SOURCE) { append(new(alloc) ListElement(form)); append(new(alloc) ListElement(state)); } } // end namespace CssmClient } // end namespace Security