]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_cdsa_client/lib/cspclient.cpp
Security-59306.101.1.tar.gz
[apple/security.git] / OSX / 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) : ObjectImpl(csp), mAlgorithm(alg), mHandle(NULL), mStaged(false), mCred(NULL)
57 {
58 }
59
60 Context::~Context()
61 {
62 try
63 {
64 deactivate();
65 } catch(...) {}
66 }
67
68 void Context::init()
69 {
70 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
71 }
72
73 void Context::deactivate()
74 {
75 StLock<Mutex> _(mActivateMutex);
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 StLock<Mutex> _(mActivateMutex);
179 if (!mActive) {
180 check(CSSM_CSP_CreatePassThroughContext(attachment()->handle(), mKey, &mHandle));
181 mActive = true;
182 }
183 }
184
185
186 //
187 // Manage Digest contexts
188 //
189 void Digest::activate()
190 {
191 StLock<Mutex> _(mActivateMutex);
192 if (!mActive) {
193 check(CSSM_CSP_CreateDigestContext(attachment()->handle(), mAlgorithm, &mHandle));
194 mActive = true;
195 }
196 }
197
198
199 void Digest::digest(const CssmData *data, uint32 count, CssmData &digest)
200 {
201 activate();
202 if (mStaged)
203 Error::throwMe(CSSMERR_CSP_STAGED_OPERATION_IN_PROGRESS);
204 check(CSSM_DigestData(handle(), data, count, &digest));
205 }
206
207 void Digest::digest(const CssmData *data, uint32 count)
208 {
209 activate();
210 if (!mStaged) {
211 check(CSSM_DigestDataInit(handle()));
212 mStaged = true;
213 }
214 check(CSSM_DigestDataUpdate(handle(), data, count));
215 }
216
217 void Digest::operator () (CssmData &digest)
218 {
219 if (!mStaged)
220 Error::throwMe(CSSMERR_CSP_STAGED_OPERATION_NOT_STARTED);
221 check(CSSM_DigestDataFinal(handle(), &digest));
222 mStaged = false;
223 }
224
225
226 //
227 // Random number generation
228 //
229 void Random::seed(const CssmCryptoData &seedData)
230 {
231 mSeed = &seedData;
232 set(CSSM_ATTRIBUTE_SEED, seedData);
233 }
234
235 void Random::size(uint32 sz)
236 {
237 mSize = sz;
238 set(CSSM_ATTRIBUTE_OUTPUT_SIZE, sz);
239 }
240
241
242 void Random::activate()
243 {
244 StLock<Mutex> _(mActivateMutex);
245 if (!mActive) {
246 check(CSSM_CSP_CreateRandomGenContext(attachment()->handle(), mAlgorithm,
247 mSeed, mSize, &mHandle));
248 mActive = true;
249 }
250 }
251
252
253 void Random::generate(CssmData &data, uint32 newSize)
254 {
255 if (newSize)
256 size(newSize);
257 activate();
258 assert(!mStaged); // not a stage-able operation
259 check(CSSM_GenerateRandom(handle(), &data));
260 }
261
262 } // end namespace CssmClient
263 } // end namespace Security