diff -r 000000000000 -r 95b198f216e5 omadrm/drmengine/roap/src/RoapSigner.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/omadrm/drmengine/roap/src/RoapSigner.cpp Thu Dec 17 08:52:27 2009 +0200 @@ -0,0 +1,297 @@ +/* +* Copyright (c) 2002 - 2008 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: ROAP message signer class implementation +* +*/ + + +// INCLUDE FILES +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "base64.h" +#include "RoapSigner.h" +#include "RoapStorageClient.h" +#include "RoapLog.h" + +using namespace Roap; + +// CONSTANTS +_LIT8( KSignatureStart, "" ); +_LIT8( KSignatureEnd, "" ); +_LIT8( KRoEndWithPrefix, "" ); +_LIT8( KRoEnd, "" ); + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// RoapSigner::RoapSigner +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CRoapSigner::CRoapSigner(): + iHash( NULL ), + iStorage( NULL ) + { + } + +// ----------------------------------------------------------------------------- +// CRIHello::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CRoapSigner::ConstructL( RRoapStorageClient& aStorageClient ) + { + iHash = CSHA1::NewL(); + iStorage = &aStorageClient; + } + + +// Destructor +CRoapSigner::~CRoapSigner() + { + iRequests.ResetAndDestroy(); + iResponses.ResetAndDestroy(); + delete iHash; + } + +// ----------------------------------------------------------------------------- +// RoapSigner:: +// +// ----------------------------------------------------------------------------- +// +CRoapSigner* CRoapSigner::NewL( RRoapStorageClient& aStorageClient ) + { + CRoapSigner* self = new ( ELeave ) CRoapSigner(); + + CleanupStack::PushL( self ); + self->ConstructL( aStorageClient ); + CleanupStack::Pop( self ); + + return self; + } + +// ----------------------------------------------------------------------------- +// CRoapSigner::ResetRequests +// ----------------------------------------------------------------------------- +// +void CRoapSigner::ResetRequests( void ) + { + iRequests.ResetAndDestroy(); + } + + +// ----------------------------------------------------------------------------- +// CRoapSigner::ResetResponses +// ----------------------------------------------------------------------------- +// +void CRoapSigner::ResetResponses( void ) + { + iResponses.ResetAndDestroy(); + } + + +// ----------------------------------------------------------------------------- +// CRoapSigner::AddResponseL +// ----------------------------------------------------------------------------- +// +void CRoapSigner::AddResponseL( + const TDesC8& aResponse ) + { + HBufC8* b = aResponse.AllocLC(); + iResponses.AppendL( b ); + CleanupStack::Pop( b ); + } + + +// ----------------------------------------------------------------------------- +// CRoapSigner::VerifyAndAddResponseL +// ----------------------------------------------------------------------------- +// +TBool CRoapSigner::VerifyAndAddResponseL( + const TDesC8& aResponse, + const TDesC8& aSignature, + const RPointerArray& aCertificateChain ) + { + TBool r = ETrue; + TInt i( 0 ); + TInt startPoint = 0; + TInt endPoint = 0; + TInt roEnd = 0; + TPtr8 ptr( 0, 0 ); + TPtrC8 hash( 0, 0 ); + HBufC8* tempMessage = NULL; + TInt lastRoEnd( 0 ); + + LOGLIT( "CRoapSigner::VerifyAndAddResponseL" ); + + // locate the last protectedRO endtag - there could be also elemet + // inside the ro element + while ( lastRoEnd >= 0 ) + { + TInt tagIncrement( KRoEndWithPrefix().Length() ); + roEnd += lastRoEnd; + TPtrC8 startPtr( aResponse.Mid( roEnd ) ); + lastRoEnd = startPtr.Find( KRoEndWithPrefix ); + if ( lastRoEnd == KErrNotFound ) + { + // try again without namespace prefix + lastRoEnd = startPtr.Find( KRoEnd ); + tagIncrement = KRoEnd().Length(); + } + if ( lastRoEnd > 0 ) + { + lastRoEnd += tagIncrement; + } + DETAILLOG2( _L( "lastRoEnd %08x:" ), lastRoEnd ); + } + DETAILLOG2( _L( "roEnd %08x:" ), roEnd ); + if ( roEnd > 0 ) + { + startPoint = aResponse.Right( aResponse.Length() - roEnd ).Find( KSignatureStart ); + startPoint += roEnd; + endPoint = aResponse.Right( aResponse.Length() - roEnd ).Find( KSignatureEnd ) + + KSignatureEnd().Length(); + endPoint += roEnd; + } + else + { + startPoint = aResponse.Find( KSignatureStart ); + endPoint = aResponse.Find( KSignatureEnd ) + KSignatureEnd().Length(); + } + + tempMessage = HBufC8::NewMax( aResponse.Length() - + 2 * KSignatureStart().Length() ); + User::LeaveIfNull( tempMessage ); + ptr.Set( tempMessage->Des() ); + ptr.Copy( aResponse.Left( startPoint ) ); + ptr.Append( aResponse.Right( aResponse.Length() - endPoint ) ); + + iResponses.Append( tempMessage ); + iHash->Reset(); + for ( i = 0; i < iResponses.Count(); i++ ) + { + DETAILLOG2( _L( "Message %d:" ), i ); + DETAILLOGHEX( iResponses[ i ]->Ptr(), iResponses[ i ]->Length() ); + iHash->Update( *iResponses[ i ] ); + } + + hash.Set( iHash->Final() ); + + LOGLIT( "Hash" ); + LOGHEX( hash.Ptr(), hash.Length() ); + LOGLIT( "Signature" ); + LOGHEX( aSignature.Ptr(), aSignature.Length() ); + + r= iStorage->VerifyL( aSignature, hash, aCertificateChain ); + +#ifdef _ROAP_TESTING + if ( r ) + { + LOGLIT( "Signature verification ok." ); + } + else + { + LOGLIT( "Signature verification failed." ); + } +#endif + + return r; + } + + +// ----------------------------------------------------------------------------- +// CRoapSigner::AddRequestL +// ----------------------------------------------------------------------------- +// +void CRoapSigner::AddRequestL( + const TDesC8& aRequest ) + { + HBufC8* b = aRequest.AllocLC(); + iRequests.AppendL( b ); + CleanupStack::Pop( b ); + } + + +// ----------------------------------------------------------------------------- +// CRoapSigner::SignAndAddRequestL +// ----------------------------------------------------------------------------- +// +HBufC8* CRoapSigner::SignAndAddRequestL( + const TDesC8& aRequest ) + { + TInt i; + TInt insertPoint; + HBufC8* s; + HBufC8* r; + TPtr8 ptr( 0, 0 ); + HBufC8* signature = NULL; + HBufC8* tempMessage = NULL; + TPtrC8 hash( 0, 0 ); + + LOGLIT( "CRoapSigner::SignAndAddRequestL" ); + + insertPoint = aRequest.Find( KSignatureStart ) + KSignatureStart().Length(); + tempMessage = HBufC8::NewMax( aRequest.Length() - + 2 * KSignatureStart().Length() ); + User::LeaveIfNull( tempMessage ); + ptr.Set( tempMessage->Des() ); + ptr.Copy( aRequest.Left( insertPoint - KSignatureStart().Length() ) ); + ptr.Append( aRequest.Right( aRequest.Length() - insertPoint - + KSignatureStart().Length() - 1 ) ); + + iHash->Reset(); + for ( i = 0; i < iRequests.Count(); i++ ) + { + DETAILLOG2( _L( "Message %d:" ), i ); + DETAILLOGHEX( iRequests[ i ]->Ptr(), iRequests[ i ]->Length() ); + iHash->Update( *iRequests[ i ] ); + } + DETAILLOG2( _L( "Message %d:" ), i ); + DETAILLOGHEX( tempMessage->Ptr(), tempMessage->Length() ); + iHash->Update( *tempMessage ); + delete tempMessage; + hash.Set( iHash->Final() ); + LOGLIT( "Hash" ); + LOGHEX( hash.Ptr(), hash.Length() ); + + iStorage->SignL( hash, signature ); + CleanupStack::PushL( signature ); + + LOGLIT( "Signature" ); + LOGHEX( signature->Ptr(), signature->Length() ); + + s = Base64EncodeL( *signature ); + CleanupStack::PushL( s ); + r = HBufC8::NewMax( s->Length() + aRequest.Length() ); + User::LeaveIfNull( r ); + ptr.Set( r->Des() ); + ptr.Copy( aRequest.Left( insertPoint ) ); + ptr.Append( *s ); + ptr.Append( aRequest.Right( aRequest.Length() - insertPoint ) ); + CleanupStack::PopAndDestroy( s ); + CleanupStack::PopAndDestroy( signature ); + + iRequests.Append( r->Des().AllocL() ); + return r; + } + +// End of File