First public contribution.
2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
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".
9 * Initial Contributors:
10 * Nokia Corporation - initial contribution.
19 #include "pkcs12macdata.h"
21 using namespace PKCS12;
23 CDecPkcs12MacData::CDecPkcs12MacData()
27 EXPORT_C CDecPkcs12MacData* CDecPkcs12MacData::NewL(const TDesC8& aMacData, const TDesC8& aAuthSafeData)
29 CDecPkcs12MacData* self = new(ELeave) CDecPkcs12MacData();
30 CleanupStack::PushL(self);
31 self->ConstructL(aMacData, aAuthSafeData);
32 CleanupStack::Pop(self);
36 CDecPkcs12MacData::~CDecPkcs12MacData()
41 void CDecPkcs12MacData::ConstructL(const TDesC8& aMacData, const TDesC8& aAuthSafeData)
43 iAuthSafeDataPtr.Set(aAuthSafeData);
45 // MacData is a Sequence
46 TASN1DecGeneric seqGen(aMacData);
48 if (seqGen.Tag() != EASN1Sequence || seqGen.Class() != EUniversal)
50 User::Leave(KErrArgument);
53 // Decode the MacData Sequence
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)
61 User::Leave(KErrArgument);
65 const TASN1DecGeneric* macDataSequenceAt0 = macDataSequence->At(0);
66 // DigestInfo is a Sequence
67 if (macDataSequenceAt0->Tag() != EASN1Sequence || macDataSequenceAt0->Class() != EUniversal)
69 User::Leave(KErrArgument);
71 iDigestInfo = CPKCS7DigestInfo::NewL(macDataSequenceAt0->Encoding());
74 const TASN1DecGeneric* macDataSequenceAt1 = macDataSequence->At(1);
75 // MacSalt is an OctetString
76 if (macDataSequenceAt1->Tag() != EASN1OctetString || macDataSequenceAt1->Class() != EUniversal)
78 User::Leave(KErrArgument);
80 iMacSalt.Set(macDataSequenceAt1->GetContentDER());
83 if(macDataSequence->Count() == 3)
85 // Check for IterationCount
86 const TASN1DecGeneric* macDataSequenceAt2 = macDataSequence->At(2);
87 if (macDataSequenceAt2->Tag() != EASN1Integer || macDataSequenceAt2->Class() != EUniversal)
89 User::Leave(KErrArgument);
92 TASN1DecInteger intDecoder;
93 iIterationCount = intDecoder.DecodeDERShortL(*macDataSequenceAt2);
94 if(iIterationCount <= 0)
96 User::Leave(KErrArgument);
99 // Assign the Default value as 1 if Iteration Count is not present.
102 iIterationCount = KDefaultIterationCount;
104 CleanupStack::PopAndDestroy(macDataSequence);
107 EXPORT_C const CPKCS7DigestInfo& CDecPkcs12MacData::DigestInfo() const
112 EXPORT_C const TDesC8& CDecPkcs12MacData::MacSalt() const
117 EXPORT_C TInt CDecPkcs12MacData::IterationCount() const
119 return iIterationCount;
122 EXPORT_C TBool CDecPkcs12MacData::VerifyIntegrityL(const TDesC& aPassword) const
125 HBufC8* encryptKey = HBufC8::NewMaxLC(KSha1HmacKeyLength);
126 TPtr8 encryptedKey(encryptKey->Des());
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);
132 PKCS12KDF::DeriveKeyL(encryptedKey, PKCS12KDF::EIDByteMACKey, *password ,MacSalt(), IterationCount());
134 CMessageDigest* digest1 = NULL;
135 TAlgorithmId algorithmId = DigestInfo().Algorithm();
136 if (algorithmId != ESHA1)
138 User::Leave(KErrNotSupported);
140 digest1 = CSHA1::NewL();
141 CleanupStack::PushL( digest1 );
143 CHMAC* hmac1 = CHMAC::NewL( encryptedKey, digest1);
144 CleanupStack::PushL( hmac1 );
146 TPtrC8 tmpHash = hmac1->Final(iAuthSafeDataPtr);
147 TInt ret = tmpHash.Compare(DigestInfo().Digest());
158 CleanupStack::PopAndDestroy(hmac1);
159 CleanupStack::Pop(digest1);
160 CleanupStack::PopAndDestroy(2,encryptKey); // encryptKey, password