|
1 /* |
|
2 * Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "keystorepassphrase.h" |
|
20 #include "FSDialog.h" |
|
21 #include "pbedata.h" |
|
22 #include "fstokenutil.h" |
|
23 #include <mctauthobject.h> |
|
24 #include <securityerr.h> |
|
25 |
|
26 const int KRetryCount = 3; |
|
27 |
|
28 // TPasswordManager //////////////////////////////////////////////////////////// |
|
29 |
|
30 /*static*/ void TPasswordManager::GetPassword(FSResources::TStrings aLabel, |
|
31 TPINValue& aValue, |
|
32 TRequestStatus& aStatus, |
|
33 TBool aRetry) |
|
34 { |
|
35 TPINParams params; |
|
36 |
|
37 params.iPINLabel = FSResources::Strings()[aLabel]; |
|
38 params.iMinLength = 0; |
|
39 params.iMaxLength = KMaxPINLength; |
|
40 |
|
41 FSDialog::Dialog()->EnterPIN(params, aRetry, aValue, aStatus); |
|
42 } |
|
43 |
|
44 /*static*/ void TPasswordManager::KeystorePassword(TPINValue& aValue, |
|
45 TRequestStatus& aStatus, |
|
46 TBool aRetry) |
|
47 { |
|
48 GetPassword(FSResources::EPinGLabel, aValue, aStatus, aRetry); |
|
49 } |
|
50 |
|
51 /*static*/ void TPasswordManager::CreatePassword(TPINValue& aValue, |
|
52 TRequestStatus& aStatus) |
|
53 { |
|
54 GetPassword(FSResources::ECreatePinGLabel, aValue, aStatus); |
|
55 } |
|
56 |
|
57 /*static*/ void TPasswordManager::ImportPassword(TPINValue& aValue, |
|
58 TRequestStatus& aStatus) |
|
59 { |
|
60 GetPassword(FSResources::EImportPassphraseLabel, aValue, aStatus); |
|
61 } |
|
62 |
|
63 /*static*/ void TPasswordManager::ExportPassword(TPINValue& aValue, |
|
64 TRequestStatus& aStatus) |
|
65 { |
|
66 GetPassword(FSResources::EExportPassphraseLabel, aValue, aStatus); |
|
67 } |
|
68 |
|
69 /*static*/ void TPasswordManager::Cancel() |
|
70 { |
|
71 FSDialog::Dialog()->Cancel(); |
|
72 } |
|
73 |
|
74 |
|
75 // CPassphrase ///////////////////////////////////////////////////////////////// |
|
76 |
|
77 CPassphrase* CPassphrase::NewLC(TInt aTimeout, CStreamStore& aStore, |
|
78 TStreamId aStreamId, const TDesC& aPassphrase) |
|
79 { |
|
80 CPassphrase* self = new (ELeave) CPassphrase(aStore, aTimeout); |
|
81 CleanupStack::PushL(self); |
|
82 self->ConstructL(aStreamId, aPassphrase); |
|
83 return self; |
|
84 } |
|
85 |
|
86 CPassphrase* CPassphrase::NewL(TInt aTimeout, CStreamStore& aStore, |
|
87 TStreamId aStreamId, const TDesC& aPassphrase) |
|
88 { |
|
89 CPassphrase* self = NewLC(aTimeout, aStore, aStreamId, aPassphrase); |
|
90 CleanupStack::Pop(self); |
|
91 return self; |
|
92 } |
|
93 |
|
94 CPassphrase* CPassphrase::NewLC(TInt aTimeout, CStreamStore& aStore, |
|
95 const TDesC& aPassphrase) |
|
96 { |
|
97 CPassphrase* self = new (ELeave) CPassphrase(aStore, aTimeout); |
|
98 CleanupStack::PushL(self); |
|
99 self->ConstructL(aPassphrase); |
|
100 return self; |
|
101 } |
|
102 |
|
103 CPassphrase* CPassphrase::NewL(TInt aTimeout, CStreamStore& aStore, |
|
104 const TDesC& aPassphrase) |
|
105 { |
|
106 CPassphrase* self = NewLC(aTimeout, aStore, aPassphrase); |
|
107 CleanupStack::Pop(self); |
|
108 return self; |
|
109 } |
|
110 |
|
111 CPassphrase::CPassphrase(CStreamStore& aStore, TInt aTimeout) |
|
112 : iStore(aStore) |
|
113 { |
|
114 iExpires = (aTimeout != KTimeoutNever); |
|
115 if (iExpires) |
|
116 { |
|
117 iExpiryTime.UniversalTime(); |
|
118 iExpiryTime += TTimeIntervalSeconds(aTimeout); |
|
119 } |
|
120 } |
|
121 |
|
122 void CPassphrase::ConstructL(TStreamId aStreamId, const TDesC& aPassphrase) |
|
123 { |
|
124 iStreamId = aStreamId; |
|
125 |
|
126 RStoreReadStream stream; |
|
127 stream.OpenLC(iStore, iStreamId); |
|
128 HBufC8* encryptedMasterKey = HBufC8::NewLC(stream, 10000); //some large number |
|
129 CPBEncryptionData* encryptionData = CPBEncryptionData::NewLC(stream); |
|
130 iSecurity = CPBEncryptSet::NewL(*encryptionData, *encryptedMasterKey, aPassphrase); |
|
131 CleanupStack::PopAndDestroy(3); // encryptionData, encryptedMasterKey, stream |
|
132 iSecureStore = CSecureStore::NewL(iStore, *iSecurity); |
|
133 } |
|
134 |
|
135 void CPassphrase::ConstructL(const TDesC& aPassphrase) |
|
136 { |
|
137 TPBPassword password(aPassphrase); |
|
138 iSecurity = CPBEncryptSet::NewL(password, ECipherAES_CBC_256); |
|
139 |
|
140 RStoreWriteStream stream; |
|
141 iStreamId = stream.CreateLC(iStore); |
|
142 stream << iSecurity->EncryptedMasterKey(); |
|
143 iSecurity->EncryptionData().ExternalizeL(stream); |
|
144 stream.CommitL(); |
|
145 CleanupStack::PopAndDestroy(); // stream |
|
146 |
|
147 iSecureStore = CSecureStore::NewL(iStore, *iSecurity); |
|
148 } |
|
149 |
|
150 CPassphrase::~CPassphrase() |
|
151 { |
|
152 delete iSecurity; |
|
153 delete iSecureStore; |
|
154 } |
|
155 |
|
156 TInt CPassphrase::TimeRemainingL(const TTime& aCurrentTime) const |
|
157 { |
|
158 if (iExpires) |
|
159 { |
|
160 TTimeIntervalSeconds seconds; |
|
161 User::LeaveIfError(iExpiryTime.SecondsFrom(aCurrentTime, seconds)); |
|
162 TInt result = seconds.Int(); |
|
163 if (result < 0) |
|
164 { |
|
165 result = 0; |
|
166 } |
|
167 return result; |
|
168 } |
|
169 else |
|
170 { |
|
171 return KTimeoutNever; |
|
172 } |
|
173 } |
|
174 |
|
175 void CPassphrase::RevertStore(TAny* aStore) |
|
176 { |
|
177 // This is a CleanupItem |
|
178 CStreamStore* store = reinterpret_cast<CStreamStore*>(aStore); |
|
179 TRAP_IGNORE(store->RevertL()); |
|
180 } |
|
181 |
|
182 void CPassphrase::ChangePassphraseL(const TDesC& aNewPassphrase) |
|
183 { |
|
184 iSecurity->ChangePasswordL(aNewPassphrase); |
|
185 |
|
186 TCleanupItem cleanupStore(RevertStore, &iStore); |
|
187 CleanupStack::PushL(cleanupStore); |
|
188 |
|
189 RStoreWriteStream stream; |
|
190 stream.ReplaceLC(iStore, iStreamId); |
|
191 stream << iSecurity->EncryptedMasterKey(); |
|
192 iSecurity->EncryptionData().ExternalizeL(stream); |
|
193 stream.CommitL(); |
|
194 CleanupStack::PopAndDestroy(); // stream |
|
195 iStore.CommitL(); |
|
196 CleanupStack::Pop(); // cleanupStore |
|
197 } |
|
198 |
|
199 CStreamStore& CPassphrase::Store() const |
|
200 { |
|
201 return *iSecureStore; |
|
202 } |
|
203 |
|
204 TStreamId CPassphrase::StreamId() const |
|
205 { |
|
206 return iStreamId; |
|
207 } |
|
208 |
|
209 // CPassphraseManager ////////////////////////////////////////////////////////// |
|
210 |
|
211 CPassphraseManager* CPassphraseManager::NewL(CStreamStore& aStore) |
|
212 { |
|
213 return new (ELeave) CPassphraseManager(aStore); |
|
214 } |
|
215 |
|
216 CPassphraseManager::CPassphraseManager(CStreamStore& aStore) |
|
217 : CActive(EPriorityNormal), iStore(aStore) |
|
218 { |
|
219 CActiveScheduler::Add(this); |
|
220 } |
|
221 |
|
222 CPassphraseManager::~CPassphraseManager() |
|
223 { |
|
224 Cancel(); |
|
225 iCache.ResetAndDestroy(); |
|
226 } |
|
227 |
|
228 /** Return a cached passphrase if present, otherwise return NULL. */ |
|
229 CPassphrase* CPassphraseManager::GetCachedPassphrase(TStreamId aStreamId) |
|
230 { |
|
231 for (TInt i = 0 ; i < iCache.Count() ; ++i) |
|
232 { |
|
233 CPassphrase* p = iCache[i]; |
|
234 if (p->StreamId() == aStreamId) |
|
235 { |
|
236 return p; |
|
237 } |
|
238 } |
|
239 |
|
240 return NULL; |
|
241 } |
|
242 |
|
243 void CPassphraseManager::GetPassphrase(TStreamId aStreamId, |
|
244 TInt aTimeout, |
|
245 CPassphrase*& aPassphrase, |
|
246 TRequestStatus& aStatus) |
|
247 { |
|
248 ASSERT(iTimeout >= KTimeoutNever); |
|
249 CPassphrase* p = GetCachedPassphrase(aStreamId); |
|
250 if (p) |
|
251 { |
|
252 aPassphrase = p; |
|
253 TRequestStatus* status = &aStatus; |
|
254 User::RequestComplete(status, KErrNone); |
|
255 } |
|
256 else |
|
257 { |
|
258 iRetries = KRetryCount; |
|
259 iClientStatus = &aStatus; |
|
260 aStatus = KRequestPending; |
|
261 iNewPassphraseStream = aStreamId; |
|
262 iTimeout = aTimeout; |
|
263 iNewPassphrasePtr = &aPassphrase; |
|
264 iState = EGetPassphrase; |
|
265 TPasswordManager::KeystorePassword(iNewPassphrase, iStatus); |
|
266 SetActive(); |
|
267 } |
|
268 } |
|
269 |
|
270 void CPassphraseManager::CreatePassphrase(TInt aTimeout, |
|
271 CPassphrase*& aPassphrase, |
|
272 TRequestStatus& aStatus) |
|
273 { |
|
274 ASSERT(iTimeout >= -1); |
|
275 iClientStatus = &aStatus; |
|
276 aStatus = KRequestPending; |
|
277 iTimeout = aTimeout; |
|
278 iNewPassphrasePtr = &aPassphrase; |
|
279 iState = ECreatePassphrase; |
|
280 TPasswordManager::CreatePassword(iNewPassphrase, iStatus); |
|
281 SetActive(); |
|
282 } |
|
283 |
|
284 void CPassphraseManager::ChangePassphrase(TStreamId aStreamId, TRequestStatus& aStatus) |
|
285 { |
|
286 iRetries = KRetryCount; |
|
287 iClientStatus = &aStatus; |
|
288 aStatus = KRequestPending; |
|
289 iNewPassphraseStream = aStreamId; |
|
290 iState = EChangePassphrase; |
|
291 |
|
292 TPINParams params; |
|
293 params.iPINLabel = |
|
294 FSResources::Strings()[FSResources::EPinGLabel]; |
|
295 params.iMinLength = 0; |
|
296 params.iMaxLength = KMaxPINLength; |
|
297 |
|
298 FSDialog::Dialog()->ChangePIN(params, EFalse, iOldPassphrase, iNewPassphrase, iStatus); |
|
299 SetActive(); |
|
300 } |
|
301 |
|
302 void CPassphraseManager::RunL() |
|
303 { |
|
304 User::LeaveIfError(iStatus.Int()); |
|
305 |
|
306 switch (iState) |
|
307 { |
|
308 case EGetPassphrase: |
|
309 { |
|
310 TRAPD(err, HandleGetPassphraseL()); |
|
311 if (err == KErrBadPassphrase && --iRetries > 0) |
|
312 { |
|
313 TPasswordManager::KeystorePassword(iNewPassphrase, iStatus, ETrue); |
|
314 SetActive(); |
|
315 } |
|
316 else |
|
317 { |
|
318 User::LeaveIfError(err); |
|
319 } |
|
320 } |
|
321 break; |
|
322 |
|
323 case ECreatePassphrase: |
|
324 { |
|
325 CPassphrase* phrase = CPassphrase::NewLC(iTimeout, iStore, |
|
326 iNewPassphrase); |
|
327 *iNewPassphrasePtr = phrase; |
|
328 User::LeaveIfError(iCache.Append(phrase)); |
|
329 CleanupStack::Pop(phrase); |
|
330 Complete(KErrNone); |
|
331 } |
|
332 break; |
|
333 |
|
334 case EChangePassphrase: |
|
335 { |
|
336 CPassphrase* phrase = NULL; |
|
337 TRAPD(err, phrase = CPassphrase::NewL( 0, |
|
338 iStore, |
|
339 iNewPassphraseStream, |
|
340 iOldPassphrase)); |
|
341 |
|
342 if(KErrBadPassphrase == err && --iRetries > 0) |
|
343 { |
|
344 TPINParams params; |
|
345 params.iPINLabel = FSResources::Strings()[FSResources::EPinGLabel]; |
|
346 params.iMinLength = 0; |
|
347 params.iMaxLength = KMaxPINLength; |
|
348 |
|
349 FSDialog::Dialog()->ChangePIN(params, ETrue, iOldPassphrase, iNewPassphrase, iStatus); |
|
350 SetActive(); |
|
351 break; |
|
352 } |
|
353 |
|
354 if(KErrNone != err) |
|
355 { |
|
356 User::Leave(err); |
|
357 } |
|
358 |
|
359 CleanupStack::PushL(phrase); |
|
360 |
|
361 phrase->ChangePassphraseL(iNewPassphrase); |
|
362 RemoveCachedPassphrases(phrase->StreamId()); |
|
363 CleanupStack::PopAndDestroy(phrase); |
|
364 Complete(KErrNone); |
|
365 } |
|
366 break; |
|
367 |
|
368 default: |
|
369 PanicServer(EPanicInvalidState); |
|
370 } |
|
371 |
|
372 } |
|
373 |
|
374 void CPassphraseManager::HandleGetPassphraseL() |
|
375 { |
|
376 CPassphrase* phrase = CPassphrase::NewLC(iTimeout, iStore, |
|
377 iNewPassphraseStream, |
|
378 iNewPassphrase); |
|
379 *iNewPassphrasePtr = phrase; |
|
380 User::LeaveIfError(iCache.Append(phrase)); |
|
381 CleanupStack::Pop(phrase); |
|
382 Complete(KErrNone); |
|
383 } |
|
384 |
|
385 TInt CPassphraseManager::RunError(TInt aError) |
|
386 { |
|
387 Complete(aError); |
|
388 return KErrNone; |
|
389 } |
|
390 |
|
391 void CPassphraseManager::DoCancel() |
|
392 { |
|
393 TPasswordManager::Cancel(); |
|
394 RunError(KErrCancel); |
|
395 } |
|
396 |
|
397 void CPassphraseManager::Complete(TInt aError) |
|
398 { |
|
399 iNewPassphrasePtr = NULL; |
|
400 iState = EIdle; |
|
401 if (iClientStatus) |
|
402 { |
|
403 User::RequestComplete(iClientStatus, aError); |
|
404 } |
|
405 } |
|
406 |
|
407 void CPassphraseManager::ExpireCacheL() |
|
408 { |
|
409 TTime timeNow; |
|
410 timeNow.UniversalTime(); |
|
411 |
|
412 for (TInt i = iCache.Count() - 1; i >= 0; --i) |
|
413 { |
|
414 CPassphrase* passphrase = iCache[i]; |
|
415 if (passphrase->TimeRemainingL(timeNow) == 0) |
|
416 { |
|
417 iCache.Remove(i); |
|
418 delete passphrase; |
|
419 } |
|
420 } |
|
421 } |
|
422 |
|
423 void CPassphraseManager::RemoveCachedPassphrases(TStreamId aStreamId) |
|
424 { |
|
425 for (TInt i = iCache.Count() - 1; i >= 0; --i) |
|
426 { |
|
427 CPassphrase* passphrase = iCache[i]; |
|
428 if (aStreamId == KNullStreamId || passphrase->StreamId() == aStreamId) |
|
429 { |
|
430 iCache.Remove(i); |
|
431 delete passphrase; |
|
432 } |
|
433 } |
|
434 } |
|
435 |
|
436 TInt CPassphraseManager::TimeRemainingL(TStreamId aStreamId) |
|
437 { |
|
438 CPassphrase* passphrase = GetCachedPassphrase(aStreamId); |
|
439 if (passphrase) |
|
440 { |
|
441 TTime timeNow; |
|
442 timeNow.UniversalTime(); |
|
443 return passphrase->TimeRemainingL(timeNow); |
|
444 } |
|
445 else |
|
446 { |
|
447 return 0; |
|
448 } |
|
449 } |