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

Annotation of /trunk/OpenPGPminidriver/CryptoOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 6 - (hide 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 vletoux 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 vletoux 6 #include "tlv.h"
27 vletoux 1
28     OPENPGP_CONTAINER_INFO Containers[] =
29     {
30 vletoux 3 {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 vletoux 1
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 vletoux 5 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
143 vletoux 1 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 vletoux 5 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
190 vletoux 1 return dwReturn;
191     }
192    
193 vletoux 2 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 vletoux 1 __out PBYTE * ppbTlv, __out PDWORD pdwTlvSize)
223     {
224 vletoux 2 // 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 vletoux 3 PBYTE pbPublicKeyData = (PBYTE) &(pbPublicKeyBlob->modulus);
238 vletoux 2 // 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 vletoux 3 DWORD dwI;
247 vletoux 1 __try
248     {
249 vletoux 2 // 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 vletoux 3 (*ppbTlv)[dwOffset++] = Containers[dwContainer].bKeyTag;
309 vletoux 2 (*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 vletoux 3 // exponent little => big endian
318 vletoux 2 (*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 vletoux 3 //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 vletoux 2 dwOffset += bitlen / 16;
329 vletoux 3
330 vletoux 2 // prime2
331 vletoux 3 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 vletoux 2 dwOffset += bitlen / 16;
337     if (bFormat & 2)
338     {
339     // coeff
340 vletoux 3 //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 vletoux 2 dwOffset += bitlen / 16;
346     // exponent1
347 vletoux 3 //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 vletoux 2 dwOffset += bitlen / 16;
353     // exponent2
354 vletoux 3 //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 vletoux 2 dwOffset += bitlen / 16;
360     }
361     if (bFormat & 1)
362     {
363     // modulus
364 vletoux 3 //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 vletoux 2 }
370 vletoux 1 }
371     __finally
372     {
373     }
374 vletoux 5 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
375 vletoux 1 return dwReturn;
376     }
377    
378 vletoux 3 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 vletoux 5 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
416 vletoux 3 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 vletoux 5 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
523 vletoux 3 return dwReturn;
524    
525     }
526    
527 vletoux 1 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 vletoux 3 DWORD dwModulusSize, dwI;
548 vletoux 1 PBYTE pbExponent;
549     PRSAPUBLICKEYBLOB pbBlob = NULL;
550 vletoux 6 DWORD dwTotalTlvSize, dwOffset;
551 vletoux 1 __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 vletoux 3 pbCmd[7] = Containers[dwContainer].bKeyTag;
562 vletoux 1 dwCmdSize = 9;
563     if (pContext->fExtentedLeLcFields)
564     {
565 vletoux 6 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength / 0x100);
566     pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength % 0x100);
567 vletoux 1 }
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 vletoux 6 dwOffset = 2;
579     dwTotalTlvSize = getTlvSize(pbData + 2,&dwOffset) + 2;
580     if (!find_tlv(pbData + dwOffset,0x81,dwTotalTlvSize,&pbModulus,&dwModulusSize))
581 vletoux 1 {
582     dwReturn = SCARD_E_UNEXPECTED;
583     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
584     __leave;
585     }
586 vletoux 6 if (!find_tlv(pbData + dwOffset,0x82,dwTotalTlvSize, (PBYTE*)&pbExponent,NULL))
587 vletoux 1 {
588     dwReturn = SCARD_E_UNEXPECTED;
589     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
590     __leave;
591     }
592 vletoux 3 Trace(WINEVENT_LEVEL_INFO, L"dwModulusSize %d bits", dwModulusSize * 8);
593 vletoux 1 *pdwPublicKeySize = sizeof(RSAPUBLICKEYBLOB) + dwModulusSize - sizeof(DWORD);
594     *pbPublicKey = pCardData->pfnCspAlloc(*pdwPublicKeySize);
595     if (!*pbPublicKey)
596     {
597     dwReturn = SCARD_E_NO_MEMORY;
598 vletoux 3 Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY %d", dwContainer);
599 vletoux 1 __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 vletoux 3 // 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 vletoux 1 dwReturn = 0;
618     }
619     __finally
620     {
621     }
622 vletoux 5 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
623 vletoux 1 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 vletoux 3 DWORD dwSecondsSince1970;
634     PBYTE pbModulus, pbExponent;
635     DWORD dwModulusSize, dwExponent;
636 vletoux 1 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 vletoux 6 DWORD dwTotalTlvSize, dwOffset;
649 vletoux 1 __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 vletoux 6 if (dwReturn)
661 vletoux 1 {
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 vletoux 3 pbCmd[7] = Containers[dwContainer].bKeyTag;
673 vletoux 1 dwCmdSize = 9;
674     if (pContext->fExtentedLeLcFields)
675     {
676 vletoux 6 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength / 0x100);
677     pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength % 0x100);
678 vletoux 1 }
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 vletoux 6 dwOffset = 2;
690     dwTotalTlvSize = getTlvSize(pbData + 2,&dwOffset) + 2;
691     if (!find_tlv(pbData + dwOffset,0x81,dwTotalTlvSize, &pbModulus,&dwModulusSize))
692 vletoux 3 {
693     dwReturn = SCARD_E_UNEXPECTED;
694     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
695     __leave;
696     }
697 vletoux 6 if (!find_tlv(pbData + dwOffset,0x82,dwTotalTlvSize, (PBYTE*)&pbExponent,NULL))
698 vletoux 3 {
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 vletoux 1 }
716     __finally
717     {
718     if (pbData)
719     pCardData->pfnCspFree(pbData);
720     }
721 vletoux 5 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
722 vletoux 1 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 vletoux 2 PBYTE pbTlv = NULL;
733     DWORD dwTlvSize;
734     PBYTE pbCommand = NULL;
735     DWORD dwCommandSize;
736 vletoux 1 OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
737     PRSAPUBLICKEYBLOB pbPublicKeyBlob = (PRSAPUBLICKEYBLOB) pBlob;
738 vletoux 2 BYTE bCommand[] = {0x00,0xDB,0x3F,0xFF};
739 vletoux 3 DWORD dwSecondsSince1970;
740 vletoux 1 __try
741     {
742     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
743     // check blob
744 vletoux 2 if (pbPublicKeyBlob->blobheader.aiKeyAlg != CALG_RSA_SIGN &&
745     pbPublicKeyBlob->blobheader.aiKeyAlg != CALG_RSA_KEYX)
746 vletoux 1 {
747     Trace(WINEVENT_LEVEL_ERROR, L"Wrong aiKeyAlg %d", pbPublicKeyBlob->blobheader.aiKeyAlg);
748     dwReturn = SCARD_E_INVALID_PARAMETER;
749     __leave;
750     }
751 vletoux 2 if (pbPublicKeyBlob->blobheader.bType != PRIVATEKEYBLOB)
752 vletoux 1 {
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 vletoux 6 if (dwReturn)
766 vletoux 1 {
767     __leave;
768     }
769     Attributes.wModulusLength = (WORD) pbPublicKeyBlob->rsapubkey.bitlen;
770     dwReturn = SetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
771     if (dwReturn)
772     {
773     __leave;
774     }
775 vletoux 2 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 vletoux 3 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 vletoux 1 }
826     __finally
827     {
828 vletoux 2 if (pbCommand)
829 vletoux 1 {
830 vletoux 2 SecureZeroMemory(pbCommand, dwCommandSize);
831     pCardData->pfnCspFree(pbCommand);
832 vletoux 1 }
833 vletoux 2 if (pbTlv)
834     {
835     SecureZeroMemory(pbTlv, dwTlvSize);
836     pCardData->pfnCspFree(pbTlv);
837     }
838 vletoux 1 }
839 vletoux 5 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
840 vletoux 1 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 vletoux 5 if (pInfo->bContainerIndex != Signature)
861 vletoux 1 {
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 vletoux 5 if (CARD_PADDING_PKCS1 & pInfo->dwPaddingType)
867 vletoux 1 {
868 vletoux 5 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 vletoux 6 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength / 0x100);
917     pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength % 0x100);
918 vletoux 5 }
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 vletoux 1 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 vletoux 3 /*for(dwI = 0 ; dwI < pInfo->cbData ; dwI++)
1017 vletoux 1 {
1018     pbCmd[dwCmdSize + dwI] = pInfo->pbData[pInfo->cbData - dwI -1];
1019 vletoux 3 }*/
1020     memcpy(pbCmd + dwCmdSize, pInfo->pbData,pInfo->cbData);
1021 vletoux 1 dwCmdSize += pInfo->cbData;
1022    
1023    
1024     if (pContext->fExtentedLeLcFields)
1025     {
1026 vletoux 6 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength / 0x100);
1027     pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength % 0x100);
1028 vletoux 1 }
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 vletoux 5 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
1060 vletoux 1 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 vletoux 3 DWORD dwI;
1077 vletoux 1 __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 vletoux 4 //little endian => big endian
1105 vletoux 3 for(dwI = 0; dwI < pInfo->cbData; dwI++)
1106     {
1107     pbCmd[dwCmdSize + dwI] = pInfo->pbData[pInfo->cbData -1 -dwI];
1108     }
1109 vletoux 1 dwCmdSize += pInfo->cbData;
1110     if (pContext->fExtentedLeLcFields)
1111     {
1112 vletoux 6 pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength / 0x100);
1113     pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxCommandDataLength % 0x100);
1114 vletoux 1 }
1115     else
1116     {
1117     pbCmd[dwCmdSize++] = 0;
1118     }
1119     dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
1120     if (dwReturn)
1121     {
1122     __leave;
1123     }
1124 vletoux 4
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 vletoux 1 {
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 vletoux 4
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 vletoux 1 }
1148     __finally
1149     {
1150     if (pbData)
1151 vletoux 3 {
1152     SecureZeroMemory(pbData, dwResponseSize);
1153 vletoux 1 pCardData->pfnCspFree(pbData);
1154 vletoux 3 }
1155 vletoux 1 }
1156 vletoux 5 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
1157 vletoux 1 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 vletoux 5 Trace(WINEVENT_LEVEL_VERBOSE, L"dwReturn = 0x%08X",dwReturn);
1200 vletoux 1 return dwReturn;
1201     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26