/*
* Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "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:
* Key Management Server session class code.
*
*/
/**
@file
*/
#include "kmsclient.h"
#include "kmsserver.h"
CKeyMgmtSession* CKeyMgmtSession::NewL()
/**
Factory function allocates new instance of CKeyMgmtSession. Used
when the KMS client opens a session with the server.
@return New, initialized instance of CKeyMgmtSession.
The returned object is owned by the caller.
*/
{
CKeyMgmtSession* self = new(ELeave) CKeyMgmtSession();
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
void CKeyMgmtSession::ConstructL()
/**
Initialize this session by opening a channel to the KMS device driver.
This session is maintained until the session is destroyed.
*/
{
TInt r = iChannel.Open();
User::LeaveIfError(r);
}
CKeyMgmtSession::~CKeyMgmtSession()
/**
Free resources owned by this session. Specifically, closes the
KMS LDD channel.
*/
{
iChannel.Close();
// if the last session was removed then stop the server
CKeyMgmtServer* srv = (CKeyMgmtServer*) Server();
srv->DecrementSessionCount();
}
void CKeyMgmtSession::ServiceL(const RMessage2& aMessage)
/**
Implement CSession2 by handling the supplied function request.
@param aMessage Information about request from client.
Provides access to function identifier
and arguments which were passed.
*/
{
RThread thd;
aMessage.ClientL(thd);
CleanupClosePushL(thd);
RProcess pr;
User::LeaveIfError(thd.Process(pr));
CleanupClosePushL(pr);
KeyMgmtSvrImpl::TServerFunction f =
static_cast<KeyMgmtSvrImpl::TServerFunction>(aMessage.Function());
switch (f)
{
case KeyMgmtSvrImpl::EGenerateKey:
GenerateKeyL(aMessage, pr);
break;
case KeyMgmtSvrImpl::EStoreKey:
StoreKeyL(aMessage, pr);
break;
case KeyMgmtSvrImpl::EDeleteKey:
DeleteKeyL(aMessage, pr);
break;
case KeyMgmtSvrImpl::EAddUsage:
AddUsageL(aMessage, pr);
break;
case KeyMgmtSvrImpl::EDeleteUsage:
DeleteUsageL(aMessage, pr);
break;
case KeyMgmtSvrImpl::ESetHeapFail:
__UHEAP_MARK;
__UHEAP_SETFAIL(RAllocator::EDeterministic, aMessage.Int0());
break;
case KeyMgmtSvrImpl::EEndHeapFail:
__UHEAP_MARKEND;
__UHEAP_RESET;
break;
default:
User::Leave(KErrNotSupported);
break;
}
CleanupStack::PopAndDestroy(2, &thd);
// if an error occured then the handler function will have left
aMessage.Complete(KErrNone);
}
void CKeyMgmtSession::ServiceError(const RMessage2& aMessage, TInt aError)
/**
Override CSession2 by handling any leave which occured during the ServiceL.
If the leave is because of a bad descriptor, then panick the client with
EBadClientDescriptor. Otherwise, complete the request with that error code.
@param aMessage Message which caused leave to occur.
@param aError Leave code. This is a Symbian OS error code.
@see CSession2::ServiceError
*/
{
if (aError == KErrBadDescriptor)
aMessage.Panic(KKmsClientPanicCat, EBadClientDescriptor);
else
aMessage.Complete(aError);
}
void CKeyMgmtSession::GenerateKeyL(const RMessage2& aMessage, RProcess aClientProc)
/**
Generate a new key in the hardware store.
@param aMessage Provides access to data sent by client.
@param aClientProc The client process, which is used to manage key ownership.
*/
{
TInt len = aMessage.Int0();
TKeyHandle kh;
TRequestStatus rs;
iChannel.GenerateKey(len, aClientProc, kh, rs);
User::WaitForRequest(rs);
User::LeaveIfError(rs.Int());
WriteHandleToClientL(aMessage, aClientProc, kh);
}
void CKeyMgmtSession::StoreKeyL(const RMessage2& aMessage, RProcess aClientProc)
/**
Store the client's descriptor as a key in the hardware store.
@param aMessage Provides access to data sent by client.
@param aClientProc The client process, which is used to manage key ownership.
*/
{
TInt dataLen = aMessage.GetDesLengthL(0);
// create server-side copy of the data
HBufC8* srvData = HBufC8::NewLC(dataLen);
TPtr8 srvPtr = srvData->Des();
aMessage.ReadL(0, srvPtr);
TKeyHandle kh;
TRequestStatus rs;
iChannel.StoreKey(srvPtr, aClientProc, kh, rs);
User::WaitForRequest(rs);
User::LeaveIfError(rs.Int());
WriteHandleToClientL(aMessage, aClientProc, kh);
CleanupStack::PopAndDestroy(srvData);
}
void CKeyMgmtSession::WriteHandleToClientL(const RMessage2& aMessage, RProcess aClientProc, TKeyHandle aHandle)
/**
Helper function for GenerateKeyL and StoreKeyL attempts to write the supplied
key handle back to the client which owns this session object.
If the handle cannot be written to the client, this function attempts to delete
the supplied key, but cannot perform further cleanup if that fails.
@param aMessage Provides access to data sent by client. Specifically, argument 1
refers to a descriptor which packages the client's TKeyHandle object.
@param aClientProc The client process, which is used to manage key ownership. This is
used to delete the newly-created key if cannot write to client handle.
@param aHandle Handle value to write back to client.
*/
{
TPckgC<TKeyHandle> khPckg(aHandle);
TInt r = aMessage.Write(1, khPckg);
if (r != KErrNone)
{
TRequestStatus rs;
iChannel.DeleteKey(aClientProc, aHandle, rs);
User::WaitForRequest(rs);
User::Leave(r);
}
}
void CKeyMgmtSession::DeleteKeyL(const RMessage2& aMessage, RProcess aClientProc)
/**
Delete a key from the hardware store.
@param aMessage Provides access to data sent by client. Specifically, argument 0
is the key handle as an integer.
@param aClientProc The client process, which is used to manage key ownership. This is
used to delete the newly-created key if cannot write to client handle.
*/
{
TKeyHandle kh = { aMessage.Int0() };
TRequestStatus rs;
iChannel.DeleteKey(aClientProc, kh, rs);
User::WaitForRequest(rs);
User::LeaveIfError(rs.Int());
}
void CKeyMgmtSession::AddUsageL(const RMessage2& aMessage, RProcess aClientProc)
/**
Add a usage entry to the hardware store.
@param aMessage Provides access to data sent by client. Specifically, argument 0
is the key handle as an integer. Argument 1 is the operation as an
integer, and argument 3 refers to the descriptor which packages the
client's security policy object.
@param aClientProc The client process, which is used to manage key ownership. This is
used to delete the newly-created key if cannot write to client handle.
*/
{
TKeyHandle kh = { aMessage.Int0() };
TInt op = aMessage.Int1();
TSecurityPolicyBuf secPolBuf;
TInt r = aMessage.Read(2, secPolBuf);
User::LeaveIfError(r);
TRequestStatus rs;
iChannel.AddUsage(aClientProc, kh, op, secPolBuf(), rs);
User::WaitForRequest(rs);
User::LeaveIfError(rs.Int());
}
void CKeyMgmtSession::DeleteUsageL(const RMessage2& aMessage, RProcess aClientProc)
/**
Delete a usage entry from the hardware store.
@param aMessage Provides access to data sent by client. Specifically, argument 0
is the key handle as an integer. Argument 1 is the operation as an
integer.
@param aClientProc The client process which claims to own the key.
*/
{
TKeyHandle kh = { aMessage.Int0() };
TInt op = aMessage.Int1();
TRequestStatus rs;
iChannel.DeleteUsage(aClientProc, kh, op, rs);
User::WaitForRequest(rs);
User::LeaveIfError(rs.Int());
}