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

Contents of /trunk/OpenPGPminidriver/CryptoOperations.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (show 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 /* 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 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 __out PBYTE * ppbTlv, __out PDWORD pdwTlvSize)
270 {
271 // 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 __try
294 {
295 // 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 }
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 PBYTE pbTlv = NULL;
570 DWORD dwTlvSize;
571 PBYTE pbCommand = NULL;
572 DWORD dwCommandSize;
573 OPENPGP_ALGORITHM_ATTRIBUTE Attributes;
574 PRSAPUBLICKEYBLOB pbPublicKeyBlob = (PRSAPUBLICKEYBLOB) pBlob;
575 BYTE bCommand[] = {0x00,0xDB,0x3F,0xFF};
576 __try
577 {
578 Trace(WINEVENT_LEVEL_VERBOSE, L"Enter dwContainer=%d",dwContainer);
579 // check blob
580 if (pbPublicKeyBlob->blobheader.aiKeyAlg != CALG_RSA_SIGN &&
581 pbPublicKeyBlob->blobheader.aiKeyAlg != CALG_RSA_KEYX)
582 {
583 Trace(WINEVENT_LEVEL_ERROR, L"Wrong aiKeyAlg %d", pbPublicKeyBlob->blobheader.aiKeyAlg);
584 dwReturn = SCARD_E_INVALID_PARAMETER;
585 __leave;
586 }
587 if (pbPublicKeyBlob->blobheader.bType != PRIVATEKEYBLOB)
588 {
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 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 }
658 __finally
659 {
660 if (pbCommand)
661 {
662 SecureZeroMemory(pbCommand, dwCommandSize);
663 pCardData->pfnCspFree(pbCommand);
664 }
665 if (pbTlv)
666 {
667 SecureZeroMemory(pbTlv, dwTlvSize);
668 pCardData->pfnCspFree(pbTlv);
669 }
670 }
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