|
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 pos = 0; |
|
92 TPtrC8 kdfTemp = Input::ParseElement(deriveKey, KKdfStart, KKdfEnd, pos, err); |
|
93 if (err == KErrNone) |
|
94 iKdf = kdfTemp.AllocL(); |
|
95 |
|
96 pos = 0; |
|
97 TPtrC8 passwdTemp = Input::ParseElement(deriveKey, KPasswdStart, KPasswdEnd, pos, err); |
|
98 iPasswd = HBufC8::NewL(passwdTemp.Length()); |
|
99 *iPasswd = passwdTemp; |
|
100 |
|
101 pos = 0; |
|
102 TPtrC8 iterationsTemp = Input::ParseElement(deriveKey, KIterationsStart, KIterationsEnd, pos, err); |
|
103 iIterations = HBufC8::NewL(iterationsTemp.Length() + 1); //added 1 for the null zero used later |
|
104 *iIterations = iterationsTemp; |
|
105 |
|
106 pos = 0; |
|
107 TPtrC8 saltTemp = Input::ParseElement(deriveKey, KSaltStart, KSaltEnd, pos, err); |
|
108 iSalt = HBufC8::NewL(saltTemp.Length()); |
|
109 *iSalt = saltTemp; |
|
110 Hex(*iSalt); |
|
111 |
|
112 pos = 0; |
|
113 TPtrC8 keyTemp = Input::ParseElement(deriveKey, KKeyStart, KKeyEnd, pos, err); |
|
114 iKey = HBufC8::NewL(keyTemp.Length()); |
|
115 *iKey = keyTemp; |
|
116 Hex(*iKey); |
|
117 |
|
118 iOutput = HBufC8::NewL(iKey->Length()); |
|
119 |
|
120 pos = 0; |
|
121 iLeaveInPerformAction = Input::ParseIntElement(deriveKey, |
|
122 KLeaveInPerformAction, KLeaveInPerformActionEnd, pos, err); |
|
123 if (err) |
|
124 { |
|
125 iLeaveInPerformAction = 0; |
|
126 } |
|
127 User::RequestComplete(status, KErrNone); |
|
128 iActionState = CTestAction::EAction; |
|
129 } |
|
130 |
|
131 void CActionDeriveKey::DoPerformPostrequisite(TRequestStatus& aStatus) |
|
132 { |
|
133 TRequestStatus* status = &aStatus; |
|
134 delete iKey; |
|
135 delete iSalt; |
|
136 delete iIterations; |
|
137 delete iPasswd; |
|
138 delete iOutput; |
|
139 delete iKdf; |
|
140 iKdf = 0; |
|
141 |
|
142 iFinished = ETrue; |
|
143 User::RequestComplete(status, KErrNone); |
|
144 } |
|
145 |
|
146 void CActionDeriveKey::DoReportAction(void) |
|
147 { |
|
148 } |
|
149 |
|
150 void CActionDeriveKey::DoCheckResult(TInt) |
|
151 { |
|
152 |
|
153 } |
|
154 |
|
155 void CActionDeriveKey::PerformAction(TRequestStatus& aStatus) |
|
156 { |
|
157 TRequestStatus* status = &aStatus; |
|
158 iResult = EFalse; |
|
159 |
|
160 if (iLeaveInPerformAction) |
|
161 { |
|
162 User::Leave(KErrArgument); |
|
163 } |
|
164 iOutput->Des().SetLength(iKey->Length()); |
|
165 |
|
166 TUint8* nptr= (TUint8*)(iIterations->Des().PtrZ()); |
|
167 TUint32 i = strtoul((char*)nptr, 0, 10); |
|
168 |
|
169 iConsole.Printf(_L(".")); |
|
170 TPtr8 outputActual = iOutput->Des(); |
|
171 TPtr8 passwdActual = iPasswd->Des(); |
|
172 if (iKdf != 0 && *iKdf == KPKCS12Kdf) |
|
173 { |
|
174 // convert the password to PKCS#12 password format |
|
175 HBufC* pwdNative = HBufC::NewLC(iPasswd->Length()); |
|
176 pwdNative->Des().Copy(*iPasswd); |
|
177 HBufC8* pwdPKCS12 = PKCS12KDF::GeneratePasswordLC(*pwdNative); |
|
178 PKCS12KDF::DeriveKeyL(outputActual, PKCS12KDF::EIDByteEncryptKey, *pwdPKCS12, *iSalt, i); |
|
179 CleanupStack::PopAndDestroy(2, pwdNative); |
|
180 } |
|
181 else // PKCS#5 |
|
182 { |
|
183 TPtr8 saltActual = iSalt->Des(); |
|
184 TPKCS5KDF::DeriveKeyL(outputActual, passwdActual, saltActual,i); |
|
185 } |
|
186 |
|
187 if(*iOutput == *iKey) |
|
188 { |
|
189 iResult = ETrue; |
|
190 } |
|
191 |
|
192 User::RequestComplete(status, KErrNone); |
|
193 iActionState = CTestAction::EPostrequisite; |
|
194 } |
|
195 |
|
196 void CActionDeriveKey::Hex(HBufC8& aString) |
|
197 /** |
|
198 Convert the supplied hex string into the binary equivalent. |
|
199 |
|
200 @param aString Hex string. On entry this contains |
|
201 a sequence of hexadecimal characters, |
|
202 e.g., "3037AFC8EA". On exit it is |
|
203 half the original length and each two-digit |
|
204 hex number is reduced to the matching |
|
205 byte value. |
|
206 */ |
|
207 { |
|
208 TPtr8 ptr=aString.Des(); |
|
209 if (aString.Length()%2) |
|
210 { |
|
211 ptr.SetLength(0); |
|
212 return; |
|
213 } |
|
214 TInt i; |
|
215 for (i=0;i<aString.Length();i+=2) |
|
216 { |
|
217 TUint8 tmp; |
|
218 tmp=(TUint8)(aString[i]-(aString[i]>'9'?('A'-10):'0')); |
|
219 tmp*=16; |
|
220 tmp|=(TUint8)(aString[i+1]-(aString[i+1]>'9'?('A'-10):'0')); |
|
221 ptr[i/2]=tmp; |
|
222 } |
|
223 ptr.SetLength(aString.Length()/2); |
|
224 } |