]> git.saurik.com Git - apple/security.git/blob - Security/libsecurity_cdsa_client/lib/cspclient.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / Security / libsecurity_cdsa_client / lib / cspclient.cpp
1 /*
2 * Copyright (c) 2000-2002,2011-2012,2014 Apple 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 StLock<Mutex> _(mActivateMutex);
77 if (mActive)
78 {
79 mActive = false;
80 check(CSSM_DeleteContext(mHandle));
81 }
82 }
83
84
85 void Context::algorithm(CSSM_ALGORITHMS alg)
86 {
87 if (isActive())
88 abort(); //@@@ can't (currently?) change algorithm with active context
89 mAlgorithm = alg;
90 }
91
92
93 void Context::cred(const CSSM_ACCESS_CREDENTIALS *cred)
94 {
95 mCred = AccessCredentials::overlay(cred);
96 set(CSSM_ATTRIBUTE_ACCESS_CREDENTIALS, *mCred);
97 }
98
99
100 //
101 // Query context operation output sizes.
102 //
103 uint32 Context::getOutputSize(uint32 inputSize, bool encrypt /*= true*/)
104 {
105 CSSM_QUERY_SIZE_DATA data;
106 data.SizeInputBlock = inputSize;
107 getOutputSize(data, 1, encrypt);
108 return data.SizeOutputBlock;
109 }
110
111 void Context::getOutputSize(CSSM_QUERY_SIZE_DATA &sizes, uint32 count, bool encrypt /*= true*/)
112 {
113 check(CSSM_QuerySize(handle(), encrypt, count, &sizes));
114 }
115
116
117 //
118 // The override() method of Context is an expert feature. It replaces the entire
119 // context with a context object provided. It is up to the caller to keep this context
120 // consistent with the purpose of the Context subclass he is (mis)using.
121 // This feature is currently used by the SecurityServer.
122 //
123 void Context::override(const Security::Context &ctx)
124 {
125 if (!isActive()) {
126 // make a valid context object (it doesn't matter what kind - keep it cheap)
127 check(CSSM_CSP_CreateDigestContext(attachment()->handle(), CSSM_ALGID_NONE, &mHandle));
128 }
129 // now replace everything with the context data provided
130 check(CSSM_SetContext(mHandle, &ctx));
131 mActive = true; // now active
132 }
133
134
135 //
136 // RccContexts
137 //
138 const ResourceControlContext &RccBearer::compositeRcc() const
139 {
140 // explicitly specified RCC wins
141 if (mRcc)
142 return *mRcc;
143
144 // cobble one up from the pieces
145 if (mOwner)
146 mWorkRcc.input() = *mOwner;
147 else
148 mWorkRcc.clearPod();
149 mWorkRcc.credentials(mOpCred);
150 return mWorkRcc;
151 }
152
153
154 void RccBearer::owner(const CSSM_ACL_ENTRY_PROTOTYPE *owner)
155 {
156 if (owner) {
157 mWorkInput = *owner;
158 this->owner(mWorkInput);
159 } else
160 this->owner((AclEntryInput*)NULL);
161 }
162
163
164 //
165 // Manage PassThrough contexts
166 //
167
168 //
169 // Invoke passThrough
170 //
171 void
172 PassThrough::operator() (uint32 passThroughId, const void *inData, void **outData)
173 {
174 check(CSSM_CSP_PassThrough(handle(), passThroughId, inData, outData));
175 }
176
177 void PassThrough::activate()
178 {
179 StLock<Mutex> _(mActivateMutex);
180 if (!mActive) {
181 check(CSSM_CSP_CreatePassThroughContext(attachment()->handle(), mKey, &mHandle));
182 mActive = true;
183 }
184 }
185
186
187 //
188 // Manage Digest contexts
189 //
190 void Digest::activate()
191 {
192 StLock<Mutex> _(mActivateMutex);
193 if (!mActive) {
194 check(CSSM_CSP_CreateDigestContext(attachment()->handle(), mAlgorithm, &mHandle));
195 mActive = true;
196 }
197 }
198
199
200 void Digest::digest(const CssmData *data, uint32 count, CssmData &digest)
201 {
202 activate();
203 if (mStaged)
204 Error::throwMe(CSSMERR_CSP_STAGED_OPERATION_IN_PROGRESS);
205 check(CSSM_DigestData(handle(), data, count, &digest));
206 }
207
208 void Digest::digest(const CssmData *data, uint32 count)
209 {
210 activate();
211 if (!mStaged) {
212 check(CSSM_DigestDataInit(handle()));
213 mStaged = true;
214 }
215 check(CSSM_DigestDataUpdate(handle(), data, count));
216 }
217
218 void Digest::operator () (CssmData &digest)
219 {
220 if (!mStaged)
221 Error::throwMe(CSSMERR_CSP_STAGED_OPERATION_NOT_STARTED);
222 check(CSSM_DigestDataFinal(handle(), &digest));
223 mStaged = false;
224 }
225
226
227 //
228 // Random number generation
229 //
230 void Random::seed(const CssmCryptoData &seedData)
231 {
232 mSeed = &seedData;
233 set(CSSM_ATTRIBUTE_SEED, seedData);
234 }
235
236 void Random::size(uint32 sz)
237 {
238 mSize = sz;
239 set(CSSM_ATTRIBUTE_OUTPUT_SIZE, sz);
240 }
241
242
243 void Random::activate()
244 {
245 StLock<Mutex> _(mActivateMutex);
246 if (!mActive) {
247 check(CSSM_CSP_CreateRandomGenContext(attachment()->handle(), mAlgorithm,
248 mSeed, mSize, &mHandle));
249 mActive = true;
250 }
251 }
252
253
254 void Random::generate(CssmData &data, uint32 newSize)
255 {
256 if (newSize)
257 size(newSize);
258 activate();
259 assert(!mStaged); // not a stage-able operation
260 check(CSSM_GenerateRandom(handle(), &data));
261 }
262
263 } // end namespace CssmClient
264 } // end namespace Security