|
1 /* |
|
2 * Copyright (c) 2008 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 "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: A class that provides a signing operation. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 #include <unifiedkeystore.h> |
|
21 #include <asymmetric.h> |
|
22 |
|
23 #include "pkiservicesigner.h" |
|
24 #include "logonservices.h" |
|
25 #include "pkidefs.h" |
|
26 #include "pkiserviceconstants.h" |
|
27 #include "pkiserviceassert.h" |
|
28 |
|
29 CPkiServiceSigner* CPkiServiceSigner::NewL(CLogonServices& aLogonServices) |
|
30 { |
|
31 CPkiServiceSigner* self = new (ELeave) CPkiServiceSigner(aLogonServices); |
|
32 return self; |
|
33 } |
|
34 |
|
35 |
|
36 CPkiServiceSigner::CPkiServiceSigner(CLogonServices& aLogonServices) |
|
37 :CActive(EPriorityStandard), iLogonServices(aLogonServices) |
|
38 { |
|
39 CActiveScheduler::Add(this); |
|
40 } |
|
41 |
|
42 |
|
43 CPkiServiceSigner::~CPkiServiceSigner() |
|
44 { |
|
45 Cancel(); |
|
46 } |
|
47 |
|
48 |
|
49 void CPkiServiceSigner::Sign(const TPKIKeyIdentifier& aKeyId, |
|
50 const TDesC8& aDataToBeSigned, |
|
51 HBufC8*& aSignature, |
|
52 CUnifiedKeyStore& aUnifiedKeyStore, |
|
53 TInt aUsedKeyStore, |
|
54 TRequestStatus& aStatus) |
|
55 { |
|
56 PKISERVICE_ASSERT(iState == ESignerIdle); |
|
57 PKISERVICE_ASSERT(iClientStatus == NULL); |
|
58 PKISERVICE_ASSERT(iKeyStore == NULL); |
|
59 PKISERVICE_ASSERT(iOutputBuffer == NULL); |
|
60 PKISERVICE_ASSERT(iRsaSigner == NULL); |
|
61 PKISERVICE_ASSERT(iDsaSigner == NULL); |
|
62 PKISERVICE_ASSERT(iRsaSignature == NULL); |
|
63 PKISERVICE_ASSERT(iDsaSignature == NULL); |
|
64 PKISERVICE_ASSERT(iKeysList.Count() == 0); |
|
65 |
|
66 |
|
67 iState = ESignerGettingKey; |
|
68 |
|
69 |
|
70 iInput.Set(aDataToBeSigned); |
|
71 |
|
72 iOutputBuffer = &aSignature; |
|
73 iKeyStore = &aUnifiedKeyStore; |
|
74 iUsedKeyStore = aUsedKeyStore; |
|
75 aStatus = KRequestPending; |
|
76 iClientStatus = &aStatus; |
|
77 |
|
78 |
|
79 TCTKeyAttributeFilter filter; |
|
80 filter.iKeyId = aKeyId; |
|
81 |
|
82 iKeyStore->List(iKeysList, filter, iStatus); |
|
83 SetActive(); |
|
84 } |
|
85 |
|
86 |
|
87 void CPkiServiceSigner::DoCancel() |
|
88 { |
|
89 switch(iState) |
|
90 { |
|
91 case ESignerGettingKey: |
|
92 iKeyStore->CancelList(); |
|
93 break; |
|
94 case ESignerOpeningSigner: |
|
95 iKeyStore->CancelOpen(); |
|
96 break; |
|
97 case ESignerSigning: |
|
98 if (iRsaSigner != NULL) |
|
99 { |
|
100 PKISERVICE_ASSERT(iDsaSigner == NULL); |
|
101 iRsaSigner->CancelSign(); |
|
102 } |
|
103 else |
|
104 { |
|
105 PKISERVICE_ASSERT(iDsaSigner != NULL); |
|
106 PKISERVICE_ASSERT(iRsaSigner == NULL ); |
|
107 iDsaSigner->CancelSign(); |
|
108 } |
|
109 Cleanup(); |
|
110 break; |
|
111 default: |
|
112 PKISERVICE_INVARIANT(); |
|
113 break; |
|
114 } |
|
115 iState = ESignerIdle; |
|
116 Cleanup(); |
|
117 User::RequestComplete(iClientStatus, KErrCancel); |
|
118 } |
|
119 |
|
120 |
|
121 void CPkiServiceSigner::RunL() |
|
122 { |
|
123 if (iStatus.Int() == KErrNone) |
|
124 { |
|
125 switch(iState) |
|
126 { |
|
127 case ESignerGettingKey: |
|
128 iState = ESignerIdle; |
|
129 |
|
130 TInt keyIndex; |
|
131 for (keyIndex = 0; keyIndex < iKeysList.Count(); keyIndex++) |
|
132 { |
|
133 if (iUsedKeyStore == STORETYPE_ANY_KEY_ID || |
|
134 iUsedKeyStore == iKeysList[keyIndex]->Token().TokenType().Type().iUid) |
|
135 { |
|
136 break; |
|
137 } |
|
138 } |
|
139 |
|
140 if (keyIndex < iKeysList.Count()) |
|
141 { |
|
142 iUsedKeyInfo = iKeysList[keyIndex]; |
|
143 TCTTokenObjectHandle tokenHandle = iUsedKeyInfo->Handle(); |
|
144 switch(iUsedKeyInfo->Algorithm()) |
|
145 { |
|
146 case CKeyInfoBase::ERSA: |
|
147 iState = ESignerOpeningSigner; |
|
148 iKeyStore->Open(tokenHandle, iRsaSigner, iStatus); |
|
149 SetActive(); |
|
150 break; |
|
151 case CKeyInfoBase::EDSA: |
|
152 iState = ESignerOpeningSigner; |
|
153 iKeyStore->Open(tokenHandle, iDsaSigner, iStatus); |
|
154 SetActive(); |
|
155 break; |
|
156 default: |
|
157 Cleanup(); |
|
158 User::RequestComplete(iClientStatus, KPKIErrNotSupported); |
|
159 break; |
|
160 } |
|
161 } |
|
162 else |
|
163 { |
|
164 Cleanup(); |
|
165 User::RequestComplete(iClientStatus, KPKIErrNotFound); |
|
166 } |
|
167 |
|
168 break; |
|
169 case ESignerOpeningSigner: |
|
170 iState = ESignerSigning; |
|
171 if (iRsaSigner != NULL) |
|
172 { |
|
173 PKISERVICE_ASSERT(iDsaSigner == NULL); |
|
174 iRsaSigner->Sign(iInput, iRsaSignature, iStatus); |
|
175 SetActive(); |
|
176 } |
|
177 else |
|
178 { |
|
179 PKISERVICE_ASSERT(iDsaSigner != NULL); |
|
180 iDsaSigner->Sign(iInput, iDsaSignature, iStatus); |
|
181 SetActive(); |
|
182 } |
|
183 break; |
|
184 case ESignerSigning: |
|
185 iState = ESignerIdle; |
|
186 |
|
187 if (iUsedKeyInfo->Protector() != NULL) |
|
188 { |
|
189 //authObject is NULL for device store |
|
190 iLogonServices.SetAuthenticationObject(iUsedKeyInfo->Protector()); |
|
191 } |
|
192 |
|
193 |
|
194 TRAPD(err, |
|
195 if (iRsaSignature != NULL) |
|
196 { |
|
197 PKISERVICE_ASSERT(iDsaSignature == NULL); |
|
198 |
|
199 const TInteger& integer = iRsaSignature->S(); |
|
200 *iOutputBuffer = integer.BufferLC(); |
|
201 CleanupStack::Pop(*iOutputBuffer); |
|
202 } |
|
203 else |
|
204 { |
|
205 PKISERVICE_ASSERT(iDsaSignature != NULL); |
|
206 |
|
207 const TInteger& integerR = iDsaSignature->R(); |
|
208 HBufC8* rBuf = integerR.BufferLC(); |
|
209 |
|
210 const TInteger& integerS = iDsaSignature->S(); |
|
211 HBufC8* sBuf = integerS.BufferLC(); |
|
212 |
|
213 (*iOutputBuffer) = HBufC8::NewL(rBuf->Length() + sBuf->Length()); |
|
214 TPtr8 outputBufferPtr = (*iOutputBuffer)->Des(); |
|
215 outputBufferPtr.Append(*rBuf); |
|
216 outputBufferPtr.Append(*sBuf); |
|
217 |
|
218 CleanupStack::PopAndDestroy(sBuf); |
|
219 CleanupStack::PopAndDestroy(rBuf); |
|
220 } |
|
221 ); |
|
222 Cleanup(); |
|
223 User::RequestComplete(iClientStatus, err); |
|
224 break; |
|
225 default: |
|
226 PKISERVICE_INVARIANT(); |
|
227 break; |
|
228 } |
|
229 } |
|
230 else |
|
231 { |
|
232 iState = ESignerIdle; |
|
233 Cleanup(); |
|
234 User::RequestComplete(iClientStatus, iStatus.Int()); |
|
235 } |
|
236 } |
|
237 |
|
238 |
|
239 void CPkiServiceSigner::Cleanup() |
|
240 { |
|
241 iUsedKeyInfo = NULL; |
|
242 |
|
243 delete iRsaSignature; |
|
244 iRsaSignature = NULL; |
|
245 |
|
246 delete iDsaSignature; |
|
247 iDsaSignature = NULL; |
|
248 |
|
249 |
|
250 if (iRsaSigner != NULL) |
|
251 { |
|
252 iRsaSigner->Release(); |
|
253 iRsaSigner = NULL; |
|
254 } |
|
255 |
|
256 if (iDsaSigner != NULL) |
|
257 { |
|
258 iDsaSigner->Release(); |
|
259 iDsaSigner = NULL; |
|
260 } |
|
261 |
|
262 iKeysList.Close(); |
|
263 |
|
264 iOutputBuffer = NULL; |
|
265 iKeyStore = NULL; |
|
266 |
|
267 } |