webservices/idwsfsecuritymechanism/src/senidwsfcrammd5saslmechanism.cpp
changeset 0 62f9d29f7211
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/webservices/idwsfsecuritymechanism/src/senidwsfcrammd5saslmechanism.cpp	Thu Jan 07 16:19:19 2010 +0200
@@ -0,0 +1,176 @@
+/*
+* Copyright (c) 2002-2005 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:        
+*
+*/
+
+
+
+
+
+
+
+
+// INCLUDE FILES
+#include <SenXmlUtils.h>
+
+#include "senidwsfcrammd5saslmechanism.h"
+#include "msensaslmessage.h"
+
+#include <flogger.h>
+
+namespace
+    {
+    _LIT8(KCrammd5, "CRAM-MD5");
+    }
+
+// Create instance of concrete ECOM interface implementation
+CSenIdWsfCrammd5SaslMechanism* CSenIdWsfCrammd5SaslMechanism::NewL(
+                                    MSenCoreServiceManager& aServiceManager)
+    {
+    CSenIdWsfCrammd5SaslMechanism* pNew =
+                        CSenIdWsfCrammd5SaslMechanism::NewLC(aServiceManager);
+    CleanupStack::Pop();
+    return pNew;
+    }
+
+CSenIdWsfCrammd5SaslMechanism*
+            CSenIdWsfCrammd5SaslMechanism::NewLC(
+                                    MSenCoreServiceManager& aServiceManager)
+    {
+    CSenIdWsfCrammd5SaslMechanism* pNew =
+                new (ELeave) CSenIdWsfCrammd5SaslMechanism(aServiceManager);
+    CleanupStack::PushL(pNew);
+    return pNew;
+    }
+
+CSenIdWsfCrammd5SaslMechanism::CSenIdWsfCrammd5SaslMechanism(
+                                    MSenCoreServiceManager& aServiceManager)
+:CSenIdWsfPlainSaslMechanism(aServiceManager)
+    {
+    }
+
+CSenIdWsfCrammd5SaslMechanism::~CSenIdWsfCrammd5SaslMechanism()
+    {
+    }
+
+const TDesC8& CSenIdWsfCrammd5SaslMechanism::Name()
+    {
+    return KCrammd5();
+    }
+
+TInt CSenIdWsfCrammd5SaslMechanism::HandleResponseL(
+                                                MSenSaslMessage& aResponse,
+                                                MSenSaslMessage& aNewRequest
+    )
+    {
+    const TInt KPasswordMinLength = 64;
+
+    TInt retVal = KErrNone;
+
+    TPtrC8 authzId = ipAccount->AuthzID();
+    TPtrC8 authnId = ipAccount->AdvisoryAuthnID();
+    if (authnId == KNullDesC8)
+        {
+        authnId.Set(authzId);
+        }
+
+    // Get challenge
+    TPtrC8 theChallengeDataBase64 = aResponse.Data();
+
+    HBufC8* pChallengeData = // push pChallengeData;
+        iServiceManager.DecodeFromBase64LC(theChallengeDataBase64);
+    if (pChallengeData->Length() == 0)
+        {
+        iServiceManager.Log()->Write(_L(
+        "ERROR: CSenIdWsfCrammd5SaslMechanism::HandleResponseL \
+        challenge date length = 0"));
+        User::Leave(KErrArgument);
+        }
+
+    // Create MD5 hash generator
+    CMD5* pMd5Gen = CMD5::NewL();
+    CleanupStack::PushL(pMd5Gen);
+
+    // The password is the shared secret
+    // transform password
+    TPtrC8 password(KNullDesC8);
+    if(ipPassword)
+        {
+        password.Set(ipPassword->Des());
+        }
+
+    HBufC8* pPassword8 = TransformL(password);
+    CleanupStack::PushL(pPassword8);
+
+    if (pPassword8->Length() <= KPasswordMinLength)
+        {
+        // Pad with 0 bytes
+        pPassword8 = pPassword8->ReAllocL(KPasswordMinLength);
+        CleanupStack::Pop();    // Replace pwd on cleanup stack,
+                                // might have changed(!)
+        CleanupStack::PushL(pPassword8);
+        pPassword8->Des().AppendFill(TChar(0),
+                                    KPasswordMinLength - pPassword8->Length());
+        }
+    else
+        {
+        // Password is longer than 64 bytes, replace pwd with MD5 hash
+        HBufC8* pPasswordHash = pMd5Gen->Hash(*pPassword8).AllocL();
+        CleanupStack::PopAndDestroy(); // pPassword8;
+        pPassword8 = pPasswordHash;
+        CleanupStack::PushL(pPassword8);
+        }
+
+    // Create HMAC generator
+    CHMAC* pHmacGen = CHMAC::NewL(*pPassword8, pMd5Gen); // takes ownership of
+                                                         // pMd5Gen AND makes
+                                                         // use of pPassword8
+    CleanupStack::PopAndDestroy(); // pPassword8
+    CleanupStack::Pop(); // pMd5Gen
+
+
+    CleanupStack::PushL(pHmacGen); // push
+
+    // Calculate hash
+    TPtrC8 ptrHash = pHmacGen->Hash(*pChallengeData);
+    if (ptrHash.Length() > 0)
+        {
+        _LIT8(KSpace," ");
+        HBufC8 *pResponseData8 = HBufC8::NewLC(
+            authnId.Length() + 1 + ptrHash.Length() * 2); // push pData8
+        TPtr8 ptrResponseData8 = pResponseData8->Des();
+
+        ptrResponseData8.Append(authnId);
+        ptrResponseData8.Append(KSpace);//CodeScannerWarning
+
+        // ptrHash needs to be converted to a lowercase hex value
+        for (TInt i = 0; i < ptrHash.Length(); i++)
+            {
+            ptrResponseData8.AppendNumFixedWidth(ptrHash[i], EHex, 2);
+            }
+
+        retVal = aNewRequest.ConstructRequestFromL(KCrammd5, ptrResponseData8);
+
+        CleanupStack::PopAndDestroy();  // pResponseData8;
+        }
+
+    CleanupStack::PopAndDestroy(); // pHmacGen
+
+
+    CleanupStack::PopAndDestroy(); // pChallengeData;
+    return retVal;
+    }
+
+// End of File