1 //==============================================================;
2 //
3 //  CARDMOD.H
4 //
5 //  Abstract:
6 //      This is the header file commonly used for card modules.
7 //
8 //  This source code is only intended as a supplement to existing Microsoft
9 //  documentation.
10 //
11 //  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
12 //  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
13 //  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
14 //  PURPOSE.
15 //
16 //  Copyright (C) Microsoft Corporation.  All Rights Reserved.
17 //
18 //==============================================================;
19 #ifndef __CARDMOD__H__
20 #define __CARDMOD__H__
21 
22 #include <windows.h>
23 #include <wincrypt.h>
24 #pragma warning(push)
25 #pragma warning(disable:4201)
26 // Disable error C4201 in public header
27 //  nonstandard extension used : nameless struct/union
28 #include <winscard.h>
29 #pragma warning(pop)
30 #include <specstrings.h>
31 
32 // This value should be passed to
33 //
34 //  SCardSetCardTypeProviderName
35 //  SCardGetCardTypeProviderName
36 //
37 // in order to query and set the Card Specific Module to be used
38 // for a given card.
39 #define SCARD_PROVIDER_CARD_MODULE 0x80000001
40 
41 typedef struct _CARD_DATA CARD_DATA, *PCARD_DATA;
42 
43 //
44 // This define can be used as a return value for queries involving
45 // card data that may be impossible to determine on a given card
46 // OS, such as the number of available card storage bytes.
47 //
48 #define CARD_DATA_VALUE_UNKNOWN                     ((DWORD) -1)
49 
50 //
51 // Well Known Logical Names
52 //
53 
54 //
55 // Logical Directory Names
56 //
57 
58 // Second-level logical directories
59 
60 #define szBASE_CSP_DIR                             "mscp"
61 
62 #define szINTERMEDIATE_CERTS_DIR                   "mscerts"
63 
64 //
65 // Logical File Names
66 //
67 // When requesting (or otherwise referring to) any logical file, the full path
68 // must be used, including when referring to well known files.  For example,
69 // to request the wszCONTAINER_MAP_FILE, the provided name will be
70 // "/mscp/cmapfile".
71 //
72 
73 // Well known logical files under Microsoft
74 #define szCACHE_FILE                               "cardcf"
75 
76 #define szCARD_IDENTIFIER_FILE                     "cardid"
77 
78 // Well known logical files under CSP
79 #define szCONTAINER_MAP_FILE                       "cmapfile"
80 #define szROOT_STORE_FILE                          "msroots"
81 
82 //
83 // Well known logical files under User Certs
84 //
85 // The following prefixes are appended with the container index of the
86 // associated key.  For example, the certificate associated with the
87 // Key Exchange key in container index 2 will have the name:
88 //  "/mscp/kxc2"
89 //
90 #define szUSER_SIGNATURE_CERT_PREFIX               "ksc"
91 #define szUSER_KEYEXCHANGE_CERT_PREFIX             "kxc"
92 #define szUSER_SIGNATURE_PRIVATE_KEY_PREFIX        "kss"
93 #define szUSER_SIGNATURE_PUBLIC_KEY_PREFIX         "ksp"
94 #define szUSER_KEYEXCHANGE_PRIVATE_KEY_PREFIX      "kxs"
95 #define szUSER_KEYEXCHANGE_PUBLIC_KEY_PREFIX       "kxp"
96 
97 //
98 // Logical Card User Names
99 //
100 #define wszCARD_USER_EVERYONE                       L"anonymous"
101 #define wszCARD_USER_USER                           L"user"
102 #define wszCARD_USER_ADMIN                          L"admin"
103 
104 // new ecc key specs
105 
106 #define AT_ECDSA_P256      3
107 #define AT_ECDSA_P384      4
108 #define AT_ECDSA_P521      5
109 #define AT_ECDHE_P256      6
110 #define AT_ECDHE_P384      7
111 #define AT_ECDHE_P521      8
112 
113 //
114 // Type: CARD_CACHE_FILE_FORMAT
115 //
116 // This struct is used as the file format of the cache file,
117 // as stored on the card.
118 //
119 
120 #define CARD_CACHE_FILE_CURRENT_VERSION         1
121 
122 typedef struct _CARD_CACHE_FILE_FORMAT
123 {
124     BYTE bVersion;
125     BYTE bPinsFreshness;
126 
127     WORD wContainersFreshness;
128     WORD wFilesFreshness;
129 } CARD_CACHE_FILE_FORMAT, *PCARD_CACHE_FILE_FORMAT;
130 
131 //
132 // Type: CONTAINER_MAP_RECORD
133 //
134 // This structure describes the format of the Base CSP's container map file,
135 // stored on the card.  This is well-known logical file wszCONTAINER_MAP_FILE.
136 // The file consists of zero or more of these records.
137 //
138 #define MAX_CONTAINER_NAME_LEN                  39
139 
140 // This flag is set in the CONTAINER_MAP_RECORD bFlags member if the
141 // corresponding container is valid and currently exists on the card.
142 // If the container is deleted, its bFlags field must be cleared.
143 #define CONTAINER_MAP_VALID_CONTAINER           1
144 
145 // This flag is set in the CONTAINER_MAP_RECORD bFlags
146 // member if the corresponding container is the default container on the card.
147 #define CONTAINER_MAP_DEFAULT_CONTAINER         2
148 
149 typedef struct _CONTAINER_MAP_RECORD
150 {
151     WCHAR wszGuid [MAX_CONTAINER_NAME_LEN + 1];
152     BYTE bFlags;
153     BYTE bReserved;
154     WORD wSigKeySizeBits;
155     WORD wKeyExchangeKeySizeBits;
156 } CONTAINER_MAP_RECORD, *PCONTAINER_MAP_RECORD;
157 
158 //
159 // Converts a card filename string from unicode to ansi
160 //
161 DWORD WINAPI I_CardConvertFileNameToAnsi(
162     IN      PCARD_DATA pCardData,
163     __in    LPWSTR wszUnicodeName,
164     __out   LPSTR *ppszAnsiName);
165 
166 // Logical Directory Access Conditions
167 typedef enum
168 {
169     InvalidDirAc = 0,
170 
171     // User Read, Write
172     UserCreateDeleteDirAc,
173 
174     // Admin Write
175     AdminCreateDeleteDirAc
176 
177 } CARD_DIRECTORY_ACCESS_CONDITION;
178 
179 // Logical File Access Conditions
180 typedef enum
181 {
182     // Invalid value, chosed to cooincide with common initialization
183     // of memory
184     InvalidAc = 0,
185 
186     // Everyone     Read
187     // User         Read, Write
188     //
189     // Example:  A user certificate file.
190     EveryoneReadUserWriteAc,
191 
192     // Everyone     None
193     // User         Write, Execute
194     //
195     // Example:  A private key file.
196     UserWriteExecuteAc,
197 
198     // Everyone     Read
199     // Admin        Read, Write
200     //
201     // Example:  The Card Identifier file.
202     EveryoneReadAdminWriteAc,
203 
204     // Explicit value to set when it is desired to say that
205     // it is unknown
206     UnknownAc,
207 
208     // Everyone No Access
209     // User Read Write
210     //
211     // Example:  A password wallet file.
212 
213     UserReadWriteAc,
214     // Everyone/User No Access
215     // Admin Read Write
216     //
217     // Example:  Administration data.
218 
219     AdminReadWriteAc
220 } CARD_FILE_ACCESS_CONDITION;
221 
222 //
223 // Function: CardAcquireContext
224 //
225 // Purpose: Initialize the CARD_DATA structure which will be used by
226 //          the CSP to interact with a specific card.
227 //
228 typedef DWORD (WINAPI *PFN_CARD_ACQUIRE_CONTEXT)(
229     IN      PCARD_DATA  pCardData,
230     __in    DWORD       dwFlags);
231 
232 DWORD
233 WINAPI
234 CardAcquireContext(
235     IN      PCARD_DATA  pCardData,
236     __in    DWORD       dwFlags);
237 
238 //
239 // Function: CardDeleteContext
240 //
241 // Purpose: Free resources consumed by the CARD_DATA structure.
242 //
243 typedef DWORD (WINAPI *PFN_CARD_DELETE_CONTEXT)(
244     __inout     PCARD_DATA  pCardData);
245 
246 DWORD
247 WINAPI
248 CardDeleteContext(
249     __inout     PCARD_DATA  pCardData);
250 
251 //
252 // Function: CardQueryCapabilities
253 //
254 // Purpose: Query the card module for specific functionality
255 //          provided by this card.
256 //
257 #define CARD_CAPABILITIES_CURRENT_VERSION 1
258 
259 typedef struct _CARD_CAPABILITIES
260 {
261     IN OUT DWORD            dwVersion;
262     IN     BOOL             fCertificateCompression;
263     IN     BOOL             fKeyGen;
264 } CARD_CAPABILITIES, *PCARD_CAPABILITIES;
265 
266 typedef DWORD (WINAPI *PFN_CARD_QUERY_CAPABILITIES)(
267     __in      PCARD_DATA          pCardData,
268     __in      PCARD_CAPABILITIES  pCardCapabilities);
269 
270 DWORD
271 WINAPI
272 CardQueryCapabilities(
273     __in      PCARD_DATA          pCardData,
274     __in      PCARD_CAPABILITIES  pCardCapabilities);
275 
276 //
277 // Function: CardDeleteContainer
278 //
279 // Purpose: Delete the specified key container.
280 //
281 typedef DWORD (WINAPI *PFN_CARD_DELETE_CONTAINER)(
282     __in      PCARD_DATA  pCardData,
283     __in      BYTE        bContainerIndex,
284     __in      DWORD       dwReserved);
285 
286 DWORD
287 WINAPI
288 CardDeleteContainer(
289     __in      PCARD_DATA  pCardData,
290     __in      BYTE        bContainerIndex,
291     __in      DWORD       dwReserved);
292 
293 //
294 // Function: CardCreateContainer
295 //
296 
297 #define CARD_CREATE_CONTAINER_KEY_GEN           1
298 #define CARD_CREATE_CONTAINER_KEY_IMPORT        2
299 
300 typedef DWORD (WINAPI *PFN_CARD_CREATE_CONTAINER)(
301     __in      PCARD_DATA  pCardData,
302     __in      BYTE        bContainerIndex,
303     __in      DWORD       dwFlags,
304     __in      DWORD       dwKeySpec,
305     __in      DWORD       dwKeySize,
306     __in      PBYTE       pbKeyData);
307 
308 DWORD
309 WINAPI
310 CardCreateContainer(
311     __in      PCARD_DATA  pCardData,
312     __in      BYTE        bContainerIndex,
313     __in      DWORD       dwFlags,
314     __in      DWORD       dwKeySpec,
315     __in      DWORD       dwKeySize,
316     __in      PBYTE       pbKeyData);
317 
318 //
319 // Function: CardGetContainerInfo
320 //
321 // Purpose: Query for all public information available about
322 //          the named key container.  This includes the Signature
323 //          and Key Exchange type public keys, if they exist.
324 //
325 //          The pbSigPublicKey and pbKeyExPublicKey buffers contain the
326 //          Signature and Key Exchange public keys, respectively, if they
327 //          exist.  The format of these buffers is a Crypto
328 //          API PUBLICKEYBLOB -
329 //
330 //              BLOBHEADER
331 //              RSAPUBKEY
332 //              modulus
333 //
334 //          In the case of ECC public keys, the pbSigPublicKey will contain
335 //          the ECDSA key and pbKeyExPublicKey will contain the ECDH key if
336 //          they exist. ECC key structure -
337 //
338 //              BCRYPT_ECCKEY_BLOB
339 //              X coord (big endian)
340 //              Y coord (big endian)
341 //
342 #define CONTAINER_INFO_CURRENT_VERSION 1
343 
344 typedef struct _CONTAINER_INFO
345 {
346     IN OUT DWORD dwVersion;
347     IN     DWORD dwReserved;
348 
349     OUT    DWORD cbSigPublicKey;
350     OUT    PBYTE pbSigPublicKey;
351 
352     OUT    DWORD cbKeyExPublicKey;
353     OUT    PBYTE pbKeyExPublicKey;
354 } CONTAINER_INFO, *PCONTAINER_INFO;
355 
356 typedef DWORD (WINAPI *PFN_CARD_GET_CONTAINER_INFO)(
357     __in      PCARD_DATA  pCardData,
358     __in      BYTE        bContainerIndex,
359     __in      DWORD       dwFlags,
360     __in      PCONTAINER_INFO pContainerInfo);
361 
362 DWORD
363 WINAPI
364 CardGetContainerInfo(
365     __in      PCARD_DATA  pCardData,
366     __in      BYTE        bContainerIndex,
367     __in      DWORD       dwFlags,
368     __in      PCONTAINER_INFO pContainerInfo);
369 
370 //
371 // Function: CardAuthenticatePin
372 //
373 typedef DWORD (WINAPI *PFN_CARD_AUTHENTICATE_PIN)(
374     __in                   PCARD_DATA  pCardData,
375     __in                   LPWSTR      pwszUserId,
376     __in_bcount(cbPin)     PBYTE       pbPin,
377     __in                   DWORD       cbPin,
378     __out_opt              PDWORD pcAttemptsRemaining);
379 
380 
381 DWORD
382 WINAPI
383 CardAuthenticatePin(
384     __in                   PCARD_DATA  pCardData,
385     __in                   LPWSTR      pwszUserId,
386     __in_bcount(cbPin)     PBYTE       pbPin,
387     __in                   DWORD       cbPin,
388     __out_opt              PDWORD pcAttemptsRemaining);
389 
390 //
391 // Function: CardGetChallenge
392 //
393 typedef DWORD (WINAPI *PFN_CARD_GET_CHALLENGE)(
394     __in                                PCARD_DATA  pCardData,
395     __out_bcount(*pcbChallengeData)     PBYTE       *ppbChallengeData,
396     __out                               PDWORD      pcbChallengeData);
397 
398 DWORD
399 WINAPI
400 CardGetChallenge(
401     __in                                  PCARD_DATA pCardData,
402     __deref_out_bcount(*pcbChallengeData) PBYTE     *ppbChallengeData,
403     __out                                 PDWORD     pcbChallengeData);
404 
405 //
406 // Function: CardAuthenticateChallenge
407 //
408 typedef DWORD (WINAPI *PFN_CARD_AUTHENTICATE_CHALLENGE)(
409     __in                             PCARD_DATA  pCardData,
410     __in_bcount(cbResponseData)      PBYTE       pbResponseData,
411     __in                             DWORD       cbResponseData,
412     __out_opt                        PDWORD pcAttemptsRemaining);
413 
414 DWORD
415 WINAPI
416 CardAuthenticateChallenge(
417     __in                             PCARD_DATA  pCardData,
418     __in_bcount(cbResponseData)      PBYTE       pbResponseData,
419     __in                             DWORD       cbResponseData,
420     __out_opt                        PDWORD pcAttemptsRemaining);
421 
422 //
423 // Function: CardUnblockPin
424 //
425 #define CARD_AUTHENTICATE_PIN_CHALLENGE_RESPONSE                 1
426 #define CARD_AUTHENTICATE_PIN_PIN                                2
427 
428 typedef DWORD (WINAPI *PFN_CARD_UNBLOCK_PIN)(
429     __in                               PCARD_DATA  pCardData,
430     __in                               LPWSTR      pwszUserId,
431     __in_bcount(cbAuthenticationData)  PBYTE       pbAuthenticationData,
432     __in                               DWORD       cbAuthenticationData,
433     __in_bcount(cbNewPinData)          PBYTE       pbNewPinData,
434     __in                               DWORD       cbNewPinData,
435     __in                               DWORD       cRetryCount,
436     __in                               DWORD       dwFlags);
437 
438 DWORD
439 WINAPI
440 CardUnblockPin(
441     __in                               PCARD_DATA  pCardData,
442     __in                               LPWSTR      pwszUserId,
443     __in_bcount(cbAuthenticationData)  PBYTE       pbAuthenticationData,
444     __in                               DWORD       cbAuthenticationData,
445     __in_bcount(cbNewPinData)          PBYTE       pbNewPinData,
446     __in                               DWORD       cbNewPinData,
447     __in                               DWORD       cRetryCount,
448     __in                               DWORD       dwFlags);
449 
450 //
451 // Function: CardChangeAuthenticator
452 //
453 typedef DWORD (WINAPI *PFN_CARD_CHANGE_AUTHENTICATOR)(
454     __in                                 PCARD_DATA  pCardData,
455     __in                                 LPWSTR      pwszUserId,
456     __in_bcount(cbCurrentAuthenticator)  PBYTE       pbCurrentAuthenticator,
457     __in                                 DWORD       cbCurrentAuthenticator,
458     __in_bcount(cbNewAuthenticator)      PBYTE       pbNewAuthenticator,
459     __in                                 DWORD       cbNewAuthenticator,
460     __in                                 DWORD       cRetryCount,
461     __in                                 DWORD       dwFlags,
462     __out_opt                            PDWORD pcAttemptsRemaining);
463 
464 DWORD
465 WINAPI
466 CardChangeAuthenticator(
467     __in                                 PCARD_DATA  pCardData,
468     __in                                 LPWSTR      pwszUserId,
469     __in_bcount(cbCurrentAuthenticator)  PBYTE       pbCurrentAuthenticator,
470     __in                                 DWORD       cbCurrentAuthenticator,
471     __in_bcount(cbNewAuthenticator)      PBYTE       pbNewAuthenticator,
472     __in                                 DWORD       cbNewAuthenticator,
473     __in                                 DWORD       cRetryCount,
474     __in                                 DWORD       dwFlags,
475     __out_opt                            PDWORD pcAttemptsRemaining);
476 
477 //
478 // Function: CardDeauthenticate
479 //
480 // Purpose: De-authenticate the specified logical user name on the card.
481 //
482 // This is an optional API.  If implemented, this API is used instead
483 // of SCARD_RESET_CARD by the Base CSP.  An example scenario is leaving
484 // a transaction in which the card has been authenticated (a Pin has been
485 // successfully presented).
486 //
487 // The pwszUserId parameter will point to a valid well-known User Name (see
488 // above).
489 //
490 // The dwFlags parameter is currently unused and will always be zero.
491 //
492 // Card modules that choose to not implement this API must set the CARD_DATA
493 // pfnCardDeauthenticate pointer to NULL.
494 //
495 typedef DWORD (WINAPI *PFN_CARD_DEAUTHENTICATE)(
496     __in      PCARD_DATA  pCardData,
497     __in      LPWSTR      pwszUserId,
498     __in      DWORD       dwFlags);
499 
500 DWORD
501 WINAPI
502 CardDeauthenticate(
503     __in    PCARD_DATA  pCardData,
504     __in    LPWSTR      pwszUserId,
505     __in    DWORD       dwFlags);
506 
507 // Directory Control Group
508 
509 //
510 // Function: CardCreateDirectory
511 //
512 // Purpose: Register the specified application name on the card, and apply the
513 //          provided access condition.
514 //
515 // Return Value:
516 //          ERROR_FILE_EXISTS - directory already exists
517 //
518 typedef DWORD (WINAPI *PFN_CARD_CREATE_DIRECTORY)(
519     __in    PCARD_DATA  pCardData,
520     __in    LPSTR       pszDirectoryName,
521     __in    CARD_DIRECTORY_ACCESS_CONDITION AccessCondition);
522 
523 DWORD
524 WINAPI
525 CardCreateDirectory(
526     __in    PCARD_DATA  pCardData,
527     __in    LPSTR       pszDirectoryName,
528     __in    CARD_DIRECTORY_ACCESS_CONDITION AccessCondition);
529 
530 //
531 // Function: CardDeleteDirectory
532 //
533 // Purpose: Unregister the specified application from the card.
534 //
535 // Return Value:
536 //          SCARD_E_DIR_NOT_FOUND - directory does not exist
537 //          ERROR_DIR_NOT_EMPTY - the directory is not empty
538 //
539 typedef DWORD (WINAPI *PFN_CARD_DELETE_DIRECTORY)(
540     __in    PCARD_DATA  pCardData,
541     __in    LPSTR       pszDirectoryName);
542 
543 DWORD
544 WINAPI
545 CardDeleteDirectory(
546     __in    PCARD_DATA  pCardData,
547     __in    LPSTR       pszDirectoryName);
548 
549 // File Control Group
550 
551 //
552 // Function: CardCreateFile
553 //
554 typedef DWORD (WINAPI *PFN_CARD_CREATE_FILE)(
555     __in    PCARD_DATA  pCardData,
556     __in    LPSTR       pszDirectoryName,
557     __in    LPSTR       pszFileName,
558     __in    DWORD       cbInitialCreationSize,
559     __in    CARD_FILE_ACCESS_CONDITION AccessCondition);
560 
561 DWORD
562 WINAPI
563 CardCreateFile(
564     __in    PCARD_DATA  pCardData,
565     __in    LPSTR       pszDirectoryName,
566     __in    LPSTR       pszFileName,
567     __in    DWORD       cbInitialCreationSize,
568     __in    CARD_FILE_ACCESS_CONDITION AccessCondition);
569 
570 //
571 // Function: CardReadFile
572 //
573 // Purpose: Read the specified file from the card.
574 //
575 //          The pbData parameter should be allocated
576 //          by the card module and freed by the CSP.  The card module
577 //          must set the cbData parameter to the size of the returned buffer.
578 //
579 typedef DWORD (WINAPI *PFN_CARD_READ_FILE)(
580     __in                       PCARD_DATA  pCardData,
581 	__in_opt                       LPSTR       pszDirectoryName,
582     __in                       LPSTR       pszFileName,
583     __in                       DWORD       dwFlags,
584 	__deref_out_bcount_opt(*pcbData)     PBYTE      *ppbData,
585 	__out_opt                      PDWORD      pcbData);
586 
587 DWORD WINAPI CardReadFile(
588     __in                             PCARD_DATA  pCardData,
589 	__in_opt                             LPSTR       pszDirectoryName,
590     __in                             LPSTR       pszFileName,
591     __in                             DWORD       dwFlags,
592 	__deref_out_bcount_opt(*pcbData)     PBYTE      *ppbData,
593 	__out_opt                            PDWORD      pcbData);
594 
595 
596 //
597 // Function: CardWriteFile
598 //
599 typedef DWORD (WINAPI *PFN_CARD_WRITE_FILE)(
600     __in                     PCARD_DATA  pCardData,
601     __in                     LPSTR       pszDirectoryName,
602     __in                     LPSTR       pszFileName,
603     __in                     DWORD       dwFlags,
604     __in_bcount(cbData)      PBYTE       pbData,
605     __in                     DWORD       cbData);
606 
607 DWORD
608 WINAPI
609 CardWriteFile(
610     __in                     PCARD_DATA  pCardData,
611     __in                     LPSTR       pszDirectoryName,
612     __in                     LPSTR       pszFileName,
613     __in                     DWORD       dwFlags,
614     __in_bcount(cbData)      PBYTE       pbData,
615     __in                     DWORD       cbData);
616 
617 //
618 // Function: CardDeleteFile
619 //
620 typedef DWORD (WINAPI *PFN_CARD_DELETE_FILE)(
621     __in    PCARD_DATA  pCardData,
622     __in    LPSTR       pszDirectoryName,
623     __in    LPSTR       pszFileName,
624     __in    DWORD       dwFlags);
625 
626 DWORD
627 WINAPI
628 CardDeleteFile(
629     __in    PCARD_DATA  pCardData,
630     __in    LPSTR       pszDirectoryName,
631     __in    LPSTR       pszFileName,
632     __in    DWORD       dwFlags);
633 
634 //
635 // Function: CardEnumFiles
636 //
637 // Purpose: Return a multi-string list of the general files
638 //          present on this card.  The multi-string is allocated
639 //          by the card module and must be freed by the CSP.
640 //
641 //  The caller must provide a logical file directory name in the
642 //  pmwszFileNames parameter (see Logical Directory Names, above).
643 //  The logical directory name indicates which group of files will be
644 //  enumerated.
645 //
646 //  The logical directory name is expected to be a static string, so the
647 //  the card module will not free it.  The card module
648 //  will allocate a new buffer in *pmwszFileNames to store the multi-string
649 //  list of enumerated files using pCardData->pfnCspAlloc.
650 //
651 //  If the function fails for any reason, *pmwszFileNames is set to NULL.
652 //
653 typedef DWORD (WINAPI *PFN_CARD_ENUM_FILES)(
654     __in      PCARD_DATA  pCardData,
655     __in      LPSTR       pszDirectoryName,
656     __out_ecount(*pdwcbFileName)
657               LPSTR      *pmszFileNames,
658     __out     LPDWORD     pdwcbFileName,
659     __in      DWORD       dwFlags);
660 
661 DWORD
662 WINAPI
663 CardEnumFiles(
664     __in      PCARD_DATA  pCardData,
665     __in      LPSTR       pszDirectoryName,
666     __out_ecount(*pdwcbFileName)
667               LPSTR      *pmszFileNames,
668     __out     LPDWORD     pdwcbFileName,
669     __in      DWORD       dwFlags);
670 
671 //
672 // Function: CardGetFileInfo
673 //
674 #define CARD_FILE_INFO_CURRENT_VERSION 1
675 
676 typedef struct _CARD_FILE_INFO
677 {
678     IN OUT DWORD dwVersion;
679     OUT    DWORD cbFileSize;
680     OUT    CARD_FILE_ACCESS_CONDITION AccessCondition;
681 } CARD_FILE_INFO, *PCARD_FILE_INFO;
682 
683 typedef DWORD (WINAPI *PFN_CARD_GET_FILE_INFO)(
684     __in         PCARD_DATA  pCardData,
685     __in         LPSTR      pszDirectoryName,
686     __in         LPSTR      pszFileName,
687     __in         PCARD_FILE_INFO pCardFileInfo);
688 
689 DWORD
690 WINAPI
691 CardGetFileInfo(
692     __in         PCARD_DATA  pCardData,
693     __in         LPSTR      pszDirectoryName,
694     __in         LPSTR      pszFileName,
695     __in         PCARD_FILE_INFO pCardFileInfo);
696 
697 //
698 // Function: CardQueryFreeSpace
699 //
700 #define CARD_FREE_SPACE_INFO_CURRENT_VERSION 1
701 
702 typedef struct _CARD_FREE_SPACE_INFO
703 {
704     IN OUT DWORD dwVersion;
705     OUT    DWORD dwBytesAvailable;
706     OUT    DWORD dwKeyContainersAvailable;
707     OUT    DWORD dwMaxKeyContainers;
708 
709 } CARD_FREE_SPACE_INFO, *PCARD_FREE_SPACE_INFO;
710 
711 typedef DWORD (WINAPI *PFN_CARD_QUERY_FREE_SPACE)(
712     __in      PCARD_DATA  pCardData,
713     __in      DWORD       dwFlags,
714     __in      PCARD_FREE_SPACE_INFO pCardFreeSpaceInfo);
715 
716 DWORD
717 WINAPI
718 CardQueryFreeSpace(
719     __in      PCARD_DATA  pCardData,
720     __in      DWORD       dwFlags,
721     __in      PCARD_FREE_SPACE_INFO pCardFreeSpaceInfo);
722 
723 //
724 // Function: CardQueryKeySizes
725 //
726 #define CARD_KEY_SIZES_CURRENT_VERSION 1
727 
728 typedef struct _CARD_KEY_SIZES
729 {
730     IN OUT  DWORD dwVersion;
731 
732     OUT     DWORD dwMinimumBitlen;
733     OUT     DWORD dwDefaultBitlen;
734     OUT     DWORD dwMaximumBitlen;
735     OUT     DWORD dwIncrementalBitlen;
736 
737 } CARD_KEY_SIZES, *PCARD_KEY_SIZES;
738 
739 typedef DWORD (WINAPI *PFN_CARD_QUERY_KEY_SIZES)(
740     __in      PCARD_DATA  pCardData,
741     __in      DWORD       dwKeySpec,
742     __in      DWORD       dwFlags,
743     __in      PCARD_KEY_SIZES pKeySizes);
744 
745 DWORD
746 WINAPI
747 CardQueryKeySizes(
748     __in      PCARD_DATA  pCardData,
749     __in      DWORD       dwKeySpec,
750     __in      DWORD       dwFlags,
751     __in      PCARD_KEY_SIZES pKeySizes);
752 
753 //
754 // Function: CardRSADecrypt
755 //
756 // Purpose: Perform a private key decryption on the supplied data.  The
757 //          card module should assume that pbData is the length of the
758 //          key modulus.
759 //
760 #define CARD_RSA_KEY_DECRYPT_INFO_CURRENT_VERSION 1
761 
762 typedef struct _CARD_RSA_DECRYPT_INFO
763 {
764     __in                        DWORD dwVersion;
765     __in                        BYTE bContainerIndex;
766 
767     // For RSA operations, this should be AT_SIGNATURE or AT_KEYEXCHANGE.
768     __in                        DWORD dwKeySpec;
769 
770     // This is the buffer and length that the caller expects to be decrypted.
771     // For RSA operations, cbData is redundant since the length of the buffer
772     // should always be equal to the length of the key modulus.
773     __out_bcount(cbData)        PBYTE pbData;
774     __out                       DWORD cbData;
775 
776 } CARD_RSA_DECRYPT_INFO, *PCARD_RSA_DECRYPT_INFO;
777 
778 typedef DWORD (WINAPI *PFN_CARD_RSA_DECRYPT)(
779     __in        PCARD_DATA              pCardData,
780     __inout     PCARD_RSA_DECRYPT_INFO  pInfo);
781 
782 DWORD
783 WINAPI
784 CardRSADecrypt(
785     __in        PCARD_DATA              pCardData,
786     __inout     PCARD_RSA_DECRYPT_INFO  pInfo);
787 
788 #define CARD_PADDING_INFO_PRESENT 0x40000000
789 #define CARD_BUFFER_SIZE_ONLY     0x20000000
790 #define CARD_PADDING_NONE         0x00000001
791 #define CARD_PADDING_PKCS1        0x00000002
792 #define CARD_PADDING_PSS          0x00000004
793 
794 // CARD_SIGNING_INFO_BASIC_VERSION is provided for thos applications
795 // do not intend to support passing in the pPaddingInfo structure
796 #define CARD_SIGNING_INFO_BASIC_VERSION 1
797 
798 //
799 // Function: CardSignData
800 //
801 // Purpose: Sign input data using a specified key
802 //
803 #define CARD_SIGNING_INFO_CURRENT_VERSION 2
804 typedef struct _CARD_SIGNING_INFO
805 {
806     IN DWORD  dwVersion;
807 
808     IN BYTE   bContainerIndex;
809 
810     // See dwKeySpec constants
811     IN DWORD  dwKeySpec;
812 
813     // If CARD_BUFFER_SIZE_ONLY flag is present then the card
814     // module should return only the size of the resulting
815     // key in cbSignedData
816     IN DWORD  dwSigningFlags;
817 
818     // If the aiHashAlg is non zero, then it specifies the algorithm
819     // to use when padding the data using PKCS
820     IN ALG_ID aiHashAlg;
821 
822     // This is the buffer and length that the caller expects to be signed.
823     // Signed version is allocated a buffer and put in cb/pbSignedData.  That should
824     // be freed using PFN_CSP_FREE callback.
825     IN PBYTE  pbData;
826     IN DWORD  cbData;
827 
828     OUT PBYTE  pbSignedData;
829     OUT DWORD  cbSignedData;
830 
831     // The following parameters are new in version 2 of the
832     // CARD_SIGNING_INFO structure.
833     // If CARD_PADDING_INFO_PRESENT is set in dwSigningFlags then
834     // pPaddingInfo will point to the BCRYPT_PADDING_INFO structure
835     // defined by dwPaddingType.  Currently supported values are
836     // CARD_PADDING_PKCS1, CARD_PADDING_PSS and CARD_PADDING_NONE
837     IN LPVOID pPaddingInfo;
838     IN DWORD  dwPaddingType;
839 } CARD_SIGNING_INFO, *PCARD_SIGNING_INFO;
840 
841 typedef DWORD (WINAPI *PFN_CARD_SIGN_DATA)(
842     __in      PCARD_DATA          pCardData,
843     __in      PCARD_SIGNING_INFO  pInfo);
844 
845 DWORD
846 WINAPI
847 CardSignData(
848     __in      PCARD_DATA          pCardData,
849     __in      PCARD_SIGNING_INFO  pInfo);
850 
851 //
852 // Type: CARD_DH_AGREEMENT_INFO
853 //
854 // CARD_DH_AGREEMENT_INFO version 1 is no longer supported and should
855 // not be implemented
856 //
857 
858 #define CARD_DH_AGREEMENT_INFO_VERSION 2
859 
860 typedef struct _CARD_DH_AGREEMENT_INFO
861 {
862     IN  DWORD dwVersion;
863     IN  BYTE  bContainerIndex;
864     IN  DWORD dwFlags;
865     IN  DWORD dwPublicKey;
866     IN  PBYTE pbPublicKey;
867     IN  PBYTE pbReserved;
868     IN  DWORD cbReserved;
869 
870     OUT BYTE bSecretAgreementIndex;
871 } CARD_DH_AGREEMENT_INFO, *PCARD_DH_AGREEMENT_INFO;
872 
873 //
874 // Function:  CardConstructDHAgreement
875 //
876 // Purpose: compute a DH secret agreement from a ECDH key on the card
877 // and the public portion of another ECDH key
878 //
879 
880 typedef DWORD (WINAPI *PFN_CARD_CONSTRUCT_DH_AGREEMENT)(
881     __in     PCARD_DATA pCardData,
882     __in     PCARD_DH_AGREEMENT_INFO pAgreementInfo);
883 
884 DWORD WINAPI CardConstructDHAgreement(
885     __in     PCARD_DATA pCardData,
886     __in     PCARD_DH_AGREEMENT_INFO pAgreementInfo);
887 
888 //
889 // Type: CARD_DERIVE_KEY_INFO
890 //
891 #define CARD_DERIVE_KEY_VERSION 1
892 
893 typedef struct _CARD_DERIVE_KEY
894 {
895     IN  DWORD             dwVersion;
896 
897     // If CARD_BUFFER_SIZE_ONLY is passed then the card module
898     // should return only the size of the resulting key in
899     // cbDerivedKey
900     IN  DWORD             dwFlags;
901     IN  LPWSTR            pwszKDF;
902     IN  BYTE              bSecretAgreementIndex;
903 
904     IN  PVOID             pParameterList;
905 
906     OUT PBYTE             pbDerivedKey;
907     OUT DWORD             cbDerivedKey;
908 
909 } CARD_DERIVE_KEY, *PCARD_DERIVE_KEY;
910 
911 //
912 // Function:  CardDeriveKey
913 //
914 // Purpose: Generate a dervived session key using a generated agreed
915 // secret and various other parameters.
916 //
917 
918 typedef DWORD (WINAPI *PFN_CARD_DERIVE_KEY)(
919     __in     PCARD_DATA pCardData,
920     __in     PCARD_DERIVE_KEY pAgreementInfo);
921 
922 DWORD WINAPI CardDeriveKey(
923     __in     PCARD_DATA pCardData,
924     __in     PCARD_DERIVE_KEY pAgreementInfo);
925 
926 //
927 // Function:  CardDestroyAgreement
928 //
929 // Purpose: Force a deletion of the DH agreed secret.
930 //
931 
932 typedef DWORD (WINAPI *PFN_CARD_DESTROY_DH_AGREEMENT)(
933     __in PCARD_DATA pCardData,
934     __in BYTE       bSecretAgreementIndex,
935     __in DWORD      dwFlags);
936 
937 DWORD WINAPI CardDestroyDHAgreement(
938     __in PCARD_DATA pCardData,
939     __in BYTE       bSecretAgreementIndex,
940     __in DWORD      dwFlags);
941 
942 //
943 // Function:  CspGetDHAgreement
944 //
945 // Purpose: The CARD_DERIVE_KEY structure contains a list of parameters
946 // (pParameterList) which might contain a reference to one or more addition
947 // agreed secrets (KDF_NCRYPT_SECRET_HANDLE).  This callback is provided by
948 // the caller of CardDeriveKey and will translate the parameter into the
949 // on card agreed secret handle.
950 //
951 
952 typedef DWORD (WINAPI *PFN_CSP_GET_DH_AGREEMENT)(
953     IN  PCARD_DATA           pCardData,
954     IN  PVOID                hSecretAgreement,
955     OUT BYTE*                pbSecretAgreementIndex,
956     IN  DWORD                dwFlags);
957 
958 DWORD WINAPI CspGetDHAgreement(
959     __in  PCARD_DATA           pCardData,
960     __in  PVOID                hSecretAgreement,
961     __out BYTE*                pbSecretAgreementIndex,
962     __in  DWORD                dwFlags);
963 
964 //
965 // Memory Management Routines
966 //
967 // These routines are supplied to the card module
968 // by the calling CSP.
969 //
970 
971 //
972 // Function: PFN_CSP_ALLOC
973 //
974 typedef LPVOID (WINAPI *PFN_CSP_ALLOC)(
975     IN      SIZE_T      Size);
976 
977 //
978 // Function: PFN_CSP_REALLOC
979 //
980 typedef LPVOID (WINAPI *PFN_CSP_REALLOC)(
981     IN      LPVOID      Address,
982     IN      SIZE_T      Size);
983 
984 //
985 // Function: PFN_CSP_FREE
986 //
987 // Note: Data allocated for the CSP by the card module must
988 //       be freed by the CSP.
989 //
990 typedef void (WINAPI *PFN_CSP_FREE)(
991     IN      LPVOID      Address);
992 
993 //
994 // Function: PFN_CSP_CACHE_ADD_FILE
995 //
996 // A copy of the pbData parameter is added to the cache.
997 //
998 typedef DWORD (WINAPI *PFN_CSP_CACHE_ADD_FILE)(
999     IN      PVOID       pvCacheContext,
1000     IN      LPWSTR      wszTag,
1001     IN      DWORD       dwFlags,
1002     IN      PBYTE       pbData,
1003     IN      DWORD       cbData);
1004 
1005 //
1006 // Function: PFN_CSP_CACHE_LOOKUP_FILE
1007 //
1008 // If the cache lookup is successful,
1009 // the caller must free the *ppbData pointer with pfnCspFree.
1010 //
1011 typedef DWORD (WINAPI *PFN_CSP_CACHE_LOOKUP_FILE)(
1012     IN      PVOID       pvCacheContext,
1013     IN      LPWSTR      wszTag,
1014     IN      DWORD       dwFlags,
1015     IN      PBYTE      *ppbData,
1016     IN      PDWORD      pcbData);
1017 
1018 //
1019 // Function: PFN_CSP_CACHE_DELETE_FILE
1020 //
1021 // Deletes the specified item from the cache.
1022 //
1023 typedef DWORD (WINAPI *PFN_CSP_CACHE_DELETE_FILE)(
1024     IN      PVOID       pvCacheContext,
1025     IN      LPWSTR      wszTag,
1026     IN      DWORD       dwFlags);
1027 
1028 //
1029 // Function: PFN_CSP_PAD_DATA
1030 //
1031 // Deletes Callback to pad buffer for cyrpto operation.  Used when
1032 // the card does not provide this.
1033 //
1034 typedef DWORD (WINAPI *PFN_CSP_PAD_DATA)(
1035     IN      PCARD_SIGNING_INFO pSigningInfo,
1036     IN      DWORD              cbMaxWidth,
1037     OUT     DWORD*             pcbPaddedBuffer,
1038     OUT     PBYTE*             ppbPaddedBuffer);
1039 
1040 // ****************
1041 // PIN SUPPORT
1042 // ****************
1043 
1044 //
1045 // There are 8 PINs currently defined in version 6. PIN values 0, 1 and 2 are
1046 // reserved for backwards compatibility, whereas PIN values 3-7 can be used
1047 // as additional PINs to protect key containers.
1048 //
1049 
1050 typedef     DWORD                       PIN_ID, *PPIN_ID;
1051 typedef     DWORD                       PIN_SET, *PPIN_SET;
1052 
1053 #define     MAX_PINS                    8
1054 
1055 #define     ROLE_EVERYONE               0
1056 #define     ROLE_USER                   1
1057 #define     ROLE_ADMIN                  2
1058 
1059 #define     PIN_SET_ALL_ROLES           0xFF
1060 #define     CREATE_PIN_SET(PinId)       (1 << PinId)
1061 #define     SET_PIN(PinSet, PinId)      PinSet |= CREATE_PIN_SET(PinId)
1062 #define     IS_PIN_SET(PinSet, PinId)   (0 != (PinSet & CREATE_PIN_SET(PinId)))
1063 #define     CLEAR_PIN(PinSet, PinId)    PinSet &= ~CREATE_PIN_SET(PinId)
1064 
1065 #define     PIN_CHANGE_FLAG_UNBLOCK     0x01
1066 #define     PIN_CHANGE_FLAG_CHANGEPIN   0x02
1067 
1068 #define     CP_CACHE_MODE_GLOBAL_CACHE  1
1069 #define     CP_CACHE_MODE_SESSION_ONLY  2
1070 #define     CP_CACHE_MODE_NO_CACHE      3
1071 
1072 #define     CARD_AUTHENTICATE_GENERATE_SESSION_PIN      0x10000000
1073 #define     CARD_AUTHENTICATE_SESSION_PIN               0x20000000
1074 
1075 #define     CARD_PIN_STRENGTH_PLAINTEXT                 0x1
1076 #define     CARD_PIN_STRENGTH_SESSION_PIN               0x2
1077 
1078 #define     CARD_PIN_SILENT_CONTEXT                     0x00000040
1079 
1080 typedef enum
1081 {
1082     AlphaNumericPinType = 0,            // Regular PIN
1083     ExternalPinType,                    // Biometric PIN
1084     ChallengeResponsePinType,           // Challenge/Response PIN
1085     EmptyPinType                        // No PIN
1086 } SECRET_TYPE;
1087 
1088 typedef enum
1089 {
1090     AuthenticationPin,                  // Authentication PIN
1091     DigitalSignaturePin,                // Digital Signature PIN
1092     EncryptionPin,                      // Encryption PIN
1093     NonRepudiationPin,                  // Non Repudiation PIN
1094     AdministratorPin,                   // Administrator PIN
1095     PrimaryCardPin                      // Primary Card PIN
1096 } SECRET_PURPOSE;
1097 
1098 typedef enum
1099 {
1100     PinCacheNormal = 0,
1101     PinCacheTimed,
1102     PinCacheNone
1103 } PIN_CACHE_POLICY_TYPE;
1104 
1105 #define      PIN_CACHE_POLICY_CURRENT_VERSION     6
1106 
1107 typedef struct _PIN_CACHE_POLICY
1108 {
1109     IN OUT  DWORD                                 dwVersion;
1110     OUT     PIN_CACHE_POLICY_TYPE                 PinCachePolicyType;
1111     OUT     DWORD                                 dwPinCachePolicyInfo;
1112 } PIN_CACHE_POLICY, *PPIN_CACHE_POLICY;
1113 
1114 #define      PIN_INFO_CURRENT_VERSION             6
1115 
1116 #define      PIN_INFO_REQUIRE_SECURE_ENTRY        1
1117 
1118 typedef struct _PIN_INFO
1119 {
1120     IN OUT  DWORD                                 dwVersion;
1121     OUT     SECRET_TYPE                           PinType;
1122     OUT     SECRET_PURPOSE                        PinPurpose;
1123     OUT     PIN_SET                               dwChangePermission;
1124     OUT     PIN_SET                               dwUnblockPermission;
1125     OUT     PIN_CACHE_POLICY                      PinCachePolicy;
1126     OUT     DWORD                                 dwFlags;
1127 } PIN_INFO, *PPIN_INFO;
1128 
1129 typedef DWORD (WINAPI *PFN_CARD_GET_CHALLENGE_EX)(
1130     __in                                PCARD_DATA  pCardData,
1131     __in                                PIN_ID      PinId,
1132     __out_bcount(*pcbChallengeData)     PBYTE       *ppbChallengeData,
1133     __out                               PDWORD      pcbChallengeData,
1134     __in                                DWORD       dwFlags);
1135 
1136 DWORD
1137 WINAPI
1138 CardGetChallengeEx(
1139     __in                                  PCARD_DATA pCardData,
1140     __in                                  PIN_ID     PinId,
1141     __deref_out_bcount(*pcbChallengeData) PBYTE     *ppbChallengeData,
1142     __out                                 PDWORD     pcbChallengeData,
1143     __in                                  DWORD      dwFlags);
1144 
1145 typedef DWORD (WINAPI *PFN_CARD_AUTHENTICATE_EX)(
1146     __in   PCARD_DATA                             pCardData,
1147     __in   PIN_ID                                 PinId,
1148     __in   DWORD                                  dwFlags,
1149     __in_bcount(cbPinData)   PBYTE                pbPinData,
1150     __in   DWORD                                  cbPinData,
1151     __deref_out_bcount_opt(*pcbSessionPin) PBYTE  *ppbSessionPin,
1152     __out_opt PDWORD                              pcbSessionPin,
1153     __out_opt PDWORD                              pcAttemptsRemaining);
1154 
1155 DWORD
1156 WINAPI
1157 CardAuthenticateEx(
1158     __in   PCARD_DATA                             pCardData,
1159     __in   PIN_ID                                 PinId,
1160     __in   DWORD                                  dwFlags,
1161     __in   PBYTE                                  pbPinData,
1162     __in   DWORD                                  cbPinData,
1163     __deref_out_bcount_opt(*pcbSessionPin) PBYTE  *ppbSessionPin,
1164     __out_opt PDWORD                              pcbSessionPin,
1165     __out_opt PDWORD                              pcAttemptsRemaining);
1166 
1167 typedef DWORD (WINAPI *PFN_CARD_CHANGE_AUTHENTICATOR_EX)(
1168     __in   PCARD_DATA                             pCardData,
1169     __in   DWORD                                  dwFlags,
1170     __in   PIN_ID                                 dwAuthenticatingPinId,
1171     __in_bcount(cbAuthenticatingPinData) PBYTE    pbAuthenticatingPinData,
1172     __in   DWORD                                  cbAuthenticatingPinData,
1173     __in   PIN_ID                                 dwTargetPinId,
1174     __in_bcount(cbTargetData)            PBYTE    pbTargetData,
1175     __in   DWORD                                  cbTargetData,
1176     __in   DWORD                                  cRetryCount,
1177     __out_opt PDWORD                              pcAttemptsRemaining);
1178 
1179 DWORD WINAPI CardChangeAuthenticatorEx(
1180     __in   PCARD_DATA                             pCardData,
1181     __in   DWORD                                  dwFlags,
1182     __in   PIN_ID                                 dwAuthenticatingPinId,
1183     __in_bcount(cbAuthenticatingPinData) PBYTE    pbAuthenticatingPinData,
1184     __in   DWORD                                  cbAuthenticatingPinData,
1185     __in   PIN_ID                                 dwTargetPinId,
1186     __in_bcount(cbTargetData)            PBYTE    pbTargetData,
1187     __in   DWORD                                  cbTargetData,
1188     __in   DWORD                                  cRetryCount,
1189     __out_opt PDWORD                              pcAttemptsRemaining);
1190 
1191 typedef DWORD (WINAPI *PFN_CARD_DEAUTHENTICATE_EX)(
1192     __in   PCARD_DATA                             pCardData,
1193     __in   PIN_SET                                PinId,
1194     __in   DWORD                                  dwFlags);
1195 
1196 DWORD WINAPI CardDeauthenticateEx(
1197     __in   PCARD_DATA                             pCardData,
1198     __in   PIN_SET                                PinId,
1199     __in   DWORD                                  dwFlags);
1200 
1201 // *******************
1202 // Container Porperties
1203 // *******************
1204 
1205 #define CCP_CONTAINER_INFO             L"Container Info" // Read only
1206 #define CCP_PIN_IDENTIFIER             L"PIN Identifier"
1207 
1208 typedef DWORD (WINAPI *PFN_CARD_GET_CONTAINER_PROPERTY)(
1209     __in   PCARD_DATA                                 pCardData,
1210     __in   BYTE                                       bContainerIndex,
1211     __in   LPCWSTR                                    wszProperty,
1212     __out_bcount_part_opt(cbData, *pdwDataLen) PBYTE  pbData,
1213     __in   DWORD                                      cbData,
1214     __out  PDWORD                                     pdwDataLen,
1215     __in   DWORD                                      dwFlags);
1216 
1217 DWORD WINAPI CardGetContainerProperty(
1218     __in   PCARD_DATA                                 pCardData,
1219     __in   BYTE                                       bContainerIndex,
1220     __in   LPCWSTR                                    wszProperty,
1221     __out_bcount_part_opt(cbData, *pdwDataLen) PBYTE  pbData,
1222     __in   DWORD                                      cbData,
1223     __out  PDWORD                                     pdwDataLen,
1224     __in   DWORD                                      dwFlags);
1225 
1226 typedef DWORD (WINAPI *PFN_CARD_SET_CONTAINER_PROPERTY)(
1227     __in   PCARD_DATA                                 pCardData,
1228     __in   BYTE                                       bContainerIndex,
1229     __in   LPCWSTR                                    wszProperty,
1230     __in_bcount(cbDataLen)  PBYTE                     pbData,
1231     __in   DWORD                                      cbDataLen,
1232     __in   DWORD                                      dwFlags);
1233 
1234 DWORD WINAPI CardSetContainerProperty(
1235     __in   PCARD_DATA                                 pCardData,
1236     __in   BYTE                                       bContainerIndex,
1237     __in   LPCWSTR                                    wszProperty,
1238     __in_bcount(cbDataLen)  PBYTE                     pbData,
1239     __in   DWORD                                      cbDataLen,
1240     __in   DWORD                                      dwFlags);
1241 
1242 // *******************
1243 // Card Properties
1244 // *******************
1245 
1246 #define CP_CARD_FREE_SPACE              L"Free Space"              // Read only
1247 #define CP_CARD_CAPABILITIES            L"Capabilities"            // Read only
1248 #define CP_CARD_KEYSIZES                L"Key Sizes"               // Read only
1249 
1250 #define CP_CARD_READ_ONLY               L"Read Only Mode"
1251 #define CP_CARD_CACHE_MODE              L"Cache Mode"
1252 #define CP_SUPPORTS_WIN_X509_ENROLLMENT L"Supports Windows x.509 Enrollment"
1253 
1254 #define CP_CARD_GUID                    L"Card Identifier"
1255 #define CP_CARD_SERIAL_NO               L"Card Serial Number"
1256 
1257 #define CP_CARD_PIN_INFO                L"PIN Information"
1258 #define CP_CARD_LIST_PINS               L"PIN List"                // Read only
1259 #define CP_CARD_AUTHENTICATED_STATE     L"Authenticated State"     // Read only
1260 
1261 #define CP_CARD_PIN_STRENGTH_VERIFY     L"PIN Strength Verify"     // Read only
1262 #define CP_CARD_PIN_STRENGTH_CHANGE     L"PIN Strength Change"     // Read only
1263 #define CP_CARD_PIN_STRENGTH_UNBLOCK    L"PIN Strength Unblock"    // Read only
1264 
1265 #define CP_PARENT_WINDOW                L"Parent Window"           // Write only
1266 #define CP_PIN_CONTEXT_STRING           L"PIN Context String"      // Write only
1267 
1268 typedef DWORD (WINAPI *PFN_CARD_GET_PROPERTY)(
1269     __in   PCARD_DATA                                 pCardData,
1270     __in   LPCWSTR                                    wszProperty,
1271     __out_bcount_part_opt(cbData, *pdwDataLen) PBYTE  pbData,
1272     __in   DWORD                                      cbData,
1273     __out PDWORD                                      pdwDataLen,
1274     __in   DWORD                                      dwFlags);
1275 
1276 DWORD WINAPI CardGetProperty(
1277     __in   PCARD_DATA                                 pCardData,
1278     __in   LPCWSTR                                    wszProperty,
1279     __out_bcount_part_opt(cbData, *pdwDataLen) PBYTE  pbData,
1280     __in   DWORD                                      cbData,
1281     __out  PDWORD                                     pdwDataLen,
1282     __in   DWORD                                      dwFlags);
1283 
1284 typedef DWORD (WINAPI *PFN_CARD_SET_PROPERTY)(
1285     __in   PCARD_DATA                                 pCardData,
1286     __in   LPCWSTR                                    wszProperty,
1287     __in_bcount(cbDataLen)  PBYTE                     pbData,
1288     __in   DWORD                                      cbDataLen,
1289     __in   DWORD                                      dwFlags);
1290 
1291 DWORD WINAPI CardSetProperty(
1292     __in   PCARD_DATA                                 pCardData,
1293     __in   LPCWSTR                                    wszProperty,
1294     __in_bcount(cbDataLen)  PBYTE                     pbData,
1295     __in   DWORD                                      cbDataLen,
1296     __in   DWORD                                      dwFlags);
1297 
1298 //
1299 // Type: CARD_DATA
1300 //
1301 
1302 #define CARD_DATA_VERSION_SIX   6
1303 
1304 // This version supports new features such as a designed
1305 // CardSecretAgreement and key derivation functions.  Also
1306 // added is the PKCS#1 2.1 (PSS) padding format.
1307 #define CARD_DATA_VERSION_FIVE  5
1308 
1309 // This is the minimum version currently supported.  Those
1310 // applications that require basic RSA crypto functionality
1311 // and file operations should use this version
1312 #define CARD_DATA_VERSION_FOUR  4
1313 
1314 // For those apps, that want the maximum version available, use
1315 // CARD_DATA_CURRENT_VERSION.  Otherwise applications should
1316 // target a specific version that includes the functionality
1317 // that they require.
1318 #define CARD_DATA_CURRENT_VERSION CARD_DATA_VERSION_SIX
1319 
1320 typedef struct _CARD_DATA
1321 {
1322     // These members must be initialized by the CSP/KSP before
1323     // calling CardAcquireContext.
1324 
1325     DWORD                               dwVersion;
1326 
1327     PBYTE                               pbAtr;
1328     DWORD                               cbAtr;
1329     LPWSTR                              pwszCardName;
1330 
1331     PFN_CSP_ALLOC                       pfnCspAlloc;
1332     PFN_CSP_REALLOC                     pfnCspReAlloc;
1333     PFN_CSP_FREE                        pfnCspFree;
1334 
1335     PFN_CSP_CACHE_ADD_FILE              pfnCspCacheAddFile;
1336     PFN_CSP_CACHE_LOOKUP_FILE           pfnCspCacheLookupFile;
1337     PFN_CSP_CACHE_DELETE_FILE           pfnCspCacheDeleteFile;
1338     PVOID                               pvCacheContext;
1339 
1340     PFN_CSP_PAD_DATA                    pfnCspPadData;
1341 
1342     SCARDCONTEXT                        hSCardCtx;
1343     SCARDHANDLE                         hScard;
1344 
1345     // pointer to vendor specific information
1346 
1347     PVOID                               pvVendorSpecific;
1348 
1349     // These members are initialized by the card module
1350 
1351     PFN_CARD_DELETE_CONTEXT             pfnCardDeleteContext;
1352     PFN_CARD_QUERY_CAPABILITIES         pfnCardQueryCapabilities;
1353     PFN_CARD_DELETE_CONTAINER           pfnCardDeleteContainer;
1354     PFN_CARD_CREATE_CONTAINER           pfnCardCreateContainer;
1355     PFN_CARD_GET_CONTAINER_INFO         pfnCardGetContainerInfo;
1356     PFN_CARD_AUTHENTICATE_PIN           pfnCardAuthenticatePin;
1357     PFN_CARD_GET_CHALLENGE              pfnCardGetChallenge;
1358     PFN_CARD_AUTHENTICATE_CHALLENGE     pfnCardAuthenticateChallenge;
1359     PFN_CARD_UNBLOCK_PIN                pfnCardUnblockPin;
1360     PFN_CARD_CHANGE_AUTHENTICATOR       pfnCardChangeAuthenticator;
1361     PFN_CARD_DEAUTHENTICATE             pfnCardDeauthenticate;
1362     PFN_CARD_CREATE_DIRECTORY           pfnCardCreateDirectory;
1363     PFN_CARD_DELETE_DIRECTORY           pfnCardDeleteDirectory;
1364     LPVOID                              pvUnused3;
1365     LPVOID                              pvUnused4;
1366     PFN_CARD_CREATE_FILE                pfnCardCreateFile;
1367     PFN_CARD_READ_FILE                  pfnCardReadFile;
1368     PFN_CARD_WRITE_FILE                 pfnCardWriteFile;
1369     PFN_CARD_DELETE_FILE                pfnCardDeleteFile;
1370     PFN_CARD_ENUM_FILES                 pfnCardEnumFiles;
1371     PFN_CARD_GET_FILE_INFO              pfnCardGetFileInfo;
1372     PFN_CARD_QUERY_FREE_SPACE           pfnCardQueryFreeSpace;
1373     PFN_CARD_QUERY_KEY_SIZES            pfnCardQueryKeySizes;
1374 
1375     PFN_CARD_SIGN_DATA                  pfnCardSignData;
1376     PFN_CARD_RSA_DECRYPT                pfnCardRSADecrypt;
1377     PFN_CARD_CONSTRUCT_DH_AGREEMENT     pfnCardConstructDHAgreement;
1378 
1379     // New functions in version five.
1380     PFN_CARD_DERIVE_KEY                 pfnCardDeriveKey;
1381     PFN_CARD_DESTROY_DH_AGREEMENT       pfnCardDestroyDHAgreement;
1382     PFN_CSP_GET_DH_AGREEMENT            pfnCspGetDHAgreement;
1383 
1384     // version 6 additions below here
1385     PFN_CARD_GET_CHALLENGE_EX           pfnCardGetChallengeEx;
1386     PFN_CARD_AUTHENTICATE_EX            pfnCardAuthenticateEx;
1387     PFN_CARD_CHANGE_AUTHENTICATOR_EX    pfnCardChangeAuthenticatorEx;
1388     PFN_CARD_DEAUTHENTICATE_EX          pfnCardDeauthenticateEx;
1389     PFN_CARD_GET_CONTAINER_PROPERTY     pfnCardGetContainerProperty;
1390     PFN_CARD_SET_CONTAINER_PROPERTY     pfnCardSetContainerProperty;
1391     PFN_CARD_GET_PROPERTY               pfnCardGetProperty;
1392     PFN_CARD_SET_PROPERTY               pfnCardSetProperty;
1393 
1394 } CARD_DATA, *PCARD_DATA;
1395 
1396 #endif
1397 
1398