--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pkiutilities/DeviceToken/Src/TruSitesStore/Server/TrustedSitesServer.cpp Tue Jan 26 15:20:08 2010 +0200
@@ -0,0 +1,1436 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Implementation of TrustedSitesStoreServer
+*
+*/
+
+
+
+#include "TrustedSitesServer.h"
+#include "TrustedSitesConduit.h"
+#include "TrustedSitesSession.h"
+#include "DevTokenCliServ.h"
+#include "DevTokenUtil.h"
+#include "DevTokenDataTypes.h"
+#include "DevTokenServer.h"
+#include "DevandTruSrvCertStoreServer.h"
+#include <x509cert.h>
+#include <ccertattributefilter.h>
+#include <e32cmn.h>
+#include <badesca.h>
+
+_LIT(KTrustedSitesStoreFilename,"TrustedSitesStore.dat");
+// Maximum length of SQL query clause
+const TInt KMaxSQLLength = 256;
+
+// API policing
+_LIT_SECURITY_POLICY_C1(KReadSecurityPolicy, ECapabilityReadUserData);
+_LIT_SECURITY_POLICY_C1(KWriteSecurityPolicy, ECapabilityWriteDeviceData);
+
+// ======== MEMBER FUNCTIONS ========
+
+//CTrustedSitesServer
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::NewL()
+// ---------------------------------------------------------------------------
+//
+CTrustedSitesServer* CTrustedSitesServer::NewL( CDevTokenServer* aServer )
+ {
+ CTrustedSitesServer* self = new (ELeave) CTrustedSitesServer( aServer );
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::CTrustedSitesServer()
+// ---------------------------------------------------------------------------
+//
+CTrustedSitesServer::CTrustedSitesServer( CDevTokenServer* aServer ) :
+ iServer ( aServer )
+ {
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::ConstructL()
+// ---------------------------------------------------------------------------
+//
+void CTrustedSitesServer::ConstructL()
+ {
+ iConduit = CTrustedSitesConduit::NewL(*this);
+
+ User::LeaveIfError( iFs.Connect() );
+
+ TBuf<KMaxFilenameLength> filename;
+
+ FileUtils::MakePrivateFilenameL(iFs, KTrustedSitesStoreFilename, filename);
+
+ TInt err = iDatabase.Open( iFs, filename );
+
+ if ( err != KErrNone )
+ {
+ CreateDBL(); // Create DB
+ User::LeaveIfError( iDatabase.Open( iFs, filename ) );
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::CreateDBL()
+// ---------------------------------------------------------------------------
+//
+void CTrustedSitesServer::CreateDBL()
+ {
+
+ RFs fsSession;
+ User::LeaveIfError( fsSession.Connect() ); // Connect to file server
+
+ CleanupClosePushL( fsSession );
+
+ RDbNamedDatabase database;
+
+ TBuf<KMaxFilenameLength> filename;
+
+ FileUtils::MakePrivateFilenameL(fsSession, KTrustedSitesStoreFilename, filename);
+
+ FileUtils::EnsurePathL(fsSession, filename);
+ CleanupClosePushL( database );
+
+ User::LeaveIfError( database.Create( fsSession, filename ) );
+
+ // Create tables
+
+ // Trusted sites table
+ _LIT( KSQLCreateTable1, "CREATE TABLE Certificates (\
+ CertID COUNTER NOT NULL,\
+ CertHash CHAR(20) NOT NULL)");
+
+ _LIT( KSQLCreateTable2, "CREATE TABLE TrustedSites (\
+ CertID INTEGER,\
+ SiteName VARCHAR(100) NOT NULL,\
+ Forgiven INTEGER NOT NULL,\
+ OutOfDate INTEGER NOT NULL,\
+ ClientUID INTEGER NOT NULL )");
+
+ User::LeaveIfError( database.Execute( KSQLCreateTable1 ) );
+ User::LeaveIfError( database.Execute( KSQLCreateTable2 ) );
+
+ CleanupStack::PopAndDestroy( 2 ); // database, fsSession
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::~CTrustedSitesServer()
+// ---------------------------------------------------------------------------
+//
+CTrustedSitesServer::~CTrustedSitesServer()
+ {
+ delete iConduit;
+ iDatabase.Close(); // Close database
+ iFs.Close();
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::CreateSessionL()
+// ---------------------------------------------------------------------------
+//
+CTrustedSitesSession* CTrustedSitesServer::CreateSessionL()
+ {
+ return CTrustedSitesSession::NewL(*iConduit);
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::AddL()
+// ---------------------------------------------------------------------------
+//
+void CTrustedSitesServer::AddL(const TDesC8& aCertHash, const TDesC& aSiteName, const RMessage2& aMessage )
+ {
+ // API policing
+ if (!KWriteSecurityPolicy.CheckPolicy(aMessage))
+ {
+ User::Leave(KErrPermissionDenied);
+ }
+
+ TInt certID;
+ GetCertIDL( aCertHash, certID ); // Get certificate ID
+
+ if ( certID == KErrNotFound ) // Not found
+ {
+ iDatabase.Begin(); // Begin transaction
+
+ TRAPD( err, DoAddCertL( aCertHash ));
+
+ if ( err ) // Some error occurred
+ {
+ iDatabase.Rollback(); // Rollback changes
+ User::Leave ( err );
+ }
+ else
+ {
+ iDatabase.Commit(); // Commit changes
+ }
+
+ GetCertIDL( aCertHash, certID );
+
+ if( certID == KErrNotFound )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ iDatabase.Begin();
+
+ TRAP( err, DoAddSiteNameL( certID, aSiteName ));
+
+ if ( err ) // Some error occurred
+ {
+ iDatabase.Rollback(); // Rollback changes
+ User::Leave ( err );
+ }
+ else
+ {
+ iDatabase.Commit(); // Commit changes
+ }
+ }
+ else
+ {
+ if(IsSiteAlreadyExistL( certID, aSiteName ))
+ {
+ return;
+ }
+ else
+ {
+ iDatabase.Begin(); // Begin transaction
+
+ TRAPD( err, DoAddSiteNameL( certID, aSiteName ));
+
+ if ( err ) // Some error occurred
+ {
+ iDatabase.Rollback(); // Rollback changes
+ User::Leave ( err );
+ }
+ else
+ {
+ iDatabase.Commit(); // Commit changes
+ }
+ return;
+ }
+ }
+
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::AddL()
+// ---------------------------------------------------------------------------
+//
+void CTrustedSitesServer::AddL(const TDesC8& aCertHash, const TDesC& aSiteName )
+ {
+ TInt certID;
+ GetCertIDL( aCertHash, certID ); // Get certificate ID
+
+ if ( certID == KErrNotFound ) // Not found
+ {
+ iDatabase.Begin(); // Begin transaction
+
+ TRAPD( err, DoAddCertL( aCertHash ));
+
+ if ( err ) // Some error occurred
+ {
+ iDatabase.Rollback(); // Rollback changes
+ User::Leave ( err );
+ }
+ else
+ {
+ iDatabase.Commit(); // Commit changes
+ }
+
+ GetCertIDL( aCertHash, certID );
+
+ if( certID == KErrNotFound )
+ {
+ User::Leave( KErrNotFound );
+ }
+
+ iDatabase.Begin();
+
+ TRAP( err, DoAddSiteNameL( certID, aSiteName ));
+
+ if ( err ) // Some error occurred
+ {
+ iDatabase.Rollback(); // Rollback changes
+ User::Leave ( err );
+ }
+ else
+ {
+ iDatabase.Commit(); // Commit changes
+ }
+ }
+ else
+ {
+ if(IsSiteAlreadyExistL( certID, aSiteName ))
+ {
+ return;
+ }
+ else
+ {
+ iDatabase.Begin(); // Begin transaction
+
+ TRAPD( err, DoAddSiteNameL( certID, aSiteName ));
+
+ if ( err ) // Some error occurred
+ {
+ iDatabase.Rollback(); // Rollback changes
+ User::Leave ( err );
+ }
+ else
+ {
+ iDatabase.Commit(); // Commit changes
+ }
+ return;
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::GetCertIDL()
+// ---------------------------------------------------------------------------
+//
+void CTrustedSitesServer::GetCertIDL( const TDesC8& aCertHash, TInt& aCertID )
+ {
+ _LIT( KSQLQuery, "SELECT CertID,\
+ CertHash\
+ FROM Certificates" );
+
+ RDbView view;
+
+ User::LeaveIfError( view.Prepare( iDatabase, TDbQuery( KSQLQuery ) ) );
+
+ CleanupClosePushL( view );
+
+ // Get data
+ TInt i = 0;
+
+ while ( i == 0 && view.NextL() ) // Should find only one ID
+ {
+ view.GetL();
+
+ if ( !view.ColDes8( 2 ).Compare( aCertHash ) )
+ {
+ aCertID = view.ColUint32( 1 );
+ i++;
+ }
+ }
+
+ if ( i == 0 ) // Not found any matching rows
+ {
+ aCertID = KErrNotFound;
+ }
+
+ CleanupStack::PopAndDestroy( 1 ); // view
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::DoAddSiteNameL()
+// ---------------------------------------------------------------------------
+//
+void CTrustedSitesServer::DoAddSiteNameL(const TInt& aCertID, const TDesC& aSiteName )
+ {
+ //insert the normal trusted site record,not for forgiven site
+ TBuf<KMaxSQLLength> SQL;
+
+ _LIT( KSQLInsert1,
+ "INSERT INTO TrustedSites (CertID,SiteName,Forgiven,OutOfDate,ClientUID) VALUES (" );
+
+ SQL.Copy(KSQLInsert1);
+ SQL.AppendNum(aCertID);
+ SQL.Append(_L(",'"));
+
+ SQL.Append( aSiteName );
+ SQL.Append(_L("',"));
+ //not forgiven
+ SQL.AppendNum(0);
+ SQL.Append(_L(","));
+ //not allowed out of date
+ SQL.AppendNum(0);
+ //set the UID to -1 since in the normal case we don't need the information
+ SQL.Append(_L(","));
+ SQL.AppendNum(-1);
+ SQL.Append(_L(")"));
+
+ User::LeaveIfError( iDatabase.Execute( SQL ) );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::DoAddCertL()
+// ---------------------------------------------------------------------------
+//
+void CTrustedSitesServer::DoAddCertL( const TDesC8& aCertHash )
+ {
+ RDbView view;
+
+ _LIT( KSQLInsertCert, "SELECT CertHash\
+ FROM Certificates" );
+
+ User::LeaveIfError( view.Prepare( iDatabase, TDbQuery( KSQLInsertCert ),
+ TDbWindow::EUnlimited, RDbView::EInsertOnly ) );
+
+ CleanupClosePushL( view );
+
+ view.InsertL();
+ view.SetColL( 1, aCertHash );
+ view.PutL();
+
+ CleanupStack::PopAndDestroy( 1 );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::IsSiteAlreadyExistL()
+// ---------------------------------------------------------------------------
+//
+TBool CTrustedSitesServer::IsSiteAlreadyExistL(const TInt& aCertID, const TDesC& aSiteName)
+ {
+ RDbView view;
+ _LIT( KSQLQuery,
+ "SELECT SiteName FROM TrustedSites WHERE certID = " );
+
+ TBuf<KMaxSQLLength> SQLStatement;
+ SQLStatement.Copy( KSQLQuery );
+
+ SQLStatement.AppendNum( aCertID );
+
+ TPtrC sqlStat( SQLStatement.PtrZ() );
+
+ TInt err = view.Prepare( iDatabase, TDbQuery( sqlStat ), TDbWindow::EUnlimited );
+
+ if ( err != KErrNone )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ err = view.EvaluateAll();
+
+ CleanupClosePushL( view );
+
+ TBool alreadyExist = EFalse;
+ // Get data
+ while ( view.NextL() ) // Should find only one certificate
+ {
+ TRAPD(error, view.GetL());
+ error = error;
+ if(!aSiteName.Compare(view.ColDes( 1 )))
+ {
+ alreadyExist = ETrue;
+ break;
+ }
+ }
+ CleanupStack::PopAndDestroy( 1 );
+ return alreadyExist;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::IsOutOfDateAllowedForTheSiteL()
+// ---------------------------------------------------------------------------
+//
+TBool CTrustedSitesServer::IsOutOfDateAllowedForTheSiteL( const TInt& aCertID, const TDesC& aSiteName )
+ {
+ RDbView view;
+ _LIT( KSQLQuery,
+ "SELECT SiteName,OutOfDate FROM TrustedSites WHERE certID = " );
+
+ TBuf<KMaxSQLLength> SQLStatement;
+ SQLStatement.Copy( KSQLQuery );
+
+ SQLStatement.AppendNum( aCertID );
+
+ TPtrC sqlStat( SQLStatement.PtrZ() );
+
+ TInt err = view.Prepare( iDatabase, TDbQuery( sqlStat ), TDbWindow::EUnlimited );
+
+ if ( err != KErrNone )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ err = view.EvaluateAll();
+
+ CleanupClosePushL( view );
+
+ TBool outofdate = EFalse;
+ // Get data
+ while ( view.NextL() ) // Should find only one certificate
+ {
+ TRAPD(error, view.GetL());
+ error = error;
+
+ if ( (!aSiteName.Compare( view.ColDes( 1 ) ) ) && ( view.ColInt( 2 ) == 1 ) )
+ {
+ outofdate = ETrue;
+ break;
+ }
+ }
+
+ CleanupStack::PopAndDestroy( 1 ); //view
+ return outofdate;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::IsTrustedSiteL()
+// ---------------------------------------------------------------------------
+//
+TBool CTrustedSitesServer::IsTrustedSiteL( const TDesC8& aCertHash, const TDesC& aSiteName, const TDesC8& aCert, const RMessage2& aMessage )
+ {
+ // API policing
+ if (!KReadSecurityPolicy.CheckPolicy(aMessage))
+ {
+ User::Leave(KErrPermissionDenied);
+ }
+
+ //is it a forgiven site
+ if ( IsForgivenSiteAlreadyL( aSiteName ) )
+ {
+ // Insert the certificate into database
+ DoOverWriteCertL( aSiteName, aCertHash );
+
+ //check if the certificate is already existing
+ CCertAttributeFilter* filter = CCertAttributeFilter::NewL();
+ CleanupStack::PushL(filter);
+ filter->SetOwnerType(EPeerCertificate);
+ RPointerArray<CDevTokenCertInfo> certs;
+ RMessage2 message;
+ iServer->CertStoreServerL().ListL( *filter,certs,message, ETrue );
+
+ CleanupStack::PopAndDestroy(); //filter
+
+ TBool exist = EFalse;
+ if ( certs.Count() )
+ {
+ for (TInt i= 0; i<certs.Count();i++)
+ {
+ HBufC8* certData = iServer->CertStoreServerL().RetrieveLC( certs[i]->CertificateId(),message,ETrue );
+ TPtr8 certPtr = certData->Des();
+
+ //certificate from trusted server certstore
+ CX509Certificate* cert = CX509Certificate::NewLC( certPtr );
+ //certificate from client
+ CX509Certificate* cert2 = CX509Certificate::NewLC( aCert );
+
+ if ( cert->Fingerprint() == cert2->Fingerprint() )
+ {
+ exist = ETrue;
+ CleanupStack::PopAndDestroy(3); //cert, cert2, certData
+ break;
+ }
+
+ CleanupStack::PopAndDestroy(3); //cert, cert2, certData
+ }
+ }
+
+ if ( exist )
+ {
+ //server certificate has saved already, no need to save again
+ return ETrue;
+ }
+
+ TDevTokenAddCertDataStruct data;
+ data.iLabel.Zero();
+ data.iSubjectKeyId.Zero();
+
+ CX509Certificate* cert = CX509Certificate::NewL(aCert);
+ data.iSubjectKeyId.Copy( cert->KeyIdentifierL() );
+ delete cert;
+
+ data.iIssuerKeyId.Zero();
+ data.iLabel.Copy(aSiteName);
+ data.iFormat = EX509Certificate;
+ data.iCertificateOwnerType = EPeerCertificate;
+
+ iServer->CertStoreServerL().AddL( data, aCert, aMessage, ETrue ) ;
+
+ return ETrue;
+ }
+
+ //It isn't a forgiven site, query in the normal way to check whether it is trusted by the user
+ TInt certID;
+ GetCertIDL( aCertHash, certID ); // Get certificate ID
+
+ if ( certID == KErrNotFound ) // Not found
+ {
+ return EFalse;
+ }
+ else
+ {
+ if(IsSiteAlreadyExistL( certID, aSiteName ))
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+ }
+
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::IsOutOfDateAllowedL()
+// ---------------------------------------------------------------------------
+//
+TBool CTrustedSitesServer::IsOutOfDateAllowedL( const TDesC8& aCertHash, const TDesC& aSiteName, const RMessage2& aMessage )
+ {
+ // API policing
+ if (!KReadSecurityPolicy.CheckPolicy(aMessage))
+ {
+ User::Leave(KErrPermissionDenied);
+ }
+
+ TInt certID;
+ GetCertIDL( aCertHash, certID ); // Get certificate ID
+
+ if ( certID == KErrNotFound ) // Not found
+ {
+ return EFalse;
+ }
+ else
+ {
+ if(IsOutOfDateAllowedForTheSiteL( certID, aSiteName ))
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::GetTrustedSitesL()
+// ---------------------------------------------------------------------------
+//
+void CTrustedSitesServer::GetTrustedSitesL( const TDesC8& aCertHash,
+ RPointerArray<HBufC>& aListOfSites,
+ const RMessage2& aMessage)
+ {
+ // API policing
+ if (!KReadSecurityPolicy.CheckPolicy(aMessage))
+ {
+ User::Leave(KErrPermissionDenied);
+ }
+
+ TInt certID;
+ GetCertIDL( aCertHash, certID );
+
+ if( certID == KErrNotFound )
+ {
+ User::Leave( KErrNotFound );
+ }
+ DoGetTrustedSitesL( certID, aListOfSites );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::DoGetTrustedSitesL()
+// ---------------------------------------------------------------------------
+//
+void CTrustedSitesServer::DoGetTrustedSitesL( const TInt& aCertID,
+ RPointerArray<HBufC>& aListOfSites)
+ {
+ RDbView view;
+ _LIT( KSQLQuery,
+ "SELECT SiteName FROM TrustedSites WHERE certID = " );
+
+ TBuf<KMaxSQLLength> SQLStatement;
+ SQLStatement.Copy( KSQLQuery );
+
+ SQLStatement.AppendNum( aCertID );
+
+ TPtrC sqlStat( SQLStatement.PtrZ() );
+
+ TInt err = view.Prepare( iDatabase, TDbQuery( sqlStat ), TDbWindow::EUnlimited );
+
+ if ( err != KErrNone )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ err = view.EvaluateAll();
+
+ CleanupClosePushL( view );
+
+ // Get data
+ while ( view.NextL() ) // Should find only one certificate
+ {
+ TRAPD(error, view.GetL());
+ error = error;
+ HBufC* temp = HBufC::NewL(KMaxSiteName);
+ TPtr ptrTemp = temp->Des();
+ ptrTemp.Copy(view.ColDes( 1 ));
+ aListOfSites.Append(temp);
+ }
+ CleanupStack::PopAndDestroy( 1 );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::RemoveL()
+// ---------------------------------------------------------------------------
+//
+void CTrustedSitesServer::RemoveL( const TDesC8& aCertHash )
+ {
+ TInt certID;
+ GetCertIDL( aCertHash, certID );
+
+ if( certID == KErrNotFound )
+ {
+ User::Leave( KErrNotFound );
+ }
+ CCertAttributeFilter* filter = CCertAttributeFilter::NewL();
+ CleanupStack::PushL(filter);
+ filter->SetOwnerType(EPeerCertificate);
+ RPointerArray<CDevTokenCertInfo> certs;
+ RMessage2 message;
+ iServer->CertStoreServerL().ListL(*filter,certs,message, ETrue );
+
+ CleanupStack::PopAndDestroy(); //filter
+
+ TBool stillexist = EFalse;
+ if ( certs.Count() )
+ {
+ for (TInt i= 0; i<certs.Count();i++)
+ {
+ HBufC8* certData = iServer->CertStoreServerL().RetrieveLC( certs[i]->CertificateId(),message,ETrue );
+
+ TPtr8 certPtr = certData->Des();
+
+ CX509Certificate* cert = CX509Certificate::NewLC( certPtr );
+
+ if ( cert->Fingerprint() == aCertHash )
+ {
+ stillexist = ETrue;
+ CleanupStack::PopAndDestroy( 2 ); //certData, cert
+ break;
+ }
+
+ CleanupStack::PopAndDestroy( 2 ); //certData, cert
+ }
+ }
+
+ if ( stillexist )
+ {
+ //there are still same server certificate saved in cert store
+ //with different label, doesn't delete information then
+ return;
+ }
+ iDatabase.Begin(); // Begin transaction
+
+ TRAPD( err, DoRemoveL( certID ));
+
+ if ( err ) // Some error occurred
+ {
+ iDatabase.Rollback(); // Rollback changes
+ User::Leave ( err );
+ }
+ else
+ {
+ iDatabase.Commit(); // Commit changes
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::DoRemoveL()
+// ---------------------------------------------------------------------------
+//
+void CTrustedSitesServer::DoRemoveL(const TInt& aCertID )
+ {
+ _LIT( KSQLDelete1, "DELETE FROM Certificates WHERE CertID = " );
+ _LIT( KSQLDelete2, "DELETE FROM TrustedSites WHERE CertID = " );
+
+ TBuf<KMaxSQLLength> SQLStatement1;
+ TBuf<KMaxSQLLength> SQLStatement2;
+
+ SQLStatement1.Copy( KSQLDelete1 );
+ SQLStatement1.AppendNum( aCertID );
+ TPtrC sqlStat1( SQLStatement1.PtrZ() );
+
+ SQLStatement2.Copy( KSQLDelete2 );
+ SQLStatement2.AppendNum( aCertID );
+ TPtrC sqlStat2( SQLStatement2.PtrZ() );
+
+ User::LeaveIfError( iDatabase.Execute( sqlStat1) );
+ User::LeaveIfError( iDatabase.Execute( sqlStat2 ) );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::AddForgivenSiteL()
+// ---------------------------------------------------------------------------
+//
+void CTrustedSitesServer::AddForgivenSiteL( const TDesC& aSite, const TBool& aOutOfDateAllowed, const RMessage2& aMessage )
+ {
+ // API policing,WriteDeviceData
+ if (!KWriteSecurityPolicy.CheckPolicy(aMessage))
+ {
+ User::Leave(KErrPermissionDenied);
+ }
+
+ if ( IsForgivenSiteAlreadyL( aSite ) )
+ {
+ //the hostname is in table already.
+ DoOverWriteOutOfDateL( aSite, aOutOfDateAllowed );
+ return;
+ }
+ else
+ {
+ iDatabase.Begin(); // Begin transaction
+
+ TRAPD( err, DoAddForgivenSiteL( aSite, aOutOfDateAllowed, aMessage.SecureId().iId ));
+
+ if ( err ) // Some error occurred
+ {
+ iDatabase.Rollback(); // Rollback changes
+ User::Leave ( err );
+ }
+ else
+ {
+ iDatabase.Commit(); // Commit changes
+ }
+ }
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::RemoveAllForgivenSitesL()
+// ---------------------------------------------------------------------------
+//
+void CTrustedSitesServer::RemoveAllForgivenSitesL( const RMessage2& aMessage )
+ {
+ // API policing,WriteDeviceData
+ if (!KWriteSecurityPolicy.CheckPolicy(aMessage))
+ {
+ User::Leave(KErrPermissionDenied);
+ }
+
+ // get certid arrays for the ClientUID
+ RDbView view;
+ _LIT( KSQLQuery,
+ "SELECT SiteName,CertID FROM TrustedSites WHERE ClientUID = " );
+
+ TBuf<KMaxSQLLength> SQLStatement;
+ SQLStatement.Copy( KSQLQuery );
+
+ SQLStatement.AppendNum( aMessage.SecureId().iId );
+
+ TPtrC sqlStat( SQLStatement.PtrZ() );
+
+ TInt err = view.Prepare( iDatabase, TDbQuery( sqlStat ), TDbWindow::EUnlimited );
+
+ if ( err != KErrNone )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ err = view.EvaluateAll();
+
+ CleanupClosePushL( view );
+
+ RArray<TInt> certIDs;
+ RArray<TInt> certIDs2;
+ if ( view.CountL() )
+ {
+ // Get data
+ while ( view.NextL() ) // Should find only one certificate
+ {
+ TRAPD(error, view.GetL());
+ error = error;
+ certIDs.Append( view.ColInt( 2 ) );
+ }
+ CleanupStack::PopAndDestroy( 1 ); //view
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy( 1 ); //view
+ //no match found, nothing to delete
+ return;
+ }
+
+ if ( certIDs.Count() == 0 )
+ {
+ //no cert id, just return;
+ return;
+ }
+
+ //the certID may contain -1, then no need to delete the certificate but go to delete the site directly
+ //filter the -1 out.
+ for ( TInt i = 0; i < certIDs.Count() ; i++ )
+ {
+ if ( certIDs[i] != -1 )
+ {
+ certIDs2.Append( certIDs[i] );
+ }
+ }
+
+ // if certid2 is not empty, it means there are certificates associated with the sitename,
+ // we should delete it.
+ if ( certIDs2.Count() > 0 )
+ {
+ // get the certhash array for certid arrays
+ //the desc8 array to put the certhash
+ TInt num = certIDs2.Count();
+ CDesC8ArrayFlat* descarray = new (ELeave) CDesC8ArrayFlat( num );
+ CleanupStack::PushL( descarray );
+
+ for ( TInt i = 0; i < certIDs2.Count(); i++ )
+ {
+ //empty the previous command
+ SQLStatement.Zero();
+ _LIT( KSQLQuery, "SELECT CertHash FROM Certificates WHERE CertID =" );
+ SQLStatement.Append( KSQLQuery );
+ SQLStatement.AppendNum( certIDs2[i] );
+
+ TPtrC sqlStat1( SQLStatement.PtrZ() );
+
+ TInt err = view.Prepare( iDatabase, TDbQuery( sqlStat1 ), TDbWindow::EUnlimited );
+
+ if ( err != KErrNone )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ err = view.EvaluateAll();
+
+ CleanupClosePushL( view );
+
+ //put the hash into array
+ while ( view.NextL() ) // Should find only one certificate
+ {
+ TRAPD(error, view.GetL());
+ error = error;
+ descarray->AppendL( view.ColDes8( 1 ) );
+ }
+ CleanupStack::PopAndDestroy( 1 ); //view
+ }
+
+ // List all of the certificate in trusted server certstore
+ // retrive them one by one to compare the certhash.
+ //if match found, remove the certificate from the trusted server certstore
+
+ CCertAttributeFilter* filter = CCertAttributeFilter::NewL();
+ CleanupStack::PushL(filter);
+ filter->SetOwnerType(EPeerCertificate);
+ RPointerArray<CDevTokenCertInfo> certs;
+ RMessage2 message;
+ iServer->CertStoreServerL().ListL(*filter,certs,message, ETrue );
+
+ CleanupStack::PopAndDestroy(); //filter
+
+ if ( certs.Count() )
+ {
+ for ( TInt i= 0; i < certs.Count(); i++ )
+ {
+ HBufC8* certData = iServer->CertStoreServerL().RetrieveLC( certs[i]->CertificateId(),message,ETrue );
+
+ TPtr8 certPtr = certData->Des();
+
+ CX509Certificate* cert = CX509Certificate::NewLC( certPtr );
+
+ for ( TInt ii=0; ii < descarray->Count(); ii++ )
+ {
+ if ( (*descarray)[ii] == cert->Fingerprint() )
+ {
+ //match, then delete it
+ iServer->CertStoreServerL().RemoveL( certs[i]->CertificateId(),message,ETrue );
+ break;
+ }
+ }
+
+ CleanupStack::PopAndDestroy( 2 ); //certData, cert
+ }
+ }
+ descarray->Reset(); //clean the buffer for certhash
+ CleanupStack::PopAndDestroy(); //descarray
+
+ //delete the cert record in Certificates Table
+ for ( TInt i = 0; i < certIDs2.Count(); i++ )
+ {
+ _LIT( KSQLDelete1, "DELETE FROM Certificates WHERE CertID = " );
+ SQLStatement.Zero();
+
+ SQLStatement.Copy( KSQLDelete1 );
+ SQLStatement.AppendNum( certIDs2[i] );
+ TPtrC sqlStat2( SQLStatement.PtrZ() );
+
+ User::LeaveIfError( iDatabase.Execute( sqlStat2 ) );
+ }
+ }
+
+ //now corresponding certificates are deleted, it is time to delete the sitenames
+ // just delete all of the record where uid matched with the client uid
+
+ _LIT( KSQLDelete2, "DELETE FROM TrustedSites WHERE ClientUID = " );
+
+ SQLStatement.Zero();
+ SQLStatement.Copy( KSQLDelete2 );
+ SQLStatement.AppendNum( aMessage.SecureId().iId );
+
+ TPtrC sqlStat3( SQLStatement.PtrZ() );
+
+ User::LeaveIfError( iDatabase.Execute( sqlStat3) );
+ }
+
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::RemoveThisForgivenSiteL()
+// ---------------------------------------------------------------------------
+//
+void CTrustedSitesServer::RemoveThisForgivenSiteL( const TDesC& aSite, const RMessage2& aMessage )
+ {
+ // API policing,WriteDeviceData
+ if (!KWriteSecurityPolicy.CheckPolicy(aMessage))
+ {
+ User::Leave(KErrPermissionDenied);
+ }
+
+ // get certid arrays for the ClientUID
+ RDbView view;
+ _LIT( KSQLQuery,
+ "SELECT CertID FROM TrustedSites WHERE ClientUID = " );
+
+ TBuf<KMaxSQLLength> SQLStatement;
+ SQLStatement.Copy( KSQLQuery );
+
+ SQLStatement.AppendNum( aMessage.SecureId().iId );
+ SQLStatement.Append(_L(" AND SiteName = '") );
+ SQLStatement.Append( aSite );
+ SQLStatement.Append(_L("'"));
+
+
+ TPtrC sqlStat( SQLStatement.PtrZ() );
+
+ TInt err = view.Prepare( iDatabase, TDbQuery( sqlStat ), TDbWindow::EUnlimited );
+
+ if ( err != KErrNone )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ err = view.EvaluateAll();
+
+
+ CleanupClosePushL( view );
+
+ RArray<TInt> certIDs;
+ RArray<TInt> certIDs2;
+ if ( view.CountL() )
+ {
+ // Get data
+ while ( view.NextL() ) // Should find only one certificate
+ {
+ TRAPD(error, view.GetL());
+ error = error;
+ certIDs.Append( view.ColInt( 1 ) );
+ }
+ CleanupStack::PopAndDestroy( 1 ); //view
+ }
+ else
+ {
+ CleanupStack::PopAndDestroy( 1 ); //view
+ //no match found, nothing to delete
+ return;
+ }
+
+ if ( certIDs.Count() == 0 )
+ {
+ //no cert id, just return;
+ return;
+ }
+
+ //the certID may contain -1, then no need to delete the certificate but go to delete the site directly
+ //filter the -1 out.
+ for ( TInt i = 0; i < certIDs.Count() ; i++ )
+ {
+ if ( certIDs[i] != -1 )
+ {
+ certIDs2.Append( certIDs[i] );
+ }
+ }
+ // if certid2 is not empty, it means there are certificates associated with the sitename,
+ // we should delete it.
+
+ if ( certIDs2.Count() > 0 )
+ {
+ // get the certhash array for certid arrays
+ //the desc8 array to put the certhash
+ TInt num = certIDs2.Count();
+ CDesC8ArrayFlat* descarray = new (ELeave) CDesC8ArrayFlat( num );
+ CleanupStack::PushL( descarray );
+
+ for ( TInt i = 0; i < certIDs2.Count(); i++ )
+ {
+ //empty the previous command
+ SQLStatement.Zero();
+ _LIT( KSQLQuery, "SELECT CertHash FROM Certificates WHERE CertID =" );
+ SQLStatement.Append( KSQLQuery );
+ SQLStatement.AppendNum( certIDs2[i] );
+
+ TPtrC sqlStat1( SQLStatement.PtrZ() );
+
+ TInt err = view.Prepare( iDatabase, TDbQuery( sqlStat1 ), TDbWindow::EUnlimited );
+
+ if ( err != KErrNone )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ err = view.EvaluateAll();
+
+ CleanupClosePushL( view );
+
+ //put the hash into array
+ while ( view.NextL() ) // Should find only one certificate
+ {
+ TRAPD(error, view.GetL());
+ error = error;
+ descarray->AppendL( view.ColDes8( 1 ) );
+ }
+ CleanupStack::PopAndDestroy( 1 ); //view
+ }
+
+ // List all of the certificate in trusted server certstore
+ // retrive them one by one to compare the certhash.
+ //if match found, remove the certificate from the trusted server certstore
+
+ CCertAttributeFilter* filter = CCertAttributeFilter::NewL();
+ CleanupStack::PushL(filter);
+ filter->SetOwnerType(EPeerCertificate);
+ RPointerArray<CDevTokenCertInfo> certs;
+ RMessage2 message;
+ iServer->CertStoreServerL().ListL(*filter,certs,message, ETrue );
+
+ CleanupStack::PopAndDestroy(); //filter
+
+ if ( certs.Count() )
+ {
+ for ( TInt i= 0; i < certs.Count(); i++ )
+ {
+ HBufC8* certData = iServer->CertStoreServerL().RetrieveLC( certs[i]->CertificateId(),message,ETrue );
+
+ TPtr8 certPtr = certData->Des();
+
+ CX509Certificate* cert = CX509Certificate::NewLC( certPtr );
+
+ for ( TInt ii=0; ii < descarray->Count(); ii++ )
+ {
+ if ( (*descarray)[ii] == cert->Fingerprint() )
+ {
+ //match, then delete it
+ iServer->CertStoreServerL().RemoveL( certs[i]->CertificateId(),message,ETrue );
+ break;
+ }
+ }
+
+ CleanupStack::PopAndDestroy( 2 ); //certData, cert
+ }
+ }
+ descarray->Reset(); //clean the buffer for certhash
+ CleanupStack::PopAndDestroy(); //descarray
+
+ //delete the cert record in Certificates Table
+ for ( TInt i = 0; i < certIDs2.Count(); i++ )
+ {
+ _LIT( KSQLDelete1, "DELETE FROM Certificates WHERE CertID = " );
+ SQLStatement.Zero();
+
+ SQLStatement.Copy( KSQLDelete1 );
+ SQLStatement.AppendNum( certIDs2[i] );
+ TPtrC sqlStat2( SQLStatement.PtrZ() );
+
+ User::LeaveIfError( iDatabase.Execute( sqlStat2 ) );
+ }
+ }
+ //now corresponding certificates are deleted, it is time to delete the sitenames
+ // just delete all of the record where uid matched with the client uid
+
+ _LIT( KSQLDelete2, "DELETE FROM TrustedSites WHERE ClientUID = " );
+
+ SQLStatement.Zero();
+ SQLStatement.Copy( KSQLDelete2 );
+ SQLStatement.AppendNum( aMessage.SecureId().iId );
+ SQLStatement.Append(_L("AND SiteName = '"));
+ SQLStatement.Append( aSite );
+ SQLStatement.Append(_L("'"));
+
+ TPtrC sqlStat3( SQLStatement.PtrZ() );
+
+ //TInt errr = iDatabase.Execute( sqlStat3);
+ User::LeaveIfError( iDatabase.Execute( sqlStat3) );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::DoAddForgivenSiteL()
+// ---------------------------------------------------------------------------
+//
+void CTrustedSitesServer::DoAddForgivenSiteL(const TDesC& aSite, const TBool& aOutOfDateAllowed, const TUint32& aUID )
+ {
+ TBuf<KMaxSQLLength> SQLStatement;
+
+ _LIT( KSQLInsert1,
+ "INSERT INTO TrustedSites (CertID,SiteName,Forgiven,OutOfDate,ClientUID) VALUES (" );
+
+ SQLStatement.Copy(KSQLInsert1);
+ SQLStatement.AppendNum(-1);
+ SQLStatement.Append(_L(",'"));
+
+ SQLStatement.Append( aSite );
+ SQLStatement.Append(_L("',"));
+ SQLStatement.AppendNum(1);
+ SQLStatement.Append(_L(","));
+ //add record for forgiven sites, check if outofdate is allowed also
+ if ( aOutOfDateAllowed )
+ {
+ SQLStatement.AppendNum(1);
+ }
+ else
+ {
+ SQLStatement.AppendNum(0);
+ }
+ SQLStatement.Append(_L(","));
+ //append the client UID.
+ SQLStatement.AppendNum( aUID );
+ SQLStatement.Append(_L(")"));
+
+ User::LeaveIfError( iDatabase.Execute( SQLStatement ) );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::IsForgivenSiteAlreadyL()
+// ---------------------------------------------------------------------------
+//
+TBool CTrustedSitesServer::IsForgivenSiteAlreadyL( const TDesC& aSite )
+ {
+ RDbView view;
+ _LIT( KSQLCheckForgivenSite,
+ "SELECT SiteName, Forgiven, OutOfDate FROM TrustedSites" );
+
+ TInt err = view.Prepare( iDatabase, TDbQuery( KSQLCheckForgivenSite ) );
+
+ if( err == KErrNotFound )
+ {
+ return EFalse;
+ }
+
+ if ( err != KErrNone )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ err = view.EvaluateAll();
+
+ CleanupClosePushL( view );
+
+ TBool alreadyExist = EFalse;
+
+ // looking for a match
+ while ( view.NextL() ) // Should find only one certificate
+ {
+ TRAPD(error, view.GetL());
+ error = error;
+
+ // sitename is matched and forgiven is set to 1
+ if( (!aSite.Compare(view.ColDes( 1 ))) && ( view.ColInt( 2 ) == 1 ) )
+ {
+ alreadyExist = ETrue;
+ break;
+ }
+ }
+
+ CleanupStack::PopAndDestroy( 1 );
+ return alreadyExist;
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::DoOverWriteOutOfDateL()
+// ---------------------------------------------------------------------------
+//
+void CTrustedSitesServer::DoOverWriteOutOfDateL(const TDesC& aSite, const TBool& aOutOfDateAllowed )
+ {
+ _LIT( KSQLOverWrite1, "UPDATE TrustedSites SET OutOfDate = ");
+
+ _LIT( KSQLOverWrite2, " WHERE SiteName = '");
+
+ TBuf<KMaxSQLLength> SQLStatement;
+ SQLStatement.Copy(KSQLOverWrite1);
+ SQLStatement.AppendNum(aOutOfDateAllowed);
+ SQLStatement.Append(KSQLOverWrite2);
+ SQLStatement.Append(aSite);
+ SQLStatement.Append(_L("'"));
+
+ User::LeaveIfError( iDatabase.Execute( SQLStatement ) );
+ }
+
+
+// ---------------------------------------------------------------------------
+// CTrustedSitesServer::DoOverWriteCertL()
+// ---------------------------------------------------------------------------
+//
+void CTrustedSitesServer::DoOverWriteCertL( const TDesC& aSiteName, const TDesC8& aCertHash )
+ {
+ TInt certID;
+ GetCertIDL( aCertHash, certID );
+
+ if( certID == KErrNotFound )
+ {
+ DoAddCertL( aCertHash );
+ GetCertIDL(aCertHash, certID);
+ }
+
+ RDbView view;
+ TBuf<KMaxSQLLength> SQLStatement;
+
+ _LIT( KSQLQuery2, "SELECT Forgiven, OutOfDate FROM TrustedSites WHERE CertID = ");
+
+ _LIT( KSQLQuery3," AND SiteName ='" );
+
+ SQLStatement.Copy( KSQLQuery2 );
+ SQLStatement.AppendNum(certID);
+ SQLStatement.Append( KSQLQuery3);
+ SQLStatement.Append( aSiteName );
+ SQLStatement.Append(_L("'"));
+
+ TPtrC sqlStat( SQLStatement.PtrZ() );
+ TInt err = view.Prepare( iDatabase, TDbQuery( sqlStat ) );
+
+ err = view.EvaluateAll();
+
+ CleanupClosePushL( view );
+
+ //same sitename and same cert exists
+ if (view.FirstL())
+ {
+ //already exist, no need to add
+ CleanupStack::PopAndDestroy(); //view
+ return;
+ }
+
+ CleanupStack::PopAndDestroy(); //view
+
+ // no match found
+
+ _LIT( KSQLQuery,
+ "SELECT Forgiven,OutOfDate, CertID FROM TrustedSites WHERE CertId = -1 AND SiteName = '" );
+
+ SQLStatement.Zero();
+ SQLStatement.Copy( KSQLQuery );
+
+ SQLStatement.Append( aSiteName );
+ SQLStatement.Append(_L("'"));
+
+ sqlStat.Set( SQLStatement.PtrZ() );
+ err = view.Prepare( iDatabase, TDbQuery( sqlStat ) );
+
+ err = view.EvaluateAll();
+
+ CleanupClosePushL( view );
+
+ if ( view.CountL() )
+ {
+ //record is there but certid is empty, add the certid into the record
+ //Update the certid
+ _LIT( KSQLOverWrite1, "UPDATE TrustedSites SET CertID = ");
+ _LIT( KSQLOverWrite2, " WHERE SiteName = '");
+
+ SQLStatement.Zero();
+ SQLStatement.Copy(KSQLOverWrite1);
+ SQLStatement.AppendNum( certID );
+ SQLStatement.Append(KSQLOverWrite2);
+ SQLStatement.Append(aSiteName);
+ SQLStatement.Append(_L("'"));
+
+ User::LeaveIfError( iDatabase.Execute(SQLStatement) );
+ }
+ else
+ {
+ //retrive the forgiven and outofdate, and make a same record for the certificate
+ TInt forgiven = 0;
+ TInt OutOfDate = 0;
+ TInt ClientUID = 0;
+ _LIT( KSQLQuery,
+ "SELECT Forgiven,OutOfDate,CertID,ClientUID FROM TrustedSites WHERE SiteName = '" );
+
+ SQLStatement.Zero();
+ SQLStatement.Copy( KSQLQuery );
+
+ SQLStatement.Append( aSiteName );
+ SQLStatement.Append(_L("'"));
+
+ sqlStat.Set( SQLStatement.PtrZ() );
+ err = view.Prepare( iDatabase, TDbQuery( sqlStat ) );
+
+ err = view.EvaluateAll();
+
+ CleanupClosePushL( view );
+
+ // looking for a match
+ if ( view.FirstL() ) // Should find only one certificate
+ {
+ TRAPD(error, view.GetL());
+ error = error;
+ //add a new record
+ forgiven = view.ColInt( 1 );
+ OutOfDate = view.ColInt( 2 );
+ ClientUID = view.ColInt( 4 );
+
+ //set the new record with new certid and same forgiven and outofdate settings
+ _LIT( KSQLInsert,
+ "INSERT INTO TrustedSites (CertID,SiteName,Forgiven,OutOfDate,ClientUID) VALUES(" );
+ SQLStatement.Zero();
+ SQLStatement.Copy(KSQLInsert);
+ SQLStatement.AppendNum(certID);
+ SQLStatement.Append(_L(",'"));
+
+ SQLStatement.Append( aSiteName );
+ SQLStatement.Append(_L("',"));
+ SQLStatement.AppendNum(forgiven);
+ SQLStatement.Append(_L(","));
+ SQLStatement.AppendNum(OutOfDate);
+ SQLStatement.Append(_L(","));
+ SQLStatement.AppendNum(ClientUID);
+ SQLStatement.Append(_L(")"));
+
+ User::LeaveIfError( iDatabase.Execute( SQLStatement ) );
+ }
+ CleanupStack::PopAndDestroy();
+ }
+ CleanupStack::PopAndDestroy(); //view
+ }
+//EOF
+