1/* 2 * Copyright (c) 2000-2004,2006,2011,2014 Apple Inc. All Rights Reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 25// 26// cssmcred - enhanced PodWrappers and construction aids for ACL credentials 27// 28#ifndef _CSSMCRED 29#define _CSSMCRED 30 31#include <security_utilities/utilities.h> 32#include <security_cdsa_utilities/cssmlist.h> 33#include <security_cdsa_utilities/cssmalloc.h> 34#include <list> 35 36namespace Security { 37 38 39// 40// PodWrappers for samples and sample groups 41// 42class CssmSample : public PodWrapper<CssmSample, CSSM_SAMPLE> { 43public: 44 CssmSample(const TypedList &list) 45 { TypedSample = list; Verifier = NULL; } 46 CssmSample(const TypedList &list, const CssmSubserviceUid &ver) 47 { TypedSample = list; Verifier = &ver; } 48 49 TypedList &value() { return TypedList::overlay(TypedSample); } 50 const TypedList &value() const { return TypedList::overlay(TypedSample); } 51 operator TypedList & () { return value(); } 52 53 const CssmSubserviceUid *verifier() const { return CssmSubserviceUid::overlay(Verifier); } 54 CssmSubserviceUid * &verifier() 55 { return const_cast<CssmSubserviceUid * &>(CssmSubserviceUid::overlayVar(Verifier)); } 56}; 57 58class SampleGroup : public PodWrapper<SampleGroup, CSSM_SAMPLEGROUP> { 59public: 60 SampleGroup() { clearPod(); } 61 SampleGroup(CssmSample &single) { NumberOfSamples = 1; Samples = &single; } 62 63 uint32 size() const { return NumberOfSamples; } 64 uint32 length() const { return size(); } // legacy; prefer size() 65 CssmSample *&samples() { return CssmSample::overlayVar(const_cast<CSSM_SAMPLE *&>(Samples)); } 66 CssmSample *samples() const { return CssmSample::overlay(const_cast<CSSM_SAMPLE *>(Samples)); } 67 68 CssmSample &operator [] (uint32 ix) const 69 { assert(ix < size()); return samples()[ix]; } 70 71public: 72 // extract all samples of a given sample type. return true if any found 73 // note that you get a shallow copy of the sample structures for temporary use ONLY 74 bool collect(CSSM_SAMPLE_TYPE sampleType, list<CssmSample> &samples) const; 75}; 76 77 78// 79// The PodWrapper for the top-level CSSM credentials structure 80// 81class AccessCredentials : public PodWrapper<AccessCredentials, CSSM_ACCESS_CREDENTIALS> { 82public: 83 AccessCredentials() { clearPod(); } 84 explicit AccessCredentials(const SampleGroup &samples, const char *tag = NULL) 85 { this->samples() = samples; this->tag(tag); } 86 explicit AccessCredentials(const SampleGroup &samples, const std::string &tag) 87 { this->samples() = samples; this->tag(tag); } 88 89 const char *tag() const { return EntryTag[0] ? EntryTag : NULL; } 90 std::string s_tag() const { return EntryTag; } 91 void tag(const char *tagString); 92 void tag(const std::string &tagString) { return tag(tagString.c_str()); } 93 94 SampleGroup &samples() { return SampleGroup::overlay(Samples); } 95 const SampleGroup &samples() const { return SampleGroup::overlay(Samples); } 96 97 // pass-throughs to our SampleGroup 98 uint32 size() const { return samples().size(); } 99 CssmSample &operator [] (uint32 ix) const { return samples()[ix]; } 100 101public: 102 static const AccessCredentials &null; // all null credential 103 104 // turn NULL into a null credential if needed 105 static const AccessCredentials *needed(const CSSM_ACCESS_CREDENTIALS *cred) 106 { return cred ? overlay(cred) : &null; } 107}; 108 109 110// 111// An AccessCredentials object with some construction help. 112// Note that this is NOT a PodWrapper. 113// 114class AutoCredentials : public AccessCredentials { 115public: 116 AutoCredentials(Allocator &alloc); 117 AutoCredentials(Allocator &alloc, uint32 nSamples); 118 119 Allocator &allocator; 120 121 CssmSample &sample(uint32 n) { return getSample(n); } 122 123 CssmSample &append(const CssmSample &sample) 124 { return getSample(samples().length()) = sample; } 125 TypedList &append(const TypedList &exhibit) 126 { return (getSample(samples().length()) = exhibit).value(); } 127 128 CssmSample &operator += (const CssmSample &sample) { return append(sample); } 129 TypedList &operator += (const TypedList &exhibit) { return append(exhibit); } 130 131private: 132 void init(); 133 CssmSample &getSample(uint32 n); 134 135 CssmSample *sampleArray; 136 uint32 nSamples; 137}; 138 139 140// 141// Walkers for the CSSM API structure types. 142// Note that there are irrational "const"s strewn about the credential sub-structures. 143// They make it essentially impossible to incrementally construction them without 144// violating them. Since we know what we're doing, we do. 145// 146namespace DataWalkers 147{ 148 149// CssmSample (with const override) 150template <class Action> 151void walk(Action &operate, CssmSample &sample) 152{ 153 operate(sample); 154 walk(operate, sample.value()); 155 if (sample.verifier()) 156 walk(operate, sample.verifier()); 157} 158 159// SampleGroup 160template <class Action> 161void walk(Action &operate, SampleGroup &samples) 162{ 163 operate(samples); 164 enumerateArray(operate, samples, &SampleGroup::samples); 165} 166 167// AccessCredentials 168template <class Action> 169AccessCredentials *walk(Action &operate, AccessCredentials * &cred) 170{ 171 operate(cred); 172 //@@@ ignoring BaseCerts 173 walk(operate, cred->samples()); 174 //@@@ ignoring challenge callback 175 return cred; 176} 177 178template <class Action> 179CSSM_ACCESS_CREDENTIALS *walk(Action &operate, CSSM_ACCESS_CREDENTIALS * &cred) 180{ return walk(operate, AccessCredentials::overlayVar(cred)); } 181 182template <class Action> 183AutoCredentials *walk(Action &operate, AutoCredentials * &cred) 184{ return (AutoCredentials *)walk(operate, (AccessCredentials * &)cred); } 185 186 187} // end namespace DataWalkers 188} // end namespace Security 189 190 191#endif //_CSSMCRED 192