pkiutilities/DeviceToken/Src/TruSitesStore/Server/TrustedSitesServer.cpp
changeset 0 164170e6151a
--- /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 
+