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

Annotation of /trunk/OpenPGPminidriver/CryptoOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26