1 /*
2  * Copyright (c) 2010 .SE (The Internet Infrastructure Foundation)
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 /*****************************************************************************
28  Session.h
29 
30  This class represents a single session
31  *****************************************************************************/
32 
33 #include "CryptoFactory.h"
34 #include "Session.h"
35 
36 // Constructor
Session(Slot * inSlot,bool inIsReadWrite,CK_VOID_PTR inPApplication,CK_NOTIFY inNotify)37 Session::Session(Slot* inSlot, bool inIsReadWrite, CK_VOID_PTR inPApplication, CK_NOTIFY inNotify)
38 {
39 	slot = inSlot;
40 	token = slot->getToken();
41 	isReadWrite = inIsReadWrite;
42 	hSession = CK_INVALID_HANDLE;
43 	pApplication = inPApplication;
44 	notify = inNotify;
45 	operation = SESSION_OP_NONE;
46 	findOp = NULL;
47 	digestOp = NULL;
48 	hashAlgo = HashAlgo::Unknown;
49 	macOp = NULL;
50 	asymmetricCryptoOp = NULL;
51 	symmetricCryptoOp = NULL;
52 	mechanism = AsymMech::Unknown;
53 	reAuthentication = false;
54 	allowSinglePartOp = false;
55 	allowMultiPartOp = false;
56 	publicKey = NULL;
57 	privateKey = NULL;
58 	symmetricKey = NULL;
59 	param = NULL;
60 	paramLen = 0;
61 }
62 
63 // Constructor
Session()64 Session::Session()
65 {
66 	slot = NULL;
67 	token = NULL;
68 	isReadWrite = false;
69 	hSession = CK_INVALID_HANDLE;
70 	pApplication = NULL;
71 	notify = NULL;
72 	operation = SESSION_OP_NONE;
73 	findOp = NULL;
74 	digestOp = NULL;
75 	hashAlgo = HashAlgo::Unknown;
76 	macOp = NULL;
77 	asymmetricCryptoOp = NULL;
78 	symmetricCryptoOp = NULL;
79 	mechanism = AsymMech::Unknown;
80 	reAuthentication = false;
81 	allowSinglePartOp = false;
82 	allowMultiPartOp = false;
83 	publicKey = NULL;
84 	privateKey = NULL;
85 	symmetricKey = NULL;
86 	param = NULL;
87 	paramLen = 0;
88 }
89 
90 // Destructor
~Session()91 Session::~Session()
92 {
93 	resetOp();
94 }
95 
96 // Get session info
getInfo(CK_SESSION_INFO_PTR pInfo)97 CK_RV Session::getInfo(CK_SESSION_INFO_PTR pInfo)
98 {
99 	if (pInfo == NULL_PTR) return CKR_ARGUMENTS_BAD;
100 
101 	pInfo->slotID = slot->getSlotID();
102 
103 	pInfo->state = getState();
104 	pInfo->flags = CKF_SERIAL_SESSION;
105 	if (isRW())
106 	{
107 		pInfo->flags |= CKF_RW_SESSION;
108 	}
109 	pInfo->ulDeviceError = 0;
110 
111 	return CKR_OK;
112 }
113 
114 // Is a read and write session
isRW()115 bool Session::isRW()
116 {
117 	return isReadWrite;
118 }
119 
120 // Get session state
getState()121 CK_STATE Session::getState()
122 {
123 	if (token->isSOLoggedIn())
124 	{
125 		return CKS_RW_SO_FUNCTIONS;
126 	}
127 
128 	if (token->isUserLoggedIn())
129 	{
130 		if (isRW())
131 		{
132 			return CKS_RW_USER_FUNCTIONS;
133 		}
134 		else
135 		{
136 			return CKS_RO_USER_FUNCTIONS;
137 		}
138 	}
139 
140 	if (isRW())
141 	{
142 		return CKS_RW_PUBLIC_SESSION;
143 	}
144 	else
145 	{
146 		return CKS_RO_PUBLIC_SESSION;
147 	}
148 }
149 
setHandle(CK_SESSION_HANDLE inHSession)150 void Session::setHandle(CK_SESSION_HANDLE inHSession)
151 {
152 	hSession = inHSession;
153 }
154 
getHandle()155 CK_SESSION_HANDLE Session::getHandle()
156 {
157 	return hSession;
158 }
159 
160 // Return the slot that the session is connected to
getSlot()161 Slot* Session::getSlot()
162 {
163 	return slot;
164 }
165 
166 // Return the token that the session is connected to
getToken()167 Token* Session::getToken()
168 {
169 	return token;
170 }
171 
172 // Set the operation type
setOpType(int inOperation)173 void Session::setOpType(int inOperation)
174 {
175 	operation = inOperation;
176 }
177 
178 // Get the operation type
getOpType()179 int Session::getOpType()
180 {
181 	return operation;
182 }
183 
184 // Reset the operations
resetOp()185 void Session::resetOp()
186 {
187 	if (param != NULL)
188 	{
189 		free(param);
190 		param = NULL;
191 		paramLen = 0;
192 	}
193 
194 	if (digestOp != NULL)
195 	{
196 		CryptoFactory::i()->recycleHashAlgorithm(digestOp);
197 		digestOp = NULL;
198 	}
199 	else if (findOp != NULL)
200 	{
201 		findOp->recycle();
202 		findOp = NULL;
203 	}
204 	else if (asymmetricCryptoOp != NULL)
205 	{
206 		if (publicKey != NULL)
207 		{
208 			asymmetricCryptoOp->recyclePublicKey(publicKey);
209 			publicKey = NULL;
210 		}
211 		if (privateKey != NULL)
212 		{
213 			asymmetricCryptoOp->recyclePrivateKey(privateKey);
214 			privateKey = NULL;
215 		}
216 		CryptoFactory::i()->recycleAsymmetricAlgorithm(asymmetricCryptoOp);
217 		asymmetricCryptoOp = NULL;
218 	}
219 	else if (symmetricCryptoOp != NULL)
220 	{
221 		if (symmetricKey != NULL)
222 		{
223 			symmetricCryptoOp->recycleKey(symmetricKey);
224 			symmetricKey = NULL;
225 		}
226 		CryptoFactory::i()->recycleSymmetricAlgorithm(symmetricCryptoOp);
227 		symmetricCryptoOp = NULL;
228 	}
229 	else if (macOp != NULL)
230 	{
231 		if (symmetricKey != NULL)
232 		{
233 			macOp->recycleKey(symmetricKey);
234 			symmetricKey = NULL;
235 		}
236 		CryptoFactory::i()->recycleMacAlgorithm(macOp);
237 		macOp = NULL;
238 	}
239 
240 	operation = SESSION_OP_NONE;
241 	reAuthentication = false;
242 }
243 
setFindOp(FindOperation * inFindOp)244 void Session::setFindOp(FindOperation *inFindOp)
245 {
246 	if (findOp != NULL) {
247 		delete findOp;
248 	}
249 	findOp = inFindOp;
250 }
251 
getFindOp()252 FindOperation *Session::getFindOp()
253 {
254 	return findOp;
255 }
256 
257 // Set the digesting operator
setDigestOp(HashAlgorithm * inDigestOp)258 void Session::setDigestOp(HashAlgorithm* inDigestOp)
259 {
260 	if (digestOp != NULL)
261 	{
262 		CryptoFactory::i()->recycleHashAlgorithm(digestOp);
263 	}
264 
265 	digestOp = inDigestOp;
266 }
267 
268 // Get the digesting operator
getDigestOp()269 HashAlgorithm* Session::getDigestOp()
270 {
271 	return digestOp;
272 }
273 
setHashAlgo(HashAlgo::Type inHashAlgo)274 void Session::setHashAlgo(HashAlgo::Type inHashAlgo)
275 {
276 	hashAlgo = inHashAlgo;
277 }
278 
getHashAlgo()279 HashAlgo::Type Session::getHashAlgo()
280 {
281 	return hashAlgo;
282 }
283 
284 // Set the MACing operator
setMacOp(MacAlgorithm * inMacOp)285 void Session::setMacOp(MacAlgorithm *inMacOp)
286 {
287 	if (macOp != NULL)
288 	{
289 		setSymmetricKey(NULL);
290 		CryptoFactory::i()->recycleMacAlgorithm(macOp);
291 	}
292 
293 	macOp = inMacOp;
294 }
295 
296 // Get the MACing operator
getMacOp()297 MacAlgorithm *Session::getMacOp()
298 {
299 	return macOp;
300 }
301 
setAsymmetricCryptoOp(AsymmetricAlgorithm * inAsymmetricCryptoOp)302 void Session::setAsymmetricCryptoOp(AsymmetricAlgorithm *inAsymmetricCryptoOp)
303 {
304 	if (asymmetricCryptoOp != NULL)
305 	{
306 		setPublicKey(NULL);
307 		setPrivateKey(NULL);
308 		CryptoFactory::i()->recycleAsymmetricAlgorithm(asymmetricCryptoOp);
309 	}
310 
311 	asymmetricCryptoOp = inAsymmetricCryptoOp;
312 }
313 
getAsymmetricCryptoOp()314 AsymmetricAlgorithm *Session::getAsymmetricCryptoOp()
315 {
316 	return asymmetricCryptoOp;
317 }
318 
setSymmetricCryptoOp(SymmetricAlgorithm * inSymmetricCryptoOp)319 void Session::setSymmetricCryptoOp(SymmetricAlgorithm *inSymmetricCryptoOp)
320 {
321 	if (symmetricCryptoOp != NULL)
322 	{
323 		setSymmetricKey(NULL);
324 		CryptoFactory::i()->recycleSymmetricAlgorithm(symmetricCryptoOp);
325 	}
326 
327 	symmetricCryptoOp = inSymmetricCryptoOp;
328 }
329 
getSymmetricCryptoOp()330 SymmetricAlgorithm *Session::getSymmetricCryptoOp()
331 {
332 	return symmetricCryptoOp;
333 }
334 
setMechanism(AsymMech::Type inMechanism)335 void Session::setMechanism(AsymMech::Type inMechanism)
336 {
337 	mechanism = inMechanism;
338 }
339 
getMechanism()340 AsymMech::Type Session::getMechanism()
341 {
342 	return mechanism;
343 }
344 
setParameters(void * inParam,size_t inParamLen)345 void Session::setParameters(void* inParam, size_t inParamLen)
346 {
347 	if (inParam == NULL || inParamLen == 0) return;
348 
349 	if (param != NULL)
350 	{
351 		free(param);
352 		paramLen = 0;
353 	}
354 
355 	param = malloc(inParamLen);
356 	if (param != NULL)
357 	{
358 		memcpy(param, inParam, inParamLen);
359 		paramLen = inParamLen;
360 	}
361 }
362 
getParameters(size_t & inParamLen)363 void* Session::getParameters(size_t& inParamLen)
364 {
365 	inParamLen = paramLen;
366 	return param;
367 }
368 
setReAuthentication(bool inReAuthentication)369 void Session::setReAuthentication(bool inReAuthentication)
370 {
371 	reAuthentication = inReAuthentication;
372 }
373 
getReAuthentication()374 bool Session::getReAuthentication()
375 {
376 	return reAuthentication;
377 }
378 
setAllowMultiPartOp(bool inAllowMultiPartOp)379 void Session::setAllowMultiPartOp(bool inAllowMultiPartOp)
380 {
381 	allowMultiPartOp = inAllowMultiPartOp;
382 }
383 
getAllowMultiPartOp()384 bool Session::getAllowMultiPartOp()
385 {
386 	return allowMultiPartOp;
387 }
388 
setAllowSinglePartOp(bool inAllowSinglePartOp)389 void Session::setAllowSinglePartOp(bool inAllowSinglePartOp)
390 {
391 	allowSinglePartOp = inAllowSinglePartOp;
392 }
393 
getAllowSinglePartOp()394 bool Session::getAllowSinglePartOp()
395 {
396 	return allowSinglePartOp;
397 }
398 
setPublicKey(PublicKey * inPublicKey)399 void Session::setPublicKey(PublicKey* inPublicKey)
400 {
401 	if (asymmetricCryptoOp == NULL)
402 		return;
403 
404 	if (publicKey != NULL)
405 	{
406 		asymmetricCryptoOp->recyclePublicKey(publicKey);
407 	}
408 
409 	publicKey = inPublicKey;
410 }
411 
getPublicKey()412 PublicKey* Session::getPublicKey()
413 {
414 	return publicKey;
415 }
416 
setPrivateKey(PrivateKey * inPrivateKey)417 void Session::setPrivateKey(PrivateKey* inPrivateKey)
418 {
419 	if (asymmetricCryptoOp == NULL)
420 		return;
421 
422 	if (privateKey != NULL)
423 	{
424 		asymmetricCryptoOp->recyclePrivateKey(privateKey);
425 	}
426 
427 	privateKey = inPrivateKey;
428 }
429 
getPrivateKey()430 PrivateKey* Session::getPrivateKey()
431 {
432 	return privateKey;
433 }
434 
setSymmetricKey(SymmetricKey * inSymmetricKey)435 void Session::setSymmetricKey(SymmetricKey* inSymmetricKey)
436 {
437 	if (symmetricKey != NULL)
438 	{
439 		if (macOp) {
440 			macOp->recycleKey(symmetricKey);
441 		} else if (symmetricCryptoOp) {
442 			symmetricCryptoOp->recycleKey(symmetricKey);
443 		} else {
444 			return;
445 		}
446 	}
447 
448 	symmetricKey = inSymmetricKey;
449 }
450 
getSymmetricKey()451 SymmetricKey* Session::getSymmetricKey()
452 {
453 	return symmetricKey;
454 }
455