sl@0
|
1 |
/*
|
sl@0
|
2 |
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
sl@0
|
3 |
* All rights reserved.
|
sl@0
|
4 |
* This component and the accompanying materials are made available
|
sl@0
|
5 |
* under the terms of the License "Eclipse Public License v1.0"
|
sl@0
|
6 |
* which accompanies this distribution, and is available
|
sl@0
|
7 |
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
sl@0
|
8 |
*
|
sl@0
|
9 |
* Initial Contributors:
|
sl@0
|
10 |
* Nokia Corporation - initial contribution.
|
sl@0
|
11 |
*
|
sl@0
|
12 |
* Contributors:
|
sl@0
|
13 |
*
|
sl@0
|
14 |
* Description:
|
sl@0
|
15 |
* This class implements the reference Crypto Token Hardware Abstraction
|
sl@0
|
16 |
* Interface (HAI). It is just intended to show how operations using
|
sl@0
|
17 |
* device keys can be performed using crypto token framework. In the
|
sl@0
|
18 |
* real world scenario, this HAI should be replaced by device drivers
|
sl@0
|
19 |
* by the licensees. In such a case, all the operations performed by
|
sl@0
|
20 |
* the replacing class would be performed in Kernel Space.
|
sl@0
|
21 |
*
|
sl@0
|
22 |
*/
|
sl@0
|
23 |
|
sl@0
|
24 |
|
sl@0
|
25 |
#include "tcryptotokenhai.h"
|
sl@0
|
26 |
#include "tkeydetails.h"
|
sl@0
|
27 |
#include "cryptosignatureapi.h"
|
sl@0
|
28 |
#include "keys.h"
|
sl@0
|
29 |
|
sl@0
|
30 |
#include <cryptospi/cryptoparams.h>
|
sl@0
|
31 |
#include <cryptospi/cryptospidef.h>
|
sl@0
|
32 |
|
sl@0
|
33 |
EXPORT_C CCryptoTokenHai* CCryptoTokenHai::NewLC(MCTToken* aToken)
|
sl@0
|
34 |
{
|
sl@0
|
35 |
CCryptoTokenHai* instance = new(ELeave) CCryptoTokenHai(*aToken);
|
sl@0
|
36 |
CleanupStack::PushL(instance);
|
sl@0
|
37 |
instance->ConstructL();
|
sl@0
|
38 |
return instance;
|
sl@0
|
39 |
}
|
sl@0
|
40 |
|
sl@0
|
41 |
EXPORT_C CCryptoTokenHai* CCryptoTokenHai::NewL(MCTToken* aToken)
|
sl@0
|
42 |
{
|
sl@0
|
43 |
CCryptoTokenHai* instance = CCryptoTokenHai::NewLC(aToken);
|
sl@0
|
44 |
CleanupStack::Pop(instance);
|
sl@0
|
45 |
return instance;
|
sl@0
|
46 |
}
|
sl@0
|
47 |
|
sl@0
|
48 |
void CCryptoTokenHai::ConstructL()
|
sl@0
|
49 |
{
|
sl@0
|
50 |
User::LeaveIfError(iFs.Connect());
|
sl@0
|
51 |
OpenStoreL();
|
sl@0
|
52 |
}
|
sl@0
|
53 |
|
sl@0
|
54 |
CCryptoTokenHai::CCryptoTokenHai(MCTToken& aToken)
|
sl@0
|
55 |
:iToken(aToken)
|
sl@0
|
56 |
{}
|
sl@0
|
57 |
|
sl@0
|
58 |
EXPORT_C CCryptoTokenHai::~CCryptoTokenHai()
|
sl@0
|
59 |
{
|
sl@0
|
60 |
if(iFileStore)
|
sl@0
|
61 |
{
|
sl@0
|
62 |
CompactStore();
|
sl@0
|
63 |
delete iFileStore;
|
sl@0
|
64 |
}
|
sl@0
|
65 |
|
sl@0
|
66 |
iFs.Close();
|
sl@0
|
67 |
iKeys.ResetAndDestroy();
|
sl@0
|
68 |
iKeys.Close();
|
sl@0
|
69 |
}
|
sl@0
|
70 |
|
sl@0
|
71 |
/**
|
sl@0
|
72 |
* Performs the decryption operation.
|
sl@0
|
73 |
*
|
sl@0
|
74 |
* This API gets called when the decryption is supposed to be done in
|
sl@0
|
75 |
* the hardware.
|
sl@0
|
76 |
*
|
sl@0
|
77 |
* @param aHandle The key handle
|
sl@0
|
78 |
* @param aCiphertext The cipher text. This is not being used presently
|
sl@0
|
79 |
* due to decryption logic used in this function.
|
sl@0
|
80 |
* @param aPlainText Output param. The decrypted plain text. Ownership
|
sl@0
|
81 |
* of the pointer lies with the caller.
|
sl@0
|
82 |
*
|
sl@0
|
83 |
* @leave This function can leave with following error codes:-
|
sl@0
|
84 |
* - KErrNotFound - If the key corresponding to given handle is not
|
sl@0
|
85 |
* found.
|
sl@0
|
86 |
* - Any other error code returned by AllocL().
|
sl@0
|
87 |
*
|
sl@0
|
88 |
* @note This function does not actually implement ECC decryption. It
|
sl@0
|
89 |
* just intends to show that the key is with this class and it can
|
sl@0
|
90 |
* do actual ECC decryption here. This function just returns the
|
sl@0
|
91 |
* private key as decrypted text. The caller can verify the decryption
|
sl@0
|
92 |
* by ensuring that test case has same public and private keys and then
|
sl@0
|
93 |
* comparing the decrypted text with public key.
|
sl@0
|
94 |
*/
|
sl@0
|
95 |
EXPORT_C void CCryptoTokenHai::DecryptL( TInt aHandle,
|
sl@0
|
96 |
const TDesC8& /* aCiphertext */,
|
sl@0
|
97 |
HBufC8*& aPlainText )
|
sl@0
|
98 |
{
|
sl@0
|
99 |
TInt keyIndex = KeyPresent(aHandle);
|
sl@0
|
100 |
if(keyIndex == KErrNotFound)
|
sl@0
|
101 |
{
|
sl@0
|
102 |
User::Leave(KErrNotFound);
|
sl@0
|
103 |
}
|
sl@0
|
104 |
|
sl@0
|
105 |
ExportPrivateKeyL(aHandle, aPlainText);
|
sl@0
|
106 |
}
|
sl@0
|
107 |
|
sl@0
|
108 |
/**
|
sl@0
|
109 |
* Performs the signing operation.
|
sl@0
|
110 |
*
|
sl@0
|
111 |
* This API gets called when the signing is supposed to be done inside
|
sl@0
|
112 |
* the hardware.
|
sl@0
|
113 |
*
|
sl@0
|
114 |
* @param aHandle The key handle
|
sl@0
|
115 |
* @param aPlaintext The text which has to be signed. This is not being
|
sl@0
|
116 |
* used due to signing logic used in this function.
|
sl@0
|
117 |
* @param aSignature Output param. The signature in HBufC8 format.
|
sl@0
|
118 |
* Ownership of the pointer lies with the caller. This should be
|
sl@0
|
119 |
* converted to CCryptoParams by the crypto token reference plugin.
|
sl@0
|
120 |
*
|
sl@0
|
121 |
* @leave This function can leave with following error codes:-
|
sl@0
|
122 |
* - KErrNotFound - If the key corresponding to given handle is not
|
sl@0
|
123 |
* found.
|
sl@0
|
124 |
* - Any other error code returned by AllocL().
|
sl@0
|
125 |
*
|
sl@0
|
126 |
* @note This function does not actually implement ECC signing. It
|
sl@0
|
127 |
* just intends to show that the key is with this class and it can
|
sl@0
|
128 |
* do actual ECC signing here. Currently this function just returns
|
sl@0
|
129 |
* the private key as output signature. The caller can verify the
|
sl@0
|
130 |
* signature by ensuring that test case has same public and private
|
sl@0
|
131 |
* keys and then comparing the signature with public key.
|
sl@0
|
132 |
*/
|
sl@0
|
133 |
EXPORT_C void CCryptoTokenHai::SignL( TInt aHandle,
|
sl@0
|
134 |
const TDesC8& /* aPlaintext */,
|
sl@0
|
135 |
HBufC8*& aSignature )
|
sl@0
|
136 |
{
|
sl@0
|
137 |
TInt keyIndex = KeyPresent(aHandle);
|
sl@0
|
138 |
if(keyIndex == KErrNotFound)
|
sl@0
|
139 |
{
|
sl@0
|
140 |
User::Leave(KErrNotFound);
|
sl@0
|
141 |
}
|
sl@0
|
142 |
|
sl@0
|
143 |
ExportPrivateKeyL(aHandle, aSignature);
|
sl@0
|
144 |
}
|
sl@0
|
145 |
|
sl@0
|
146 |
/**
|
sl@0
|
147 |
* Returns the index of the key whose handle is given.
|
sl@0
|
148 |
*
|
sl@0
|
149 |
* @param aHandle Handle of the key. This is used to search the key.
|
sl@0
|
150 |
*
|
sl@0
|
151 |
* @return index of the key if search is successful, KErrNotFound
|
sl@0
|
152 |
* otherwise.
|
sl@0
|
153 |
*/
|
sl@0
|
154 |
EXPORT_C TInt CCryptoTokenHai::KeyPresent( TInt aHandle )
|
sl@0
|
155 |
{
|
sl@0
|
156 |
int keysCount = iKeys.Count();
|
sl@0
|
157 |
for(TInt i=0; i < keysCount; ++i)
|
sl@0
|
158 |
{
|
sl@0
|
159 |
if(iKeys[i]->Handle() == aHandle)
|
sl@0
|
160 |
{
|
sl@0
|
161 |
return i;
|
sl@0
|
162 |
}
|
sl@0
|
163 |
}
|
sl@0
|
164 |
return KErrNotFound;
|
sl@0
|
165 |
}
|
sl@0
|
166 |
|
sl@0
|
167 |
/**
|
sl@0
|
168 |
* Extracts the private key.
|
sl@0
|
169 |
*
|
sl@0
|
170 |
* @param aHandle Handle of the private key to be extracted.
|
sl@0
|
171 |
* @param aKey Output Parameter. Stores the private key on success.
|
sl@0
|
172 |
* Ownership of pointer is with the caller.
|
sl@0
|
173 |
*
|
sl@0
|
174 |
* @leave Following leave codes possible:-
|
sl@0
|
175 |
* - Any leave code returned by AllocL().
|
sl@0
|
176 |
* - KErrNotFound - If key corresponding to the given handle is not
|
sl@0
|
177 |
* found.
|
sl@0
|
178 |
*
|
sl@0
|
179 |
* @note In the actual implementation, licensees should ensure that
|
sl@0
|
180 |
* this function can be called only in Kernel space. In the reference
|
sl@0
|
181 |
* implementation, this function gets called only by CCryptoSpiHai,
|
sl@0
|
182 |
* which is assumed to operate in kernel space. This would ensure that
|
sl@0
|
183 |
* the private key always stays inside the hardware.
|
sl@0
|
184 |
*/
|
sl@0
|
185 |
EXPORT_C void CCryptoTokenHai::ExportPrivateKeyL( TInt aHandle, HBufC8*& aKey )
|
sl@0
|
186 |
{
|
sl@0
|
187 |
int keysCount = iKeys.Count();
|
sl@0
|
188 |
for(int i = 0; i < keysCount; ++i)
|
sl@0
|
189 |
{
|
sl@0
|
190 |
if(iKeys[i]->Handle() == aHandle)
|
sl@0
|
191 |
{
|
sl@0
|
192 |
aKey = iKeys[i]->PrivateKey()->AllocL();
|
sl@0
|
193 |
return;
|
sl@0
|
194 |
}
|
sl@0
|
195 |
}
|
sl@0
|
196 |
User::Leave(KErrNotFound);
|
sl@0
|
197 |
}
|
sl@0
|
198 |
|
sl@0
|
199 |
/**
|
sl@0
|
200 |
* Extracts the public key.
|
sl@0
|
201 |
*
|
sl@0
|
202 |
* @param aHandle Handle of the public key to be extracted.
|
sl@0
|
203 |
* @param aKey Output Parameter. Stores the public key on success.
|
sl@0
|
204 |
* Ownership of pointer is with the caller.
|
sl@0
|
205 |
*
|
sl@0
|
206 |
* @leave Following leave codes possible:-
|
sl@0
|
207 |
* - Any leave code returned by AllocL().
|
sl@0
|
208 |
* - KErrNotFound - If key corresponding to the given handle is not
|
sl@0
|
209 |
* found.
|
sl@0
|
210 |
*/
|
sl@0
|
211 |
EXPORT_C void CCryptoTokenHai::ExportPublicKeyL( TInt aHandle, HBufC8*& aKey )
|
sl@0
|
212 |
{
|
sl@0
|
213 |
int keysCount = iKeys.Count();
|
sl@0
|
214 |
for(int i = 0; i < keysCount; ++i)
|
sl@0
|
215 |
{
|
sl@0
|
216 |
if(iKeys[i]->Handle() == aHandle)
|
sl@0
|
217 |
{
|
sl@0
|
218 |
aKey = iKeys[i]->PublicKey()->AllocL();
|
sl@0
|
219 |
return;
|
sl@0
|
220 |
}
|
sl@0
|
221 |
}
|
sl@0
|
222 |
User::Leave(KErrNotFound);
|
sl@0
|
223 |
}
|
sl@0
|
224 |
|
sl@0
|
225 |
/**
|
sl@0
|
226 |
* Stores the key with given details.
|
sl@0
|
227 |
*
|
sl@0
|
228 |
* @param aLabel Label of the key.
|
sl@0
|
229 |
* @param aPrivateKey Private component of the key.
|
sl@0
|
230 |
* @param aPublicKey Public component of the key.
|
sl@0
|
231 |
*
|
sl@0
|
232 |
* @leave Following leave codes possible:-
|
sl@0
|
233 |
* - KErrAlreadyExists If there is already a key with the inputted
|
sl@0
|
234 |
* label.
|
sl@0
|
235 |
* - Any other leave code returned by NewL() or AppendL().
|
sl@0
|
236 |
*
|
sl@0
|
237 |
* @note In the present reference implementation this function is not
|
sl@0
|
238 |
* being used, since device keys are pre-provisioned by the licensees.
|
sl@0
|
239 |
* Hence licensees may decide not to implement this function in their
|
sl@0
|
240 |
* real implementation.
|
sl@0
|
241 |
*/
|
sl@0
|
242 |
EXPORT_C void CCryptoTokenHai::ImportKeyL(const TDesC& aLabel,
|
sl@0
|
243 |
const TDesC8& aPrivateKey, const TDesC8& aPublicKey)
|
sl@0
|
244 |
{
|
sl@0
|
245 |
int keysCount = iKeys.Count();
|
sl@0
|
246 |
for(int i = 0; i < keysCount; ++i)
|
sl@0
|
247 |
{
|
sl@0
|
248 |
if(iKeys[i]->Label() == aLabel)
|
sl@0
|
249 |
{
|
sl@0
|
250 |
User::Leave(KErrAlreadyExists);
|
sl@0
|
251 |
}
|
sl@0
|
252 |
}
|
sl@0
|
253 |
CKeyDetails* keyDetails = CKeyDetails::NewL(keysCount+1,aLabel,aPrivateKey,aPublicKey);
|
sl@0
|
254 |
iKeys.AppendL(keyDetails);
|
sl@0
|
255 |
}
|
sl@0
|
256 |
|
sl@0
|
257 |
/**
|
sl@0
|
258 |
* Populates the string containing full RAM path of file containing
|
sl@0
|
259 |
* keys.
|
sl@0
|
260 |
*/
|
sl@0
|
261 |
void CCryptoTokenHai::MakePrivateFilenameL(RFs& aFs, const TDesC& aLeafName, TDes& aNameOut)
|
sl@0
|
262 |
{
|
sl@0
|
263 |
aNameOut.SetLength(0);
|
sl@0
|
264 |
aNameOut.Append(RFs::GetSystemDriveChar());
|
sl@0
|
265 |
|
sl@0
|
266 |
aNameOut.Append(':');
|
sl@0
|
267 |
|
sl@0
|
268 |
// Get private path
|
sl@0
|
269 |
TBuf<20> privatePath;
|
sl@0
|
270 |
User::LeaveIfError(aFs.PrivatePath(privatePath));
|
sl@0
|
271 |
aNameOut.Append(privatePath);
|
sl@0
|
272 |
|
sl@0
|
273 |
aNameOut.Append(aLeafName);
|
sl@0
|
274 |
}
|
sl@0
|
275 |
|
sl@0
|
276 |
/**
|
sl@0
|
277 |
* Creates the corresponding directory, if it does not exist.
|
sl@0
|
278 |
*/
|
sl@0
|
279 |
void CCryptoTokenHai::EnsurePathL(RFs& aFs, const TDesC& aFile)
|
sl@0
|
280 |
{
|
sl@0
|
281 |
TInt err = aFs.MkDirAll(aFile);
|
sl@0
|
282 |
if (err != KErrNone && err != KErrAlreadyExists)
|
sl@0
|
283 |
{
|
sl@0
|
284 |
User::Leave(err);
|
sl@0
|
285 |
}
|
sl@0
|
286 |
}
|
sl@0
|
287 |
|
sl@0
|
288 |
/**
|
sl@0
|
289 |
* Populates the string containing full ROM path of the keys file.
|
sl@0
|
290 |
*/
|
sl@0
|
291 |
void CCryptoTokenHai::MakePrivateROMFilenameL(RFs& aFs, const TDesC& aLeafName, TDes& aNameOut)
|
sl@0
|
292 |
{
|
sl@0
|
293 |
_LIT(KFileStoreROMDrive, "Z:");
|
sl@0
|
294 |
|
sl@0
|
295 |
aNameOut.Copy(KFileStoreROMDrive);
|
sl@0
|
296 |
|
sl@0
|
297 |
// Get private path
|
sl@0
|
298 |
TBuf<20> privatePath;
|
sl@0
|
299 |
User::LeaveIfError(aFs.PrivatePath(privatePath));
|
sl@0
|
300 |
aNameOut.Append(privatePath);
|
sl@0
|
301 |
aNameOut.Append(aLeafName);
|
sl@0
|
302 |
}
|
sl@0
|
303 |
|
sl@0
|
304 |
/**
|
sl@0
|
305 |
* Copies the contents of source file to destination file.
|
sl@0
|
306 |
*
|
sl@0
|
307 |
* This is typically used to copy the keys file from ROM to RAM.
|
sl@0
|
308 |
*/
|
sl@0
|
309 |
void CCryptoTokenHai::CopyL(RFs& aFs, const TDesC& aSouce, const TDesC& aDest)
|
sl@0
|
310 |
{
|
sl@0
|
311 |
RFileReadStream in;
|
sl@0
|
312 |
User::LeaveIfError(in.Open(aFs, aSouce, EFileRead | EFileShareReadersOnly));
|
sl@0
|
313 |
CleanupClosePushL(in);
|
sl@0
|
314 |
|
sl@0
|
315 |
RFileWriteStream out;
|
sl@0
|
316 |
User::LeaveIfError(out.Replace(aFs, aDest, EFileWrite | EFileShareExclusive));
|
sl@0
|
317 |
CleanupClosePushL(out);
|
sl@0
|
318 |
|
sl@0
|
319 |
in.ReadL(out);
|
sl@0
|
320 |
CleanupStack::PopAndDestroy(2, &in);
|
sl@0
|
321 |
}
|
sl@0
|
322 |
|
sl@0
|
323 |
/**
|
sl@0
|
324 |
* Keys corresponding to this store are present in hwkeys.dat.
|
sl@0
|
325 |
* In the production code written by licensees, this would be the path
|
sl@0
|
326 |
* where device keys are stored.
|
sl@0
|
327 |
*/
|
sl@0
|
328 |
_LIT(KKeyStoreFilename,"hwkeys.dat");
|
sl@0
|
329 |
|
sl@0
|
330 |
/**
|
sl@0
|
331 |
* Opens a store containing hardware keys.
|
sl@0
|
332 |
*
|
sl@0
|
333 |
* This function uses the following logic to open the store:-
|
sl@0
|
334 |
* -# Try to open the store from the private directory.
|
sl@0
|
335 |
* -# If this fails copy the file from ROM to RAM.
|
sl@0
|
336 |
* -# If both fail, create your own keys store from scratch.
|
sl@0
|
337 |
*/
|
sl@0
|
338 |
void CCryptoTokenHai::OpenStoreL()
|
sl@0
|
339 |
{
|
sl@0
|
340 |
TFileName fullPath;
|
sl@0
|
341 |
MakePrivateFilenameL(iFs, KKeyStoreFilename, fullPath);
|
sl@0
|
342 |
|
sl@0
|
343 |
EnsurePathL(iFs, fullPath);
|
sl@0
|
344 |
TRAPD(result, OpenStoreInFileL(fullPath));
|
sl@0
|
345 |
|
sl@0
|
346 |
if (result == KErrInUse )
|
sl@0
|
347 |
{
|
sl@0
|
348 |
// Cannot access the file now. Abort rather than wiping the keystore.
|
sl@0
|
349 |
User::Leave(result);
|
sl@0
|
350 |
}
|
sl@0
|
351 |
|
sl@0
|
352 |
if (result != KErrNone )
|
sl@0
|
353 |
{
|
sl@0
|
354 |
/*
|
sl@0
|
355 |
* Not yet opened a valid store, either no file to be found, or
|
sl@0
|
356 |
* no valid store in it. Copy the original one stored in the
|
sl@0
|
357 |
* ROM.
|
sl@0
|
358 |
*/
|
sl@0
|
359 |
TRAPD(result2, CopyStoreFromROML(fullPath, result));
|
sl@0
|
360 |
|
sl@0
|
361 |
if (KErrNone != result2)
|
sl@0
|
362 |
{
|
sl@0
|
363 |
/*
|
sl@0
|
364 |
* We tried to copy the keystore from ROM. For some reason this
|
sl@0
|
365 |
* failed and we still cannot open the file. Create a new one from
|
sl@0
|
366 |
* scratch.
|
sl@0
|
367 |
*/
|
sl@0
|
368 |
CreateStoreInFileL(fullPath);
|
sl@0
|
369 |
}
|
sl@0
|
370 |
}
|
sl@0
|
371 |
|
sl@0
|
372 |
}
|
sl@0
|
373 |
|
sl@0
|
374 |
/**
|
sl@0
|
375 |
* Copies the key store file from ROM to RAM.
|
sl@0
|
376 |
*/
|
sl@0
|
377 |
void CCryptoTokenHai::CopyStoreFromROML(const TDesC& fullPath, TInt result)
|
sl@0
|
378 |
{
|
sl@0
|
379 |
if (result != KErrNotFound)
|
sl@0
|
380 |
{
|
sl@0
|
381 |
// Wipe the keystore if we can't open it (it's corrupt anyway)
|
sl@0
|
382 |
User::LeaveIfError(iFs.Delete(fullPath));
|
sl@0
|
383 |
}
|
sl@0
|
384 |
|
sl@0
|
385 |
TFileName romPath;
|
sl@0
|
386 |
MakePrivateROMFilenameL(iFs, KKeyStoreFilename, romPath);
|
sl@0
|
387 |
|
sl@0
|
388 |
// Copy data from rom and open it
|
sl@0
|
389 |
CopyL(iFs, romPath, fullPath);
|
sl@0
|
390 |
OpenStoreInFileL(fullPath);
|
sl@0
|
391 |
}
|
sl@0
|
392 |
|
sl@0
|
393 |
/**
|
sl@0
|
394 |
* Opens a store from the given file.
|
sl@0
|
395 |
*/
|
sl@0
|
396 |
void CCryptoTokenHai::OpenStoreInFileL(const TDesC& aFile)
|
sl@0
|
397 |
{
|
sl@0
|
398 |
RFile file;
|
sl@0
|
399 |
User::LeaveIfError(file.Open(iFs, aFile, EFileRead | EFileWrite | EFileShareAny));
|
sl@0
|
400 |
CleanupClosePushL(file);
|
sl@0
|
401 |
delete iFileStore;
|
sl@0
|
402 |
iFileStore = NULL;
|
sl@0
|
403 |
|
sl@0
|
404 |
iFileStore = CPermanentFileStore::FromL(file);
|
sl@0
|
405 |
// iFileStore takes ownership of file now
|
sl@0
|
406 |
CleanupStack::Pop(&file);
|
sl@0
|
407 |
|
sl@0
|
408 |
// Get the salt, root and manager TStreamIds
|
sl@0
|
409 |
iRootStreamId = iFileStore->Root();
|
sl@0
|
410 |
if (iRootStreamId == KNullStreamId)
|
sl@0
|
411 |
{
|
sl@0
|
412 |
User::Leave(KErrCorrupt);
|
sl@0
|
413 |
}
|
sl@0
|
414 |
RStoreReadStream rootStream;
|
sl@0
|
415 |
rootStream.OpenLC(*iFileStore, iRootStreamId);
|
sl@0
|
416 |
ReadKeysFromStoreL();
|
sl@0
|
417 |
CleanupStack::PopAndDestroy(&rootStream);
|
sl@0
|
418 |
}
|
sl@0
|
419 |
|
sl@0
|
420 |
/**
|
sl@0
|
421 |
* Creates a keys store in RAM from scratch.
|
sl@0
|
422 |
*
|
sl@0
|
423 |
* @note This function should never get called as hwkeys.dat should be
|
sl@0
|
424 |
* always present in ROM. If this function somehow gets called, it
|
sl@0
|
425 |
* will create a hwkeys.dat file from scratch. However, this file would
|
sl@0
|
426 |
* not contain any keys and tests would not pass.
|
sl@0
|
427 |
*/
|
sl@0
|
428 |
void CCryptoTokenHai::CreateStoreInFileL(const TDesC& aFile)
|
sl@0
|
429 |
{
|
sl@0
|
430 |
TInt r = iFs.MkDirAll(aFile);
|
sl@0
|
431 |
if ( (r!=KErrNone) && (r!=KErrAlreadyExists) )
|
sl@0
|
432 |
User::Leave(r);
|
sl@0
|
433 |
|
sl@0
|
434 |
delete iFileStore;
|
sl@0
|
435 |
iFileStore = NULL;
|
sl@0
|
436 |
iFileStore = CPermanentFileStore::ReplaceL(iFs, aFile, EFileRead | EFileWrite | EFileShareExclusive);
|
sl@0
|
437 |
iFileStore->SetTypeL(KPermanentFileStoreLayoutUid);
|
sl@0
|
438 |
|
sl@0
|
439 |
TCleanupItem cleanupStore(RevertStore, iFileStore);
|
sl@0
|
440 |
CleanupStack::PushL(cleanupStore);
|
sl@0
|
441 |
|
sl@0
|
442 |
// Create root stream - just contains id of info stream
|
sl@0
|
443 |
RStoreWriteStream rootStream;
|
sl@0
|
444 |
iRootStreamId = rootStream.CreateLC(*iFileStore);
|
sl@0
|
445 |
iFileStore->SetRootL(iRootStreamId);
|
sl@0
|
446 |
WriteKeysToStoreL(rootStream);
|
sl@0
|
447 |
iFileStore->CommitL();
|
sl@0
|
448 |
CleanupStack::PopAndDestroy(&rootStream);
|
sl@0
|
449 |
CleanupStack::Pop(); // cleanupStore
|
sl@0
|
450 |
}
|
sl@0
|
451 |
|
sl@0
|
452 |
/**
|
sl@0
|
453 |
* Copies the keys stored in the instance to inputted write stream.
|
sl@0
|
454 |
*
|
sl@0
|
455 |
* This invokes the CKeyDetails::ExternalizeL() function.
|
sl@0
|
456 |
*/
|
sl@0
|
457 |
void CCryptoTokenHai::WriteKeysToStoreL(RStoreWriteStream& aRootStream)
|
sl@0
|
458 |
{
|
sl@0
|
459 |
TInt keyCount = iKeys.Count();
|
sl@0
|
460 |
aRootStream.WriteInt32L(keyCount);
|
sl@0
|
461 |
|
sl@0
|
462 |
for (TInt index = 0; index < keyCount; index++)
|
sl@0
|
463 |
{
|
sl@0
|
464 |
aRootStream << *iKeys[index];
|
sl@0
|
465 |
}
|
sl@0
|
466 |
aRootStream.CommitL();
|
sl@0
|
467 |
}
|
sl@0
|
468 |
|
sl@0
|
469 |
/**
|
sl@0
|
470 |
* Copies the keys present in the read store to instance of class.
|
sl@0
|
471 |
*
|
sl@0
|
472 |
* This eventually invokes the CKeyDetails::InternalizeL() function.
|
sl@0
|
473 |
*/
|
sl@0
|
474 |
void CCryptoTokenHai::ReadKeysFromStoreL()
|
sl@0
|
475 |
{
|
sl@0
|
476 |
RStoreReadStream rootStream;
|
sl@0
|
477 |
|
sl@0
|
478 |
rootStream.OpenLC(*iFileStore, iRootStreamId);
|
sl@0
|
479 |
TInt keyCount = rootStream.ReadInt32L();
|
sl@0
|
480 |
|
sl@0
|
481 |
for (TInt index = 0; index < keyCount; index++)
|
sl@0
|
482 |
{
|
sl@0
|
483 |
CKeyDetails* keyDetails = CKeyDetails::NewL(rootStream);
|
sl@0
|
484 |
iKeys.Append(keyDetails);
|
sl@0
|
485 |
}
|
sl@0
|
486 |
CleanupStack::PopAndDestroy(&rootStream);
|
sl@0
|
487 |
}
|
sl@0
|
488 |
|
sl@0
|
489 |
/**
|
sl@0
|
490 |
* This is a cleanup item that reverts the store.
|
sl@0
|
491 |
*/
|
sl@0
|
492 |
void CCryptoTokenHai::RevertStore(TAny* aStore)
|
sl@0
|
493 |
{
|
sl@0
|
494 |
CPermanentFileStore* store = reinterpret_cast<CPermanentFileStore*>(aStore);
|
sl@0
|
495 |
TRAP_IGNORE(store->RevertL());
|
sl@0
|
496 |
}
|
sl@0
|
497 |
|
sl@0
|
498 |
/**
|
sl@0
|
499 |
* Compacts the store.
|
sl@0
|
500 |
*/
|
sl@0
|
501 |
void CCryptoTokenHai::CompactStore()
|
sl@0
|
502 |
{
|
sl@0
|
503 |
ASSERT(iFileStore);
|
sl@0
|
504 |
TRAP_IGNORE(iFileStore->ReclaimL(); iFileStore->CompactL());
|
sl@0
|
505 |
}
|
sl@0
|
506 |
|
sl@0
|
507 |
/**
|
sl@0
|
508 |
* Populates the list of keys based on the input filter.
|
sl@0
|
509 |
*
|
sl@0
|
510 |
* @param aFilter Set of conditions to be used to decide which keys
|
sl@0
|
511 |
* should be listed
|
sl@0
|
512 |
* @param aKeys Output param. Contains the array of keys which fulfil
|
sl@0
|
513 |
* criteria mentioned in filter. Caller should take responsibility of
|
sl@0
|
514 |
* this array.
|
sl@0
|
515 |
*
|
sl@0
|
516 |
* @leave Any of the system wide error codes.
|
sl@0
|
517 |
*
|
sl@0
|
518 |
* @note Though Crypto Token HAI internally operates in CKeyDetails,
|
sl@0
|
519 |
* this function returns CCTKeyInfo array.
|
sl@0
|
520 |
*/
|
sl@0
|
521 |
EXPORT_C void CCryptoTokenHai::ListL(const TCTKeyAttributeFilter& aFilter ,
|
sl@0
|
522 |
RPointerArray<CCTKeyInfo>& aKeys) const
|
sl@0
|
523 |
{
|
sl@0
|
524 |
TInt count = iKeys.Count();
|
sl@0
|
525 |
for(TInt index = 0 ;index < count; ++ index)
|
sl@0
|
526 |
{
|
sl@0
|
527 |
const CKeyDetails* keyDetails = iKeys[index];
|
sl@0
|
528 |
|
sl@0
|
529 |
if(KeyMatchesFilterL(*keyDetails,aFilter))
|
sl@0
|
530 |
{
|
sl@0
|
531 |
MCTAuthenticationObject* authObject = NULL;
|
sl@0
|
532 |
HBufC8* attribute = keyDetails->PKCS8AttributeSet().AllocLC();
|
sl@0
|
533 |
HBufC* label = keyDetails->Label().AllocLC();
|
sl@0
|
534 |
|
sl@0
|
535 |
CCTKeyInfo* keyInfo = CCTKeyInfo::NewL(
|
sl@0
|
536 |
keyDetails->ID(),keyDetails->Usage(),keyDetails->Size(),
|
sl@0
|
537 |
authObject,label,iToken,keyDetails->Handle(),keyDetails->UsePolicy(),
|
sl@0
|
538 |
keyDetails->ManagementPolicy(),keyDetails->Algorithm(),keyDetails->AccessType(),
|
sl@0
|
539 |
keyDetails->Native(),keyDetails->StartDate(),keyDetails->EndDate(),attribute);
|
sl@0
|
540 |
|
sl@0
|
541 |
CleanupStack::Pop(2, attribute); // label
|
sl@0
|
542 |
CleanupReleasePushL(*keyInfo);
|
sl@0
|
543 |
|
sl@0
|
544 |
User::LeaveIfError(aKeys.Append(keyInfo));
|
sl@0
|
545 |
CleanupStack::Pop(keyInfo);
|
sl@0
|
546 |
|
sl@0
|
547 |
}
|
sl@0
|
548 |
}
|
sl@0
|
549 |
|
sl@0
|
550 |
}
|
sl@0
|
551 |
|
sl@0
|
552 |
/**
|
sl@0
|
553 |
* Takes in a filter and key details and decides if key fulfils the
|
sl@0
|
554 |
* filter criteria.
|
sl@0
|
555 |
*
|
sl@0
|
556 |
* @param aInfo The Key Details
|
sl@0
|
557 |
* @param aFilter Filter specifying the conditions to be satisfied for
|
sl@0
|
558 |
* listing the keys.
|
sl@0
|
559 |
*
|
sl@0
|
560 |
* @retval ETrue if key satisfies the conditions specified in filter
|
sl@0
|
561 |
* @retval EFalse otherwise.
|
sl@0
|
562 |
*
|
sl@0
|
563 |
* @leave KErrArgument If there is an issue in policy filter.
|
sl@0
|
564 |
*/
|
sl@0
|
565 |
TBool CCryptoTokenHai::KeyMatchesFilterL(const CKeyDetails& aInfo,
|
sl@0
|
566 |
const TCTKeyAttributeFilter& aFilter) const
|
sl@0
|
567 |
{
|
sl@0
|
568 |
|
sl@0
|
569 |
if (aFilter.iKeyId.Length() && aFilter.iKeyId != aInfo.ID())
|
sl@0
|
570 |
{
|
sl@0
|
571 |
return EFalse;
|
sl@0
|
572 |
}
|
sl@0
|
573 |
|
sl@0
|
574 |
if (aFilter.iUsage != EPKCS15UsageAll)
|
sl@0
|
575 |
{
|
sl@0
|
576 |
if ((aInfo.Usage() & aFilter.iUsage) == 0)
|
sl@0
|
577 |
return EFalse;
|
sl@0
|
578 |
}
|
sl@0
|
579 |
|
sl@0
|
580 |
if (aFilter.iKeyAlgorithm != CCTKeyInfo::EInvalidAlgorithm &&
|
sl@0
|
581 |
aFilter.iKeyAlgorithm != aInfo.Algorithm())
|
sl@0
|
582 |
{
|
sl@0
|
583 |
return EFalse;
|
sl@0
|
584 |
}
|
sl@0
|
585 |
|
sl@0
|
586 |
switch (aFilter.iPolicyFilter)
|
sl@0
|
587 |
{
|
sl@0
|
588 |
case TCTKeyAttributeFilter::EAllKeys:
|
sl@0
|
589 |
// All keys pass
|
sl@0
|
590 |
break;
|
sl@0
|
591 |
|
sl@0
|
592 |
case TCTKeyAttributeFilter::EUsableKeys:
|
sl@0
|
593 |
if (!aInfo.UsePolicy().CheckPolicy(RThread()))
|
sl@0
|
594 |
{
|
sl@0
|
595 |
return EFalse;
|
sl@0
|
596 |
}
|
sl@0
|
597 |
break;
|
sl@0
|
598 |
case TCTKeyAttributeFilter::EManageableKeys:
|
sl@0
|
599 |
// As this key store implementation is a hardware simulation,
|
sl@0
|
600 |
// the support for managing through software interface has been diabled.
|
sl@0
|
601 |
return EFalse;
|
sl@0
|
602 |
|
sl@0
|
603 |
case TCTKeyAttributeFilter::EUsableOrManageableKeys:
|
sl@0
|
604 |
if (!aInfo.UsePolicy().CheckPolicy(RThread()) &&
|
sl@0
|
605 |
!aInfo.ManagementPolicy().CheckPolicy(RThread()))
|
sl@0
|
606 |
{
|
sl@0
|
607 |
return EFalse;
|
sl@0
|
608 |
}
|
sl@0
|
609 |
break;
|
sl@0
|
610 |
|
sl@0
|
611 |
default:
|
sl@0
|
612 |
User::Leave(KErrArgument);
|
sl@0
|
613 |
}
|
sl@0
|
614 |
|
sl@0
|
615 |
return ETrue;
|
sl@0
|
616 |
}
|
sl@0
|
617 |
|
sl@0
|
618 |
|
sl@0
|
619 |
|