os/security/cryptoservices/filebasedcertificateandkeystores/source/keystore/Server/OpenedKeys.cpp
First public contribution.
2 * Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
19 #include "OpenedKeys.h"
20 #include "cfskeystoreserver.h"
21 #include "keystreamutils.h"
22 #include "fsdatatypes.h"
23 #include "keystorepassphrase.h"
25 #include <asymmetric.h>
26 #include <asymmetrickeys.h>
29 #include <securityerr.h>
31 #include <mctkeystoreuids.h>
33 #ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
34 #include <authserver/authtypes.h>
35 #include <authserver/auth_srv_errs.h>
37 #include "keystore_errs.h"
38 #endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
40 // COpenedKey //////////////////////////////////////////////////////////////////
42 COpenedKey* COpenedKey::NewL(const CFileKeyData& aKeyData, TUid aType, const RMessage2& aMessage,
43 CFileKeyDataManager& aKeyDataMan, CPassphraseManager& aPassMan)
45 COpenedKey* self = NULL;
47 if (aType == KRSARepudiableSignerUID)
49 self = new (ELeave) CRSARepudiableSigner(aKeyData, aKeyDataMan, aPassMan);
51 else if (aType == KDSARepudiableSignerUID)
53 self = new (ELeave) CDSARepudiableSigner(aKeyData, aKeyDataMan, aPassMan);
55 else if (aType == KPrivateDecryptorUID)
57 self = new (ELeave) CFSRSADecryptor(aKeyData, aKeyDataMan, aPassMan);
59 else if (aType == KKeyAgreementUID)
61 self = new (ELeave) CDHAgreement(aKeyData, aKeyDataMan, aPassMan);
68 CleanupStack::PushL(self);
69 self->ConstructL(aMessage);
70 CleanupStack::Pop(self);
74 COpenedKey::COpenedKey(const CFileKeyData& aKeyData, CFileKeyDataManager& aKeyDataMan, CPassphraseManager& aPassMan) :
75 CActive(EPriorityStandard),
77 iKeyDataMan(aKeyDataMan),
79 #ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
81 #endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
85 void COpenedKey::ConstructL(const RMessage2& aMessage)
87 CKeyInfo* keyInfo = iKeyDataMan.ReadKeyInfoLC(iKeyData);
88 CleanupStack::Pop(keyInfo);
91 iLabel = iKeyInfo->Label().AllocL();
92 #ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
93 User::LeaveIfError(iAuthClient.Connect());
94 #endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
95 CActiveScheduler::Add(this);
98 COpenedKey::~COpenedKey()
103 #ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
106 delete iUserIdentity;
107 #endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
111 const TDesC& COpenedKey::Label() const
116 TInt COpenedKey::Handle() const
118 return iKeyData.Handle();
121 void COpenedKey::CheckKeyL(const RMessage2& aMessage)
123 // Check the client is allowed to use the key
124 if (!iKeyInfo->UsePolicy().CheckPolicy(aMessage))
126 User::Leave(KErrPermissionDenied);
129 // Check that the operation represented by this object is supported for this
131 if (iKeyInfo->Algorithm() != Algorithm())
133 User::Leave(KErrKeyAlgorithm);
136 // Check the key usage allows the operation
137 if ((iKeyInfo->Usage() & RequiredUsage()) == 0)
139 User::Leave(KErrKeyUsage);
142 // Check current time is after start date (if set) and before end date (if
145 timeNow.UniversalTime();
146 if (iKeyInfo->StartDate().Int64() != 0 && timeNow < iKeyInfo->StartDate())
148 User::Leave(KErrKeyValidity);
150 if (iKeyInfo->EndDate().Int64() != 0 && timeNow >= iKeyInfo->EndDate())
152 User::Leave(KErrKeyValidity);
157 #ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
158 void COpenedKey::GetPassphrase(TRequestStatus& aStatus)
160 ASSERT(iState == EIdle);
162 TInt timeout = iKeyDataMan.GetPassphraseTimeout();
163 TStreamId passphraseId = iKeyDataMan.DefaultPassphraseId();
164 ASSERT(passphraseId != KNullStreamId);
165 iClientStatus = &aStatus;
167 iPassMan.GetPassphrase(passphraseId, timeout, iPassphrase, iStatus);
168 iState = EGetPassphrase;
172 void COpenedKey::AuthenticateL()
174 iExpression = iAuthClient.CreateAuthExpressionL(iKeyInfo->AuthExpression());
175 TUid uid = TUid::Uid(0);
176 iAuthClient.AuthenticateL(*iExpression,iKeyInfo->Freshness(), EFalse, uid, EFalse, KNullDesC, iUserIdentity, iStatus);
177 iState = EAuthenticate;
180 #endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
182 void COpenedKey::RunL()
184 User::LeaveIfError(iStatus.Int());
188 #ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
189 case EDoAuthenticate:
194 if(iUserIdentity->Id() == AuthServer::KUnknownIdentity)
196 User::Leave(KErrAuthenticationFailure);
201 RStoreReadStream stream;
202 iKeyDataMan.OpenPrivateDataStreamLC(iKeyData, stream);
203 TPtrC8 key = iUserIdentity->Key().KeyData();
204 HBufC8* plaintext = DecryptFromStreamL(stream, key);
205 CleanupStack::PushL(plaintext);
206 TAny* ptr = const_cast<TAny*>(static_cast<const TAny*>(plaintext->Des().PtrZ()));
208 RMemReadStream decryptedStream(ptr, plaintext->Length());
209 decryptedStream.PushL();
210 ReadPrivateKeyL(decryptedStream);
211 CleanupStack::PopAndDestroy(3,&stream); // plaintext, decryptedStream
215 delete iUserIdentity;
216 iUserIdentity = NULL;
227 RStoreReadStream stream;
228 iKeyDataMan.OpenPrivateDataStreamLC(iKeyData, *iPassphrase, stream);
229 ReadPrivateKeyL(stream);
230 CleanupStack::PopAndDestroy(&stream);
236 #endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
242 TInt COpenedKey::RunError(TInt aError)
248 void COpenedKey::DoCancel()
250 Complete(KErrCancel);
253 void COpenedKey::Complete(TInt aError)
259 User::RequestComplete(iClientStatus, aError);
264 void COpenedKey::Cleanup()
266 #ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
267 delete iUserIdentity;
268 iUserIdentity = NULL;
271 #endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
274 // CRSARepudiableSigner ////////////////////////////////////////////////////////
276 CRSARepudiableSigner::CRSARepudiableSigner(const CFileKeyData& aKeyData, CFileKeyDataManager& aKeyDataMan, CPassphraseManager& aPassMan) :
277 COpenedKey(aKeyData, aKeyDataMan, aPassMan)
281 CRSARepudiableSigner::~CRSARepudiableSigner()
286 TUid CRSARepudiableSigner::Type() const
288 return KRSARepudiableSignerUID;
291 CKeyInfo::EKeyAlgorithm CRSARepudiableSigner::Algorithm() const
293 return CKeyInfo::ERSA;
296 TKeyUsagePKCS15 CRSARepudiableSigner::RequiredUsage() const
298 return EPKCS15UsageSignSignRecover;
301 void CRSARepudiableSigner::Sign(const TDesC8& aPlaintext,
302 CRSASignature*& aSignature,
303 TRequestStatus& aStatus)
305 ASSERT(iPlaintext.Ptr() == NULL);
306 ASSERT(iSignaturePtr == NULL);
307 iPlaintext.Set(aPlaintext);
308 iSignaturePtr = &aSignature;
309 #ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
310 GetPassphrase(aStatus);
312 aStatus = KRequestPending;
313 iClientStatus = &aStatus;
314 iState = EDoAuthenticate;
316 TRequestStatus* status = &iStatus;
317 User::RequestComplete(status, KErrNone);
318 #endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
321 void CRSARepudiableSigner::ReadPrivateKeyL(RReadStream& aStream)
323 ASSERT(iPrivateKey == NULL);
324 CreateL(aStream, iPrivateKey);
327 void CRSARepudiableSigner::PerformOperationL()
331 CRSAPKCS1v15Signer* signer = CRSAPKCS1v15Signer::NewLC(*iPrivateKey);
332 const CRSASignature* signature = signer->SignL(iPlaintext);
333 CleanupStack::PopAndDestroy(signer);
334 *iSignaturePtr = const_cast<CRSASignature*>(signature);
337 void CRSARepudiableSigner::Cleanup()
339 #ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
340 COpenedKey::Cleanup();
341 #endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
342 iPlaintext.Set(NULL, 0);
343 iSignaturePtr = NULL;
346 // CDSARepudiableSigner ////////////////////////////////////////////////////////
348 CDSARepudiableSigner::CDSARepudiableSigner(const CFileKeyData& aKeyData, CFileKeyDataManager& aKeyDataMan, CPassphraseManager& aPassMan) :
349 COpenedKey(aKeyData, aKeyDataMan, aPassMan)
353 CDSARepudiableSigner::~CDSARepudiableSigner()
358 TUid CDSARepudiableSigner::Type() const
360 return KDSARepudiableSignerUID;
363 CKeyInfo::EKeyAlgorithm CDSARepudiableSigner::Algorithm() const
365 return CKeyInfo::EDSA;
368 TKeyUsagePKCS15 CDSARepudiableSigner::RequiredUsage() const
370 return EPKCS15UsageSignSignRecover;
373 void CDSARepudiableSigner::Sign(const TDesC8& aPlaintext,
374 CDSASignature*& aSignature,
375 TRequestStatus& aStatus)
377 ASSERT(iPlaintext.Ptr() == NULL);
378 ASSERT(iSignaturePtr == NULL);
379 iPlaintext.Set(aPlaintext);
380 iSignaturePtr = &aSignature;
381 #ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
382 GetPassphrase(aStatus);
384 aStatus = KRequestPending;
385 iClientStatus = &aStatus;
386 iState = EDoAuthenticate;
388 TRequestStatus* status = &iStatus;
389 User::RequestComplete(status, KErrNone);
390 #endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
393 void CDSARepudiableSigner::ReadPrivateKeyL(RReadStream& aStream)
395 ASSERT(iPrivateKey == NULL);
396 CreateL(aStream, iPrivateKey);
399 void CDSARepudiableSigner::PerformOperationL()
403 CDSASigner* signer = CDSASigner::NewLC(*iPrivateKey);
404 const CDSASignature* signature = signer->SignL(iPlaintext);
405 CleanupStack::PopAndDestroy(signer);
406 *iSignaturePtr = const_cast<CDSASignature*>(signature);
409 void CDSARepudiableSigner::Cleanup()
411 #ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
412 COpenedKey::Cleanup();
413 #endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
415 iPlaintext.Set(NULL, 0);
416 iSignaturePtr = NULL;
419 // CFSRSADecryptor /////////////////////////////////////////////////////////////
421 CFSRSADecryptor::CFSRSADecryptor(const CFileKeyData& aKeyData, CFileKeyDataManager& aKeyDataMan, CPassphraseManager& aPassMan) :
422 COpenedKey(aKeyData, aKeyDataMan, aPassMan)
426 CFSRSADecryptor::~CFSRSADecryptor()
431 TUid CFSRSADecryptor::Type() const
433 return KPrivateDecryptorUID;
436 CKeyInfo::EKeyAlgorithm CFSRSADecryptor::Algorithm() const
438 return CKeyInfo::ERSA;
441 TKeyUsagePKCS15 CFSRSADecryptor::RequiredUsage() const
443 return EPKCS15UsageDecryptUnwrap;
446 void CFSRSADecryptor::Decrypt(const TDesC8& aCiphertext,
448 TRequestStatus& aStatus)
450 ASSERT(iCiphertext.Ptr() == NULL);
451 ASSERT(iPlaintextPtr == NULL);
452 iCiphertext.Set(aCiphertext);
453 iPlaintextPtr = &aPlaintext;
454 #ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
455 GetPassphrase(aStatus);
457 aStatus = KRequestPending;
458 iClientStatus = &aStatus;
459 iState = EDoAuthenticate;
461 TRequestStatus* status = &iStatus;
462 User::RequestComplete(status, KErrNone);
463 #endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
466 void CFSRSADecryptor::ReadPrivateKeyL(RReadStream& aStream)
468 ASSERT(iPrivateKey == NULL);
469 CreateL(aStream, iPrivateKey);
472 void CFSRSADecryptor::PerformOperationL()
476 CRSAPKCS1v15Decryptor* decryptor = CRSAPKCS1v15Decryptor::NewLC(*iPrivateKey);
477 HBufC8* plaintext = HBufC8::NewMaxLC(decryptor->MaxOutputLength());
478 TPtr8 ptr = plaintext->Des();
479 decryptor->DecryptL(iCiphertext, ptr);
481 *iPlaintextPtr = plaintext;
482 CleanupStack::Pop(plaintext); // now owned by client
483 CleanupStack::PopAndDestroy(decryptor);
486 void CFSRSADecryptor::Cleanup()
488 #ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
489 COpenedKey::Cleanup();
490 #endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
492 iCiphertext.Set(NULL, 0);
493 iPlaintextPtr = NULL;
496 // CDHAgreement ////////////////////////////////////////////////////////////////
498 CDHAgreement::CDHAgreement(const CFileKeyData& aKeyData, CFileKeyDataManager& aKeyDataMan, CPassphraseManager& aPassMan) :
499 COpenedKey(aKeyData, aKeyDataMan, aPassMan)
503 CDHAgreement::~CDHAgreement()
508 TUid CDHAgreement::Type() const
510 return KKeyAgreementUID;
513 CKeyInfo::EKeyAlgorithm CDHAgreement::Algorithm() const
515 return CKeyInfo::EDH;
518 TKeyUsagePKCS15 CDHAgreement::RequiredUsage() const
520 return EPKCS15UsageDerive;
523 void CDHAgreement::PublicKey(CDHParams& aParameters, RInteger& aPublicKey, TRequestStatus& aStatus)
525 ASSERT(iPKParams == NULL);
526 ASSERT(iPKPublicKeyPtr == NULL);
527 iPKParams = &aParameters;
528 iPKPublicKeyPtr = &aPublicKey;
529 iDHState = EPublicKey;
530 #ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
531 GetPassphrase(aStatus);
533 aStatus = KRequestPending;
534 iClientStatus = &aStatus;
535 iState = EDoAuthenticate;
537 TRequestStatus* status = &iStatus;
538 User::RequestComplete(status, KErrNone);
539 #endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
542 void CDHAgreement::Agree(CDHPublicKey& aY, HBufC8*& aAgreedKey, TRequestStatus& aStatus)
544 ASSERT(iAKPublicKey == NULL);
545 ASSERT(iAKAgreedKeyPtr == NULL);
547 iAKAgreedKeyPtr = &aAgreedKey;
549 #ifndef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
550 GetPassphrase(aStatus);
552 aStatus = KRequestPending;
553 iClientStatus = &aStatus;
554 iState = EDoAuthenticate;
556 TRequestStatus* status = &iStatus;
557 User::RequestComplete(status, KErrNone);
558 #endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
561 void CDHAgreement::ReadPrivateKeyL(RReadStream& aStream)
563 CreateLC(aStream, iKey);
564 CleanupStack::Pop(&iKey);
567 void CDHAgreement::PerformOperationL()
582 void CDHAgreement::DoPublicKeyL()
585 ASSERT(iPKPublicKeyPtr);
587 RInteger n = iPKParams->TakeN();
588 CleanupStack::PushL(n);
589 RInteger g = iPKParams->TakeG();
590 CleanupStack::PushL(g);
591 RInteger x = RInteger::NewL(iKey);
592 CleanupStack::PushL(x);
593 CDHKeyPair* keyPair = CDHKeyPair::NewL(n, g, x);
594 CleanupStack::Pop(3); // x, g, n
595 CleanupStack::PushL(keyPair);
597 const CDHPublicKey& pubKey = keyPair->PublicKey();
598 *iPKPublicKeyPtr = RInteger::NewL(pubKey.X());
599 CleanupStack::PopAndDestroy(keyPair);
602 void CDHAgreement::DoAgreeL()
604 ASSERT(iAKPublicKey);
605 ASSERT(iAKAgreedKeyPtr);
607 RInteger n = RInteger::NewL(iAKPublicKey->N());
608 CleanupStack::PushL(n);
609 RInteger g = RInteger::NewL(iAKPublicKey->G());
610 CleanupStack::PushL(g);
611 RInteger x = RInteger::NewL(iKey);
612 CleanupStack::PushL(x);
613 CDHPrivateKey* privKey = CDHPrivateKey::NewL(n, g, x);
614 CleanupStack::Pop(3); // x, g, n
615 CleanupStack::PushL(privKey);
616 CDH* dh = CDH::NewLC(*privKey);
617 *iAKAgreedKeyPtr = const_cast<HBufC8*>(dh->AgreeL(*iAKPublicKey));
618 CleanupStack::PopAndDestroy(2, privKey);
621 void CDHAgreement::Cleanup()
623 #ifdef SYMBIAN_KEYSTORE_USE_AUTH_SERVER
624 COpenedKey::Cleanup();
625 #endif // SYMBIAN_KEYSTORE_USE_AUTH_SERVER
628 iPKPublicKeyPtr = NULL;
630 iAKAgreedKeyPtr = NULL;