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

Annotation of /trunk/OpenPGPminidriver/CryptoOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (hide annotations)
Wed Feb 24 07:13:15 2010 UTC (15 years, 2 months ago) by vletoux
File MIME type: text/plain
File size: 28007 byte(s)
fix key import
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 vletoux 2 DWORD BuildSingleTlv(__in PBYTE buffer, __in BYTE bTlv, __in DWORD dwTlvSize, __inout PDWORD pdwOffset)
241     {
242     DWORD dwSize = 1;
243     buffer[(*pdwOffset)++] = bTlv;
244     // truncate if too long
245     if (dwTlvSize > 0xFFFF) dwTlvSize = 0xFFFF;
246     if (dwTlvSize < 0x7F)
247     {
248     buffer[(*pdwOffset)++] = (BYTE) dwTlvSize;
249     dwSize++;
250     }
251     else if (dwTlvSize < 0xFF)
252     {
253     buffer[(*pdwOffset)++] = 0x81;
254     buffer[(*pdwOffset)++] = (BYTE) dwTlvSize;
255     dwSize+=2;
256     }
257     else
258     {
259     buffer[(*pdwOffset)++] = 0x82;
260     buffer[(*pdwOffset)++] = (BYTE) (dwTlvSize / 0x100);
261     buffer[(*pdwOffset)++] = (BYTE) (dwTlvSize % 0x100);
262     dwSize+=3;
263     }
264     return dwSize;
265     }
266    
267     DWORD BuildPrivateKeyTlv(__in PCARD_DATA pCardData, __in PRSAPUBLICKEYBLOB pbPublicKeyBlob,
268     __in OPENPGP_CONTAINER dwContainer, __in BYTE bFormat,
269 vletoux 1 __out PBYTE * ppbTlv, __out PDWORD pdwTlvSize)
270     {
271 vletoux 2 // structure of the keyblob
272     //BLOBHEADER blobheader;
273     //RSAPUBKEY rsapubkey;
274     //BYTE modulus[rsapubkey.bitlen/8];
275     //BYTE prime1[rsapubkey.bitlen/16];
276     //BYTE prime2[rsapubkey.bitlen/16];
277     //BYTE exponent1[rsapubkey.bitlen/16];
278     //BYTE exponent2[rsapubkey.bitlen/16];
279     //BYTE coefficient[rsapubkey.bitlen/16];
280     //BYTE privateExponent[rsapubkey.bitlen/8];
281     DWORD dwReturn = 0;
282    
283     DWORD bitlen = pbPublicKeyBlob->rsapubkey.bitlen;
284     PBYTE pbPublicKeyData = (PBYTE) pbPublicKeyBlob + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY);
285     // 7F48 len is < 7F so its encoded len is 1 bytes
286     // 3 bytes max + length * 7 potential plv
287     BYTE b7F48Header[(3 +1) * 7 + 3] = {0x7F, 0x48};
288     BYTE b5F48Header[3 + 2] = {0x5F, 0x48};
289     BYTE b4DHeader[3 + 1] = {0x4D};
290     DWORD dwOffset = 0;
291     DWORD dw7F48HeaderSize, dw5F48HeaderSize, dw4DHeaderSize;
292     DWORD dwKeyDataSize, dwExtendedHeaderListSize;
293 vletoux 1 __try
294     {
295 vletoux 2 // build the 7F48 header + the data into a buffer
296     dwOffset = 3;
297     dw7F48HeaderSize = 0;
298     dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x91, sizeof(DWORD), &dwOffset);
299     dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x92, bitlen / 16, &dwOffset);
300     dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x93, bitlen / 16, &dwOffset);
301     if (bFormat & 2)
302     {
303     // add crt (chineese reminder theorem) template
304     dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x94, bitlen / 16, &dwOffset);
305     dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x95, bitlen / 16, &dwOffset);
306     dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x96, bitlen / 16, &dwOffset);
307     }
308     if (bFormat & 1)
309     {
310     dw7F48HeaderSize += BuildSingleTlv(b7F48Header, 0x97, bitlen / 8, &dwOffset);
311     }
312     b7F48Header[2] = (BYTE) dw7F48HeaderSize;
313     dw7F48HeaderSize += 3; // before = only content, after += header size
314     // build 5F48 header in a buffer
315     // size of the data
316     dwKeyDataSize = sizeof(DWORD) // e
317     + bitlen / 16 //prime1
318     + bitlen / 16 //prime2
319     ;
320     if (bFormat & 2)
321     {
322     dwKeyDataSize+= bitlen / 16 //coefficient
323     + bitlen / 16 //exp1
324     + bitlen / 16 //exp2
325     ;
326     }
327     if (bFormat & 1)
328     {
329     dwKeyDataSize+= bitlen / 8 ; //modulus
330     }
331     dwOffset = 1;
332     dw5F48HeaderSize = 1 + BuildSingleTlv(b5F48Header, 0x48, dwKeyDataSize, &dwOffset);
333     // build the extended header list in a buffer
334     dwExtendedHeaderListSize = 2 // for the crt to indicate the private key
335     + dw7F48HeaderSize
336     + dw5F48HeaderSize
337     + dwKeyDataSize;
338     dwOffset = 0;
339     dw4DHeaderSize = BuildSingleTlv(b4DHeader, 0x4D, dwExtendedHeaderListSize, &dwOffset);
340    
341     // allocate the memory
342     *pdwTlvSize = dw4DHeaderSize + dwExtendedHeaderListSize;
343     *ppbTlv = pCardData->pfnCspAlloc(*pdwTlvSize);
344     if (! *ppbTlv)
345     {
346     dwReturn = SCARD_E_NO_MEMORY;
347     __leave;
348     }
349     // 4D header
350     dwOffset = 0;
351     memcpy(*ppbTlv + dwOffset, b4DHeader, dw4DHeaderSize);
352     dwOffset += dw4DHeaderSize;
353     // control reference templace
354     (*ppbTlv)[dwOffset++] = Containers[dwContainer].Tag;
355     (*ppbTlv)[dwOffset++] = 0;
356     // cardholder private key template
357     memcpy(*ppbTlv + dwOffset, b7F48Header, dw7F48HeaderSize);
358     dwOffset += dw7F48HeaderSize;
359     // Concatenation of key data header
360     memcpy(*ppbTlv + dwOffset, b5F48Header, dw5F48HeaderSize);
361     dwOffset += dw5F48HeaderSize;
362     // Concatenation of key data
363     // exponent in little endian
364     (*ppbTlv)[dwOffset++] = (BYTE) (pbPublicKeyBlob->rsapubkey.pubexp / 0x1000000);
365     (*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x1000000) / 0x10000);
366     (*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x10000) / 0x100);
367     (*ppbTlv)[dwOffset++] = (BYTE) ((pbPublicKeyBlob->rsapubkey.pubexp % 0x100) / 0x1);
368     // prime1
369     memcpy(*ppbTlv + dwOffset, pbPublicKeyData + bitlen/8 , bitlen / 16);
370     dwOffset += bitlen / 16;
371     // prime2
372     memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1) * bitlen / 16 , bitlen / 16);
373     dwOffset += bitlen / 16;
374     if (bFormat & 2)
375     {
376     // coeff
377     memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1 + 3) * bitlen / 16 , bitlen / 16);
378     dwOffset += bitlen / 16;
379     // exponent1
380     memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1 + 1) * bitlen / 16 , bitlen / 16);
381     dwOffset += bitlen / 16;
382     // exponent2
383     memcpy(*ppbTlv + dwOffset, pbPublicKeyData + (2+1 + 2) * bitlen / 16 , bitlen / 16);
384     dwOffset += bitlen / 16;
385     }
386     if (bFormat & 1)
387     {
388     // modulus
389     memcpy(*ppbTlv + dwOffset, pbPublicKeyData, bitlen / 8);
390     }
391 vletoux 1 }
392     __finally
393     {
394     }
395     return dwReturn;
396     }
397    
398     DWORD SCardReadPublicKey(PCARD_DATA pCardData, OPENPGP_CONTAINER dwContainer, PBYTE *pbPublicKey, PDWORD pdwPublicKeySize)
399     {
400     DWORD dwReturn;
401     PBYTE pbData = NULL;
402     DWORD dwResponseSize = 0;
403     BYTE pbCmd[] = {0x00,
404     0x47,
405     0x81,
406     0x00,
407     0x00,
408     0x00,
409     0x02,
410     0x00,
411     0x00,
412     0x00,
413     0x00
414     };
415     DWORD dwCmdSize;
416     POPENPGP_CONTEXT pContext;
417     PBYTE pbModulus;
418     DWORD dwModulusSize;
419     PBYTE pbExponent;
420     PRSAPUBLICKEYBLOB pbBlob = NULL;
421     __try
422     {
423     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
424     if (dwContainer >= MaxContainer)
425     {
426     dwReturn = SCARD_E_NO_KEY_CONTAINER;
427     Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwContainer);
428     __leave;
429     }
430     pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
431     pbCmd[7] = Containers[dwContainer].Tag;
432     dwCmdSize = 9;
433     if (pContext->fExtentedLeLcFields)
434     {
435     pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength / 0x100);
436     pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength % 0x100);
437     }
438     else
439     {
440     pbCmd[dwCmdSize++] = 0xFF;
441     }
442    
443     dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
444     if (dwReturn)
445     {
446     __leave;
447     }
448     //TraceDump(WINEVENT_LEVEL_INFO, pbData,dwSize);
449     if (!find_tlv(pbData,0x81,&pbModulus,&dwModulusSize))
450     {
451     dwReturn = SCARD_E_UNEXPECTED;
452     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
453     __leave;
454     }
455     if (!find_tlv(pbData,0x82,(PBYTE*)&pbExponent,NULL))
456     {
457     dwReturn = SCARD_E_UNEXPECTED;
458     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_UNEXPECTED 0x81");
459     __leave;
460     }
461     *pdwPublicKeySize = sizeof(RSAPUBLICKEYBLOB) + dwModulusSize - sizeof(DWORD);
462     *pbPublicKey = pCardData->pfnCspAlloc(*pdwPublicKeySize);
463     if (!*pbPublicKey)
464     {
465     dwReturn = SCARD_E_NO_MEMORY;
466     Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_MEMORY %d", dwContainer);
467     __leave;
468     }
469     pbBlob = (PRSAPUBLICKEYBLOB) *pbPublicKey;
470     memset(pbBlob,0,*pdwPublicKeySize);
471     pbBlob->blobheader.bType = PUBLICKEYBLOB;
472     pbBlob->blobheader.bVersion = CUR_BLOB_VERSION;
473     pbBlob->blobheader.reserved = 0;
474     pbBlob->blobheader.aiKeyAlg = Containers[dwContainer].aiKeyAlg;
475     pbBlob->rsapubkey.magic = 0x31415352; //'RSA1';
476     pbBlob->rsapubkey.bitlen = dwModulusSize*8;
477     pbBlob->rsapubkey.pubexp = pbExponent[0] * 0x1000000 + pbExponent[1] * 0x10000 + pbExponent[2] * 0x100 + pbExponent[3];
478     memcpy(pbBlob->modulus, pbModulus, dwModulusSize);
479     //TraceDump(WINEVENT_LEVEL_INFO, (PBYTE) pbBlob,*pdwPublicKeySize);
480     dwReturn = 0;
481     }
482     __finally
483     {
484     }
485     return dwReturn;
486     }
487    
488     DWORD SCardCreateKey(PCARD_DATA pCardData, OPENPGP_CONTAINER dwContainer, DWORD dwBitLen)
489     {
490     DWORD dwReturn;
491     PBYTE pbData = NULL;
492     DWORD dwResponseSize = 0, dwCmdSize;
493     OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
494     POPENPGP_CONTEXT pContext;
495     BYTE pbCmd[] = {0x00,
496     0x47,
497     0x80,
498     0x00,
499     0x00,
500     0x00,
501     0x02,
502     0x00,
503     0x00,
504     0x00,
505     0x00
506     };
507     __try
508     {
509     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
510     if (dwContainer >= MaxContainer)
511     {
512     dwReturn = SCARD_E_NO_KEY_CONTAINER;
513     Trace(WINEVENT_LEVEL_INFO, L"SCARD_E_NO_KEY_CONTAINER %d", dwContainer);
514     __leave;
515     }
516     // key len
517     dwReturn = GetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
518     if (dwReturn == SCARD_E_FILE_NOT_FOUND)
519     {
520     Attributes.bAlgoId = 0x01;
521     Attributes.bFormat = 0;
522     Attributes.wExponentLength = 0x20;
523     }
524     else if (dwReturn)
525     {
526     __leave;
527     }
528     Attributes.wModulusLength = (WORD) dwBitLen;
529     dwReturn = SetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
530     if (dwReturn)
531     {
532     __leave;
533     }
534    
535     pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
536     pbCmd[7] = Containers[dwContainer].Tag;
537     dwCmdSize = 9;
538     if (pContext->fExtentedLeLcFields)
539     {
540     pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength / 0x100);
541     pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength % 0x100);
542     }
543     else
544     {
545     pbCmd[dwCmdSize++] = 0xFF;
546     }
547    
548     dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
549     if (dwReturn)
550     {
551     __leave;
552     }
553     }
554     __finally
555     {
556     if (pbData)
557     pCardData->pfnCspFree(pbData);
558     }
559     return dwReturn;
560     }
561    
562     DWORD SCardImportKey(PCARD_DATA pCardData,
563     OPENPGP_CONTAINER dwContainer,
564     PBYTE pBlob,
565     DWORD dwKeySize)
566     {
567     DWORD dwReturn;
568     PSTR szAlgorithmAttributes = NULL;
569 vletoux 2 PBYTE pbTlv = NULL;
570     DWORD dwTlvSize;
571     PBYTE pbCommand = NULL;
572     DWORD dwCommandSize;
573 vletoux 1 OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
574     PRSAPUBLICKEYBLOB pbPublicKeyBlob = (PRSAPUBLICKEYBLOB) pBlob;
575 vletoux 2 BYTE bCommand[] = {0x00,0xDB,0x3F,0xFF};
576 vletoux 1 __try
577     {
578     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
579     // check blob
580 vletoux 2 if (pbPublicKeyBlob->blobheader.aiKeyAlg != CALG_RSA_SIGN &&
581     pbPublicKeyBlob->blobheader.aiKeyAlg != CALG_RSA_KEYX)
582 vletoux 1 {
583     Trace(WINEVENT_LEVEL_ERROR, L"Wrong aiKeyAlg %d", pbPublicKeyBlob->blobheader.aiKeyAlg);
584     dwReturn = SCARD_E_INVALID_PARAMETER;
585     __leave;
586     }
587 vletoux 2 if (pbPublicKeyBlob->blobheader.bType != PRIVATEKEYBLOB)
588 vletoux 1 {
589     Trace(WINEVENT_LEVEL_ERROR, L"Wrong bType %d", pbPublicKeyBlob->blobheader.bType);
590     dwReturn = SCARD_E_INVALID_PARAMETER;
591     __leave;
592     }
593     if (pbPublicKeyBlob->rsapubkey.magic != 0x32415352)
594     {
595     Trace(WINEVENT_LEVEL_ERROR, L"Wrong magic");
596     dwReturn = SCARD_E_INVALID_PARAMETER;
597     __leave;
598     }
599    
600     dwReturn = GetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
601     if (dwReturn == SCARD_E_FILE_NOT_FOUND)
602     {
603     Attributes.bAlgoId = 0x01;
604     Attributes.bFormat = 0;
605     Attributes.wExponentLength = 0x20;
606     }
607     else if (dwReturn)
608     {
609     __leave;
610     }
611     Attributes.wModulusLength = (WORD) pbPublicKeyBlob->rsapubkey.bitlen;
612     dwReturn = SetKeyAlgorithmAttributes(pCardData, dwContainer, &Attributes);
613     if (dwReturn)
614     {
615     __leave;
616     }
617 vletoux 2 dwReturn = BuildPrivateKeyTlv(pCardData, pbPublicKeyBlob, dwContainer, Attributes.bFormat, &pbTlv, &dwTlvSize);
618     if (dwReturn)
619     {
620     __leave;
621     }
622     //TraceDump(WINEVENT_LEVEL_VERBOSE, pbTlv, dwTlvSize);
623     if (dwTlvSize > 0xFF)
624     {
625     dwCommandSize = 7 + dwTlvSize;
626    
627     }
628     else
629     {
630     dwCommandSize = 5 + dwTlvSize;
631     }
632     pbCommand = pCardData->pfnCspAlloc(dwCommandSize);
633     if (!pbCommand)
634     {
635     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_MEMORY");
636     dwReturn = SCARD_E_NO_MEMORY;
637     __leave;
638     }
639     memcpy(pbCommand, bCommand, 4);
640     if (dwTlvSize > 0xFF)
641     {
642     pbCommand[4] = 0;
643     pbCommand[5] = (BYTE)(dwTlvSize / 0x100);
644     pbCommand[6] = (BYTE)(dwTlvSize % 0x100);
645     memcpy(pbCommand + 7, pbTlv, dwTlvSize);
646     }
647     else
648     {
649     pbCommand[4] = (BYTE) dwTlvSize;
650     memcpy(pbCommand + 5, pbTlv, dwTlvSize);
651     }
652     dwReturn = SCardSendCommand(pCardData, pbCommand, dwCommandSize);
653     if (dwReturn)
654     {
655     __leave;
656     }
657 vletoux 1 }
658     __finally
659     {
660 vletoux 2 if (pbCommand)
661 vletoux 1 {
662 vletoux 2 SecureZeroMemory(pbCommand, dwCommandSize);
663     pCardData->pfnCspFree(pbCommand);
664 vletoux 1 }
665 vletoux 2 if (pbTlv)
666     {
667     SecureZeroMemory(pbTlv, dwTlvSize);
668     pCardData->pfnCspFree(pbTlv);
669     }
670 vletoux 1 }
671     return dwReturn;
672     }
673    
674     DWORD SCardSign(PCARD_DATA pCardData,
675     PCARD_SIGNING_INFO pInfo)
676     {
677     DWORD dwReturn;
678     PBYTE pbData = NULL;
679     DWORD dwCmdSize = 0, dwI;
680     POPENPGP_CONTEXT pContext;
681     BYTE pbCmd[6 + 256 + 256] = {0x00,
682     0x2A,
683     0x9E,
684     0x9A,
685     0x00,
686     0x00,
687     };
688     __try
689     {
690     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
691     if (pInfo->bContainerIndex >= MaxContainer)
692     {
693     dwReturn = SCARD_E_NO_KEY_CONTAINER;
694     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
695     __leave;
696     }
697     if (pInfo->bContainerIndex != Signature)
698     {
699     dwReturn = SCARD_E_NO_KEY_CONTAINER;
700     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
701     __leave;
702     }
703     if (CARD_PADDING_PKCS1 & pInfo->dwPaddingType)
704     {
705     dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
706     Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PKCS1");
707     __leave;
708     }
709     else if (CARD_PADDING_PSS & pInfo->dwPaddingType)
710     {
711     dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
712     Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PSS");
713     __leave;
714     }
715     for(dwI = 0 ; dwI < dwSignatureAlgorithmCount ; dwI++)
716     {
717     if (SignatureAlgorithm[dwI].aiHashAlg == pInfo->aiHashAlg)
718     {
719     // found
720     break;
721     }
722     }
723     if (dwI >= dwSignatureAlgorithmCount)
724     {
725     Trace(WINEVENT_LEVEL_ERROR, L"alg not found %d", pInfo->aiHashAlg);
726     __leave;
727     }
728     if (SignatureAlgorithm[dwI].dwHashSize != pInfo->cbData)
729     {
730     Trace(WINEVENT_LEVEL_ERROR, L"wrong hash size %d", pInfo->cbData);
731     __leave;
732     }
733     pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
734    
735     dwCmdSize = 5;
736     if (pContext->fExtentedLeLcFields)
737     {
738     dwCmdSize++;
739     }
740     pbCmd[dwCmdSize++] = (BYTE) (SignatureAlgorithm[dwI].dwEncodedOidSize + pInfo->cbData);
741     memcpy(pbCmd + dwCmdSize , SignatureAlgorithm[dwI].pbEncodedOid,SignatureAlgorithm[dwI].dwEncodedOidSize);
742     dwCmdSize += SignatureAlgorithm[dwI].dwEncodedOidSize;
743     for(dwI = 0 ; dwI < pInfo->cbData ; dwI++)
744     {
745     pbCmd[dwCmdSize + dwI] = pInfo->pbData[pInfo->cbData - dwI -1];
746     }
747     //memcpy(pbCmd + dwCmdSize, pInfo->pbData,pInfo->cbData);
748     dwCmdSize += pInfo->cbData;
749    
750    
751     if (pContext->fExtentedLeLcFields)
752     {
753     pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength / 0x100);
754     pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength % 0x100);
755     }
756     else
757     {
758     pbCmd[dwCmdSize++] = 0;
759     }
760     dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &(pInfo->pbSignedData), &(pInfo->cbSignedData));
761     if (dwReturn == SCARD_W_WRONG_CHV)
762     {
763     dwReturn = SCARD_W_SECURITY_VIOLATION;
764     __leave;
765     }
766     if (dwReturn)
767     {
768     __leave;
769     }
770     // revert the BYTES
771     for(dwI = 0 ; dwI < pInfo->cbSignedData / 2 ; dwI++)
772     {
773     BYTE bTemp = pInfo->pbSignedData[dwI];
774     pInfo->pbSignedData[dwI] = pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI];
775     pInfo->pbSignedData[pInfo->cbSignedData - 1 - dwI] = bTemp;
776     }
777     TraceDump(WINEVENT_LEVEL_ERROR,pInfo->pbSignedData,pInfo->cbSignedData);
778     }
779     __finally
780     {
781     if (dwReturn)
782     {
783     if (pInfo->pbSignedData)
784     pCardData->pfnCspFree(pInfo->pbSignedData);
785     }
786     }
787     return dwReturn;
788     }
789    
790     DWORD SCardDecrypt(PCARD_DATA pCardData,
791     PCARD_RSA_DECRYPT_INFO pInfo)
792     {
793     DWORD dwReturn;
794     PBYTE pbData = NULL;
795     DWORD dwCmdSize = 0, dwResponseSize;
796     BYTE pbCmd[6 + 256 + 256] = {0x00,
797     0x2A,
798     0x80,
799     0x86,
800     0x00,
801     };
802     POPENPGP_CONTEXT pContext;
803     __try
804     {
805     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
806     if (pInfo->bContainerIndex >= MaxContainer)
807     {
808     dwReturn = SCARD_E_NO_KEY_CONTAINER;
809     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
810     __leave;
811     }
812     if (pInfo->bContainerIndex != Confidentiality)
813     {
814     dwReturn = SCARD_E_NO_KEY_CONTAINER;
815     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
816     __leave;
817     }
818     pContext = (POPENPGP_CONTEXT) pCardData->pvVendorSpecific;
819     dwCmdSize = 5;
820     if (pContext->fExtentedLeLcFields)
821     {
822     pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) / 0x100);
823     pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) % 0x100);
824     }
825     else
826     {
827     pbCmd[dwCmdSize++] = (BYTE)((pInfo->cbData +1) % 0x100);
828     }
829     pbCmd[dwCmdSize++] = 0;
830     memcpy(pbCmd + dwCmdSize, pInfo->pbData, pInfo->cbData);
831     dwCmdSize += pInfo->cbData;
832     if (pContext->fExtentedLeLcFields)
833     {
834     pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength / 0x100);
835     pbCmd[dwCmdSize++] = (BYTE)(pContext->dwMaxLength % 0x100);
836     }
837     else
838     {
839     pbCmd[dwCmdSize++] = 0;
840     }
841     dwReturn = SCardGetData(pCardData, pbCmd, dwCmdSize, &pbData, &dwResponseSize);
842     if (dwReturn)
843     {
844     __leave;
845     }
846     if ( pInfo->cbData < dwResponseSize)
847     {
848     dwReturn = SCARD_E_INSUFFICIENT_BUFFER;
849     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_INSUFFICIENT_BUFFER %d expected = %d", pInfo->cbData, dwResponseSize);
850     __leave;
851     }
852     pInfo->cbData = dwResponseSize;
853     memcpy( pInfo->pbData, pbData, dwResponseSize);
854     }
855     __finally
856     {
857     if (pbData)
858     pCardData->pfnCspFree(pbData);
859     }
860     return dwReturn;
861     }
862    
863     DWORD SCardAuthenticate(PCARD_DATA pCardData,
864     PCARD_SIGNING_INFO pInfo)
865     {
866     DWORD dwReturn;
867     PBYTE pbData = NULL;
868     DWORD dwSize = 0, dwI;
869     BYTE pbCmd[6 + 256 + 256] = {0x00,
870     0x88,
871     0x00,
872     0x00,
873     0x00,
874     };
875     __try
876     {
877     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",pInfo->bContainerIndex);
878     if (pInfo->bContainerIndex >= MaxContainer)
879     {
880     dwReturn = SCARD_E_NO_KEY_CONTAINER;
881     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
882     __leave;
883     }
884     if (pInfo->bContainerIndex != Authentication)
885     {
886     dwReturn = SCARD_E_NO_KEY_CONTAINER;
887     Trace(WINEVENT_LEVEL_ERROR, L"SCARD_E_NO_KEY_CONTAINER %d", pInfo->bContainerIndex);
888     __leave;
889     }
890     if (CARD_PADDING_PKCS1 & pInfo->dwPaddingType)
891     {
892     dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
893     Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PKCS1");
894     __leave;
895     }
896     else if (CARD_PADDING_PSS & pInfo->dwPaddingType)
897     {
898     dwReturn = SCARD_E_UNSUPPORTED_FEATURE;
899     Trace(WINEVENT_LEVEL_ERROR, L"CARD_PADDING_PSS");
900     __leave;
901     }
902     for(dwI = 0 ; dwI < dwSignatureAlgorithmCount ; dwI++)
903     {
904     if (SignatureAlgorithm[dwI].aiHashAlg == pInfo->aiHashAlg)
905     {
906     // found
907     break;
908     }
909     }
910     if (dwI >= dwSignatureAlgorithmCount)
911     {
912     Trace(WINEVENT_LEVEL_ERROR, L"alg not found %d", pInfo->aiHashAlg);
913     __leave;
914     }
915     if (SignatureAlgorithm[dwI].dwHashSize != pInfo->cbData)
916     {
917     Trace(WINEVENT_LEVEL_ERROR, L"wrong hash size %d", pInfo->cbData);
918     __leave;
919     }
920     memcpy(pbCmd +5, SignatureAlgorithm[dwI].pbEncodedOid,SignatureAlgorithm[dwI].dwEncodedOidSize);
921     memcpy(pbCmd +5 + SignatureAlgorithm[dwI].dwEncodedOidSize, pInfo->pbData,pInfo->cbData);
922    
923     dwReturn = SCardGetData(pCardData, pbCmd, ARRAYSIZE(pbCmd), &(pInfo->pbSignedData), &(pInfo->cbSignedData));
924     if (dwReturn)
925     {
926     __leave;
927     }
928     }
929     __finally
930     {
931     }
932     return dwReturn;
933     }
934    
935     DWORD GetPinInfo(DWORD __in dwPinIndex, __inout PPIN_INFO pPinInfo)
936     {
937     DWORD dwReturn=0;
938     __try
939     {
940     Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwPinIndex=%d",dwPinIndex);
941     switch(dwPinIndex)
942     {
943     case ROLE_SIGNATURE:
944     pPinInfo->PinType = AlphaNumericPinType;
945     pPinInfo->PinPurpose = DigitalSignaturePin;
946     pPinInfo->dwChangePermission = PIN_CHANGE_FLAG_CHANGEPIN;
947     pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
948     pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheAlwaysPrompt;
949     break;
950     case ROLE_AUTHENTICATION:
951     pPinInfo->PinType = AlphaNumericPinType;
952     pPinInfo->PinPurpose = AuthenticationPin;
953     pPinInfo->dwChangePermission = PIN_CHANGE_FLAG_CHANGEPIN;
954     pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
955     pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheAlwaysPrompt;
956     break;
957     case ROLE_CONFIDENTIALITY:
958     pPinInfo->PinType = AlphaNumericPinType;
959     pPinInfo->PinPurpose = EncryptionPin;
960     pPinInfo->dwChangePermission = PIN_CHANGE_FLAG_CHANGEPIN;
961     pPinInfo->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
962     pPinInfo->PinCachePolicy.PinCachePolicyType = PinCacheAlwaysPrompt;
963     break;
964     default:
965     Trace(WINEVENT_LEVEL_ERROR, L"dwPinIndex == %d", dwPinIndex);
966     dwReturn = SCARD_E_INVALID_PARAMETER ;
967     __leave;
968     }
969     }
970     __finally
971     {
972     }
973     return dwReturn;
974     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26