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  TestsNoPINInitBase.cpp
29 
30  Base class for test classes. Used when there is no need for user login.
31  *****************************************************************************/
32 
33 #include "TestsNoPINInitBase.h"
34 #include <cstring>
35 #include <cppunit/extensions/HelperMacros.h>
36 #include <vector>
37 #include <sstream>
38 
39 #ifdef P11M
40 #ifdef _WIN32
getFunctionListPtr(const char * const libName,HINSTANCE__ * p11Library,const char * getFunctionList)41 CK_FUNCTION_LIST_PTR FunctionList::getFunctionListPtr(const char*const libName,  HINSTANCE__* p11Library, const char*getFunctionList) {
42 #else
43 #include <dlfcn.h>
44 
45 static CK_FUNCTION_LIST_PTR getFunctionListPtr(const char*const libName, void *const p11Library, const char*getFunctionList) {
46 #endif //_WIN32
47 	CPPUNIT_ASSERT_MESSAGE(libName, p11Library);
48 #ifdef _WIN32
49 	const CK_C_GetFunctionList pGFL( (CK_C_GetFunctionList)GetProcAddress(
50 			p11Library,
51 			getFunctionList.c_str()
52 	) );
53 #else
54 	const CK_C_GetFunctionList pGFL( (CK_C_GetFunctionList)dlsym(
55 			p11Library,
56 			getFunctionList
57 	) );
58 #endif //_WIN32
59 	CPPUNIT_ASSERT_MESSAGE(libName, pGFL);
60 	CK_FUNCTION_LIST_PTR ptr(NULL_PTR);
61 	const CK_RV retCode( pGFL(&ptr) );
62 	if ( !ptr && (retCode)!=CKR_OK) {
63 		std::ostringstream oss;
64 		oss << "C_GetFunctionList failed...error no = 0x" << std::hex << retCode << " libName '" << libName << "'.";
65 		CPPUNIT_ASSERT_MESSAGE(oss.str(), false);
66 	}
67 	return ptr;
68 }
69 #endif //P11M
70 void TestsNoPINInitBase::getSlotIDs() {
71 	bool hasFoundFree(false);
72 	bool hasFoundInitialized(false);
73 	CK_ULONG nrOfSlots;
74 	CPPUNIT_ASSERT( CRYPTOKI_F_PTR( C_GetSlotList(CK_TRUE, NULL_PTR, &nrOfSlots)==CKR_OK ) );
75 	std::vector<CK_SLOT_ID> slotIDs(nrOfSlots);
76 	CPPUNIT_ASSERT( CRYPTOKI_F_PTR( C_GetSlotList(CK_TRUE, &slotIDs.front(), &nrOfSlots)==CKR_OK ) );
77 	for ( std::vector<CK_SLOT_ID>::iterator i=slotIDs.begin(); i!=slotIDs.end(); i++ ) {
78 		CK_TOKEN_INFO tokenInfo;
79 		CPPUNIT_ASSERT( CRYPTOKI_F_PTR( C_GetTokenInfo(*i, &tokenInfo)==CKR_OK ) );
80 		if ( tokenInfo.flags&CKF_TOKEN_INITIALIZED ) {
81 			if ( !hasFoundInitialized ) {
82 				hasFoundInitialized = true;
83 				m_initializedTokenSlotID = *i;
84 			}
85 		} else {
86 			if ( !hasFoundFree ) {
87 				hasFoundFree = true;
88 				m_notInitializedTokenSlotID = *i;
89 			}
90 		}
91 	}
92 	if ( !hasFoundInitialized ) {
93 		m_initializedTokenSlotID = m_notInitializedTokenSlotID;
94 	}
95 }
96 
97 TestsNoPINInitBase::TestsNoPINInitBase() :
98 #ifdef P11M
99 #ifdef _WIN32
100 		p11Library( LoadLibrary(libName.c_str()) ),
101 #else
102 		p11Library( dlopen(P11M, RTLD_LAZY) ),
103 #endif
104 		m_ptr(getFunctionListPtr(P11M, p11Library, "C_GetFunctionList")),
105 #endif
106 		m_invalidSlotID(((CK_SLOT_ID)1<<31)),
107 		m_initializedTokenSlotID(m_invalidSlotID),
108 		m_notInitializedTokenSlotID(m_invalidSlotID),
109 		m_soPin1((CK_UTF8CHAR_PTR)"12345678"),
110 		m_soPin1Length(strlen((char*)m_soPin1)),
111 		m_userPin1((CK_UTF8CHAR_PTR)"1234"),
112 		m_userPin1Length(strlen((char*)m_userPin1)) {};
113 
114 void TestsNoPINInitBase::setUp() {
115 	CK_UTF8CHAR label[32];
116 	memset(label, ' ', 32);
117 	memcpy(label, "token1", strlen("token1"));
118 
119 	// initialize cryptoki
120 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) ) );
121 	// update slot IDs to initialized and not initialized token.
122 	getSlotIDs();
123 	// (Re)initialize the token
124 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_InitToken(m_initializedTokenSlotID, m_soPin1, m_soPin1Length, label) ) );
125 	// Reset cryptoki to get new slot IDs.
126 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) ) );
127 	CPPUNIT_ASSERT_EQUAL( (CK_RV)CKR_OK, CRYPTOKI_F_PTR( C_Initialize(NULL_PTR) ) );
128 	// slot IDs must be updated since the ID of the initialized token has changed.
129 	getSlotIDs();
130 }
131 
132 void TestsNoPINInitBase::tearDown() {
133 	const CK_RV result(CRYPTOKI_F_PTR( C_Finalize(NULL_PTR) ) );
134 	if ( result==CKR_OK||result==CKR_CRYPTOKI_NOT_INITIALIZED ) {
135 		return;
136 	}
137 	std::ostringstream oss;
138 	oss << "C_Finalize failed with CK_RV: " << std::hex << result;
139 	CPPUNIT_ASSERT_MESSAGE(oss.str(), false);
140 }
141 
142 #ifdef P11M
143 TestsNoPINInitBase::~TestsNoPINInitBase() {
144 	if ( !p11Library ) {
145 		return;
146 	}
147 #ifdef _WIN32
148 	FreeLibrary(p11Library);
149 #else
150 	dlclose(p11Library);
151 #endif // _WIN32
152 }
153 
154 #else
155 TestsNoPINInitBase::~TestsNoPINInitBase() {}
156 #endif // P11M
157