webservices/wsutils/src/sencryptoutils.cpp
changeset 0 62f9d29f7211
child 14 ab1e518f96da
equal deleted inserted replaced
-1:000000000000 0:62f9d29f7211
       
     1 /*
       
     2 * Copyright (c) 2006-2006 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:           
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 
       
    21 
       
    22 
       
    23 
       
    24 
       
    25 
       
    26 
       
    27 #include "sencryptoutils.h"
       
    28 #include <imcvcodc.h>
       
    29 #include "senguidgen.h"
       
    30 #include <e32math.h>
       
    31 #include <SenDomFragment.h>
       
    32 #include <SenNameSpace.h>
       
    33 #include "SenWsSecurityHeader.h"
       
    34 //#include "senxmldebug.h"
       
    35 
       
    36 namespace
       
    37     {
       
    38     _LIT(KTimeReference,         "19700000:000000");
       
    39     const TInt KToBase64CoefficientNumerator  = 4;
       
    40     const TInt KToBase64CoefficientNominative = 3;
       
    41     const TInt KInt64Length = 20;
       
    42 	const TInt KInt32Length = 10;
       
    43 	const TInt KHexWidth = 2;
       
    44     }
       
    45 
       
    46 EXPORT_C HBufC8* SenCryptoUtils::GetPSHA1HashL( const TDesC8& aSecret, 
       
    47                                                 const TDesC8& aSeed, 
       
    48                                                 const TInt aLength )
       
    49 {
       
    50     HBufC8* output = HBufC8::NewLC(aLength);
       
    51 
       
    52     CSHA1* sha1 = CSHA1::NewL();    
       
    53     CleanupStack::PushL(sha1);
       
    54 
       
    55     CHMAC* hmac = CHMAC::NewL(aSecret, sha1);
       
    56     CleanupStack::Pop(sha1);
       
    57     CleanupStack::PushL(hmac);    
       
    58     
       
    59     HBufC8* A = HBufC8::NewLC(Max(aSeed.Length(), hmac->HashSize())); // simulate the "A" array from the rfc
       
    60     HBufC8* msg = HBufC8::NewLC(hmac->HashSize() + aSeed.Length());
       
    61     
       
    62     TInt generated = 0;    
       
    63     A->Des() = aSeed;    
       
    64     while (generated < aLength)
       
    65     {
       
    66         hmac->Reset();
       
    67         A->Des() = hmac->Hash(*A);
       
    68         msg->Des() = *A;
       
    69         msg->Des().Append(aSeed);
       
    70         
       
    71         TInt length = Min(aLength - generated, hmac->HashSize());
       
    72         
       
    73         hmac->Reset();        
       
    74         output->Des().Append(hmac->Hash(*msg).Left(length));
       
    75         
       
    76         generated += length;
       
    77     }
       
    78     
       
    79     CleanupStack::PopAndDestroy(msg);
       
    80     CleanupStack::PopAndDestroy(A);
       
    81     CleanupStack::PopAndDestroy(hmac);    
       
    82     CleanupStack::Pop(output);
       
    83     
       
    84     return output;
       
    85 }
       
    86 
       
    87 EXPORT_C HBufC8* SenCryptoUtils::EncodeBase64L(const TDesC8& aData)
       
    88 {
       
    89     if (aData.Length() == 0)
       
    90         {
       
    91         return NULL;
       
    92         }
       
    93 
       
    94     TInt remainder = aData.Length() % KToBase64CoefficientNominative;
       
    95     TInt length = aData.Length() * KToBase64CoefficientNumerator;
       
    96     length /= KToBase64CoefficientNominative;
       
    97     if (remainder)
       
    98         {
       
    99         length++;
       
   100         length += KToBase64CoefficientNominative - remainder;
       
   101         }
       
   102 
       
   103     HBufC8* buffer = HBufC8::NewLC(length);
       
   104     
       
   105     
       
   106     TImCodecB64 base64Codec;
       
   107     base64Codec.Initialise();
       
   108     TPtr8 des = buffer->Des();  // don't blame me, it's the compiler's fault    
       
   109     base64Codec.Encode(aData, des);
       
   110     
       
   111     CleanupStack::Pop(buffer);
       
   112     return buffer;
       
   113 }
       
   114 
       
   115 EXPORT_C HBufC8* SenCryptoUtils::DecodeBase64L(const TDesC8& aData)
       
   116 {
       
   117     const TUint8 KBase64Fill = '=';
       
   118 
       
   119     TInt length = aData.Length();
       
   120     if (aData[length-1] == KBase64Fill)
       
   121         {
       
   122         length--;
       
   123         if (aData[length-2] == KBase64Fill)
       
   124             {
       
   125             length--;
       
   126             }
       
   127         }
       
   128     length *= KToBase64CoefficientNominative;
       
   129     length /= KToBase64CoefficientNumerator;
       
   130     if (length <= 0)
       
   131         {
       
   132         return NULL;
       
   133         }
       
   134 
       
   135     HBufC8* buffer = HBufC8::NewLC(length);
       
   136 
       
   137     TImCodecB64 base64Codec;
       
   138     base64Codec.Initialise();
       
   139     TPtr8 des = buffer->Des();  // don't blame me, it's the compiler's fault    
       
   140 
       
   141     base64Codec.Decode(aData, des);
       
   142 
       
   143     CleanupStack::Pop(buffer);
       
   144     return buffer;    
       
   145 }
       
   146 
       
   147 EXPORT_C HBufC8* SenCryptoUtils::RandomAndHashMd5LC()
       
   148     {
       
   149     HBufC8* hashedRandom = NULL;
       
   150     TTime homeTime;
       
   151     homeTime.HomeTime();
       
   152     TInt64 seed = homeTime.Int64();
       
   153     TBuf8<KSenUuidMaxInt64Length> valueBeforeMd5;
       
   154     //randomize
       
   155     valueBeforeMd5.AppendNum(Math::Rand(seed));
       
   156     //hashing
       
   157     CMD5* md5HashGen = CMD5::NewL();
       
   158     CleanupStack::PushL(md5HashGen);
       
   159     TPtrC8 hash = md5HashGen->Hash(valueBeforeMd5);
       
   160     hashedRandom = hash.AllocL();
       
   161     CleanupStack::PopAndDestroy(md5HashGen);
       
   162     CleanupStack::PushL(hashedRandom);
       
   163     return hashedRandom;
       
   164     }    
       
   165 
       
   166 EXPORT_C HBufC8* SenCryptoUtils::CreateEncodedBinarySecretL(const TDesC8& aSecret, const TDesC8& aValueType)
       
   167     {
       
   168     //from MSP guide
       
   169     //aSecret "...Contains the Compact mobile security token. The contents should be Base64 encoded and passed as the BinarySecurityToken element in the WS-Security header 
       
   170     
       
   171     TPtrC8 pSecret(aSecret);
       
   172     CSenXmlReader* reader = CSenXmlReader::NewL(KXmlParserMimeType); // use libxml2 sax parser
       
   173     CleanupStack::PushL(reader);
       
   174     CSenDomFragment* pFragment = CSenDomFragment::NewL();
       
   175     CleanupStack::PushL(pFragment);
       
   176     pFragment->SetReader(*reader);    
       
   177     pFragment->BuildFrom(aSecret);  
       
   178     CSenElement& pElement = pFragment->AsElement();
       
   179     if (pElement.LocalName() == KBinarySecurityToken
       
   180         && (pElement.Namespace()->URI() == KSecuritySchemeXmlNs
       
   181         || pElement.Namespace()->URI() == KSecurityXmlNs))
       
   182         {
       
   183         pSecret.Set(pElement.Content());
       
   184         }
       
   185     else
       
   186         {
       
   187         pSecret.Set(aSecret);
       
   188         }
       
   189     HBufC8* encodedSecurityToken = EncodeBase64L(pSecret);
       
   190     CleanupStack::PushL(encodedSecurityToken);
       
   191     HBufC8* binarySecurityToken(NULL);
       
   192     if (aValueType.Length())
       
   193         {
       
   194         CSenWsSecurityHeader::BinarySecurityTokenL(*encodedSecurityToken, aValueType, binarySecurityToken);
       
   195         }
       
   196     else
       
   197         {
       
   198         CSenWsSecurityHeader::BinarySecurityTokenL(*encodedSecurityToken, binarySecurityToken);
       
   199         }
       
   200     CleanupStack::PopAndDestroy(encodedSecurityToken);
       
   201     CleanupStack::PopAndDestroy(pFragment);
       
   202     CleanupStack::PopAndDestroy(reader);
       
   203     return binarySecurityToken;
       
   204     }
       
   205 
       
   206 EXPORT_C HBufC8* SenCryptoUtils::GetTimestampL()
       
   207 	{
       
   208 	TTime time;
       
   209 	time.UniversalTime();
       
   210 	TTimeIntervalSeconds timestamp;
       
   211 	TTime refTime(KTimeReference);
       
   212 
       
   213 	time.SecondsFrom(refTime, timestamp);
       
   214 	HBufC8* pTimestamp = HBufC8::NewL(KInt32Length);
       
   215     TPtr8 buf = pTimestamp->Des();
       
   216     buf.AppendNum(timestamp.Int());
       
   217 	return pTimestamp;
       
   218 	}
       
   219 EXPORT_C HBufC8* SenCryptoUtils::GetTimestampL(TTime aTime)
       
   220     {
       
   221     TTimeIntervalSeconds timestamp;
       
   222     TTime refTime(KTimeReference);
       
   223 
       
   224     aTime.SecondsFrom(refTime, timestamp);
       
   225     HBufC8* pTimestamp = HBufC8::NewL(KInt32Length);
       
   226     TPtr8 buf = pTimestamp->Des();
       
   227     buf.AppendNum(timestamp.Int());
       
   228     return pTimestamp;
       
   229     }
       
   230 EXPORT_C HBufC8* SenCryptoUtils::GetRandomNonceL()
       
   231 	{
       
   232 	TTime time;
       
   233 	time.UniversalTime();
       
   234 	CMD5 *pMD5HashGen = CMD5::NewL();
       
   235 	CleanupStack::PushL (pMD5HashGen);
       
   236     TBuf8<KInt64Length+KInt32Length> valueBeforeHash;
       
   237     // Append current system time
       
   238     valueBeforeHash.AppendNum(time.Int64());
       
   239     // Append random number
       
   240     valueBeforeHash.AppendNum(Math::Random()); //TUint32 Random();
       
   241 	
       
   242     // Calculate hash
       
   243     TPtrC8 hash (pMD5HashGen->Hash(valueBeforeHash));
       
   244     HBufC8* pResult = HBufC8::NewL(hash.Length() * KHexWidth);
       
   245     TPtr8 buf = pResult->Des();
       
   246     for (TInt i = 0; i < hash.Length(); i++)
       
   247         {
       
   248         buf.AppendNumFixedWidth(hash[i], EHex, KHexWidth);
       
   249         }
       
   250     CleanupStack::PopAndDestroy(pMD5HashGen);
       
   251     return pResult;
       
   252 	}