os/security/cryptoservices/certificateandkeymgmt/pkcs12/pkcs12macdata.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     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 	
   167 
   168