/[openpgpmdrv]/trunk/OpenPGPminidriver/CryptoOperations.c
ViewVC logotype

Contents of /trunk/OpenPGPminidriver/CryptoOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6 - (show annotations)
Thu Mar 4 21:17:51 2010 UTC (15 years, 2 months ago) by vletoux
File MIME type: text/plain
File size: 36711 byte(s)
Everything is working except the certificate
1 /* OpenPGP Smart Card Mini Driver
2 Copyright (C) 2009 Vincent Le Toux
3
4 This library is Free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License version 2.1 as published by the Free Software Foundation.
7
8 This library is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 Lesser General Public License for more details.
12
13 You should have received a copy of the GNU Lesser General Public
14 License along with this library; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17
18 #include <windows.h>
19 #include <cardmod.h>
20 #include "Tracing.h"
21 #include "Context.h"
22 #include "SmartCard.h"
23 #include "CryptoOperations.h"
24 #include "PinOperations.h"
25 #include "PublicDataOperations.h"
26 #include "tlv.h"
27
28 OPENPGP_CONTAINER_INFO Containers[] =
29 {
30 {0xB6, 0xCE, 0xC7, CALG_RSA_SIGN, AT_SIGNATURE, ROLE_SIGNATURE},
31 {0xA4, 0xD0, 0xC9, CALG_RSA_SIGN, AT_SIGNATURE, ROLE_AUTHENTICATION},
32 {0xB8, 0xCF, 0xC8, CALG_RSA_KEYX, AT_KEYEXCHANGE, ROLE_CONFIDENTIALITY}
33
34 };
35
36 typedef struct _OPENPGP_SUPPORTED_SIGNATURE_ALGORITHM
37 {
38 ALG_ID aiHashAlg;
39 DWORD dwHashSize;
40 PBYTE pbEncodedOid;
41 DWORD dwEncodedOidSize;
42 } OPENPGP_SUPPORTED_SIGNATURE_ALGORITHM, *POPENPGP_SUPPORTED_SIGNATURE_ALGORITHM;
43
44 BYTE dwSHA1EncodedOid[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
45 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14};
46 BYTE dwSHA256EncodedOid[] = {0x30, 0x31, 0x30, 0x0D,0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
47 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};
48 BYTE dwSHA384EncodedOid[] = {0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
49 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30};
50 BYTE dwSHA512EncodedOid[] = {0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
51 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40};
52
53 OPENPGP_SUPPORTED_SIGNATURE_ALGORITHM SignatureAlgorithm[] =
54 {
55 {CALG_SHA1,20,
56 dwSHA1EncodedOid,
57 ARRAYSIZE(dwSHA1EncodedOid)},
58 {CALG_SHA-256,32,
59 dwSHA256EncodedOid,
60 ARRAYSIZE(dwSHA256EncodedOid)},
61 {CALG_SHA-384,48,
62 dwSHA384EncodedOid,
63 ARRAYSIZE(dwSHA384EncodedOid)},
64 {CALG_SHA-512,64,
65 dwSHA512EncodedOid,
66 ARRAYSIZE(dwSHA512EncodedOid)},
67 };
68
69 DWORD dwSignatureAlgorithmCount = ARRAYSIZE(SignatureAlgorithm);
70
71 #pragma pack(push,1)
72 typedef struct _OPENPGP_ALGORITHM_ATTRIBUTE
73 {
74 BYTE bAlgoId;
75 unsigned short wModulusLength;
76 unsigned short wExponentLength;
77 BYTE bFormat;
78 } OPENPGP_ALGORITHM_ATTRIBUTE, *POPENPGP_ALGORITHM_ATTRIBUTE;
79 #pragma pack(pop)
80
81 typedef struct _RSAPUBLICKEYBLOB
82 {
83 BLOBHEADER blobheader;
84 RSAPUBKEY rsapubkey;
85 BYTE modulus[sizeof(DWORD)];
86 } RSAPUBLICKEYBLOB, *PRSAPUBLICKEYBLOB;
87
88
89 DWORD GetKeyAlgorithmAttributes(__in PCARD_DATA pCardData,
90 __in OPENPGP_CONTAINER dwContainer,
91 __out POPENPGP_ALGORITHM_ATTRIBUTE pAttributes)
92 {
93 DWORD dwReturn;
94 PSTR szAlgorithmAttributes = NULL;
95 PBYTE pbData = NULL;
96 DWORD dwResponseSize;
97 WORD wTemp;
98 __try
99 {
100 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
101 switch(dwContainer)
102 {
103 case Signature:
104 szAlgorithmAttributes = szOpenPGPAlgoAttributesSignature;
105 break;
106 case Authentication:
107 szAlgorithmAttributes = szOpenPGPAlgoAttributesDecryption;
108 break;
109 case Confidentiality:
110 szAlgorithmAttributes = szOpenPGPAlgoAttributesAuthentication;
111 break;
112 default:
113 dwReturn = SCARD_E_NO_KEY_CONTAINER;
114 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", dwContainer);
115 __leave;
116 }
117 dwReturn = SCardReadFile(pCardData, szOpenPGPDir, szAlgorithmAttributes, &pbData, &dwResponseSize);
118 if (dwReturn)
119 {
120 __leave;
121 }
122 if (dwResponseSize != sizeof(OPENPGP_ALGORITHM_ATTRIBUTE))
123 {
124 dwReturn = SCARD_E_UNEXPECTED;
125 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED");
126 __leave;
127 }
128 memcpy(pAttributes, pbData, dwResponseSize);
129 // big endian, little endian ...
130 wTemp = pAttributes->wExponentLength;
131 pAttributes->wExponentLength = (wTemp % 0x100) * 0x100 + (wTemp / 0x100);
132 wTemp = pAttributes->wModulusLength;
133 pAttributes->wModulusLength = (wTemp % 0x100) * 0x100 + (wTemp / 0x100);
134
135 dwReturn = 0;
136 }
137 __finally
138 {
139 if (pbData)
140 pCardData->pfnCspFree(pbData);
141 }
142 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
143 return dwReturn;
144 }
145
146 DWORD SetKeyAlgorithmAttributes(__in PCARD_DATA pCardData,
147 __in OPENPGP_CONTAINER dwContainer,
148 __out POPENPGP_ALGORITHM_ATTRIBUTE pAttributes)
149 {
150 DWORD dwReturn;
151 PSTR szAlgorithmAttributes = NULL;
152 OPENPGP_ALGORITHM_ATTRIBUTE TempAttributes;
153 WORD wTemp;
154 __try
155 {
156 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
157 switch(dwContainer)
158 {
159 case Signature:
160 szAlgorithmAttributes = szOpenPGPAlgoAttributesSignature;
161 break;
162 case Authentication:
163 szAlgorithmAttributes = szOpenPGPAlgoAttributesDecryption;
164 break;
165 case Confidentiality:
166 szAlgorithmAttributes = szOpenPGPAlgoAttributesAuthentication;
167 break;
168 default:
169 dwReturn = SCARD_E_NO_KEY_CONTAINER;
170 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", dwContainer);
171 __leave;
172 }
173 memcpy(&TempAttributes, pAttributes, sizeof(OPENPGP_ALGORITHM_ATTRIBUTE));
174 wTemp = TempAttributes.wExponentLength;
175 TempAttributes.wExponentLength = (wTemp % 0x100) * 0x100 + (wTemp / 0x100);
176 wTemp = TempAttributes.wModulusLength;
177 TempAttributes.wModulusLength = (wTemp % 0x100) * 0x100 + (wTemp / 0x100);
178
179 dwReturn = SCardWriteFile(pCardData, szOpenPGPDir, szAlgorithmAttributes, (PBYTE) &TempAttributes, sizeof(OPENPGP_ALGORITHM_ATTRIBUTE));
180 if (dwReturn)
181 {
182 __leave;
183 }
184 dwReturn = 0;
185 }
186 __finally
187 {
188 }
189 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
190 return dwReturn;
191 }
192
193 DWORD BuildSingleTlv(__in PBYTE buffer, __in BYTE bTlv, __in DWORD dwTlvSize, __inout PDWORD pdwOffset)
194 {
195 DWORD dwSize = 1;
196 buffer[(*pdwOffset)++] = bTlv;
197 // truncate if too long
198 if (dwTlvSize > 0xFFFF) dwTlvSize = 0xFFFF;
199 if (dwTlvSize < 0x7F)
200 {
201 buffer[(*pdwOffset)++] = (BYTE) dwTlvSize;
202 dwSize++;
203 }
204 else if (dwTlvSize < 0xFF)
205 {
206 buffer[(*pdwOffset)++] = 0x81;
207 buffer[(*pdwOffset)++] = (BYTE) dwTlvSize;
208 dwSize+=2;
209 }
210 else
211 {
212 buffer[(*pdwOffset)++] = 0x82;
213 buffer[(*pdwOffset)++] = (BYTE) (dwTlvSize / 0x100);
214 buffer[(*pdwOffset)++] = (BYTE) (dwTlvSize % 0x100);
215 dwSize+=3;
216 }
217 return dwSize;
218 }
219
220 DWORD BuildPrivateKeyTlv(__in PCARD_DATA pCardData, __in PRSAPUBLICKEYBLOB pbPublicKeyBlob,
221 __in OPENPGP_CONTAINER dwContainer, __in BYTE bFormat,
222 __out PBYTE * ppbTlv, __out PDWORD pdwTlvSize)
223 {
224 // structure of the keyblob
225 //BLOBHEADER blobheader;
226 //RSAPUBKEY rsapubkey;
227 //BYTE modulus[rsapubkey.bitlen/8];
228 //BYTE prime1[rsapubkey.bitlen/16];
229 //BYTE prime2[rsapubkey.bitlen/16];
230 //BYTE exponent1[rsapubkey.bitlen/16];
231 //BYTE exponent2[rsapubkey.bitlen/16];
232 //BYTE coefficient[rsapubkey.bitlen/16];
233 //BYTE privateExponent[rsapubkey.bitlen/8];
234 DWORD dwReturn = 0;
235
236 DWORD bitlen = pbPublicKeyBlob->rsapubkey.bitlen;
237 PBYTE pbPublicKeyData = (PBYTE) &(pbPublicKeyBlob->modulus);
238 // 7F48 len is < 7F so its encoded len is 1 bytes
239 // 3 bytes max + length * 7 potential plv
240 BYTE b7F48Header[(3 +1) * 7 + 3] = {0x7F, 0x48};
241 BYTE b5F48Header[3 + 2] = {0x5F, 0x48};
242 BYTE b4DHeader[3 + 1] = {0x4D};
243 DWORD dwOffset = 0;
244 DWORD dw7F48HeaderSize, dw5F48HeaderSize, dw4DHeaderSize;
245 DWORD dwKeyDataSize, dwExtendedHeaderListSize;
246 DWORD dwI;
247 __try
248 {
249 // build the 7F48 header + the data into a buffer
250 dwOffset = 3;
251 dw7F48HeaderSize = 0;
252 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x91, sizeof(DWORD), &dwOffset);
253 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x92, bitlen / 16, &dwOffset);
254 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x93, bitlen / 16, &dwOffset);
255 if (bFormat & 2)
256 {
257 // add crt (chineese reminder theorem) template
258 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x94, bitlen / 16, &dwOffset);
259 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x95, bitlen / 16, &dwOffset);
260 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x96, bitlen / 16, &dwOffset);
261 }
262 if (bFormat & 1)
263 {
264 dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x97, bitlen / 8, &dwOffset);
265 }
266 b7F48Header[2] = (BYTE) dw7F48HeaderSize;
267 dw7F48HeaderSize += 3; // before = only content, after += header size
268 // build 5F48 header in a buffer
269 // size of the data
270 dwKeyDataSize = sizeof(DWORD) // e
271 + bitlen / 16 //prime1
272 + bitlen / 16 //prime2
273 ;
274 if (bFormat & 2)
275 {
276 dwKeyDataSize+= bitlen / 16 //coefficient
277 + bitlen / 16 //exp1
278 + bitlen / 16 //exp2
279 ;
280 }
281 if (bFormat & 1)
282 {
283 dwKeyDataSize+= bitlen / 8 ; //modulus
284 }
285 dwOffset = 1;
286 dw5F48HeaderSize = 1 + BuildSingleTlv(b5F48Header, 0x48, dwKeyDataSize, &dwOffset);
287 // build the extended header list in a buffer
288 dwExtendedHeaderListSize = 2 // for the crt to indicate the private key
289 + dw7F48HeaderSize
290 + dw5F48HeaderSize
291 + dwKeyDataSize;
292 dwOffset = 0;
293 dw4DHeaderSize = BuildSingleTlv(b4DHeader, 0x4D, dwExtendedHeaderListSize, &dwOffset);
294
295 // allocate the memory
296 *pdwTlvSize = dw4DHeaderSize + dwExtendedHeaderListSize;
297 *ppbTlv = pCardData->pfnCspAlloc(*pdwTlvSize);
298 if (! *ppbTlv)
299 {
300 dwReturn = SCARD_E_NO_MEMORY;
301 __leave;
302 }
303 // 4D header
304 dwOffset = 0;
305 memcpy(*ppbTlv + dwOffset, b4DHeader, dw4DHeaderSize);
306 dwOffset += dw4DHeaderSize;
307 // control reference templace
308 (*ppbTlv)[dwOffset++] = Containers[dwContainer].bKeyTag;
309 (*ppbTlv)[dwOffset++] = 0;
310 // cardholder private key template
311 memcpy(*ppbTlv + dwOffset, b7F48Header, dw7F48HeaderSize);
312 dwOffset += dw7F48HeaderSize;
313 // Concatenation of key data header
314 memcpy(*ppbTlv + dwOffset, b5F48Header, dw5F48HeaderSize);
315 dwOffset += dw5F48HeaderSize;
316 // Concatenation of key data
317 // exponent little => big endian
318 (*ppbTlv)[dwOffset++] = (BYTE) (pbPublicKeyBlob->rsapubkey.pubexp / 0x1000000);
319 (*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x1000000) / 0x10000);
320 (*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x10000) / 0x100);
321 (*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x100) / 0x1);
322 // prime1
323 //memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2*bitlen)/16, bitlen / 16);
324 for(dwI = 0; dwI < bitlen / 16; dwI++)
325 {
326 (*ppbTlv)[dwOffset+dwI] = pbPublicKeyData[(3*bitlen)/16 - 1 - dwI];
327 }
328 dwOffset += bitlen / 16;
329
330 // prime2
331 for(dwI = 0; dwI < bitlen / 16; dwI++)
332 {
333 (*ppbTlv)[dwOffset+dwI] = pbPublicKeyData[(4*bitlen)/16 - 1 - dwI];
334 }
335 //memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (3*bitlen)/16, bitlen / 16);
336 dwOffset += bitlen / 16;
337 if (bFormat & 2)
338 {
339 // coeff
340 //memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1 + 3) * bitlen / 16 , bitlen / 16);
341 for(dwI = 0; dwI < bitlen / 16; dwI++)
342 {
343 (*ppbTlv)[dwOffset+dwI] = pbPublicKeyData[(7*bitlen)/16 - 1 - dwI];
344 }
345 dwOffset += bitlen / 16;
346 // exponent1
347 //memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1 + 1) * bitlen / 16 , bitlen / 16);
348 for(dwI = 0; dwI < bitlen / 16; dwI++)
349 {
350 (*ppbTlv)[dwOffset+dwI] = pbPublicKeyData[(5*bitlen)/16 - 1 - dwI];
351 }
352 dwOffset += bitlen / 16;
353 // exponent2
354 //memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1 + 2) * bitlen / 16 , bitlen / 16);
355 for(dwI = 0; dwI < bitlen / 16; dwI++)
356 {
357 (*ppbTlv)[dwOffset+dwI] = pbPublicKeyData[(6*bitlen)/16 - 1 - dwI];
358 }
359 dwOffset += bitlen / 16;
360 }
361 if (bFormat & 1)
362 {
363 // modulus
364 //memcpy(*ppbTlv + dwOffset, pbPublicKeyData, bitlen / 8);
365 for(dwI = 0; dwI < bitlen / 8; dwI++)
366 {
367 (*ppbTlv)[dwOffset+dwI] = pbPublicKeyData[bitlen / 8 - 1 - dwI];
368 }
369 }
370 }
371 __finally
372 {
373 }
374 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
375 return dwReturn;
376 }
377
378 DWORD UpdateGenerationDateTime(__in PCARD_DATA pCardData, __in OPENPGP_CONTAINER dwContainer,
379 __out PDWORD pdwSecondsSince1970)
380 {
381 DWORD dwReturn = 0;
382 LARGE_INTEGER UnixZeroTime = {0}, WindowsTime;
383 SYSTEMTIME WindowsSystemTime;
384 FILETIME WindowsFileTime;
385 BYTE pbCommand[] = {0x00, 0xDA, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00};
386 DWORD dwCommandSize = ARRAYSIZE(pbCommand);
387 __try
388 {
389 UnixZeroTime.QuadPart = 116444736000000000I64; // january 1st 1970
390 GetSystemTime(&WindowsSystemTime);
391 SystemTimeToFileTime(&WindowsSystemTime, &WindowsFileTime);
392 /* It is not recommended that you add and subtract values from the FILETIME
393 structure to obtain relative times. Instead, you should copy the low- and high-order
394 parts of the file time to a ULARGE_INTEGER structure, perform 64-bit arithmetic
395 on the QuadPart member, and copy the LowPart and HighPart members into the
396 FILETIME structure.
397
398 Do not cast a pointer to a FILETIME structure to either a ULARGE_INTEGER*
399 or __int64* value because it can cause alignment faults on 64-bit Windows.
400 */
401 WindowsTime.HighPart = WindowsFileTime.dwHighDateTime;
402 WindowsTime.LowPart = WindowsFileTime.dwLowDateTime;
403 *pdwSecondsSince1970 = (DWORD)((WindowsTime.QuadPart - UnixZeroTime.QuadPart) / 10000000);
404
405 pbCommand[3] = Containers[dwContainer].bDateTimeTag;
406 pbCommand[5] = (BYTE) (*pdwSecondsSince1970 / 0x1000000);
407 pbCommand[6] = (BYTE) ((*pdwSecondsSince1970 % 0x1000000) / 0x10000);
408 pbCommand[7] = (BYTE) ((*pdwSecondsSince1970 % 0x10000) / 0x100);
409 pbCommand[8] = (BYTE) ((*pdwSecondsSince1970 % 0x100) / 0x1);
410 dwReturn = SCardSendCommand(pCardData, pbCommand, dwCommandSize);
411 }
412 __finally
413 {
414 }
415 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
416 return dwReturn;
417 }
418
419 DWORD UpdateFingerPrint(__in PCARD_DATA pCardData, __in OPENPGP_CONTAINER dwContainer,
420 __in DWORD dwSecondsSince1970,
421 __in PBYTE pbModulus, __in DWORD dwModulusSizeInBit,
422 __in BOOL fIsModulusInBigEndian,
423 __in DWORD dwExponent)
424 {
425 // modulus in input are in big endian
426 // rfc4880 12.2
427 DWORD dwReturn = 0;
428 PBYTE pbBuffer = NULL;
429 DWORD dwBufferSize;
430 DWORD dwOffset = 0;
431 HCRYPTPROV hProv = 0;
432 HCRYPTHASH hHash = 0;
433 BYTE pbCommand[25] = {0x00, 0xDA, 0x00, 0x00, 0x14};
434 DWORD dwCommandSize = ARRAYSIZE(pbCommand);
435 DWORD dwHashLen = 0x14;
436 __try
437 {
438 dwBufferSize = dwModulusSizeInBit / 8 + sizeof(DWORD) + 10 + 3;
439 pbBuffer = (PBYTE) pCardData->pfnCspAlloc(dwBufferSize);
440 if (!pbBuffer)
441 {
442 dwReturn = SCARD_E_NO_MEMORY;
443 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
444 __leave;
445 }
446 pbBuffer[dwOffset++] = 0x99;
447 // -3 because of the header size
448 pbBuffer[dwOffset++] = (BYTE) ((dwBufferSize-3) / 0x100);
449 pbBuffer[dwOffset++] = (BYTE) ((dwBufferSize-3) % 0x100);
450 // rfc4880 5.5.2
451 // version
452 pbBuffer[dwOffset++] = 4;
453 // timestamp
454 pbBuffer[dwOffset++] = (BYTE) (dwSecondsSince1970 / 0x1000000);
455 pbBuffer[dwOffset++] = (BYTE) ((dwSecondsSince1970 % 0x1000000) / 0x10000);
456 pbBuffer[dwOffset++] = (BYTE) ((dwSecondsSince1970 % 0x10000) / 0x100);
457 pbBuffer[dwOffset++] = (BYTE) ((dwSecondsSince1970 % 0x100) / 0x1);
458 // RSA
459 pbBuffer[dwOffset++] = 1;
460 // size of modulus
461 pbBuffer[dwOffset++] = (BYTE) ((dwModulusSizeInBit % 0x10000) / 0x100);
462 pbBuffer[dwOffset++] = (BYTE) ((dwModulusSizeInBit % 0x100) / 0x1);
463 if (fIsModulusInBigEndian)
464 {
465 memcpy(pbBuffer + dwOffset, pbModulus, dwModulusSizeInBit / 8);
466 }
467 else
468 {
469 DWORD dwI;
470 for(dwI = 0; dwI < dwModulusSizeInBit / 8; dwI++)
471 {
472 pbBuffer[dwOffset + dwI] = pbModulus[dwModulusSizeInBit / 8 - 1 - dwI];
473 }
474 }
475 // size of exponent
476 pbBuffer[dwOffset++] = 0;
477 pbBuffer[dwOffset++] = sizeof(DWORD);
478 // exponent
479 pbBuffer[dwOffset++] = (BYTE) (dwExponent / 0x1000000);
480 pbBuffer[dwOffset++] = (BYTE) ((dwExponent % 0x1000000) / 0x10000);
481 pbBuffer[dwOffset++] = (BYTE) ((dwExponent % 0x10000) / 0x100);
482 pbBuffer[dwOffset++] = (BYTE) ((dwExponent % 0x100) / 0x1);
483
484 // hash using SHA1
485 if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
486 {
487 dwReturn = GetLastError();
488 Trace(WINEVENT_LEVEL_ERROR, L"CryptAcquireContext 0x%08X", dwReturn);
489 __leave;
490 }
491 if(!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
492 {
493 dwReturn = GetLastError();
494 Trace(WINEVENT_LEVEL_ERROR, L"CryptCreateHash 0x%08X", dwReturn);
495 __leave;
496 }
497 if(!CryptHashData(hHash, pbBuffer, dwBufferSize, 0))
498 {
499 dwReturn = GetLastError();
500 Trace(WINEVENT_LEVEL_ERROR, L"CryptHashData 0x%08X", dwReturn);
501 __leave;
502 }
503 if(!CryptGetHashParam(hHash, HP_HASHVAL, pbCommand + 5, &dwHashLen, 0)) {
504 dwReturn = GetLastError();
505 Trace(WINEVENT_LEVEL_ERROR, L"CryptGetHashParam 0x%08X", dwReturn);
506 __leave;
507 }
508 pbCommand[3] = Containers[dwContainer].bSignatureTag;
509 dwReturn = SCardSendCommand(pCardData, pbCommand, dwCommandSize);
510
511 }
512 __finally
513 {
514 if (pbBuffer)
515 pCardData->pfnCspFree(pbBuffer);
516 if(hHash)
517 CryptDestroyHash(hHash);
518 if(hProv)
519 CryptReleaseContext(hProv,0);
520
521 }
522 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
523 return dwReturn;
524
525 }
526
527 DWORD SCardReadPublicKey(PCARD_DATA pCardData, OPENPGP_CONTAINER dwContainer, PBYTE *pbPublicKey, PDWORD pdwPublicKeySize)
528 {
529 DWORD dwReturn;
530 PBYTE pbData = NULL;
531 DWORD dwResponseSize = 0;
532 BYTE pbCmd[] = {0x00,
533 0x47,
534 0x81,
535 0x00,
536 0x00,
537 0x00,
538 0x02,
539 0x00,
540 0x00,
541 0x00,
542 0x00
543 };
544 DWORD dwCmdSize;
545 POPENPGP_CONTEXT pContext;
546 PBYTE pbModulus;
547 DWORD dwModulusSize, dwI;
548 PBYTE pbExponent;
549 PRSAPUBLICKEYBLOB pbBlob = NULL;
550 DWORD dwTotalTlvSize, dwOffset;
551 __try
552 {
553 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
554 if (dwContainer >= MaxContainer)
555 {
556 dwReturn = SCARD_E_NO_KEY_CONTAINER;
557 Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwContainer);
558 __leave;
559 }
560 pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
561 pbCmd[7] = Containers[dwContainer].bKeyTag;
562 dwCmdSize = 9;
563 if (pContext->fExtentedLeLcFields)
564 {
565 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength / 0x100);
566 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength % 0x100);
567 }
568 else
569 {
570 pbCmd[dwCmdSize++] = 0xFF;
571 }
572
573 dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
574 if (dwReturn)
575 {
576 __leave;
577 }
578 dwOffset = 2;
579 dwTotalTlvSize = getTlvSize(pbData + 2,&dwOffset) + 2;
580 if (!find_tlv(pbData + dwOffset,0x81,dwTotalTlvSize,&pbModulus,&dwModulusSize))
581 {
582 dwReturn = SCARD_E_UNEXPECTED;
583 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
584 __leave;
585 }
586 if (!find_tlv(pbData + dwOffset,0x82,dwTotalTlvSize, (PBYTE*)&pbExponent,NULL))
587 {
588 dwReturn = SCARD_E_UNEXPECTED;
589 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
590 __leave;
591 }
592 Trace(WINEVENT_LEVEL_INFO, L"dwModulusSize %d bits", dwModulusSize * 8);
593 *pdwPublicKeySize = sizeof(RSAPUBLICKEYBLOB) + dwModulusSize - sizeof(DWORD);
594 *pbPublicKey = pCardData->pfnCspAlloc(*pdwPublicKeySize);
595 if (!*pbPublicKey)
596 {
597 dwReturn = SCARD_E_NO_MEMORY;
598 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY %d", dwContainer);
599 __leave;
600 }
601 pbBlob = (PRSAPUBLICKEYBLOB) *pbPublicKey;
602 memset(pbBlob,0,*pdwPublicKeySize);
603 pbBlob->blobheader.bType = PUBLICKEYBLOB;
604 pbBlob->blobheader.bVersion = CUR_BLOB_VERSION;
605 pbBlob->blobheader.reserved = 0;
606 pbBlob->blobheader.aiKeyAlg = Containers[dwContainer].aiKeyAlg;
607 pbBlob->rsapubkey.magic = 0x31415352; //'RSA1';
608 pbBlob->rsapubkey.bitlen = dwModulusSize*8;
609 pbBlob->rsapubkey.pubexp = pbExponent[0] * 0x1000000 + pbExponent[1] * 0x10000 + pbExponent[2] * 0x100 + pbExponent[3];
610 // convert big endian into little endian
611 //memcpy(pbBlob->modulus, pbModulus, dwModulusSize);
612 for (dwI = 0; dwI < dwModulusSize; dwI++)
613 {
614 pbBlob->modulus[dwI] = pbModulus[dwModulusSize - 1 - dwI];
615 }
616
617 dwReturn = 0;
618 }
619 __finally
620 {
621 }
622 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
623 return dwReturn;
624 }
625
626 DWORD SCardCreateKey(PCARD_DATA pCardData, OPENPGP_CONTAINER dwContainer, DWORD dwBitLen)
627 {
628 DWORD dwReturn;
629 PBYTE pbData = NULL;
630 DWORD dwResponseSize = 0, dwCmdSize;
631 OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
632 POPENPGP_CONTEXT pContext;
633 DWORD dwSecondsSince1970;
634 PBYTE pbModulus, pbExponent;
635 DWORD dwModulusSize, dwExponent;
636 BYTE pbCmd[] = {0x00,
637 0x47,
638 0x80,
639 0x00,
640 0x00,
641 0x00,
642 0x02,
643 0x00,
644 0x00,
645 0x00,
646 0x00
647 };
648 DWORD dwTotalTlvSize, dwOffset;
649 __try
650 {
651 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
652 if (dwContainer >= MaxContainer)
653 {
654 dwReturn = SCARD_E_NO_KEY_CONTAINER;
655 Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwContainer);
656 __leave;
657 }
658 // key len
659 dwReturn = GetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
660 if (dwReturn)
661 {
662 __leave;
663 }
664 Attributes.wModulusLength = (WORD) dwBitLen;
665 dwReturn = SetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
666 if (dwReturn)
667 {
668 __leave;
669 }
670
671 pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
672 pbCmd[7] = Containers[dwContainer].bKeyTag;
673 dwCmdSize = 9;
674 if (pContext->fExtentedLeLcFields)
675 {
676 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength / 0x100);
677 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength % 0x100);
678 }
679 else
680 {
681 pbCmd[dwCmdSize++] = 0xFF;
682 }
683
684 dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
685 if (dwReturn)
686 {
687 __leave;
688 }
689 dwOffset = 2;
690 dwTotalTlvSize = getTlvSize(pbData + 2,&dwOffset) + 2;
691 if (!find_tlv(pbData + dwOffset,0x81,dwTotalTlvSize, &pbModulus,&dwModulusSize))
692 {
693 dwReturn = SCARD_E_UNEXPECTED;
694 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
695 __leave;
696 }
697 if (!find_tlv(pbData + dwOffset,0x82,dwTotalTlvSize, (PBYTE*)&pbExponent,NULL))
698 {
699 dwReturn = SCARD_E_UNEXPECTED;
700 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
701 __leave;
702 }
703 dwExponent = pbExponent[0] * 0x1000000 + pbExponent[1] * 0x10000 + pbExponent[2] * 0x100 + pbExponent[3];
704 dwReturn = UpdateGenerationDateTime(pCardData, dwContainer, &dwSecondsSince1970);
705 if (dwReturn)
706 {
707 __leave;
708 }
709 dwReturn = UpdateFingerPrint(pCardData, dwContainer, dwSecondsSince1970,
710 pbModulus,
711 dwModulusSize * 8,
712 TRUE,
713 dwExponent
714 );
715 }
716 __finally
717 {
718 if (pbData)
719 pCardData->pfnCspFree(pbData);
720 }
721 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
722 return dwReturn;
723 }
724
725 DWORD SCardImportKey(PCARD_DATA pCardData,
726 OPENPGP_CONTAINER dwContainer,
727 PBYTE pBlob,
728 DWORD dwKeySize)
729 {
730 DWORD dwReturn;
731 PSTR szAlgorithmAttributes = NULL;
732 PBYTE pbTlv = NULL;
733 DWORD dwTlvSize;
734 PBYTE pbCommand = NULL;
735 DWORD dwCommandSize;
736 OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
737 PRSAPUBLICKEYBLOB pbPublicKeyBlob = (PRSAPUBLICKEYBLOB) pBlob;
738 BYTE bCommand[] = {0x00,0xDB,0x3F,0xFF};
739 DWORD dwSecondsSince1970;
740 __try
741 {
742 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
743 // check blob
744 if (pbPublicKeyBlob->blobheader.aiKeyAlg != CALG_RSA_SIGN &&
745 pbPublicKeyBlob->blobheader.aiKeyAlg != CALG_RSA_KEYX)
746 {
747 Trace(WINEVENT_LEVEL_ERROR, L"Wrong aiKeyAlg %d", pbPublicKeyBlob->blobheader.aiKeyAlg);
748 dwReturn = SCARD_E_INVALID_PARAMETER;
749 __leave;
750 }
751 if (pbPublicKeyBlob->blobheader.bType != PRIVATEKEYBLOB)
752 {
753 Trace(WINEVENT_LEVEL_ERROR, L"Wrong bType %d", pbPublicKeyBlob->blobheader.bType);
754 dwReturn = SCARD_E_INVALID_PARAMETER;
755 __leave;
756 }
757 if (pbPublicKeyBlob->rsapubkey.magic != 0x32415352)
758 {
759 Trace(WINEVENT_LEVEL_ERROR, L"Wrong magic");
760 dwReturn = SCARD_E_INVALID_PARAMETER;
761 __leave;
762 }
763
764 dwReturn = GetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
765 if (dwReturn)
766 {
767 __leave;
768 }
769 Attributes.wModulusLength = (WORD) pbPublicKeyBlob->rsapubkey.bitlen;
770 dwReturn = SetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
771 if (dwReturn)
772 {
773 __leave;
774 }
775 dwReturn = BuildPrivateKeyTlv(pCardData, pbPublicKeyBlob, dwContainer, Attributes.bFormat, &pbTlv, &dwTlvSize);
776 if (dwReturn)
777 {
778 __leave;
779 }
780 if (dwTlvSize > 0xFF)
781 {
782 dwCommandSize = 7 + dwTlvSize;
783
784 }
785 else
786 {
787 dwCommandSize = 5 + dwTlvSize;
788 }
789 pbCommand = pCardData->pfnCspAlloc(dwCommandSize);
790 if (!pbCommand)
791 {
792 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
793 dwReturn = SCARD_E_NO_MEMORY;
794 __leave;
795 }
796 memcpy(pbCommand, bCommand, 4);
797 if (dwTlvSize > 0xFF)
798 {
799 pbCommand[4] = 0;
800 pbCommand[5] = (BYTE)(dwTlvSize / 0x100);
801 pbCommand[6] = (BYTE)(dwTlvSize % 0x100);
802 memcpy(pbCommand + 7, pbTlv, dwTlvSize);
803 }
804 else
805 {
806 pbCommand[4] = (BYTE) dwTlvSize;
807 memcpy(pbCommand + 5, pbTlv, dwTlvSize);
808 }
809 dwReturn = SCardSendCommand(pCardData, pbCommand, dwCommandSize);
810 if (dwReturn)
811 {
812 __leave;
813 }
814 dwReturn = UpdateGenerationDateTime(pCardData, dwContainer, &dwSecondsSince1970);
815 if (dwReturn)
816 {
817 __leave;
818 }
819 dwReturn = UpdateFingerPrint(pCardData, dwContainer, dwSecondsSince1970,
820 pbPublicKeyBlob->modulus,
821 pbPublicKeyBlob->rsapubkey.bitlen,
822 FALSE,
823 pbPublicKeyBlob->rsapubkey.pubexp
824 );
825 }
826 __finally
827 {
828 if (pbCommand)
829 {
830 SecureZeroMemory(pbCommand, dwCommandSize);
831 pCardData->pfnCspFree(pbCommand);
832 }
833 if (pbTlv)
834 {
835 SecureZeroMemory(pbTlv, dwTlvSize);
836 pCardData->pfnCspFree(pbTlv);
837 }
838 }
839 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
840 return dwReturn;
841 }
842
843 DWORD SCardSign(PCARD_DATA pCardData,
844 PCARD_SIGNING_INFO pInfo)
845 {
846 DWORD dwReturn;
847 PBYTE pbData = NULL;
848 DWORD dwCmdSize = 0, dwI;
849 POPENPGP_CONTEXT pContext;
850 BYTE pbCmd[6 + 256 + 256] = {0x00,
851 0x2A,
852 0x9E,
853 0x9A,
854 0x00,
855 0x00,
856 };
857 __try
858 {
859 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
860 if (pInfo->bContainerIndex != Signature)
861 {
862 dwReturn = SCARD_E_NO_KEY_CONTAINER;
863 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
864 __leave;
865 }
866 if (CARD_PADDING_PKCS1 & pInfo->dwPaddingType)
867 {
868 dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
869 Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PKCS1");
870 __leave;
871 }
872 else if (CARD_PADDING_PSS & pInfo->dwPaddingType)
873 {
874 dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
875 Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PSS");
876 __leave;
877 }
878 for(dwI = 0 ; dwI < dwSignatureAlgorithmCount ; dwI++)
879 {
880 if (SignatureAlgorithm[dwI].aiHashAlg == pInfo->aiHashAlg)
881 {
882 // found
883 break;
884 }
885 }
886 if (dwI >= dwSignatureAlgorithmCount)
887 {
888 Trace(WINEVENT_LEVEL_ERROR, L"alg not found %d", pInfo->aiHashAlg);
889 __leave;
890 }
891 if (SignatureAlgorithm[dwI].dwHashSize != pInfo->cbData)
892 {
893 Trace(WINEVENT_LEVEL_ERROR, L"wrong hash size %d", pInfo->cbData);
894 __leave;
895 }
896 pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
897
898 dwCmdSize = 5;
899 if (pContext->fExtentedLeLcFields)
900 {
901 dwCmdSize++;
902 }
903 pbCmd[dwCmdSize++] = (BYTE) (SignatureAlgorithm[dwI].dwEncodedOidSize + pInfo->cbData);
904 memcpy(pbCmd + dwCmdSize , SignatureAlgorithm[dwI].pbEncodedOid,SignatureAlgorithm[dwI].dwEncodedOidSize);
905 dwCmdSize += SignatureAlgorithm[dwI].dwEncodedOidSize;
906 /*for(dwI = 0 ; dwI < pInfo->cbData ; dwI++)
907 {
908 pbCmd[dwCmdSize + dwI] = pInfo->pbData[pInfo->cbData - dwI -1];
909 }*/
910 memcpy(pbCmd + dwCmdSize, pInfo->pbData,pInfo->cbData);
911 dwCmdSize += pInfo->cbData;
912
913
914 if (pContext->fExtentedLeLcFields)
915 {
916 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength / 0x100);
917 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength % 0x100);
918 }
919 else
920 {
921 pbCmd[dwCmdSize++] = 0;
922 }
923 dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &(pInfo->pbSignedData), &(pInfo->cbSignedData));
924 if (dwReturn == SCARD_W_WRONG_CHV)
925 {
926 dwReturn = SCARD_W_SECURITY_VIOLATION;
927 __leave;
928 }
929 if (dwReturn)
930 {
931 __leave;
932 }
933 // revert the BYTES
934 for(dwI = 0 ; dwI < pInfo->cbSignedData / 2 ; dwI++)
935 {
936 BYTE bTemp = pInfo->pbSignedData[dwI];
937 pInfo->pbSignedData[dwI] = pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI];
938 pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI] = bTemp;
939 }
940 }
941 __finally
942 {
943 if (dwReturn)
944 {
945 if (pInfo->pbSignedData)
946 pCardData->pfnCspFree(pInfo->pbSignedData);
947 }
948 }
949 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
950 return dwReturn;
951 }
952
953 DWORD SCardAuthenticate(PCARD_DATA pCardData,
954 PCARD_SIGNING_INFO pInfo)
955 {
956 DWORD dwReturn;
957 PBYTE pbData = NULL;
958 DWORD dwCmdSize = 0, dwI;
959 POPENPGP_CONTEXT pContext;
960 BYTE pbCmd[6 + 256 + 256] = {0x00,
961 0x88,
962 0x00,
963 0x00,
964 0x00,
965 0x00,
966 };
967 __try
968 {
969 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
970 if (pInfo->bContainerIndex != Authentication)
971 {
972 dwReturn = SCARD_E_NO_KEY_CONTAINER;
973 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
974 __leave;
975 }
976 if (CARD_PADDING_PKCS1 & pInfo->dwPaddingType)
977 {
978 dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
979 Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PKCS1");
980 __leave;
981 }
982 else if (CARD_PADDING_PSS & pInfo->dwPaddingType)
983 {
984 dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
985 Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PSS");
986 __leave;
987 }
988 for(dwI = 0 ; dwI < dwSignatureAlgorithmCount ; dwI++)
989 {
990 if (SignatureAlgorithm[dwI].aiHashAlg == pInfo->aiHashAlg)
991 {
992 // found
993 break;
994 }
995 }
996 if (dwI >= dwSignatureAlgorithmCount)
997 {
998 Trace(WINEVENT_LEVEL_ERROR, L"alg not found %d", pInfo->aiHashAlg);
999 __leave;
1000 }
1001 if (SignatureAlgorithm[dwI].dwHashSize != pInfo->cbData)
1002 {
1003 Trace(WINEVENT_LEVEL_ERROR, L"wrong hash size %d", pInfo->cbData);
1004 __leave;
1005 }
1006 pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
1007
1008 dwCmdSize = 5;
1009 if (pContext->fExtentedLeLcFields)
1010 {
1011 dwCmdSize++;
1012 }
1013 pbCmd[dwCmdSize++] = (BYTE) (SignatureAlgorithm[dwI].dwEncodedOidSize + pInfo->cbData);
1014 memcpy(pbCmd + dwCmdSize , SignatureAlgorithm[dwI].pbEncodedOid,SignatureAlgorithm[dwI].dwEncodedOidSize);
1015 dwCmdSize += SignatureAlgorithm[dwI].dwEncodedOidSize;
1016 /*for(dwI = 0 ; dwI < pInfo->cbData ; dwI++)
1017 {
1018 pbCmd[dwCmdSize + dwI] = pInfo->pbData[pInfo->cbData - dwI -1];
1019 }*/
1020 memcpy(pbCmd + dwCmdSize, pInfo->pbData,pInfo->cbData);
1021 dwCmdSize += pInfo->cbData;
1022
1023
1024 if (pContext->fExtentedLeLcFields)
1025 {
1026 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength / 0x100);
1027 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength % 0x100);
1028 }
1029 else
1030 {
1031 pbCmd[dwCmdSize++] = 0;
1032 }
1033 dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &(pInfo->pbSignedData), &(pInfo->cbSignedData));
1034 if (dwReturn == SCARD_W_WRONG_CHV)
1035 {
1036 dwReturn = SCARD_W_SECURITY_VIOLATION;
1037 __leave;
1038 }
1039 if (dwReturn)
1040 {
1041 __leave;
1042 }
1043 // revert the BYTES
1044 for(dwI = 0 ; dwI < pInfo->cbSignedData / 2 ; dwI++)
1045 {
1046 BYTE bTemp = pInfo->pbSignedData[dwI];
1047 pInfo->pbSignedData[dwI] = pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI];
1048 pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI] = bTemp;
1049 }
1050 }
1051 __finally
1052 {
1053 if (dwReturn)
1054 {
1055 if (pInfo->pbSignedData)
1056 pCardData->pfnCspFree(pInfo->pbSignedData);
1057 }
1058 }
1059 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
1060 return dwReturn;
1061 }
1062
1063 DWORD SCardDecrypt(PCARD_DATA pCardData,
1064 PCARD_RSA_DECRYPT_INFO pInfo)
1065 {
1066 DWORD dwReturn;
1067 PBYTE pbData = NULL;
1068 DWORD dwCmdSize = 0, dwResponseSize;
1069 BYTE pbCmd[6 + 256 + 256] = {0x00,
1070 0x2A,
1071 0x80,
1072 0x86,
1073 0x00,
1074 };
1075 POPENPGP_CONTEXT pContext;
1076 DWORD dwI;
1077 __try
1078 {
1079 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
1080 if (pInfo->bContainerIndex >= MaxContainer)
1081 {
1082 dwReturn = SCARD_E_NO_KEY_CONTAINER;
1083 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
1084 __leave;
1085 }
1086 if (pInfo->bContainerIndex != Confidentiality)
1087 {
1088 dwReturn = SCARD_E_NO_KEY_CONTAINER;
1089 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
1090 __leave;
1091 }
1092 pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
1093 dwCmdSize = 5;
1094 if (pContext->fExtentedLeLcFields)
1095 {
1096 pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) / 0x100);
1097 pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) % 0x100);
1098 }
1099 else
1100 {
1101 pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) % 0x100);
1102 }
1103 pbCmd[dwCmdSize++] = 0;
1104 //little endian => big endian
1105 for(dwI = 0; dwI < pInfo->cbData; dwI++)
1106 {
1107 pbCmd[dwCmdSize + dwI] = pInfo->pbData[pInfo->cbData -1 -dwI];
1108 }
1109 dwCmdSize += pInfo->cbData;
1110 if (pContext->fExtentedLeLcFields)
1111 {
1112 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength / 0x100);
1113 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength % 0x100);
1114 }
1115 else
1116 {
1117 pbCmd[dwCmdSize++] = 0;
1118 }
1119 dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
1120 if (dwReturn)
1121 {
1122 __leave;
1123 }
1124
1125 // CryptDecrypt expects the data decrypted using rsa (only the mathematical computation)
1126 // this means the data with the padding (removed by the card)
1127 // and in little endian (while the card return the data in big endian)
1128 // so we rebuilt the padding in reverse order
1129
1130 if ( pInfo->cbData < dwResponseSize + 3 + 11)
1131 {
1132 dwReturn = SCARD_E_INSUFFICIENT_BUFFER;
1133 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_INSUFFICIENT_BUFFER %d expected = %d", pInfo->cbData, dwResponseSize);
1134 __leave;
1135 }
1136
1137 pInfo->pbData[pInfo->cbData - 1] = 0; // start byte
1138 pInfo->pbData[pInfo->cbData - 2] = 02; // block type
1139 // padding
1140 memset(pInfo->pbData + dwResponseSize + 1,1,pInfo->cbData - 3 - dwResponseSize);
1141 pInfo->pbData[dwResponseSize] = 0; // separator
1142 // data field in reverse order
1143 for(dwI = 0; dwI < dwResponseSize; dwI++)
1144 {
1145 pInfo->pbData[dwI] = pbData[dwResponseSize - 1 - dwI];
1146 }
1147 }
1148 __finally
1149 {
1150 if (pbData)
1151 {
1152 SecureZeroMemory(pbData, dwResponseSize);
1153 pCardData->pfnCspFree(pbData);
1154 }
1155 }
1156 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
1157 return dwReturn;
1158 }
1159
1160
1161 DWORD GetPinInfo(DWORD __in dwPinIndex, __inout PPIN_INFO pPinInfo)
1162 {
1163 DWORD dwReturn=0;
1164 __try
1165 {
1166 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwPinIndex=%d",dwPinIndex);
1167 switch(dwPinIndex)
1168 {
1169 case ROLE_SIGNATURE:
1170 pPinInfo->PinType = AlphaNumericPinType;
1171 pPinInfo->PinPurpose = DigitalSignaturePin;
1172 pPinInfo->dwChangePermission = PIN_CHANGE_FLAG_CHANGEPIN;
1173 pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
1174 pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheAlwaysPrompt;
1175 break;
1176 case ROLE_AUTHENTICATION:
1177 pPinInfo->PinType = AlphaNumericPinType;
1178 pPinInfo->PinPurpose = AuthenticationPin;
1179 pPinInfo->dwChangePermission = PIN_CHANGE_FLAG_CHANGEPIN;
1180 pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
1181 pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheAlwaysPrompt;
1182 break;
1183 case ROLE_CONFIDENTIALITY:
1184 pPinInfo->PinType = AlphaNumericPinType;
1185 pPinInfo->PinPurpose = EncryptionPin;
1186 pPinInfo->dwChangePermission = PIN_CHANGE_FLAG_CHANGEPIN;
1187 pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
1188 pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheAlwaysPrompt;
1189 break;
1190 default:
1191 Trace(WINEVENT_LEVEL_ERROR, L"dwPinIndex == %d", dwPinIndex);
1192 dwReturn = SCARD_E_INVALID_PARAMETER ;
1193 __leave;
1194 }
1195 }
1196 __finally
1197 {
1198 }
1199 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
1200 return dwReturn;
1201 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26