cryptoservices/certificateandkeymgmt/pkcs12/pkcs12macdata.cpp
changeset 0 2c201484c85f
child 8 35751d3474b7
equal deleted inserted replaced
-1:000000000000 0:2c201484c85f
       
     1 /*
       
     2 * Copyright (c) 2005-2009 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 the License "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 #include "pkcs12macdata.h"
       
    20 
       
    21 using namespace PKCS12;
       
    22 
       
    23 CDecPkcs12MacData::CDecPkcs12MacData()
       
    24 	{
       
    25 	}
       
    26 	
       
    27 EXPORT_C CDecPkcs12MacData* CDecPkcs12MacData::NewL(const TDesC8& aMacData, const TDesC8& aAuthSafeData)
       
    28 	{
       
    29 	CDecPkcs12MacData* self = new(ELeave) CDecPkcs12MacData();
       
    30 	CleanupStack::PushL(self);
       
    31 	self->ConstructL(aMacData, aAuthSafeData);
       
    32 	CleanupStack::Pop(self);
       
    33 	return self;
       
    34 	}
       
    35 
       
    36 CDecPkcs12MacData::~CDecPkcs12MacData()
       
    37 	{
       
    38 	delete iDigestInfo;
       
    39 	}
       
    40 	
       
    41 void CDecPkcs12MacData::ConstructL(const TDesC8& aMacData, const TDesC8& aAuthSafeData)
       
    42 	{
       
    43 	iAuthSafeDataPtr.Set(aAuthSafeData);
       
    44 		
       
    45 	// MacData is a Sequence
       
    46 	TASN1DecGeneric seqGen(aMacData);
       
    47 	seqGen.InitL();
       
    48 	if (seqGen.Tag() != EASN1Sequence || seqGen.Class() != EUniversal)
       
    49 		{
       
    50 		User::Leave(KErrArgument);
       
    51 		}
       
    52 		
       
    53 	// Decode the MacData Sequence
       
    54 	TASN1DecSequence seq;
       
    55 	CArrayPtr<TASN1DecGeneric>* macDataSequence = seq.DecodeDERLC(seqGen);
       
    56 	TInt macDataCount = macDataSequence->Count();
       
    57 	// Check if Mac, MacSalt and Iteration Count are present
       
    58 	// Iteration Count is 1 by default
       
    59 	if (macDataCount < 2 || macDataCount > 3)
       
    60 		{
       
    61 		User::Leave(KErrArgument);
       
    62 		}
       
    63 	
       
    64 	// DigestInfo
       
    65 	const TASN1DecGeneric* macDataSequenceAt0 = macDataSequence->At(0);
       
    66 	// DigestInfo is a Sequence
       
    67 	if (macDataSequenceAt0->Tag() != EASN1Sequence || macDataSequenceAt0->Class() != EUniversal)
       
    68 		{
       
    69 		User::Leave(KErrArgument);
       
    70 		}
       
    71 	iDigestInfo = CPKCS7DigestInfo::NewL(macDataSequenceAt0->Encoding());
       
    72 		
       
    73 	// MacSalt
       
    74 	const TASN1DecGeneric* macDataSequenceAt1 = macDataSequence->At(1);
       
    75 	// MacSalt is an OctetString
       
    76 	if (macDataSequenceAt1->Tag() != EASN1OctetString || macDataSequenceAt1->Class() != EUniversal)
       
    77 		{
       
    78 		User::Leave(KErrArgument);
       
    79 		}  
       
    80     iMacSalt.Set(macDataSequenceAt1->GetContentDER());
       
    81     
       
    82     // Iteration Count
       
    83 	if(macDataSequence->Count() == 3)
       
    84 		{
       
    85 		// Check for IterationCount
       
    86 		const TASN1DecGeneric* macDataSequenceAt2 = macDataSequence->At(2);
       
    87 		if (macDataSequenceAt2->Tag() != EASN1Integer || macDataSequenceAt2->Class() != EUniversal)
       
    88 			{
       
    89 			User::Leave(KErrArgument);
       
    90 			}
       
    91 		
       
    92 		TASN1DecInteger intDecoder;
       
    93 		iIterationCount = intDecoder.DecodeDERShortL(*macDataSequenceAt2);
       
    94 		if(iIterationCount <= 0)
       
    95 			{
       
    96 			User::Leave(KErrArgument);
       
    97 			}
       
    98 		}
       
    99     // Assign the Default value as 1 if Iteration Count is not present.
       
   100 	else
       
   101 		{
       
   102 		iIterationCount = KDefaultIterationCount;
       
   103 		}	
       
   104 	CleanupStack::PopAndDestroy(macDataSequence);
       
   105     }
       
   106 	
       
   107 EXPORT_C const CPKCS7DigestInfo& CDecPkcs12MacData::DigestInfo() const
       
   108 	{
       
   109 	return *iDigestInfo;
       
   110 	}
       
   111 	
       
   112 EXPORT_C const TDesC8& CDecPkcs12MacData::MacSalt() const
       
   113 	{
       
   114 	return iMacSalt;	
       
   115 	}
       
   116 	
       
   117 EXPORT_C TInt CDecPkcs12MacData::IterationCount() const
       
   118 	{
       
   119 	return iIterationCount;	
       
   120 	}
       
   121 
       
   122 EXPORT_C TBool CDecPkcs12MacData::VerifyIntegrityL(const TDesC& aPassword) const
       
   123 	{	
       
   124 	__UHEAP_MARK;
       
   125 	HBufC8* encryptKey = HBufC8::NewMaxLC(KSha1HmacKeyLength);
       
   126 	TPtr8 encryptedKey(encryptKey->Des());
       
   127 	
       
   128 	// Convert the supplied string to a byte string. Each character is converted to a big 
       
   129 	// endian two-byte value, and a terminating NULL character is appended to the end.
       
   130 	HBufC8* password = PKCS12KDF::GeneratePasswordLC(aPassword);
       
   131 		
       
   132 	PKCS12KDF::DeriveKeyL(encryptedKey, PKCS12KDF::EIDByteMACKey, *password ,MacSalt(), IterationCount());
       
   133 	
       
   134 	CMessageDigest* digest1 = NULL;
       
   135 	TAlgorithmId algorithmId = DigestInfo().Algorithm();
       
   136 	if (algorithmId != ESHA1)
       
   137 		{
       
   138 		User::Leave(KErrNotSupported);
       
   139 		}
       
   140 	digest1 = CSHA1::NewL();
       
   141 	CleanupStack::PushL( digest1 );
       
   142 	
       
   143 	CHMAC* hmac1 = CHMAC::NewL( encryptedKey, digest1);
       
   144 	CleanupStack::PushL( hmac1 );
       
   145 	
       
   146 	TPtrC8 tmpHash = hmac1->Final(iAuthSafeDataPtr);
       
   147 	TInt ret = tmpHash.Compare(DigestInfo().Digest());
       
   148 	TBool result;
       
   149 	if(ret)
       
   150 		{
       
   151 		result = EFalse;
       
   152 		}
       
   153 	else
       
   154 		{
       
   155 		result = ETrue;
       
   156 		}
       
   157 	
       
   158 	CleanupStack::PopAndDestroy(hmac1);
       
   159 	CleanupStack::Pop(digest1);
       
   160 	CleanupStack::PopAndDestroy(2,encryptKey); // encryptKey, password
       
   161 			
       
   162 	__UHEAP_MARKEND;
       
   163 
       
   164 	return result;	
       
   165 	}
       
   166