]> git.saurik.com Git - apple/security.git/blob - libsecurity_cdsa_client/lib/cspclient.cpp
Security-55163.44.tar.gz
[apple/security.git] / libsecurity_cdsa_client / lib / cspclient.cpp
1 /*
2 * Copyright (c) 2000-2002 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 //
20 // cspclient - client interface to CSSM CSPs and their operations
21 //
22 #include <security_cdsa_client/cspclient.h>
23
24 namespace Security {
25 namespace CssmClient {
26
27
28 //
29 // Manage CSP attachments
30 //
31 CSPImpl::CSPImpl(const Guid &guid) : AttachmentImpl(guid, CSSM_SERVICE_CSP)
32 {
33 }
34
35 CSPImpl::CSPImpl(const Module &module) : AttachmentImpl(module, CSSM_SERVICE_CSP)
36 {
37 }
38
39 CSPImpl::~CSPImpl()
40 {
41 }
42
43
44 //
45 // Delete a key explicitly
46 //
47 void CSPImpl::freeKey(CssmKey &key, const AccessCredentials *cred, bool permanent)
48 {
49 check(CSSM_FreeKey(handle(), cred, &key, permanent));
50 }
51
52
53 //
54 // Manage generic context objects
55 //
56 Context::Context(const CSP &csp, CSSM_ALGORITHMS alg)
57 : ObjectImpl(csp), mAlgorithm(alg), mStaged(false), mCred(NULL)
58 {
59 }
60
61 Context::~Context()
62 {
63 try
64 {
65 deactivate();
66 } catch(...) {}
67 }
68
69 void Context::init()
70 {
71 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
72 }
73
74 void Context::deactivate()
75 {
76 if (mActive)
77 {
78 mActive = false;
79 check(CSSM_DeleteContext(mHandle));
80 }
81 }
82
83
84 void Context::algorithm(CSSM_ALGORITHMS alg)
85 {
86 if (isActive())
87 abort(); //@@@ can't (currently?) change algorithm with active context
88 mAlgorithm = alg;
89 }
90
91
92 void Context::cred(const CSSM_ACCESS_CREDENTIALS *cred)
93 {
94 mCred = AccessCredentials::overlay(cred);
95 set(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS, *mCred);
96 }
97
98
99 //
100 // Query context operation output sizes.
101 //
102 uint32 Context::getOutputSize(uint32 inputSize, bool encrypt /*= true*/)
103 {
104 CSSM_QUERY_SIZE_DATA data;
105 data.SizeInputBlock = inputSize;
106 getOutputSize(data, 1, encrypt);
107 return data.SizeOutputBlock;
108 }
109
110 void Context::getOutputSize(CSSM_QUERY_SIZE_DATA &sizes, uint32 count, bool encrypt /*= true*/)
111 {
112 check(CSSM_QuerySize(handle(), encrypt, count, &sizes));
113 }
114
115
116 //
117 // The override() method of Context is an expert feature. It replaces the entire
118 // context with a context object provided. It is up to the caller to keep this context
119 // consistent with the purpose of the Context subclass he is (mis)using.
120 // This feature is currently used by the SecurityServer.
121 //
122 void Context::override(const Security::Context &ctx)
123 {
124 if (!isActive()) {
125 // make a valid context object (it doesn't matter what kind - keep it cheap)
126 check(CSSM_CSP_CreateDigestContext(attachment()->handle(), CSSM_ALGID_NONE, &mHandle));
127 }
128 // now replace everything with the context data provided
129 check(CSSM_SetContext(mHandle, &ctx));
130 mActive = true; // now active
131 }
132
133
134 //
135 // RccContexts
136 //
137 const ResourceControlContext &RccBearer::compositeRcc() const
138 {
139 // explicitly specified RCC wins
140 if (mRcc)
141 return *mRcc;
142
143 // cobble one up from the pieces
144 if (mOwner)
145 mWorkRcc.input() = *mOwner;
146 else
147 mWorkRcc.clearPod();
148 mWorkRcc.credentials(mOpCred);
149 return mWorkRcc;
150 }
151
152
153 void RccBearer::owner(const CSSM_ACL_ENTRY_PROTOTYPE *owner)
154 {
155 if (owner) {
156 mWorkInput = *owner;
157 this->owner(mWorkInput);
158 } else
159 this->owner((AclEntryInput*)NULL);
160 }
161
162
163 //
164 // Manage PassThrough contexts
165 //
166
167 //
168 // Invoke passThrough
169 //
170 void
171 PassThrough::operator() (uint32 passThroughId, const void *inData, void **outData)
172 {
173 check(CSSM_CSP_PassThrough(handle(), passThroughId, inData, outData));
174 }
175
176 void PassThrough::activate()
177 {
178 if (!mActive) {
179 check(CSSM_CSP_CreatePassThroughContext(attachment()->handle(), mKey, &mHandle));
180 mActive = true;
181 }
182 }
183
184
185 //
186 // Manage Digest contexts
187 //
188 void Digest::activate()
189 {
190 if (!mActive) {
191 check(CSSM_CSP_CreateDigestContext(attachment()->handle(), mAlgorithm, &mHandle));
192 mActive = true;
193 }
194 }
195
196
197 void Digest::digest(const CssmData *data, uint32 count, CssmData &digest)
198 {
199 activate();
200 if (mStaged)
201 Error::throwMe(CSSMERR_CSP_STAGED_OPERATION_IN_PROGRESS);
202 check(CSSM_DigestData(handle(), data, count, &digest));
203 }
204
205 void Digest::digest(const CssmData *data, uint32 count)
206 {
207 activate();
208 if (!mStaged) {
209 check(CSSM_DigestDataInit(handle()));
210 mStaged = true;
211 }
212 check(CSSM_DigestDataUpdate(handle(), data, count));
213 }
214
215 void Digest::operator () (CssmData &digest)
216 {
217 if (!mStaged)
218 Error::throwMe(CSSMERR_CSP_STAGED_OPERATION_NOT_STARTED);
219 check(CSSM_DigestDataFinal(handle(), &digest));
220 mStaged = false;
221 }
222
223
224 //
225 // Random number generation
226 //
227 void Random::seed(const CssmCryptoData &seedData)
228 {
229 mSeed = &seedData;
230 set(CSSM_ATTRIBUTE_SEED, seedData);
231 }
232
233 void Random::size(uint32 sz)
234 {
235 mSize = sz;
236 set(CSSM_ATTRIBUTE_OUTPUT_SIZE, sz);
237 }
238
239
240 void Random::activate()
241 {
242 if (!mActive) {
243 check(CSSM_CSP_CreateRandomGenContext(attachment()->handle(), mAlgorithm,
244 mSeed, mSize, &mHandle));
245 mActive = true;
246 }
247 }
248
249
250 void Random::generate(CssmData &data, uint32 newSize)
251 {
252 if (newSize)
253 size(newSize);
254 activate();
255 assert(!mStaged); // not a stage-able operation
256 check(CSSM_GenerateRandom(handle(), &data));
257 }
258
259 } // end namespace CssmClient
260 } // end namespace Security