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

Annotation of /trunk/OpenPGPminidriver/CryptoOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (hide annotations)
Tue Feb 23 19:18:59 2010 UTC (15 years, 2 months ago) by vletoux
File MIME type: text/plain
File size: 21502 byte(s)


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    
27     OPENPGP_CONTAINER_INFO Containers[] =
28     {
29     {0xB6, CALG_RSA_SIGN, AT_SIGNATURE, ROLE_SIGNATURE},
30     {0xA4, CALG_RSA_SIGN, AT_SIGNATURE, ROLE_AUTHENTICATION},
31     {0xB8, CALG_RSA_KEYX, AT_KEYEXCHANGE, ROLE_CONFIDENTIALITY}
32    
33     };
34    
35     typedef struct _OPENPGP_SUPPORTED_SIGNATURE_ALGORITHM
36     {
37     ALG_ID aiHashAlg;
38     DWORD dwHashSize;
39     PBYTE pbEncodedOid;
40     DWORD dwEncodedOidSize;
41     } OPENPGP_SUPPORTED_SIGNATURE_ALGORITHM, *POPENPGP_SUPPORTED_SIGNATURE_ALGORITHM;
42    
43     BYTE dwSHA1EncodedOid[] = {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
44     0x02, 0x1a, 0x05, 0x00, 0x04, 0x14};
45     BYTE dwSHA256EncodedOid[] = {0x30, 0x31, 0x30, 0x0D,0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
46     0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};
47     BYTE dwSHA384EncodedOid[] = {0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
48     0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30};
49     BYTE dwSHA512EncodedOid[] = {0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
50     0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40};
51    
52     OPENPGP_SUPPORTED_SIGNATURE_ALGORITHM SignatureAlgorithm[] =
53     {
54     {CALG_SHA1,20,
55     dwSHA1EncodedOid,
56     ARRAYSIZE(dwSHA1EncodedOid)},
57     {CALG_SHA-256,32,
58     dwSHA256EncodedOid,
59     ARRAYSIZE(dwSHA256EncodedOid)},
60     {CALG_SHA-384,48,
61     dwSHA384EncodedOid,
62     ARRAYSIZE(dwSHA384EncodedOid)},
63     {CALG_SHA-512,64,
64     dwSHA512EncodedOid,
65     ARRAYSIZE(dwSHA512EncodedOid)},
66     };
67    
68     DWORD dwSignatureAlgorithmCount = ARRAYSIZE(SignatureAlgorithm);
69    
70     #pragma pack(push,1)
71     typedef struct _OPENPGP_ALGORITHM_ATTRIBUTE
72     {
73     BYTE bAlgoId;
74     unsigned short wModulusLength;
75     unsigned short wExponentLength;
76     BYTE bFormat;
77     } OPENPGP_ALGORITHM_ATTRIBUTE, *POPENPGP_ALGORITHM_ATTRIBUTE;
78     #pragma pack(pop)
79    
80     typedef struct _RSAPUBLICKEYBLOB
81     {
82     BLOBHEADER blobheader;
83     RSAPUBKEY rsapubkey;
84     BYTE modulus[sizeof(DWORD)];
85     } RSAPUBLICKEYBLOB, *PRSAPUBLICKEYBLOB;
86    
87     DWORD getTlvSize(__in PBYTE pbPointer, __in PDWORD pdwOffset)
88     {
89     DWORD dwSize;
90     switch(*pbPointer)
91     {
92     case 0x81:
93     *pdwOffset+=2;
94     dwSize = pbPointer[1];
95     break;
96     case 0x82:
97     *pdwOffset+=3;
98     dwSize = pbPointer[1] * 0x100 + pbPointer[2];
99     break;
100     default:
101     dwSize = *pbPointer;
102     *pdwOffset+=1;
103     break;
104     }
105     return dwSize;
106     }
107    
108     BOOL find_tlv(__in PBYTE pbData, __in BYTE bCode, __out PBYTE *pbDataOut, __out_opt PDWORD pdwSize)
109     {
110     DWORD dwOffset = 2;
111     DWORD dwSize;
112     DWORD dwTotalSize = getTlvSize(pbData + 2,&dwOffset) + 2;
113     while (dwOffset < dwTotalSize)
114     {
115     if (bCode == pbData[dwOffset])
116     {
117     dwOffset++;
118     // size sequence
119     dwSize = getTlvSize(pbData + dwOffset,&dwOffset);
120     if (pdwSize)
121     {
122     *pdwSize = dwSize;
123     }
124     *pbDataOut = pbData + dwOffset;
125     return TRUE;
126     }
127     else
128     {
129     dwOffset++;
130     dwSize = getTlvSize(pbData + dwOffset,&dwOffset);
131     dwOffset += dwSize;
132     }
133     }
134     return FALSE;
135     }
136    
137    
138     DWORD GetKeyAlgorithmAttributes(__in PCARD_DATA pCardData,
139     __in OPENPGP_CONTAINER dwContainer,
140     __out POPENPGP_ALGORITHM_ATTRIBUTE pAttributes)
141     {
142     DWORD dwReturn;
143     PSTR szAlgorithmAttributes = NULL;
144     PBYTE pbData = NULL;
145     DWORD dwResponseSize;
146     WORD wTemp;
147     __try
148     {
149     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
150     switch(dwContainer)
151     {
152     case Signature:
153     szAlgorithmAttributes = szOpenPGPAlgoAttributesSignature;
154     break;
155     case Authentication:
156     szAlgorithmAttributes = szOpenPGPAlgoAttributesDecryption;
157     break;
158     case Confidentiality:
159     szAlgorithmAttributes = szOpenPGPAlgoAttributesAuthentication;
160     break;
161     default:
162     dwReturn = SCARD_E_NO_KEY_CONTAINER;
163     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", dwContainer);
164     __leave;
165     }
166     dwReturn = SCardReadFile(pCardData, szOpenPGPDir, szAlgorithmAttributes, &pbData, &dwResponseSize);
167     if (dwReturn)
168     {
169     __leave;
170     }
171     if (dwResponseSize != sizeof(OPENPGP_ALGORITHM_ATTRIBUTE))
172     {
173     dwReturn = SCARD_E_UNEXPECTED;
174     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED");
175     __leave;
176     }
177     memcpy(pAttributes, pbData, dwResponseSize);
178     // big endian, little endian ...
179     wTemp = pAttributes->wExponentLength;
180     pAttributes->wExponentLength = (wTemp % 0x100) * 0x100 + (wTemp / 0x100);
181     wTemp = pAttributes->wModulusLength;
182     pAttributes->wModulusLength = (wTemp % 0x100) * 0x100 + (wTemp / 0x100);
183    
184     dwReturn = 0;
185     }
186     __finally
187     {
188     if (pbData)
189     pCardData->pfnCspFree(pbData);
190     }
191     return dwReturn;
192     }
193    
194     DWORD SetKeyAlgorithmAttributes(__in PCARD_DATA pCardData,
195     __in OPENPGP_CONTAINER dwContainer,
196     __out POPENPGP_ALGORITHM_ATTRIBUTE pAttributes)
197     {
198     DWORD dwReturn;
199     PSTR szAlgorithmAttributes = NULL;
200     OPENPGP_ALGORITHM_ATTRIBUTE TempAttributes;
201     WORD wTemp;
202     __try
203     {
204     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
205     switch(dwContainer)
206     {
207     case Signature:
208     szAlgorithmAttributes = szOpenPGPAlgoAttributesSignature;
209     break;
210     case Authentication:
211     szAlgorithmAttributes = szOpenPGPAlgoAttributesDecryption;
212     break;
213     case Confidentiality:
214     szAlgorithmAttributes = szOpenPGPAlgoAttributesAuthentication;
215     break;
216     default:
217     dwReturn = SCARD_E_NO_KEY_CONTAINER;
218     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", dwContainer);
219     __leave;
220     }
221     memcpy(&TempAttributes, pAttributes, sizeof(OPENPGP_ALGORITHM_ATTRIBUTE));
222     wTemp = TempAttributes.wExponentLength;
223     TempAttributes.wExponentLength = (wTemp % 0x100) * 0x100 + (wTemp / 0x100);
224     wTemp = TempAttributes.wModulusLength;
225     TempAttributes.wModulusLength = (wTemp % 0x100) * 0x100 + (wTemp / 0x100);
226    
227     dwReturn = SCardWriteFile(pCardData, szOpenPGPDir, szAlgorithmAttributes, (PBYTE) &TempAttributes, sizeof(OPENPGP_ALGORITHM_ATTRIBUTE));
228     if (dwReturn)
229     {
230     __leave;
231     }
232     dwReturn = 0;
233     }
234     __finally
235     {
236     }
237     return dwReturn;
238     }
239    
240     DWORD BuildPrivateKeyTlv(__in PCARD_DATA pCardData, __in PRSAPUBLICKEYBLOB pbPublicKeyBlob,
241     __out PBYTE * ppbTlv, __out PDWORD pdwTlvSize)
242     {
243     DWORD dwReturn;
244     __try
245     {
246     }
247     __finally
248     {
249     }
250     return dwReturn;
251     }
252    
253     DWORD SCardReadPublicKey(PCARD_DATA pCardData, OPENPGP_CONTAINER dwContainer, PBYTE *pbPublicKey, PDWORD pdwPublicKeySize)
254     {
255     DWORD dwReturn;
256     PBYTE pbData = NULL;
257     DWORD dwResponseSize = 0;
258     BYTE pbCmd[] = {0x00,
259     0x47,
260     0x81,
261     0x00,
262     0x00,
263     0x00,
264     0x02,
265     0x00,
266     0x00,
267     0x00,
268     0x00
269     };
270     DWORD dwCmdSize;
271     POPENPGP_CONTEXT pContext;
272     PBYTE pbModulus;
273     DWORD dwModulusSize;
274     PBYTE pbExponent;
275     PRSAPUBLICKEYBLOB pbBlob = NULL;
276     __try
277     {
278     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
279     if (dwContainer >= MaxContainer)
280     {
281     dwReturn = SCARD_E_NO_KEY_CONTAINER;
282     Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwContainer);
283     __leave;
284     }
285     pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
286     pbCmd[7] = Containers[dwContainer].Tag;
287     dwCmdSize = 9;
288     if (pContext->fExtentedLeLcFields)
289     {
290     pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength / 0x100);
291     pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength % 0x100);
292     }
293     else
294     {
295     pbCmd[dwCmdSize++] = 0xFF;
296     }
297    
298     dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
299     if (dwReturn)
300     {
301     __leave;
302     }
303     //TraceDump(WINEVENT_LEVEL_INFO, pbData,dwSize);
304     if (!find_tlv(pbData,0x81,&pbModulus,&dwModulusSize))
305     {
306     dwReturn = SCARD_E_UNEXPECTED;
307     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
308     __leave;
309     }
310     if (!find_tlv(pbData,0x82,(PBYTE*)&pbExponent,NULL))
311     {
312     dwReturn = SCARD_E_UNEXPECTED;
313     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
314     __leave;
315     }
316     *pdwPublicKeySize = sizeof(RSAPUBLICKEYBLOB) + dwModulusSize - sizeof(DWORD);
317     *pbPublicKey = pCardData->pfnCspAlloc(*pdwPublicKeySize);
318     if (!*pbPublicKey)
319     {
320     dwReturn = SCARD_E_NO_MEMORY;
321     Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_MEMORY %d", dwContainer);
322     __leave;
323     }
324     pbBlob = (PRSAPUBLICKEYBLOB) *pbPublicKey;
325     memset(pbBlob,0,*pdwPublicKeySize);
326     pbBlob->blobheader.bType = PUBLICKEYBLOB;
327     pbBlob->blobheader.bVersion = CUR_BLOB_VERSION;
328     pbBlob->blobheader.reserved = 0;
329     pbBlob->blobheader.aiKeyAlg = Containers[dwContainer].aiKeyAlg;
330     pbBlob->rsapubkey.magic = 0x31415352; //'RSA1';
331     pbBlob->rsapubkey.bitlen = dwModulusSize*8;
332     pbBlob->rsapubkey.pubexp = pbExponent[0] * 0x1000000 + pbExponent[1] * 0x10000 + pbExponent[2] * 0x100 + pbExponent[3];
333     memcpy(pbBlob->modulus, pbModulus, dwModulusSize);
334     //TraceDump(WINEVENT_LEVEL_INFO, (PBYTE) pbBlob,*pdwPublicKeySize);
335     dwReturn = 0;
336     }
337     __finally
338     {
339     }
340     return dwReturn;
341     }
342    
343     DWORD SCardCreateKey(PCARD_DATA pCardData, OPENPGP_CONTAINER dwContainer, DWORD dwBitLen)
344     {
345     DWORD dwReturn;
346     PBYTE pbData = NULL;
347     DWORD dwResponseSize = 0, dwCmdSize;
348     OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
349     POPENPGP_CONTEXT pContext;
350     BYTE pbCmd[] = {0x00,
351     0x47,
352     0x80,
353     0x00,
354     0x00,
355     0x00,
356     0x02,
357     0x00,
358     0x00,
359     0x00,
360     0x00
361     };
362     __try
363     {
364     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
365     if (dwContainer >= MaxContainer)
366     {
367     dwReturn = SCARD_E_NO_KEY_CONTAINER;
368     Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwContainer);
369     __leave;
370     }
371     // key len
372     dwReturn = GetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
373     if (dwReturn == SCARD_E_FILE_NOT_FOUND)
374     {
375     Attributes.bAlgoId = 0x01;
376     Attributes.bFormat = 0;
377     Attributes.wExponentLength = 0x20;
378     }
379     else if (dwReturn)
380     {
381     __leave;
382     }
383     Attributes.wModulusLength = (WORD) dwBitLen;
384     dwReturn = SetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
385     if (dwReturn)
386     {
387     __leave;
388     }
389    
390     pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
391     pbCmd[7] = Containers[dwContainer].Tag;
392     dwCmdSize = 9;
393     if (pContext->fExtentedLeLcFields)
394     {
395     pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength / 0x100);
396     pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength % 0x100);
397     }
398     else
399     {
400     pbCmd[dwCmdSize++] = 0xFF;
401     }
402    
403     dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
404     if (dwReturn)
405     {
406     __leave;
407     }
408     }
409     __finally
410     {
411     if (pbData)
412     pCardData->pfnCspFree(pbData);
413     }
414     return dwReturn;
415     }
416    
417     DWORD SCardImportKey(PCARD_DATA pCardData,
418     OPENPGP_CONTAINER dwContainer,
419     PBYTE pBlob,
420     DWORD dwKeySize)
421     {
422     DWORD dwReturn;
423     PSTR szAlgorithmAttributes = NULL;
424     PBYTE pbData = NULL;
425     DWORD dwResponseSize;
426     OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
427     PRSAPUBLICKEYBLOB pbPublicKeyBlob = (PRSAPUBLICKEYBLOB) pBlob;
428     __try
429     {
430     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
431     // check blob
432     if (pbPublicKeyBlob->blobheader.aiKeyAlg != Containers[dwContainer].aiKeyAlg)
433     {
434     Trace(WINEVENT_LEVEL_ERROR, L"Wrong aiKeyAlg %d", pbPublicKeyBlob->blobheader.aiKeyAlg);
435     dwReturn = SCARD_E_INVALID_PARAMETER;
436     __leave;
437     }
438     if (pbPublicKeyBlob->blobheader.bType != PUBLICKEYBLOB)
439     {
440     Trace(WINEVENT_LEVEL_ERROR, L"Wrong bType %d", pbPublicKeyBlob->blobheader.bType);
441     dwReturn = SCARD_E_INVALID_PARAMETER;
442     __leave;
443     }
444     if (pbPublicKeyBlob->rsapubkey.magic != 0x32415352)
445     {
446     Trace(WINEVENT_LEVEL_ERROR, L"Wrong magic");
447     dwReturn = SCARD_E_INVALID_PARAMETER;
448     __leave;
449     }
450    
451     dwReturn = GetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
452     if (dwReturn == SCARD_E_FILE_NOT_FOUND)
453     {
454     Attributes.bAlgoId = 0x01;
455     Attributes.bFormat = 0;
456     Attributes.wExponentLength = 0x20;
457     }
458     else if (dwReturn)
459     {
460     __leave;
461     }
462     Attributes.wModulusLength = (WORD) pbPublicKeyBlob->rsapubkey.bitlen;
463     dwReturn = SetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
464     if (dwReturn)
465     {
466     __leave;
467     }
468     }
469     __finally
470     {
471     if (dwReturn)
472     {
473    
474     }
475     }
476     return dwReturn;
477     }
478    
479     DWORD SCardSign(PCARD_DATA pCardData,
480     PCARD_SIGNING_INFO pInfo)
481     {
482     DWORD dwReturn;
483     PBYTE pbData = NULL;
484     DWORD dwCmdSize = 0, dwI;
485     POPENPGP_CONTEXT pContext;
486     BYTE pbCmd[6 + 256 + 256] = {0x00,
487     0x2A,
488     0x9E,
489     0x9A,
490     0x00,
491     0x00,
492     };
493     __try
494     {
495     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
496     if (pInfo->bContainerIndex >= MaxContainer)
497     {
498     dwReturn = SCARD_E_NO_KEY_CONTAINER;
499     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
500     __leave;
501     }
502     if (pInfo->bContainerIndex != Signature)
503     {
504     dwReturn = SCARD_E_NO_KEY_CONTAINER;
505     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
506     __leave;
507     }
508     if (CARD_PADDING_PKCS1 & pInfo->dwPaddingType)
509     {
510     dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
511     Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PKCS1");
512     __leave;
513     }
514     else if (CARD_PADDING_PSS & pInfo->dwPaddingType)
515     {
516     dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
517     Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PSS");
518     __leave;
519     }
520     for(dwI = 0 ; dwI < dwSignatureAlgorithmCount ; dwI++)
521     {
522     if (SignatureAlgorithm[dwI].aiHashAlg == pInfo->aiHashAlg)
523     {
524     // found
525     break;
526     }
527     }
528     if (dwI >= dwSignatureAlgorithmCount)
529     {
530     Trace(WINEVENT_LEVEL_ERROR, L"alg not found %d", pInfo->aiHashAlg);
531     __leave;
532     }
533     if (SignatureAlgorithm[dwI].dwHashSize != pInfo->cbData)
534     {
535     Trace(WINEVENT_LEVEL_ERROR, L"wrong hash size %d", pInfo->cbData);
536     __leave;
537     }
538     pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
539    
540     dwCmdSize = 5;
541     if (pContext->fExtentedLeLcFields)
542     {
543     dwCmdSize++;
544     }
545     pbCmd[dwCmdSize++] = (BYTE) (SignatureAlgorithm[dwI].dwEncodedOidSize + pInfo->cbData);
546     memcpy(pbCmd + dwCmdSize , SignatureAlgorithm[dwI].pbEncodedOid,SignatureAlgorithm[dwI].dwEncodedOidSize);
547     dwCmdSize += SignatureAlgorithm[dwI].dwEncodedOidSize;
548     for(dwI = 0 ; dwI < pInfo->cbData ; dwI++)
549     {
550     pbCmd[dwCmdSize + dwI] = pInfo->pbData[pInfo->cbData - dwI -1];
551     }
552     //memcpy(pbCmd + dwCmdSize, pInfo->pbData,pInfo->cbData);
553     dwCmdSize += pInfo->cbData;
554    
555    
556     if (pContext->fExtentedLeLcFields)
557     {
558     pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength / 0x100);
559     pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength % 0x100);
560     }
561     else
562     {
563     pbCmd[dwCmdSize++] = 0;
564     }
565     dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &(pInfo->pbSignedData), &(pInfo->cbSignedData));
566     if (dwReturn == SCARD_W_WRONG_CHV)
567     {
568     dwReturn = SCARD_W_SECURITY_VIOLATION;
569     __leave;
570     }
571     if (dwReturn)
572     {
573     __leave;
574     }
575     // revert the BYTES
576     for(dwI = 0 ; dwI < pInfo->cbSignedData / 2 ; dwI++)
577     {
578     BYTE bTemp = pInfo->pbSignedData[dwI];
579     pInfo->pbSignedData[dwI] = pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI];
580     pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI] = bTemp;
581     }
582     TraceDump(WINEVENT_LEVEL_ERROR,pInfo->pbSignedData,pInfo->cbSignedData);
583     }
584     __finally
585     {
586     if (dwReturn)
587     {
588     if (pInfo->pbSignedData)
589     pCardData->pfnCspFree(pInfo->pbSignedData);
590     }
591     }
592     return dwReturn;
593     }
594    
595     DWORD SCardDecrypt(PCARD_DATA pCardData,
596     PCARD_RSA_DECRYPT_INFO pInfo)
597     {
598     DWORD dwReturn;
599     PBYTE pbData = NULL;
600     DWORD dwCmdSize = 0, dwResponseSize;
601     BYTE pbCmd[6 + 256 + 256] = {0x00,
602     0x2A,
603     0x80,
604     0x86,
605     0x00,
606     };
607     POPENPGP_CONTEXT pContext;
608     __try
609     {
610     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
611     if (pInfo->bContainerIndex >= MaxContainer)
612     {
613     dwReturn = SCARD_E_NO_KEY_CONTAINER;
614     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
615     __leave;
616     }
617     if (pInfo->bContainerIndex != Confidentiality)
618     {
619     dwReturn = SCARD_E_NO_KEY_CONTAINER;
620     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
621     __leave;
622     }
623     pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
624     dwCmdSize = 5;
625     if (pContext->fExtentedLeLcFields)
626     {
627     pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) / 0x100);
628     pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) % 0x100);
629     }
630     else
631     {
632     pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) % 0x100);
633     }
634     pbCmd[dwCmdSize++] = 0;
635     memcpy(pbCmd + dwCmdSize, pInfo->pbData, pInfo->cbData);
636     dwCmdSize += pInfo->cbData;
637     if (pContext->fExtentedLeLcFields)
638     {
639     pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength / 0x100);
640     pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength % 0x100);
641     }
642     else
643     {
644     pbCmd[dwCmdSize++] = 0;
645     }
646     dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
647     if (dwReturn)
648     {
649     __leave;
650     }
651     if ( pInfo->cbData < dwResponseSize)
652     {
653     dwReturn = SCARD_E_INSUFFICIENT_BUFFER;
654     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_INSUFFICIENT_BUFFER %d expected = %d", pInfo->cbData, dwResponseSize);
655     __leave;
656     }
657     pInfo->cbData = dwResponseSize;
658     memcpy( pInfo->pbData, pbData, dwResponseSize);
659     }
660     __finally
661     {
662     if (pbData)
663     pCardData->pfnCspFree(pbData);
664     }
665     return dwReturn;
666     }
667    
668     DWORD SCardAuthenticate(PCARD_DATA pCardData,
669     PCARD_SIGNING_INFO pInfo)
670     {
671     DWORD dwReturn;
672     PBYTE pbData = NULL;
673     DWORD dwSize = 0, dwI;
674     BYTE pbCmd[6 + 256 + 256] = {0x00,
675     0x88,
676     0x00,
677     0x00,
678     0x00,
679     };
680     __try
681     {
682     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
683     if (pInfo->bContainerIndex >= MaxContainer)
684     {
685     dwReturn = SCARD_E_NO_KEY_CONTAINER;
686     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
687     __leave;
688     }
689     if (pInfo->bContainerIndex != Authentication)
690     {
691     dwReturn = SCARD_E_NO_KEY_CONTAINER;
692     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
693     __leave;
694     }
695     if (CARD_PADDING_PKCS1 & pInfo->dwPaddingType)
696     {
697     dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
698     Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PKCS1");
699     __leave;
700     }
701     else if (CARD_PADDING_PSS & pInfo->dwPaddingType)
702     {
703     dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
704     Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PSS");
705     __leave;
706     }
707     for(dwI = 0 ; dwI < dwSignatureAlgorithmCount ; dwI++)
708     {
709     if (SignatureAlgorithm[dwI].aiHashAlg == pInfo->aiHashAlg)
710     {
711     // found
712     break;
713     }
714     }
715     if (dwI >= dwSignatureAlgorithmCount)
716     {
717     Trace(WINEVENT_LEVEL_ERROR, L"alg not found %d", pInfo->aiHashAlg);
718     __leave;
719     }
720     if (SignatureAlgorithm[dwI].dwHashSize != pInfo->cbData)
721     {
722     Trace(WINEVENT_LEVEL_ERROR, L"wrong hash size %d", pInfo->cbData);
723     __leave;
724     }
725     memcpy(pbCmd +5, SignatureAlgorithm[dwI].pbEncodedOid,SignatureAlgorithm[dwI].dwEncodedOidSize);
726     memcpy(pbCmd +5 + SignatureAlgorithm[dwI].dwEncodedOidSize, pInfo->pbData,pInfo->cbData);
727    
728     dwReturn = SCardGetData(pCardData, pbCmd, ARRAYSIZE(pbCmd), &(pInfo->pbSignedData), &(pInfo->cbSignedData));
729     if (dwReturn)
730     {
731     __leave;
732     }
733     }
734     __finally
735     {
736     }
737     return dwReturn;
738     }
739    
740     DWORD GetPinInfo(DWORD __in dwPinIndex, __inout PPIN_INFO pPinInfo)
741     {
742     DWORD dwReturn=0;
743     __try
744     {
745     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwPinIndex=%d",dwPinIndex);
746     switch(dwPinIndex)
747     {
748     case ROLE_SIGNATURE:
749     pPinInfo->PinType = AlphaNumericPinType;
750     pPinInfo->PinPurpose = DigitalSignaturePin;
751     pPinInfo->dwChangePermission = PIN_CHANGE_FLAG_CHANGEPIN;
752     pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
753     pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheAlwaysPrompt;
754     break;
755     case ROLE_AUTHENTICATION:
756     pPinInfo->PinType = AlphaNumericPinType;
757     pPinInfo->PinPurpose = AuthenticationPin;
758     pPinInfo->dwChangePermission = PIN_CHANGE_FLAG_CHANGEPIN;
759     pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
760     pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheAlwaysPrompt;
761     break;
762     case ROLE_CONFIDENTIALITY:
763     pPinInfo->PinType = AlphaNumericPinType;
764     pPinInfo->PinPurpose = EncryptionPin;
765     pPinInfo->dwChangePermission = PIN_CHANGE_FLAG_CHANGEPIN;
766     pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
767     pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheAlwaysPrompt;
768     break;
769     default:
770     Trace(WINEVENT_LEVEL_ERROR, L"dwPinIndex == %d", dwPinIndex);
771     dwReturn = SCARD_E_INVALID_PARAMETER ;
772     __leave;
773     }
774     }
775     __finally
776     {
777     }
778     return dwReturn;
779     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26