|
1 /* |
|
2 * Copyright (c) 1998-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 "tactionderivekey.h" |
|
20 #include "t_input.h" |
|
21 #include <pkcs5kdf.h> |
|
22 #include <pkcs12kdf.h> |
|
23 #include <stdlib.h> |
|
24 |
|
25 _LIT8(KKdfStart, "<kdf>"); |
|
26 _LIT8(KKdfEnd, "</kdf>"); |
|
27 _LIT8(KPKCS12Kdf, "pkcs#12"); |
|
28 _LIT8(KDeriveKeyStart, "<derivekey>"); |
|
29 _LIT8(KDeriveKeyEnd, "</derivekey>"); |
|
30 _LIT8(KKeyStart, "<key>"); |
|
31 _LIT8(KKeyEnd, "</key>"); |
|
32 _LIT8(KPasswdStart, "<passwd>"); |
|
33 _LIT8(KPasswdEnd, "</passwd>"); |
|
34 _LIT8(KSaltStart, "<salt>"); |
|
35 _LIT8(KSaltEnd, "</salt>"); |
|
36 _LIT8(KIterationsStart, "<iterations>"); |
|
37 _LIT8(KIterationsEnd, "</iterations>"); |
|
38 _LIT8(KLeaveInPerformAction, "<leaveinperformaction>"); |
|
39 _LIT8(KLeaveInPerformActionEnd, "</leaveinperformaction>"); |
|
40 |
|
41 CTestAction* CActionDeriveKey::NewL(RFs& aFs, |
|
42 CConsoleBase& aConsole, |
|
43 Output& aOut, |
|
44 const TTestActionSpec& aTestActionSpec) |
|
45 { |
|
46 CTestAction* self = CActionDeriveKey::NewLC(aFs, aConsole, |
|
47 aOut, aTestActionSpec); |
|
48 CleanupStack::Pop(); |
|
49 return self; |
|
50 } |
|
51 |
|
52 CTestAction* CActionDeriveKey::NewLC(RFs& aFs, |
|
53 CConsoleBase& aConsole, |
|
54 Output& aOut, |
|
55 const TTestActionSpec& aTestActionSpec) |
|
56 { |
|
57 CActionDeriveKey* self = new(ELeave) CActionDeriveKey(aFs, aConsole, aOut); |
|
58 CleanupStack::PushL(self); |
|
59 self->ConstructL(aTestActionSpec); |
|
60 return self; |
|
61 } |
|
62 |
|
63 CActionDeriveKey::~CActionDeriveKey() |
|
64 { |
|
65 delete iBody; |
|
66 } |
|
67 |
|
68 CActionDeriveKey::CActionDeriveKey(RFs& aFs, |
|
69 CConsoleBase& aConsole, |
|
70 Output& aOut) |
|
71 |
|
72 : CTestAction(aConsole, aOut), iFs(aFs) |
|
73 { |
|
74 } |
|
75 |
|
76 void CActionDeriveKey::ConstructL(const TTestActionSpec& aTestActionSpec) |
|
77 { |
|
78 CTestAction::ConstructL(aTestActionSpec); |
|
79 iBody = HBufC8::NewL(aTestActionSpec.iActionBody.Length()); |
|
80 iBody->Des().Copy(aTestActionSpec.iActionBody); |
|
81 } |
|
82 |
|
83 void CActionDeriveKey::DoPerformPrerequisite(TRequestStatus& aStatus) |
|
84 { |
|
85 TRequestStatus* status = &aStatus; |
|
86 TInt err = KErrNone; |
|
87 TInt pos = 0; |
|
88 TPtrC8 deriveKey = Input::ParseElement(*iBody, KDeriveKeyStart, KDeriveKeyEnd, pos, err); |
|
89 |
|
90 // KDF is only explicitly specified for PKCS#12 derived keys |
|
91 TPtrC8 kdfTemp = Input::ParseElement(deriveKey, KKdfStart, KKdfEnd, pos=0, err); |
|
92 if (err == KErrNone) |
|
93 iKdf = kdfTemp.AllocL(); |
|
94 |
|
95 TPtrC8 passwdTemp = Input::ParseElement(deriveKey, KPasswdStart, KPasswdEnd, pos=0, err); |
|
96 iPasswd = HBufC8::NewL(passwdTemp.Length()); |
|
97 *iPasswd = passwdTemp; |
|
98 |
|
99 TPtrC8 iterationsTemp = Input::ParseElement(deriveKey, KIterationsStart, KIterationsEnd, pos=0, err); |
|
100 iIterations = HBufC8::NewL(iterationsTemp.Length() + 1); //added 1 for the null zero used later |
|
101 *iIterations = iterationsTemp; |
|
102 |
|
103 TPtrC8 saltTemp = Input::ParseElement(deriveKey, KSaltStart, KSaltEnd, pos=0, err); |
|
104 iSalt = HBufC8::NewL(saltTemp.Length()); |
|
105 *iSalt = saltTemp; |
|
106 Hex(*iSalt); |
|
107 |
|
108 TPtrC8 keyTemp = Input::ParseElement(deriveKey, KKeyStart, KKeyEnd, pos=0, err); |
|
109 iKey = HBufC8::NewL(keyTemp.Length()); |
|
110 *iKey = keyTemp; |
|
111 Hex(*iKey); |
|
112 |
|
113 iOutput = HBufC8::NewL(iKey->Length()); |
|
114 |
|
115 iLeaveInPerformAction = Input::ParseIntElement(deriveKey, |
|
116 KLeaveInPerformAction, KLeaveInPerformActionEnd, pos=0, err); |
|
117 if (err) |
|
118 { |
|
119 iLeaveInPerformAction = 0; |
|
120 } |
|
121 User::RequestComplete(status, KErrNone); |
|
122 iActionState = CTestAction::EAction; |
|
123 } |
|
124 |
|
125 void CActionDeriveKey::DoPerformPostrequisite(TRequestStatus& aStatus) |
|
126 { |
|
127 TRequestStatus* status = &aStatus; |
|
128 delete iKey; |
|
129 delete iSalt; |
|
130 delete iIterations; |
|
131 delete iPasswd; |
|
132 delete iOutput; |
|
133 delete iKdf; |
|
134 iKdf = 0; |
|
135 |
|
136 iFinished = ETrue; |
|
137 User::RequestComplete(status, KErrNone); |
|
138 } |
|
139 |
|
140 void CActionDeriveKey::DoReportAction(void) |
|
141 { |
|
142 } |
|
143 |
|
144 void CActionDeriveKey::DoCheckResult(TInt) |
|
145 { |
|
146 |
|
147 } |
|
148 |
|
149 void CActionDeriveKey::PerformAction(TRequestStatus& aStatus) |
|
150 { |
|
151 TRequestStatus* status = &aStatus; |
|
152 iResult = EFalse; |
|
153 |
|
154 if (iLeaveInPerformAction) |
|
155 { |
|
156 User::Leave(KErrArgument); |
|
157 } |
|
158 iOutput->Des().SetLength(iKey->Length()); |
|
159 |
|
160 TUint8* nptr= (TUint8*)(iIterations->Des().PtrZ()); |
|
161 TUint32 i = strtoul((char*)nptr, 0, 10); |
|
162 |
|
163 iConsole.Printf(_L(".")); |
|
164 TPtr8 outputActual = iOutput->Des(); |
|
165 TPtr8 passwdActual = iPasswd->Des(); |
|
166 if (iKdf != 0 && *iKdf == KPKCS12Kdf) |
|
167 { |
|
168 // convert the password to PKCS#12 password format |
|
169 HBufC* pwdNative = HBufC::NewLC(iPasswd->Length()); |
|
170 pwdNative->Des().Copy(*iPasswd); |
|
171 HBufC8* pwdPKCS12 = PKCS12KDF::GeneratePasswordLC(*pwdNative); |
|
172 PKCS12KDF::DeriveKeyL(outputActual, PKCS12KDF::EIDByteEncryptKey, *pwdPKCS12, *iSalt, i); |
|
173 CleanupStack::PopAndDestroy(2, pwdNative); |
|
174 } |
|
175 else // PKCS#5 |
|
176 { |
|
177 TPtr8 saltActual = iSalt->Des(); |
|
178 TPKCS5KDF::DeriveKeyL(outputActual, passwdActual, saltActual,i); |
|
179 } |
|
180 |
|
181 if(*iOutput == *iKey) |
|
182 { |
|
183 iResult = ETrue; |
|
184 } |
|
185 |
|
186 User::RequestComplete(status, KErrNone); |
|
187 iActionState = CTestAction::EPostrequisite; |
|
188 } |
|
189 |
|
190 void CActionDeriveKey::Hex(HBufC8& aString) |
|
191 /** |
|
192 Convert the supplied hex string into the binary equivalent. |
|
193 |
|
194 @param aString Hex string. On entry this contains |
|
195 a sequence of hexadecimal characters, |
|
196 e.g., "3037AFC8EA". On exit it is |
|
197 half the original length and each two-digit |
|
198 hex number is reduced to the matching |
|
199 byte value. |
|
200 */ |
|
201 { |
|
202 TPtr8 ptr=aString.Des(); |
|
203 if (aString.Length()%2) |
|
204 { |
|
205 ptr.SetLength(0); |
|
206 return; |
|
207 } |
|
208 TInt i; |
|
209 for (i=0;i<aString.Length();i+=2) |
|
210 { |
|
211 TUint8 tmp; |
|
212 tmp=(TUint8)(aString[i]-(aString[i]>'9'?('A'-10):'0')); |
|
213 tmp*=16; |
|
214 tmp|=(TUint8)(aString[i+1]-(aString[i+1]>'9'?('A'-10):'0')); |
|
215 ptr[i/2]=tmp; |
|
216 } |
|
217 ptr.SetLength(aString.Length()/2); |
|
218 } |
|
219 |