|
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 |