]> git.saurik.com Git - apple/security.git/blob - cdsa/cdsa_client/cspclient.cpp
Security-163.tar.gz
[apple/security.git] / cdsa / cdsa_client / 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/cspclient.h>
23
24 using namespace CssmClient;
25
26
27 //
28 // Manage CSP attachments
29 //
30 CSPImpl::CSPImpl(const Guid &guid) : AttachmentImpl(guid, CSSM_SERVICE_CSP)
31 {
32 }
33
34 CSPImpl::CSPImpl(const Module &module) : AttachmentImpl(module, CSSM_SERVICE_CSP)
35 {
36 }
37
38 CSPImpl::~CSPImpl()
39 {
40 }
41
42
43 //
44 // Delete a key explicitly
45 //
46 void CSPImpl::freeKey(CssmKey &key, const AccessCredentials *cred, bool permanent)
47 {
48 check(CSSM_FreeKey(handle(), cred, &key, permanent));
49 }
50
51
52 //
53 // Manage generic context objects
54 //
55 CssmClient::Context::Context(const CSP &csp, CSSM_ALGORITHMS alg)
56 : ObjectImpl(csp), mAlgorithm(alg), mStaged(false)
57 {
58 }
59
60 CssmClient::Context::~Context()
61 {
62 try
63 {
64 deactivate();
65 } catch(...) {}
66 }
67
68 void CssmClient::Context::init()
69 {
70 CssmError::throwMe(CSSM_ERRCODE_FUNCTION_NOT_IMPLEMENTED);
71 }
72
73 void CssmClient::Context::deactivate()
74 {
75 if (mActive)
76 {
77 mActive = false;
78 check(CSSM_DeleteContext(mHandle));
79 }
80 }
81
82
83 void CssmClient::Context::algorithm(CSSM_ALGORITHMS alg)
84 {
85 if (isActive())
86 abort(); //@@@ can't (currently?) change algorithm with active context
87 mAlgorithm = alg;
88 }
89
90
91 //
92 // Query context operation output sizes.
93 //
94 uint32 CssmClient::Context::getOutputSize(uint32 inputSize, bool encrypt /*= true*/)
95 {
96 CSSM_QUERY_SIZE_DATA data;
97 data.SizeInputBlock = inputSize;
98 getOutputSize(data, 1, encrypt);
99 return data.SizeOutputBlock;
100 }
101
102 void CssmClient::Context::getOutputSize(CSSM_QUERY_SIZE_DATA &sizes, uint32 count, bool encrypt /*= true*/)
103 {
104 check(CSSM_QuerySize(handle(), encrypt, count, &sizes));
105 }
106
107
108 //
109 // The override() method of Context is an expert feature. It replaces the entire
110 // context with a context object provided. It is up to the caller to keep this context
111 // consistent with the purpose of the Context subclass he is (mis)using.
112 // This feature is currently used by the SecurityServer.
113 //
114 void CssmClient::Context::override(const Security::Context &ctx)
115 {
116 if (!isActive()) {
117 // make a valid context object (it doesn't matter what kind - keep it cheap)
118 check(CSSM_CSP_CreateDigestContext(attachment()->handle(), CSSM_ALGID_NONE, &mHandle));
119 }
120 // now replace everything with the context data provided
121 check(CSSM_SetContext(mHandle, &ctx));
122 mActive = true; // now active
123 }
124
125
126 //
127 // Manage PassThrough contexts
128 //
129
130 //
131 // Invoke passThrough
132 //
133 void
134 PassThrough::operator() (uint32 passThroughId, const void *inData, void **outData)
135 {
136 check(CSSM_CSP_PassThrough(handle(), passThroughId, inData, outData));
137 }
138
139 void PassThrough::activate()
140 {
141 if (!mActive) {
142 check(CSSM_CSP_CreatePassThroughContext(attachment()->handle(), mKey, &mHandle));
143 mActive = true;
144 }
145 }
146
147
148 //
149 // Manage Digest contexts
150 //
151 void Digest::activate()
152 {
153 if (!mActive) {
154 check(CSSM_CSP_CreateDigestContext(attachment()->handle(), mAlgorithm, &mHandle));
155 mActive = true;
156 }
157 }
158
159
160 void Digest::digest(const CssmData *data, uint32 count, CssmData &digest)
161 {
162 activate();
163 if (mStaged)
164 Error::throwMe(CSSMERR_CSP_STAGED_OPERATION_IN_PROGRESS);
165 check(CSSM_DigestData(handle(), data, count, &digest));
166 }
167
168 void Digest::digest(const CssmData *data, uint32 count)
169 {
170 activate();
171 if (!mStaged) {
172 check(CSSM_DigestDataInit(handle()));
173 mStaged = true;
174 }
175 check(CSSM_DigestDataUpdate(handle(), data, count));
176 }
177
178 void Digest::operator () (CssmData &digest)
179 {
180 if (!mStaged)
181 Error::throwMe(CSSMERR_CSP_STAGED_OPERATION_NOT_STARTED);
182 check(CSSM_DigestDataFinal(handle(), &digest));
183 mStaged = false;
184 }
185
186
187 //
188 // Random number generation
189 //
190 void Random::seed(const CssmCryptoData &seedData)
191 {
192 mSeed = &seedData;
193 set(CSSM_ATTRIBUTE_SEED, seedData);
194 }
195
196 void Random::size(uint32 sz)
197 {
198 mSize = sz;
199 set(CSSM_ATTRIBUTE_OUTPUT_SIZE, sz);
200 }
201
202
203 void Random::activate()
204 {
205 if (!mActive) {
206 check(CSSM_CSP_CreateRandomGenContext(attachment()->handle(), mAlgorithm,
207 mSeed, mSize, &mHandle));
208 mActive = true;
209 }
210 }
211
212
213 void Random::generate(CssmData &data, uint32 newSize)
214 {
215 if (newSize)
216 size(newSize);
217 activate();
218 assert(!mStaged); // not a stage-able operation
219 check(CSSM_GenerateRandom(handle(), &data));
220 }