#include <security_cdsa_client/cssmclient.h>
#include <security_cdsa_client/aclclient.h>
#include <security_cdsa_client/keychainacl.h>
#include <security_cdsa_utilities/cssmwalkers.h>
#include <security_cdsa_utilities/cssmdata.h>
namespace Security {
namespace CssmClient {
static inline void check(CSSM_RETURN rc)
{
ObjectImpl::check(rc);
}
AclBearer::~AclBearer()
{ }
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);
}
void KeyAclBearer::getAcl(AutoAclEntryInfoList &aclInfos, const char *selectionTag) const
{
aclInfos.allocator(allocator);
check(CSSM_GetKeyAcl(csp, &key, reinterpret_cast<const CSSM_STRING *>(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));
}
struct Statics {
Statics();
Allocator &alloc;
AutoCredentials nullCred;
AutoCredentials promptCred;
AutoCredentials unlockCred;
AutoCredentials cancelCred;
AutoCredentials promptedPINCred;
AutoCredentials promptedPINItemCred;
AclOwnerPrototype anyOwner;
AclEntryInfo anyAcl;
};
namespace {
ModuleNexus<Statics> statics;
}
Statics::Statics()
: alloc(Allocator::standard()),
nullCred(alloc, 1),
promptCred(alloc, 3),
unlockCred(alloc, 1),
cancelCred(alloc, 1),
promptedPINCred(alloc, 1),
promptedPINItemCred(alloc, 1),
anyOwner(TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_ANY)),
anyAcl(AclEntryPrototype(TypedList(alloc, CSSM_ACL_SUBJECT_TYPE_ANY), 1))
{
nullCred.sample(0) = TypedList(alloc, CSSM_SAMPLE_TYPE_THRESHOLD);
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.sample(0) = TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK,
new(alloc) ListElement(CSSM_SAMPLE_TYPE_KEYCHAIN_PROMPT));
cancelCred.sample(0) = TypedList(alloc, CSSM_SAMPLE_TYPE_KEYCHAIN_LOCK,
new(alloc) ListElement(CSSM_WORDID_CANCELED));
promptedPINCred.sample(0) = TypedList(alloc, CSSM_SAMPLE_TYPE_PROMPTED_PASSWORD,
new(alloc) ListElement(alloc, CssmData()));
promptedPINItemCred.tag("PIN1");
promptedPINItemCred.sample(0) = TypedList(alloc, CSSM_SAMPLE_TYPE_PROMPTED_PASSWORD,
new(alloc) ListElement(alloc, CssmData()));
}
AclFactory::AclFactory()
{ }
AclFactory::~AclFactory()
{ }
const AccessCredentials *AclFactory::nullCred() const
{ return &statics().nullCred; }
const AccessCredentials *AclFactory::promptCred() const
{ return &statics().promptCred; }
const AccessCredentials *AclFactory::unlockCred() const
{ return &statics().unlockCred; }
const AccessCredentials *AclFactory::cancelCred() const
{ return &statics().cancelCred; }
const AccessCredentials *AclFactory::promptedPINCred() const
{ return &statics().promptedPINCred; }
const AccessCredentials *AclFactory::promptedPINItemCred() const
{ return &statics().promptedPINItemCred; }
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()));
}
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()));
}
const AclOwnerPrototype &AclFactory::anyOwner() const
{ return statics().anyOwner; }
const AclEntryInfo &AclFactory::anyAcl() const
{ return statics().anyAcl; }
AclFactory::AnyResourceContext::AnyResourceContext(const CSSM_ACCESS_CREDENTIALS *cred)
: mAny(CSSM_ACL_SUBJECT_TYPE_ANY), mTag(CSSM_ACL_AUTHORIZATION_ANY)
{
input().proto().subject() += &mAny;
AuthorizationGroup &authGroup = input().proto().authorization();
authGroup.NumberOfAuthTags = 1;
authGroup.AuthTags = &mTag;
credentials(cred);
}
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)
: Subject(alloc, CSSM_ACL_SUBJECT_TYPE_PREAUTH_SOURCE)
{
append(new(alloc) ListElement(form));
}
} }