source: OpenSC/src/minidriver/minidriver.c @ f0ab932

Revision f0ab932, 62.7 KB checked in by vtarasov <vtarasov@…>, 12 months ago (diff)

minidriver: 'PinObject?-info' data type is changed for the 'AuthenticatioObject?-info' data type

git-svn-id:  https://www.opensc-project.org/svnp/opensc/trunk@5554 c6295689-39f2-0310-b995-f0e70906c6a9

  • Property mode set to 100644
Line 
1/*
2 * minidriver.c: OpenSC minidriver
3 *
4 * Copyright (C) 2009,2010 francois.leblanc@cev-sa.com
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21/*
22 * This module requires "cardmod.h" from CNG SDK or platform SDK to build.
23 */
24
25#include "config.h"
26#ifdef ENABLE_MINIDRIVER
27
28#ifdef _MANAGED
29#pragma managed(push, off)
30#endif
31
32#include <stdio.h>
33#include <stdlib.h>
34
35#include <windows.h>
36#include "cardmod.h"
37
38#include "libopensc/cardctl.h"
39#include "libopensc/opensc.h"
40#include "libopensc/pkcs15.h"
41#include "libopensc/log.h"
42#include "libopensc/internal.h"
43
44#if defined(__MINGW32__)
45/* Part of the build svn project in the include directory */
46#include "cardmod-mingw-compat.h"
47#endif
48
49#define NULLSTR(a) (a == NULL ? "<NULL>" : a)
50#define NULLWSTR(a) (a == NULL ? L"<NULL>" : a)
51
52/* if use of internal-winscard.h */
53#ifndef SCARD_E_INVALID_PARAMETER
54#define SCARD_E_INVALID_PARAMETER               0x80100004L
55#define SCARD_E_UNSUPPORTED_FEATURE             0x80100022L
56#define SCARD_E_NO_MEMORY                               0x80100006L
57#define SCARD_W_WRONG_CHV                               0x8010006BL
58#define SCARD_E_FILE_NOT_FOUND                  0x80100024L
59#define SCARD_E_UNKNOWN_CARD                    0x8010000DL
60#define SCARD_F_UNKNOWN_ERROR                   0x80100014L
61#endif
62
63typedef struct _VENDOR_SPECIFIC
64{
65        char *pin;
66
67        sc_pkcs15_object_t *cert_objs[32];
68        int cert_count;
69        sc_pkcs15_object_t *prkey_objs[32];
70        int prkey_count;
71        sc_pkcs15_object_t *pin_objs[8];
72        int pin_count;
73
74        sc_context_t *ctx;
75        sc_reader_t *reader;
76        sc_card_t *card;
77        sc_pkcs15_card_t *p15card;
78
79        sc_pkcs15_object_t *pkey;
80
81        struct {
82                BYTE file_appdir[9];
83                CARD_CACHE_FILE_FORMAT file_cardcf;
84                BYTE file_cardid[16];
85        }cardFiles;
86        SCARDCONTEXT hSCardCtx;
87        SCARDHANDLE hScard;
88
89}VENDOR_SPECIFIC;
90
91static int associate_card(PCARD_DATA pCardData);
92static int disassociate_card(PCARD_DATA pCardData);
93
94static void logprintf(PCARD_DATA pCardData, int level, const char* format, ...)
95{
96        va_list arg;
97        VENDOR_SPECIFIC *vs;
98/* #define CARDMOD_LOW_LEVEL_DEBUG 1 */
99#ifdef CARDMOD_LOW_LEVEL_DEBUG
100/* Use a simplied log to get all messages including messages
101 * before opensc is loaded. The file must be modifiable by all
102 * users as we maybe called under lsa or user. Note data from
103 * multiple process and threads may get intermingled.
104 * flush to get last message before ann crash
105 * close so as the file is not left open during any wait.
106 */
107        {
108                FILE* lldebugfp = NULL;
109
110                lldebugfp = fopen("C:\\tmp\\cardmod.log.txt","ab");
111                if (lldebugfp != NULL) {
112                        va_start(arg, format);
113                        vfprintf(lldebugfp, format, arg);
114                        va_end(arg);
115                        fflush(lldebugfp);
116                        fclose(lldebugfp);
117                        lldebugfp = NULL;
118                }
119        return;
120        }
121#endif
122
123        va_start(arg, format);
124        if(pCardData != NULL)
125        {
126                vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
127                if(vs != NULL && vs->ctx != NULL)
128                {
129#ifdef _MSC_VER
130                        sc_do_log_noframe(vs->ctx, level, format, arg);
131#else
132                        /* FIXME: trouble in vsprintf with %S arg under
133                        mingw32
134                        */
135                        if(vs->ctx->debug>=level) {
136                                vfprintf(vs->ctx->debug_file, format, arg);
137                        }
138#endif
139                }
140        }
141        va_end(arg);
142}
143
144static void loghex(PCARD_DATA pCardData, int level, PBYTE data, int len)
145{
146        char line[74];
147        char *c;
148        int i, a;
149        unsigned char * p;
150
151        logprintf(pCardData, level, "--- %p:%d\n", data, len);
152
153        if (data == NULL || len <= 0) return;
154
155        p = data;
156        c = line;
157        i = 0;
158        a = 0;
159        memset(line, 0, sizeof(line));
160
161        while(i < len) {
162                sprintf(c,"%02X", *p);
163                p++;
164                c += 2;
165                i++;
166                if (i%32 == 0) {
167                        logprintf(pCardData, level, " %04X  %s\n", a, line);
168                        a +=32;
169                        memset(line, 0, sizeof(line));
170                        c = line;
171                } else {
172                        if (i%4 == 0) *(c++) = ' ';
173                        if (i%16 == 0) *(c++) = ' ';
174                }
175        }
176        if (i%32 != 0)
177                logprintf(pCardData, level, " %04X  %s\n", a, line);
178}
179
180static void print_werror(PCARD_DATA pCardData, char *str)
181{
182        void *buf;
183        FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
184          FORMAT_MESSAGE_FROM_SYSTEM |
185          FORMAT_MESSAGE_IGNORE_INSERTS,
186          NULL,GetLastError(),0,
187          (LPTSTR) &buf,0,NULL);
188
189        logprintf(pCardData, 0, "%s%s\n", str, buf);
190        LocalFree(buf);
191}
192
193/*
194 * check if the card has been removed, or the
195 * caller has changed the handles.
196 * if so, then free up all previous card info
197 * and reestablish
198 */
199static int check_reader_status(PCARD_DATA pCardData) {
200
201        int r;
202        VENDOR_SPECIFIC *vs = NULL;
203
204        logprintf(pCardData, 4, "check_reader_status\n");
205
206        if(!pCardData)
207                return SCARD_E_INVALID_PARAMETER;
208
209        vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
210        if(!vs)
211                return SCARD_E_INVALID_PARAMETER;
212
213        logprintf(pCardData, 7, "pCardData->hSCardCtx:0x%08X hScard:0x%08X\n",
214                        pCardData->hSCardCtx, pCardData->hScard);
215
216        if (pCardData->hSCardCtx != vs->hSCardCtx
217                                || pCardData->hScard != vs->hScard) {
218                        logprintf (pCardData, 1, "HANDLES CHANGED from 0x%08X 0x%08X\n", vs->hSCardCtx, vs->hScard);
219
220                         r = disassociate_card(pCardData);
221                         logprintf(pCardData, 1, "disassociate_card r = 0x%08X\n");
222                         r = associate_card(pCardData); /* need to check return codes */
223                         logprintf(pCardData, 1, "associate_card r = 0x%08X\n");
224        } else
225
226        /* This should always work, as BaseCSP should be checking for removal too */
227        if (vs->reader) {
228                r = sc_detect_card_presence(vs->reader);
229                logprintf(pCardData, 2, "check_reader_status r=%d flags 0x%08X\n",
230                        r, vs->reader->flags);
231        }
232        return SCARD_S_SUCCESS;
233}
234
235
236/*
237 * Compute modulus length
238 */
239static size_t compute_keybits(sc_pkcs15_bignum_t *bn)
240{
241        unsigned int mask, bits;
242
243        if (!bn || !bn->len)
244                return 0;
245        bits = bn->len << 3;
246        for (mask = 0x80; !(bn->data[0] & mask); mask >>= 1)
247                bits--;
248        return bits;
249}
250
251
252static int get_pin_by_role(PCARD_DATA pCardData, PIN_ID role, struct sc_pkcs15_object **ret_obj)
253{
254        VENDOR_SPECIFIC *vs;
255        int i;
256
257        if (!pCardData)
258                return SCARD_E_INVALID_PARAMETER;
259
260        logprintf(pCardData, 2, "get PIN with role %i\n", role);
261
262        vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
263        if (vs->pin_count == 0)   {
264                logprintf(pCardData, 2, "cannot get PIN object: no PIN defined\n");
265                return SCARD_E_UNSUPPORTED_FEATURE;
266        }
267
268        if (!ret_obj)
269                return SCARD_E_INVALID_PARAMETER;
270
271        *ret_obj = NULL;
272
273        for(i = 0; i < vs->pin_count; i++)
274        {
275                struct sc_pkcs15_object *obj = vs->pin_objs[i];
276                struct sc_pkcs15_auth_info *auth_info = (struct sc_pkcs15_auth_info *) (obj->data);
277                unsigned int pin_flags = auth_info->attrs.pin.flags;
278                unsigned int admin_pin_flags = SC_PKCS15_PIN_FLAG_UNBLOCKING_PIN | SC_PKCS15_PIN_FLAG_SO_PIN;
279
280                logprintf(pCardData, 2, "PIN[%s] flags 0x%X\n", obj->label, pin_flags);
281                if (role == ROLE_USER)   {
282                        if (!(pin_flags & admin_pin_flags))   {
283                                *ret_obj = obj;
284                                break;
285                        }
286                }
287                else if (role == ROLE_ADMIN)   {
288                        if (pin_flags & admin_pin_flags)   {
289                                *ret_obj = obj;
290                                break;
291                        }
292                }
293                else   {
294                        logprintf(pCardData, 2, "cannot get PIN object: unsupported role\n");
295                        return SCARD_E_UNSUPPORTED_FEATURE;
296                }
297        }
298
299        if (i == vs->pin_count)   {
300                logprintf(pCardData, 2, "cannot get PIN object: not found\n");
301                return SCARD_E_UNSUPPORTED_FEATURE;
302        }
303
304        return SCARD_S_SUCCESS;
305}
306
307static void dump_objects (PCARD_DATA pCardData)
308{
309        VENDOR_SPECIFIC *vs;
310        sc_pkcs15_prkey_info_t *prkey_info;
311        sc_pkcs15_cert_t *cert;
312        int i;
313
314        if (!pCardData)
315                return;
316
317        vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
318        if (!vs)
319                return;
320
321        for(i = 0; i < vs->prkey_count; i++)
322        {
323                prkey_info = (sc_pkcs15_prkey_info_t*)(vs->prkey_objs[i]->data);
324                logprintf(pCardData, 5, "prkey_info->subject %d (subject_len=%d)" \
325                        "modulus_length=%d subject ", i, prkey_info->subject.len, \
326                                prkey_info->modulus_length);
327                loghex(pCardData, 5, prkey_info->subject.value, prkey_info->subject.len);
328        }
329
330        for(i = 0; i < vs->cert_count; i++)
331        {
332                sc_pkcs15_read_certificate(vs->p15card, \
333                        (struct sc_pkcs15_cert_info *)(vs->cert_objs[i]->data), &cert);
334                logprintf(pCardData, 5, "cert->subject %d ", i);
335                loghex(pCardData, 5, cert->subject, cert->subject_len);
336                sc_pkcs15_free_certificate(cert);
337        }
338
339        for(i = 0; i < vs->pin_count; i++)
340        {
341                const char *pin_flags[] =
342                {
343                        "case-sensitive", "local", "change-disabled",
344                        "unblock-disabled", "initialized", "needs-padding",
345                        "unblockingPin", "soPin", "disable_allowed",
346                        "integrity-protected", "confidentiality-protected",
347                        "exchangeRefData"
348                };
349                const char *pin_types[] = {"bcd", "ascii-numeric", "UTF-8",
350                        "halfnibble bcd", "iso 9664-1"};
351                const struct sc_pkcs15_object *obj = vs->pin_objs[i];
352                const struct sc_pkcs15_auth_info *auth_info = (const struct sc_pkcs15_auth_info *) (obj->data);
353                const struct sc_pkcs15_pin_attributes *pin_attrs = &auth_info->attrs.pin;
354                const size_t pf_count = sizeof(pin_flags)/sizeof(pin_flags[0]);
355                size_t j;
356
357                logprintf(pCardData, 2, "PIN [%s]\n", obj->label);
358                logprintf(pCardData, 2, "\tCom. Flags: 0x%X\n", obj->flags);
359                logprintf(pCardData, 2, "\tID        : %s\n", sc_pkcs15_print_id(&auth_info->auth_id));
360                logprintf(pCardData, 2, "\tFlags     : [0x%02X]", pin_attrs->flags);
361                for (j = 0; j < pf_count; j++)
362                        if (pin_attrs->flags & (1 << j)) {
363                                logprintf(pCardData, 2, ", %s", pin_flags[j]);
364                        }
365                logprintf(pCardData, 2, "\n");
366                logprintf(pCardData, 2, "\tLength    : min_len:%lu, max_len:%lu, stored_len:%lu\n",
367                        (unsigned long)pin_attrs->min_length, (unsigned long)pin_attrs->max_length,
368                        (unsigned long)pin_attrs->stored_length);
369                logprintf(pCardData, 2, "\tPad char  : 0x%02X\n", pin_attrs->pad_char);
370                logprintf(pCardData, 2, "\tReference : %d\n", pin_attrs->reference);
371                if (pin_attrs->type < sizeof(pin_types)/sizeof(pin_types[0]))
372                        logprintf(pCardData, 2, "\tType      : %s\n", pin_types[pin_attrs->type]);
373                else
374                        logprintf(pCardData, 2, "\tType      : [encoding %d]\n", pin_attrs->type);
375                logprintf(pCardData, 2, "\tPath      : %s\n", sc_print_path(&auth_info->path));
376                if (auth_info->tries_left >= 0)
377                        logprintf(pCardData, 2, "\tTries left: %d\n", auth_info->tries_left);
378        }
379}
380
381
382DWORD WINAPI CardDeleteContext(__inout PCARD_DATA  pCardData)
383{
384        VENDOR_SPECIFIC *vs = NULL;
385
386        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
387        logprintf(pCardData, 1, "CardDeleteContext\n");
388
389        if(!pCardData)
390                return SCARD_E_INVALID_PARAMETER;
391
392        vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
393
394        if(!vs)
395                return SCARD_E_INVALID_PARAMETER;
396
397        disassociate_card(pCardData);
398
399        if(vs->ctx)
400        {
401                logprintf(pCardData, 6, "release context\n");
402                sc_release_context(vs->ctx);
403                vs->ctx = NULL;
404        }
405
406        logprintf(pCardData, 1, "***********************************" \
407                                        "***********************************\n");
408
409        pCardData->pfnCspFree(pCardData->pvVendorSpecific);
410        pCardData->pvVendorSpecific = NULL;
411
412        return SCARD_S_SUCCESS;
413}
414
415DWORD WINAPI CardQueryCapabilities(__in PCARD_DATA pCardData,
416        __in PCARD_CAPABILITIES  pCardCapabilities)
417{
418
419        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
420        logprintf(pCardData, 1, "pCardCapabilities=%X\n", pCardCapabilities);
421
422        if (!pCardData) return SCARD_E_INVALID_PARAMETER;
423        if (!pCardCapabilities) return SCARD_E_INVALID_PARAMETER;
424
425        if (pCardCapabilities->dwVersion != CARD_CAPABILITIES_CURRENT_VERSION
426                && pCardCapabilities->dwVersion != 0)
427                        return ERROR_REVISION_MISMATCH;
428
429        pCardCapabilities->dwVersion = CARD_CAPABILITIES_CURRENT_VERSION;
430        pCardCapabilities->fCertificateCompression = TRUE;
431        pCardCapabilities->fKeyGen = FALSE;
432
433        check_reader_status(pCardData);
434
435        return SCARD_S_SUCCESS;
436}
437
438DWORD WINAPI CardDeleteContainer(__in PCARD_DATA pCardData,
439        __in BYTE bContainerIndex,
440        __in DWORD dwReserved)
441{
442        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
443        logprintf(pCardData, 1, "CardDeleteContainer - unsupported\n");
444        return SCARD_E_UNSUPPORTED_FEATURE;
445}
446
447DWORD WINAPI CardCreateContainer(__in PCARD_DATA pCardData,
448        __in BYTE bContainerIndex,
449        __in DWORD dwFlags,
450        __in DWORD dwKeySpec,
451        __in DWORD dwKeySize,
452        __in PBYTE pbKeyData)
453{
454        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
455        logprintf(pCardData, 1, "CardCreateContainer - unsupported\n");
456        return SCARD_E_UNSUPPORTED_FEATURE;
457}
458
459typedef struct {
460        PUBLICKEYSTRUC  publickeystruc;
461        RSAPUBKEY rsapubkey;
462} PUBKEYSTRUCT_BASE;
463
464DWORD WINAPI CardGetContainerInfo(__in PCARD_DATA pCardData,
465        __in BYTE bContainerIndex,
466        __in DWORD dwFlags,
467        __in PCONTAINER_INFO pContainerInfo)
468{
469        int r;
470        sc_pkcs15_cert_t *cert = NULL;
471        VENDOR_SPECIFIC *vs = NULL;
472
473        PUBKEYSTRUCT_BASE *oh = NULL;
474        PUBKEYSTRUCT_BASE *oh2 = NULL;
475
476        DWORD sz = 0;
477        DWORD sz2 = 0;
478
479        DWORD ret;
480        sc_pkcs15_pubkey_t *pubkey = NULL;
481
482        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
483        logprintf(pCardData, 1, "CardGetContainerInfo bContainerIndex=%u, dwFlags=0x%08X, " \
484                "dwVersion=%u, cbSigPublicKey=%u, cbKeyExPublicKey=%u\n", \
485                bContainerIndex, dwFlags, pContainerInfo->dwVersion, \
486                pContainerInfo->cbSigPublicKey, pContainerInfo->cbKeyExPublicKey);
487
488        if(!pCardData) return SCARD_E_INVALID_PARAMETER;
489        if (!pContainerInfo) SCARD_E_INVALID_PARAMETER;
490        if (dwFlags) return SCARD_E_INVALID_PARAMETER;
491        if (pContainerInfo->dwVersion < 0
492                || pContainerInfo->dwVersion >  CONTAINER_INFO_CURRENT_VERSION)
493                        return ERROR_REVISION_MISMATCH;
494
495        vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
496
497        check_reader_status(pCardData);
498
499        if(bContainerIndex>=vs->cert_count)
500                return SCARD_E_INVALID_PARAMETER;
501
502        r = sc_pkcs15_read_certificate(vs->p15card, \
503                (struct sc_pkcs15_cert_info *)(vs->cert_objs[bContainerIndex]->data), \
504                &cert);
505        logprintf(pCardData, 1, "read_certificate %d return %d, cert = %p\n", \
506                bContainerIndex, r, cert);
507        if(r)
508        {
509                return SCARD_E_FILE_NOT_FOUND;
510        }
511        pubkey = cert->key;
512
513        if(pubkey->algorithm == SC_ALGORITHM_RSA)
514        {
515                int modulus = compute_keybits(&(pubkey->u.rsa.modulus));
516
517                PCCERT_CONTEXT cer = CertCreateCertificateContext(X509_ASN_ENCODING \
518                        | PKCS_7_ASN_ENCODING, cert->data, cert->data_len);
519                PCERT_PUBLIC_KEY_INFO pinf = \
520                        &(cer->pCertInfo->SubjectPublicKeyInfo);
521
522                sz = 0; /* get size */
523                CryptDecodeObject(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, \
524                RSA_CSP_PUBLICKEYBLOB, pinf->PublicKey.pbData, \
525                pinf->PublicKey.cbData , 0, oh, &sz);
526                sz2 = sz;
527
528                oh = (PUBKEYSTRUCT_BASE*)pCardData->pfnCspAlloc(sz);
529                oh2 = (PUBKEYSTRUCT_BASE*)pCardData->pfnCspAlloc(sz2);
530                if(oh && oh2)
531                {
532                        CryptDecodeObject(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, \
533                                RSA_CSP_PUBLICKEYBLOB, pinf->PublicKey.pbData, \
534                                pinf->PublicKey.cbData , 0, oh, &sz);
535
536                        oh->publickeystruc.aiKeyAlg = CALG_RSA_SIGN;
537                        pContainerInfo->cbSigPublicKey = sz;
538                        pContainerInfo->pbSigPublicKey = (PBYTE)oh;
539
540                        CryptDecodeObject(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, \
541                                RSA_CSP_PUBLICKEYBLOB, pinf->PublicKey.pbData, \
542                                pinf->PublicKey.cbData , 0, oh2, &sz2);
543
544                        oh2->publickeystruc.aiKeyAlg = CALG_RSA_KEYX;
545                        pContainerInfo->cbKeyExPublicKey = sz2;
546                        pContainerInfo->pbKeyExPublicKey = (PBYTE)oh2;
547
548                        pContainerInfo->dwVersion = CONTAINER_INFO_CURRENT_VERSION;
549
550                        logprintf(pCardData, 3, "return info on SIGN_CONTAINER_INDEX\n");
551                        ret = SCARD_S_SUCCESS;
552                }
553                else
554                {
555                        ret = SCARD_E_NO_MEMORY;
556                }
557        }
558
559        if(cert)
560        {
561                sc_pkcs15_free_certificate(cert);
562        }
563
564        return ret;
565}
566
567DWORD WINAPI CardAuthenticatePin(__in PCARD_DATA pCardData,
568        __in LPWSTR pwszUserId,
569        __in PBYTE pbPin,
570        __in DWORD cbPin,
571        __out_opt PDWORD pcAttemptsRemaining)
572{
573        int r;
574        sc_pkcs15_object_t *pin_obj;
575        char type[256];
576        VENDOR_SPECIFIC *vs;
577
578        if(!pCardData) return SCARD_E_INVALID_PARAMETER;
579
580        vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
581
582        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
583        logprintf(pCardData, 1, "CardAuthenticatePin %S %d %d\n", NULLWSTR(pwszUserId), \
584                cbPin, vs->cardFiles.file_cardcf.bPinsFreshness);
585
586        check_reader_status(pCardData);
587
588        if (NULL == pwszUserId) return SCARD_E_INVALID_PARAMETER;
589        if (wcscmp(wszCARD_USER_USER,pwszUserId) != 0 && \
590                wcscmp(wszCARD_USER_ADMIN,pwszUserId) != 0) \
591                        return SCARD_E_INVALID_PARAMETER;
592        if (NULL == pbPin) return SCARD_E_INVALID_PARAMETER;
593
594        if (cbPin < 4 || cbPin > 12) return SCARD_W_WRONG_CHV;
595
596        if (wcscmp(wszCARD_USER_ADMIN,pwszUserId) == 0)
597        {
598                return SCARD_W_WRONG_CHV;
599        }
600
601        wcstombs(type, pwszUserId, 100);
602        type[10] = 0;
603
604        logprintf(pCardData, 1, "CardAuthenticatePin %.20s, %d, %d\n", NULLSTR(type), \
605                cbPin, (pcAttemptsRemaining==NULL?-2:*pcAttemptsRemaining));
606
607        r = get_pin_by_role(pCardData, ROLE_USER, &pin_obj);
608        if (r != SCARD_S_SUCCESS)
609        {
610                logprintf(pCardData, 2, "Cannot get User PIN object");
611                return r;
612        }
613
614        r = sc_pkcs15_verify_pin(vs->p15card, pin_obj, (const u8 *) pbPin, cbPin);
615        if (r)
616        {
617                logprintf(pCardData, 1, "PIN code verification failed: %s\n", sc_strerror(r));
618
619                if(pcAttemptsRemaining)
620                {
621                        (*pcAttemptsRemaining) = -1;
622                }
623                return SCARD_W_WRONG_CHV;
624        }
625
626        logprintf(pCardData, 3, "Pin code correct.\n");
627
628        SET_PIN(vs->cardFiles.file_cardcf.bPinsFreshness, ROLE_USER);
629        logprintf(pCardData, 3, "PinsFreshness = %d\n",
630                vs->cardFiles.file_cardcf.bPinsFreshness);
631
632        return SCARD_S_SUCCESS;
633}
634
635DWORD WINAPI CardGetChallenge(__in PCARD_DATA pCardData,
636        __deref_out_bcount(*pcbChallengeData) PBYTE *ppbChallengeData,
637        __out                                 PDWORD pcbChallengeData)
638{
639        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
640        logprintf(pCardData, 1, "CardGetChallenge - unsupported\n");
641        return SCARD_E_UNSUPPORTED_FEATURE;
642}
643
644DWORD WINAPI CardAuthenticateChallenge(__in PCARD_DATA  pCardData,
645        __in_bcount(cbResponseData) PBYTE  pbResponseData,
646        __in DWORD  cbResponseData,
647        __out_opt PDWORD pcAttemptsRemaining)
648{
649        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
650        logprintf(pCardData, 1, "CardAuthenticateChallenge - unsupported\n");
651        return SCARD_E_UNSUPPORTED_FEATURE;
652}
653
654DWORD WINAPI CardUnblockPin(__in PCARD_DATA  pCardData,
655        __in LPWSTR pwszUserId,
656        __in_bcount(cbAuthenticationData) PBYTE  pbAuthenticationData,
657        __in DWORD  cbAuthenticationData,
658        __in_bcount(cbNewPinData) PBYTE  pbNewPinData,
659        __in DWORD  cbNewPinData,
660        __in DWORD  cRetryCount,
661        __in DWORD  dwFlags)
662{
663        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
664        logprintf(pCardData, 1, "CardUnblockPin - unsupported\n");
665        return SCARD_E_UNSUPPORTED_FEATURE;
666}
667
668DWORD WINAPI CardChangeAuthenticator(__in PCARD_DATA  pCardData,
669        __in LPWSTR pwszUserId,
670        __in_bcount(cbCurrentAuthenticator) PBYTE pbCurrentAuthenticator,
671        __in DWORD cbCurrentAuthenticator,
672        __in_bcount(cbNewAuthenticator) PBYTE pbNewAuthenticator,
673        __in DWORD cbNewAuthenticator,
674        __in DWORD cRetryCount,
675        __in DWORD dwFlags,
676        __out_opt PDWORD pcAttemptsRemaining)
677{
678        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
679        logprintf(pCardData, 1, "CardChangeAuthenticator - unsupported\n");
680        return SCARD_E_UNSUPPORTED_FEATURE;
681}
682
683
684DWORD WINAPI CardDeauthenticate(__in PCARD_DATA pCardData,
685        __in LPWSTR pwszUserId,
686        __in DWORD dwFlags)
687{
688        VENDOR_SPECIFIC *vs;
689
690        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
691        logprintf(pCardData, 1, "CardDeauthenticate%S %d\n", NULLWSTR(pwszUserId),
692                        dwFlags);
693
694        if(!pCardData) return SCARD_E_INVALID_PARAMETER;
695
696        vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
697
698        check_reader_status(pCardData);
699
700        /* TODO This does not look correct, as it does not look at the pwszUserId */
701        /* TODO We need to tell the card the pin is no longer valid */
702        CLEAR_PIN(vs->cardFiles.file_cardcf.bPinsFreshness, ROLE_USER);
703        logprintf(pCardData, 5, "PinsFreshness = %d\n",
704                vs->cardFiles.file_cardcf.bPinsFreshness);
705
706        /*TODO Should we reset the card ? */
707
708        return SCARD_S_SUCCESS;
709}
710
711DWORD WINAPI CardCreateDirectory(__in PCARD_DATA pCardData,
712        __in LPSTR pszDirectoryName,
713        __in CARD_DIRECTORY_ACCESS_CONDITION AccessCondition)
714{
715        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
716        logprintf(pCardData, 1, "CardCreateDirectory - unsupported\n");
717        return SCARD_E_UNSUPPORTED_FEATURE;
718}
719
720DWORD WINAPI CardDeleteDirectory(__in PCARD_DATA pCardData,
721        __in LPSTR pszDirectoryName)
722
723{
724        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
725        logprintf(pCardData, 1, "CardDeleteDirectory - unsupported\n");
726        return SCARD_E_UNSUPPORTED_FEATURE;
727}
728
729DWORD WINAPI CardCreateFile(__in PCARD_DATA pCardData,
730        __in LPSTR pszDirectoryName,
731        __in LPSTR pszFileName,
732        __in DWORD cbInitialCreationSize,
733        __in CARD_FILE_ACCESS_CONDITION AccessCondition)
734{
735        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
736        logprintf(pCardData, 1, "CardCreateFile - unsupported\n");
737        return SCARD_E_UNSUPPORTED_FEATURE;
738}
739
740DWORD WINAPI CardReadFile(__in PCARD_DATA pCardData,
741        __in LPSTR pszDirectoryName,
742        __in LPSTR pszFileName,
743        __in DWORD dwFlags,
744        __deref_out_bcount(*pcbData) PBYTE *ppbData,
745        __out PDWORD pcbData)
746{
747        VENDOR_SPECIFIC *vs;
748
749        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
750        logprintf(pCardData, 1, "CardReadFile\n");
751
752        if(!pCardData) return SCARD_E_INVALID_PARAMETER;
753
754        vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
755
756        logprintf(pCardData, 2, "pszDirectoryName = %s, pszFileName = %s, " \
757                "dwFlags = %X, pcbData=%d, *ppbData=%X\n", \
758                NULLSTR(pszDirectoryName), NULLSTR(pszFileName), \
759                dwFlags, *pcbData, *ppbData);
760
761        if (!pszFileName) return SCARD_E_INVALID_PARAMETER;
762        if (!strlen(pszFileName)) return SCARD_E_INVALID_PARAMETER;
763        if (!ppbData) return SCARD_E_INVALID_PARAMETER;
764        if (!pcbData) return SCARD_E_INVALID_PARAMETER;
765        if (dwFlags) return SCARD_E_INVALID_PARAMETER;
766
767        check_reader_status(pCardData);
768
769        if(pszDirectoryName == NULL)
770        {
771                if(strcmp(pszFileName, "cardid") == 0)
772                {
773                        *pcbData = sizeof(vs->cardFiles.file_cardid);
774                        *ppbData = pCardData->pfnCspAlloc(*pcbData);
775                        if(!*ppbData)
776                                return SCARD_E_NO_MEMORY;
777
778                        memcpy(*ppbData, &(vs->cardFiles.file_cardid), *pcbData);
779
780                        logprintf(pCardData, 7, "return cardid ");
781                        loghex(pCardData, 7, *ppbData, *pcbData);
782
783                        return SCARD_S_SUCCESS;
784                }
785
786                if(strcmp(pszFileName, "cardcf") == 0)
787                {
788                        *pcbData = sizeof(vs->cardFiles.file_cardcf);
789                        *ppbData = pCardData->pfnCspAlloc(*pcbData);
790                        if(!*ppbData)
791                        {
792                                return SCARD_E_NO_MEMORY;
793                        }
794
795                        memcpy(*ppbData, &(vs->cardFiles.file_cardcf), *pcbData);
796
797                        logprintf(pCardData, 7, "return cardcf ");
798                        loghex(pCardData, 7, *ppbData, *pcbData);
799
800                        return SCARD_S_SUCCESS;
801                }
802
803        }
804
805        if(pszDirectoryName != NULL && strcmp(pszDirectoryName, "mscp") == 0)
806        {
807                int r,i,n;
808                sc_pkcs15_cert_t *cert = NULL;
809
810                if(strcmp(pszFileName, "cmapfile") == 0)
811                {
812                        PCONTAINER_MAP_RECORD p;
813                        sc_pkcs15_pubkey_t *pubkey = NULL;
814
815                        *pcbData = 32*sizeof(CONTAINER_MAP_RECORD);
816                        *ppbData = pCardData->pfnCspAlloc(*pcbData);
817                        if(!*ppbData)
818                        {
819                                return SCARD_E_NO_MEMORY;
820                        }
821
822                        memset(*ppbData, 0, *pcbData);
823
824                        for(i = 0, p = (PCONTAINER_MAP_RECORD)*ppbData; \
825                                i < vs->cert_count; i++,p++)
826                        {
827                                struct sc_pkcs15_cert_info *cert_info = (sc_pkcs15_cert_info_t *)vs->cert_objs[i]->data;
828                                sc_pkcs15_cert_t *cert = NULL;
829
830                                r = sc_pkcs15_read_certificate(vs->p15card, cert_info, &cert);
831                                logprintf(pCardData, 2, "sc_pkcs15_read_certificate return %d\n", r);
832                                if(r)
833                                {
834                                        return SCARD_E_FILE_NOT_FOUND;
835                                }
836                                pubkey = cert->key;
837                                if(pubkey->algorithm == SC_ALGORITHM_RSA)
838                                {
839                                        struct sc_card *card = vs->p15card->card;
840                                        char guid[MAX_CONTAINER_NAME_LEN + 1];
841
842                                        r = sc_pkcs15_get_guid(vs->p15card, vs->cert_objs[i], guid, sizeof(guid));
843                                        if (r)
844                                                return r;
845
846                                        logprintf(pCardData, 7, "Guid=%s\n", guid);
847
848                                        mbstowcs(p->wszGuid, guid, MAX_CONTAINER_NAME_LEN + 1);
849
850                                        p->bFlags += CONTAINER_MAP_VALID_CONTAINER;
851                                        if(i == 0)
852                                        {
853                                                p->bFlags += CONTAINER_MAP_DEFAULT_CONTAINER;
854                                        }
855                                        /* TODO Looks like these should be based on sc_pkcs15_prkey_info usage */
856                                        /* On PIV on W7, auth cert is AT_KEYEXCHANGE, Signing cert is AT_SIGNATURE */
857
858                                        p->wSigKeySizeBits = \
859                                                compute_keybits(&(pubkey->u.rsa.modulus));
860                                        p->wKeyExchangeKeySizeBits = \
861                                                compute_keybits(&(pubkey->u.rsa.modulus));
862                                }
863                                sc_pkcs15_free_certificate(cert);
864
865                                logprintf(pCardData, 7, "cmapfile entry %d ",i);
866                                loghex(pCardData, 7, (PBYTE) p, sizeof(CONTAINER_MAP_RECORD));
867                        }
868
869                        return SCARD_S_SUCCESS;
870                }
871
872                if(sscanf(pszFileName, "ksc%d", &n) <= 0)
873                {
874                        if(sscanf(pszFileName, "kxc%d", &n) <= 0)
875                        {
876                                n = -1;
877                        }
878                }
879
880                logprintf(pCardData, 7, "n = %d\n", n);
881
882                if(n>=0 && n<vs->cert_count)
883                {
884                        sc_pkcs15_cert_t *cert = NULL;
885
886                        r = sc_pkcs15_read_certificate(vs->p15card, \
887                                (struct sc_pkcs15_cert_info *)(vs->cert_objs[n]->data), \
888                                &cert);
889                        logprintf(pCardData, 2, "Reading certificat return %d\n", r);
890                        if(r)
891                        {
892                                return SCARD_E_FILE_NOT_FOUND;
893                        }
894
895                        *pcbData = cert->data_len;
896                        *ppbData = pCardData->pfnCspAlloc(*pcbData);
897
898                        if(*ppbData == NULL)
899                        {
900                                logprintf(pCardData, 0, "memory error\n");
901                                return SCARD_E_NO_MEMORY;
902                        }
903
904                        CopyMemory(*ppbData, cert->data, *pcbData);
905
906                        if(1)
907                        {
908                                logprintf(pCardData, 6, "cert returned ");
909                                loghex(pCardData, 6, *ppbData, *pcbData);
910                        }
911
912                        sc_pkcs15_free_certificate(cert);
913
914                        return SCARD_S_SUCCESS;
915                }
916        }
917
918        logprintf(pCardData, 5, "File not found\n");
919        return SCARD_E_FILE_NOT_FOUND;
920}
921
922DWORD WINAPI CardWriteFile(__in PCARD_DATA pCardData,
923        __in LPSTR pszDirectoryName,
924        __in LPSTR pszFileName,
925        __in DWORD dwFlags,
926        __in_bcount(cbData) PBYTE pbData,
927        __in DWORD cbData)
928{
929        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
930        logprintf(pCardData, 1, "CardWriteFile %s %d\n", NULLSTR(pszFileName), cbData);
931
932        if(!pCardData)
933                return SCARD_E_INVALID_PARAMETER;
934
935        if(pszDirectoryName == NULL)
936        {
937                if(strcmp(pszFileName, "cardcf") == 0)
938                {
939                        logprintf(pCardData, 2, "write cardcf ok.\n");
940                        loghex(pCardData, 2, pbData, cbData); /*TODO did it change */
941                        return SCARD_S_SUCCESS;
942                }
943        }
944
945        return SCARD_E_FILE_NOT_FOUND;
946}
947
948DWORD WINAPI CardDeleteFile(__in PCARD_DATA pCardData,
949        __in LPSTR pszDirectoryName,
950        __in LPSTR pszFileName,
951        __in DWORD dwFlags)
952{
953        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
954        logprintf(pCardData, 1, "CardDeleteFile - unsupported\n");
955        return SCARD_E_UNSUPPORTED_FEATURE;
956}
957
958DWORD WINAPI CardEnumFiles(__in PCARD_DATA pCardData,
959        __in LPSTR pszDirectoryName,
960        __out_ecount(*pdwcbFileName) LPSTR *pmszFileNames,
961        __out LPDWORD pdwcbFileName,
962        __in DWORD dwFlags)
963{
964        const char root_files[] = "cardapps\0cardcf\0cardid\0\0";
965        const char mscp_files[] = "kxc00\0kxc01\0cmapfile\0\0";
966
967        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
968        logprintf(pCardData, 1, "CardEnumFiles\n");
969
970        if (!pCardData) return SCARD_E_INVALID_PARAMETER;
971        if (!pmszFileNames) return SCARD_E_INVALID_PARAMETER;
972        if (!pdwcbFileName) return SCARD_E_INVALID_PARAMETER;
973        if (dwFlags) return SCARD_E_INVALID_PARAMETER;
974
975        if (!pszDirectoryName || !strlen(pszDirectoryName))
976        {
977                DWORD sz = sizeof(root_files) - 1;
978                LPSTR t = (LPSTR)(*pCardData->pfnCspAlloc)(sz);
979                if (!t) return SCARD_E_NO_MEMORY;
980                CopyMemory(t,root_files,sz);
981                *pmszFileNames = t;
982                *pdwcbFileName = sz;
983                return SCARD_S_SUCCESS;
984        }
985        if (strcmpi(pszDirectoryName,"mscp") == 0)
986        {
987                DWORD sz = sizeof(mscp_files) - 1;
988                LPSTR t = (LPSTR)(*pCardData->pfnCspAlloc)(sz);
989                if (!t) return SCARD_E_NO_MEMORY;
990                CopyMemory(t,mscp_files,sz);
991                *pmszFileNames = t;
992                *pdwcbFileName = sz;
993                return SCARD_S_SUCCESS;
994        }
995
996        return SCARD_E_FILE_NOT_FOUND;
997}
998
999DWORD WINAPI CardGetFileInfo(__in PCARD_DATA pCardData,
1000        __in LPSTR pszDirectoryName,
1001        __in LPSTR pszFileName,
1002        __in PCARD_FILE_INFO pCardFileInfo)
1003{
1004        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
1005        logprintf(pCardData, 1, "CardGetFileInfo - unsupported\n");
1006        return SCARD_E_UNSUPPORTED_FEATURE;
1007}
1008
1009DWORD WINAPI CardQueryFreeSpace(__in PCARD_DATA pCardData,
1010        __in DWORD dwFlags,
1011        __in PCARD_FREE_SPACE_INFO pCardFreeSpaceInfo)
1012{
1013        VENDOR_SPECIFIC *vs;
1014
1015        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
1016        logprintf(pCardData, 1, "CardQueryFreeSpace %X, dwFlags=%X, version=%X\n", \
1017                pCardFreeSpaceInfo, dwFlags, pCardFreeSpaceInfo->dwVersion);
1018
1019        if (!pCardData) return SCARD_E_INVALID_PARAMETER;
1020
1021        vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
1022
1023        check_reader_status(pCardData);
1024
1025        pCardFreeSpaceInfo->dwVersion = CARD_FREE_SPACE_INFO_CURRENT_VERSION;
1026        pCardFreeSpaceInfo->dwBytesAvailable = -1;
1027        pCardFreeSpaceInfo->dwMaxKeyContainers = vs->cert_count;
1028
1029        pCardFreeSpaceInfo->dwKeyContainersAvailable = vs->cert_count; /*TODO should this be 0 */
1030
1031        return SCARD_S_SUCCESS;
1032}
1033
1034
1035DWORD WINAPI CardQueryKeySizes(__in PCARD_DATA pCardData,
1036        __in  DWORD dwKeySpec,
1037        __in  DWORD dwFlags,
1038        __out PCARD_KEY_SIZES pKeySizes)
1039{
1040        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
1041        logprintf(pCardData, 1, "CardQueryKeySizes dwKeySpec=%X, dwFlags=%X, version=%X\n", \
1042                dwKeySpec, dwFlags, pKeySizes->dwVersion);
1043
1044        if (!pCardData) return SCARD_E_INVALID_PARAMETER;
1045        if (!pKeySizes) return SCARD_E_INVALID_PARAMETER;
1046
1047        pKeySizes->dwVersion = CARD_KEY_SIZES_CURRENT_VERSION;
1048        pKeySizes->dwMinimumBitlen = 512;
1049        pKeySizes->dwDefaultBitlen = 1024;
1050        pKeySizes->dwMaximumBitlen = 16384;
1051        pKeySizes->dwIncrementalBitlen = 64;
1052
1053        return SCARD_S_SUCCESS;
1054}
1055
1056DWORD WINAPI CardRSADecrypt(__in PCARD_DATA pCardData,
1057        __inout PCARD_RSA_DECRYPT_INFO  pInfo)
1058
1059{
1060        int r, i, opt_crypt_flags = 0;
1061        unsigned ui;
1062        VENDOR_SPECIFIC *vs;
1063        sc_pkcs15_cert_info_t *cert_info;
1064        sc_pkcs15_prkey_info_t *prkey_info;
1065        BYTE *pbuf = NULL, *pbuf2 = NULL;
1066        DWORD lg= 0, lg2 = 0;
1067
1068        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
1069        logprintf(pCardData, 1, "CardRSADecrypt\n");
1070        if (!pCardData) return SCARD_E_INVALID_PARAMETER;
1071        if (!pInfo) return SCARD_E_INVALID_PARAMETER;
1072
1073        vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
1074
1075        check_reader_status(pCardData);
1076
1077        vs->pkey = NULL;
1078
1079        logprintf(pCardData, 2, "CardRSADecrypt dwVersion=%u, bContainerIndex=%u," \
1080                "dwKeySpec=%u pbData=%p, cbData=%u\n", \
1081                pInfo->dwVersion,pInfo->bContainerIndex ,pInfo->dwKeySpec, \
1082                pInfo->pbData,  pInfo->cbData);
1083
1084        if (pInfo->dwVersion == CARD_RSA_KEY_DECRYPT_INFO_VERSION_TWO) {
1085                logprintf(pCardData, 2, "  pPaddingInfo=%p dwPaddingType=0x%08X\n", \
1086                        pInfo->pPaddingInfo, pInfo->dwPaddingType);
1087        }
1088
1089        if (!(pInfo->bContainerIndex < vs->cert_count))
1090    {
1091        return SCARD_E_INVALID_PARAMETER;
1092    }
1093
1094
1095        cert_info = (struct sc_pkcs15_cert_info *) \
1096        (vs->cert_objs[pInfo->bContainerIndex]->data);
1097
1098    for(i = 0; i < vs->prkey_count; i++)
1099    {
1100        sc_pkcs15_object_t *obj = (sc_pkcs15_object_t *)vs->prkey_objs[i];
1101        if(sc_pkcs15_compare_id(&((struct sc_pkcs15_prkey_info *) obj->data)->id, &(cert_info->id)))
1102        {
1103            vs->pkey = vs->prkey_objs[i];
1104            break;
1105        }
1106    }
1107
1108    if(vs->pkey == NULL)
1109    {
1110                logprintf(pCardData, 2, "CardRSADecrypt prkey not found\n");
1111        return SCARD_E_INVALID_PARAMETER;
1112    }
1113
1114    prkey_info = (sc_pkcs15_prkey_info_t*)(vs->pkey->data);
1115
1116
1117        /* input and output buffers are always the same size */
1118        pbuf = pCardData->pfnCspAlloc(pInfo->cbData);
1119        if (!pbuf) {
1120                return SCARD_E_NO_MEMORY;
1121        }
1122        lg2 = pInfo->cbData;
1123        pbuf2 = pCardData->pfnCspAlloc(pInfo->cbData);
1124        if (!pbuf2) {
1125                return SCARD_E_NO_MEMORY;
1126        }
1127
1128        /*inversion donnees*/
1129        for(ui = 0; ui < pInfo->cbData; ui++) pbuf[ui] = pInfo->pbData[pInfo->cbData-ui-1];
1130
1131        r = sc_pkcs15_decipher(vs->p15card, vs->pkey,
1132                opt_crypt_flags, pbuf, pInfo->cbData, pbuf2, pInfo->cbData);
1133        logprintf(pCardData, 2, "sc_pkcs15_decipher return %d\n", r);
1134        if ( r != pInfo->cbData || r < 0) {
1135                logprintf(pCardData, 2, "sc_pkcs15_decipher erreur %s\n", \
1136                        sc_strerror(r));
1137        }
1138
1139        /*inversion donnees */
1140        for(ui = 0; ui < pInfo->cbData; ui++) pInfo->pbData[ui] = pbuf2[pInfo->cbData-ui-1];
1141
1142        pCardData->pfnCspFree(pbuf);
1143        pCardData->pfnCspFree(pbuf2);
1144
1145        return SCARD_S_SUCCESS;
1146}
1147
1148DWORD WINAPI CardSignData(__in PCARD_DATA pCardData,
1149        __in PCARD_SIGNING_INFO pInfo)
1150{
1151        VENDOR_SPECIFIC *vs;
1152        ALG_ID hashAlg;
1153        sc_pkcs15_cert_info_t *cert_info;
1154        sc_pkcs15_prkey_info_t *prkey_info;
1155        BYTE dataToSign[0x200];
1156        int r, opt_crypt_flags = 0, opt_hash_flags = 0;
1157        size_t dataToSignLen = sizeof(dataToSign);
1158
1159        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
1160        logprintf(pCardData, 1, "CardSignData\n");
1161
1162        if (!pCardData) return SCARD_E_INVALID_PARAMETER;
1163        if (!pInfo) return SCARD_E_INVALID_PARAMETER;
1164
1165        logprintf(pCardData, 2, "CardSignData dwVersion=%u, bContainerIndex=%u," \
1166                "dwKeySpec=%u, dwSigningFlags=0x%08X, aiHashAlg=0x%08X\n", \
1167                pInfo->dwVersion,pInfo->bContainerIndex ,pInfo->dwKeySpec, \
1168                pInfo->dwSigningFlags, pInfo->aiHashAlg);
1169
1170        logprintf(pCardData, 7, "pInfo->pbData(%i) ", pInfo->cbData);
1171        loghex(pCardData, 7, pInfo->pbData, pInfo->cbData);
1172
1173        hashAlg = pInfo->aiHashAlg;
1174
1175        vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
1176
1177        check_reader_status(pCardData);
1178
1179        vs->pkey = NULL;
1180
1181        logprintf(pCardData, 2, "pInfo->dwVersion = %d\n", pInfo->dwVersion);
1182
1183        if (dataToSignLen < pInfo->cbData) return SCARD_E_INSUFFICIENT_BUFFER;
1184        memcpy(dataToSign, pInfo->pbData, pInfo->cbData);
1185        dataToSignLen = pInfo->cbData;
1186
1187        if (CARD_PADDING_INFO_PRESENT & pInfo->dwSigningFlags)
1188        {
1189                BCRYPT_PKCS1_PADDING_INFO *pinf = (BCRYPT_PKCS1_PADDING_INFO *)pInfo->pPaddingInfo;
1190                if (CARD_PADDING_PKCS1 != pInfo->dwPaddingType)
1191                {
1192                        logprintf(pCardData, 0, "unsupported paddingtype\n");
1193                        return SCARD_E_UNSUPPORTED_FEATURE;
1194                }
1195                if (!pinf->pszAlgId)
1196                {
1197                        /* hashAlg = CALG_SSL3_SHAMD5; */
1198                        logprintf(pCardData, 3, "Using CALG_SSL3_SHAMD5  hashAlg\n");
1199                        opt_hash_flags = SC_ALGORITHM_RSA_HASH_MD5_SHA1;
1200                }
1201                else
1202                {
1203
1204                        if (wcscmp(pinf->pszAlgId, L"MD5") == 0)  opt_hash_flags = SC_ALGORITHM_RSA_HASH_MD5;
1205                        else if (wcscmp(pinf->pszAlgId, L"SHA1") == 0)  opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA1;
1206                        else if (wcscmp(pinf->pszAlgId, L"SHAMD5") == 0) opt_hash_flags = SC_ALGORITHM_RSA_HASH_MD5_SHA1;
1207                        else
1208                                logprintf(pCardData, 0,"unknown AlgId %S\n",NULLWSTR(pinf->pszAlgId));
1209                }
1210        }
1211        else
1212        {
1213                logprintf(pCardData, 3, "CARD_PADDING_INFO_PRESENT not set\n");
1214
1215                if (GET_ALG_CLASS(hashAlg) != ALG_CLASS_HASH)
1216                {
1217                        logprintf(pCardData, 0, "bogus aiHashAlg\n");
1218                        return SCARD_E_INVALID_PARAMETER;
1219                }
1220
1221                if (hashAlg == CALG_MD5)
1222                        opt_hash_flags = SC_ALGORITHM_RSA_HASH_MD5;
1223                else if (hashAlg == CALG_SHA1)
1224                        opt_hash_flags = SC_ALGORITHM_RSA_HASH_SHA1;
1225                else if (hashAlg == CALG_SSL3_SHAMD5)
1226                        opt_hash_flags = SC_ALGORITHM_RSA_HASH_MD5_SHA1;
1227                else if (hashAlg !=0)
1228                        return SCARD_E_UNSUPPORTED_FEATURE;
1229        }
1230
1231        /* From sc-minidriver_specs_v7.docx pp.76:
1232         * 'The Base CSP/KSP performs the hashing operation on the data before passing it
1233         *      to CardSignData for signature.'
1234         * So, the SC_ALGORITHM_RSA_HASH_* flags should not be passed to pkcs15 library
1235         *      when calculating the signature .
1236         *
1237         * From sc-minidriver_specs_v7.docx pp.76:
1238         * 'If the aiHashAlg member is nonzero, it specifies the hash algorithm’s object identifier (OID)
1239         *  that is encoded in the PKCS padding.'
1240         * So, the digest info has be included into the data to be signed.
1241         * */
1242        if (opt_hash_flags)   {
1243                logprintf(pCardData, 2, "include digest info of the algorithm 0x%08X\n", opt_hash_flags);
1244                dataToSignLen = sizeof(dataToSign);
1245                r = sc_pkcs1_encode(vs->p15card->card->ctx, opt_hash_flags,
1246                        pInfo->pbData, pInfo->cbData, dataToSign, &dataToSignLen, 0);
1247                if (r)   {
1248                        logprintf(pCardData, 2, "PKCS#1 encode error %s\n", sc_strerror(r));
1249                        return SCARD_E_INVALID_VALUE;
1250                }
1251        }
1252        opt_crypt_flags = SC_ALGORITHM_RSA_PAD_PKCS1 | SC_ALGORITHM_RSA_HASH_NONE;
1253
1254        if(!(pInfo->bContainerIndex < vs->cert_count))
1255        {
1256                return SCARD_E_INVALID_PARAMETER;
1257        }
1258
1259        cert_info = (struct sc_pkcs15_cert_info *) \
1260                (vs->cert_objs[pInfo->bContainerIndex]->data);
1261
1262        r = sc_pkcs15_find_prkey_by_id(vs->p15card, &cert_info->id, &vs->pkey);
1263        if (r)
1264                return SCARD_E_INVALID_PARAMETER;
1265
1266        prkey_info = (sc_pkcs15_prkey_info_t*)(vs->pkey->data);
1267
1268        pInfo->cbSignedData = prkey_info->modulus_length / 8;
1269        logprintf(pCardData, 3, "pInfo->cbSignedData = %d\n", pInfo->cbSignedData);
1270
1271        if(!(pInfo->dwSigningFlags&CARD_BUFFER_SIZE_ONLY))
1272        {
1273                int r,i;
1274                BYTE *pbuf = NULL;
1275                DWORD lg;
1276
1277                lg = pInfo->cbSignedData;
1278                logprintf(pCardData, 3, "lg = %d\n", lg);
1279                pbuf = pCardData->pfnCspAlloc(lg);
1280                if (!pbuf)
1281                {
1282                        return SCARD_E_NO_MEMORY;
1283                }
1284
1285                logprintf(pCardData, 7, "Data to sign: ");
1286                loghex(pCardData, 7, dataToSign, dataToSignLen);
1287
1288                pInfo->pbSignedData = pCardData->pfnCspAlloc(pInfo->cbSignedData);
1289                if (!pInfo->pbSignedData)
1290                {
1291                        pCardData->pfnCspFree(pbuf);
1292                        return SCARD_E_NO_MEMORY;
1293                }
1294
1295                r = sc_pkcs15_compute_signature(vs->p15card, vs->pkey, \
1296                        opt_crypt_flags, dataToSign, dataToSignLen, pbuf, lg);
1297                logprintf(pCardData, 2, "sc_pkcs15_compute_signature return %d\n", r);
1298                if(r < 0)
1299                {
1300                        logprintf(pCardData, 2, "sc_pkcs15_compute_signature erreur %s\n", \
1301                                sc_strerror(r));
1302                }
1303
1304                pInfo->cbSignedData = r;
1305
1306                /*inversion donnees*/
1307                for(i = 0; i < r; i++) pInfo->pbSignedData[i] = pbuf[r-i-1];
1308
1309                logprintf(pCardData, 7, "pbuf ");
1310                loghex(pCardData, 7, pbuf, r);
1311
1312                pCardData->pfnCspFree(pbuf);
1313
1314                logprintf(pCardData, 7, "pInfo->pbSignedData ");
1315                loghex(pCardData, 7, pInfo->pbSignedData, pInfo->cbSignedData);
1316
1317        }
1318
1319        logprintf(pCardData, 3, "CardSignData, dwVersion=%u, name=%S, hScard=0x%08X," \
1320                "hSCardCtx=0x%08X\n", pCardData->dwVersion, \
1321                NULLWSTR(pCardData->pwszCardName),pCardData->hScard, \
1322                pCardData->hSCardCtx);
1323
1324        return SCARD_S_SUCCESS;
1325}
1326
1327DWORD WINAPI CardConstructDHAgreement(__in PCARD_DATA pCardData,
1328        __in PCARD_DH_AGREEMENT_INFO pAgreementInfo)
1329{
1330        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
1331        logprintf(pCardData, 1, "CardConstructDHAgreement - unsupported\n");
1332        return SCARD_E_UNSUPPORTED_FEATURE;
1333}
1334
1335DWORD WINAPI CardDeriveKey(__in PCARD_DATA pCardData,
1336        __in PCARD_DERIVE_KEY pAgreementInfo)
1337{
1338        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
1339        logprintf(pCardData, 1, "CardDeriveKey - unsupported\n");
1340        return SCARD_E_UNSUPPORTED_FEATURE;
1341}
1342
1343DWORD WINAPI CardDestroyDHAgreement(
1344        __in PCARD_DATA pCardData,
1345        __in BYTE bSecretAgreementIndex,
1346        __in DWORD dwFlags)
1347{
1348        logprintf(pCardData, 1, "CardDestroyDHAgreement - unsupported\n");
1349        return SCARD_E_UNSUPPORTED_FEATURE;
1350}
1351
1352DWORD WINAPI CspGetDHAgreement(__in  PCARD_DATA pCardData,
1353        __in  PVOID hSecretAgreement,
1354        __out BYTE* pbSecretAgreementIndex,
1355        __in  DWORD dwFlags)
1356{
1357        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
1358        logprintf(pCardData, 1, "CspGetDHAgreement - unsupported\n");
1359        return SCARD_E_UNSUPPORTED_FEATURE;
1360}
1361
1362DWORD WINAPI CardGetChallengeEx(__in PCARD_DATA pCardData,
1363        __in PIN_ID PinId,
1364        __deref_out_bcount(*pcbChallengeData) PBYTE *ppbChallengeData,
1365        __out PDWORD pcbChallengeData,
1366        __in DWORD dwFlags)
1367{
1368        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
1369        logprintf(pCardData, 1, "CardGetChallengeEx - unsupported\n");
1370        return SCARD_E_UNSUPPORTED_FEATURE;
1371}
1372
1373DWORD WINAPI CardAuthenticateEx(__in PCARD_DATA pCardData,
1374        __in   PIN_ID PinId,
1375        __in   DWORD dwFlags,
1376        __in   PBYTE pbPinData,
1377        __in   DWORD cbPinData,
1378        __deref_out_bcount_opt(*pcbSessionPin) PBYTE *ppbSessionPin,
1379        __out_opt PDWORD pcbSessionPin,
1380        __out_opt PDWORD pcAttemptsRemaining)
1381{
1382        int r;
1383        VENDOR_SPECIFIC *vs;
1384        sc_pkcs15_object_t *pin_obj = NULL;
1385
1386        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
1387        logprintf(pCardData, 1, "CardAuthenticateEx\n");
1388
1389        if (!pCardData) return SCARD_E_INVALID_PARAMETER;
1390
1391        logprintf(pCardData, 2, "CardAuthenticateEx: PinId=%u, dwFlags=0x%08X, cbPinData=%u, Attempts %s\n",
1392                PinId,dwFlags,cbPinData,pcAttemptsRemaining ? "YES" : "NO");
1393
1394        vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
1395
1396        check_reader_status(pCardData);
1397
1398        if (dwFlags == CARD_AUTHENTICATE_GENERATE_SESSION_PIN ||
1399                dwFlags == CARD_AUTHENTICATE_SESSION_PIN)
1400                        return SCARD_E_UNSUPPORTED_FEATURE;
1401        if (dwFlags && dwFlags != CARD_PIN_SILENT_CONTEXT)
1402                return SCARD_E_INVALID_PARAMETER;
1403
1404        if (NULL == pbPinData) return SCARD_E_INVALID_PARAMETER;
1405
1406        if (PinId != ROLE_USER) return SCARD_E_INVALID_PARAMETER;
1407
1408        r = get_pin_by_role(pCardData, ROLE_USER, &pin_obj);
1409        if (r != SCARD_S_SUCCESS)
1410        {
1411                logprintf(pCardData, 2, "Cannot get User PIN object");
1412                return r;
1413        }
1414
1415        r = sc_pkcs15_verify_pin(vs->p15card, pin_obj, (const u8 *) pbPinData, cbPinData);
1416        if (r)
1417        {
1418                logprintf(pCardData, 2, "PIN code verification failed: %s\n", sc_strerror(r));
1419
1420                if(pcAttemptsRemaining)
1421                {
1422                        (*pcAttemptsRemaining) = -1;
1423                }
1424                return SCARD_W_WRONG_CHV;
1425        }
1426
1427        logprintf(pCardData, 2, "Pin code correct.\n");
1428
1429        SET_PIN(vs->cardFiles.file_cardcf.bPinsFreshness, ROLE_USER);
1430        logprintf(pCardData, 7, "PinsFreshness = %d\n",
1431                vs->cardFiles.file_cardcf.bPinsFreshness);
1432
1433        return SCARD_S_SUCCESS;
1434}
1435
1436DWORD WINAPI CardChangeAuthenticatorEx(__in PCARD_DATA pCardData,
1437        __in   DWORD dwFlags,
1438        __in   PIN_ID dwAuthenticatingPinId,
1439        __in_bcount(cbAuthenticatingPinData) PBYTE pbAuthenticatingPinData,
1440        __in   DWORD cbAuthenticatingPinData,
1441        __in   PIN_ID dwTargetPinId,
1442        __in_bcount(cbTargetData) PBYTE pbTargetData,
1443        __in   DWORD cbTargetData,
1444        __in   DWORD cRetryCount,
1445        __out_opt PDWORD pcAttemptsRemaining)
1446{
1447        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
1448        logprintf(pCardData, 1, "CardChangeAuthenticatorEx - unsupported\n");
1449        return SCARD_E_UNSUPPORTED_FEATURE;
1450}
1451
1452DWORD WINAPI CardDeauthenticateEx(__in PCARD_DATA pCardData,
1453        __in PIN_SET PinId,
1454        __in DWORD dwFlags)
1455{
1456        VENDOR_SPECIFIC *vs;
1457
1458        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
1459        logprintf(pCardData, 1, "CardDeauthenticateEx PinId=%d dwFlags=0x%08X\n",PinId, dwFlags);
1460
1461        if (!pCardData) return SCARD_E_INVALID_PARAMETER;
1462
1463        vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
1464
1465        check_reader_status(pCardData);
1466
1467        /*TODO Should we reset the card? */
1468        vs->cardFiles.file_cardcf.bPinsFreshness &= ~PinId;
1469        logprintf(pCardData, 7, "PinsFreshness = %d\n",
1470                vs->cardFiles.file_cardcf.bPinsFreshness);
1471
1472        return SCARD_S_SUCCESS;
1473}
1474
1475DWORD WINAPI CardGetContainerProperty(__in PCARD_DATA pCardData,
1476        __in BYTE bContainerIndex,
1477        __in LPCWSTR wszProperty,
1478        __out_bcount_part_opt(cbData, *pdwDataLen) PBYTE pbData,
1479        __in DWORD cbData,
1480        __out PDWORD pdwDataLen,
1481        __in DWORD dwFlags)
1482{
1483        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
1484        logprintf(pCardData, 1, "CardGetContainerProperty\n");
1485
1486        check_reader_status(pCardData);
1487
1488        if (!pCardData) return SCARD_E_INVALID_PARAMETER;
1489        logprintf(pCardData, 2, "CardGetContainerProperty bContainerIndex=%u, wszProperty=%S," \
1490                "cbData=%u, dwFlags=0x%08X\n",bContainerIndex,NULLWSTR(wszProperty),cbData,dwFlags);
1491        if (!wszProperty) return SCARD_E_INVALID_PARAMETER;
1492        if (dwFlags) return SCARD_E_INVALID_PARAMETER;
1493        if (!pbData) return SCARD_E_INVALID_PARAMETER;
1494        if (!pdwDataLen) return SCARD_E_INVALID_PARAMETER;
1495
1496        if (wcscmp(CCP_CONTAINER_INFO,wszProperty)  == 0)
1497        {
1498                PCONTAINER_INFO p = (PCONTAINER_INFO) pbData;
1499                if (pdwDataLen) *pdwDataLen = sizeof(*p);
1500                if (cbData >= sizeof(DWORD))
1501                        if (p->dwVersion != CONTAINER_INFO_CURRENT_VERSION &&
1502                                p->dwVersion != 0 ) return ERROR_REVISION_MISMATCH;
1503                if (cbData < sizeof(*p)) return ERROR_INSUFFICIENT_BUFFER;
1504                return CardGetContainerInfo(pCardData,bContainerIndex,0,p);
1505        }
1506
1507        if (wcscmp(CCP_PIN_IDENTIFIER,wszProperty) == 0)
1508        {
1509                PPIN_ID p = (PPIN_ID) pbData;
1510                if (pdwDataLen) *pdwDataLen = sizeof(*p);
1511                if (cbData < sizeof(*p)) return ERROR_INSUFFICIENT_BUFFER;
1512                *p = ROLE_USER;
1513                logprintf(pCardData, 2,"Return Pin id %u\n",*p);
1514                return SCARD_S_SUCCESS;
1515        }
1516
1517        return SCARD_E_INVALID_PARAMETER;
1518}
1519
1520DWORD WINAPI CardSetContainerProperty(__in PCARD_DATA pCardData,
1521        __in BYTE bContainerIndex,
1522        __in LPCWSTR wszProperty,
1523        __in_bcount(cbDataLen) PBYTE pbData,
1524        __in DWORD cbDataLen,
1525        __in DWORD dwFlags)
1526{
1527        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
1528        logprintf(pCardData, 1, "CardSetContainerProperty - unsupported\n");
1529        return SCARD_E_UNSUPPORTED_FEATURE;
1530}
1531
1532DWORD WINAPI CardGetProperty(__in PCARD_DATA pCardData,
1533        __in LPCWSTR wszProperty,
1534        __out_bcount_part_opt(cbData, *pdwDataLen) PBYTE pbData,
1535        __in DWORD cbData,
1536        __out PDWORD pdwDataLen,
1537        __in DWORD dwFlags)
1538{
1539        VENDOR_SPECIFIC *vs;
1540
1541        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
1542        logprintf(pCardData, 1, "CardGetProperty\n");
1543        if (!pCardData) return SCARD_E_INVALID_PARAMETER;
1544        logprintf(pCardData, 2, "CardGetProperty wszProperty=%S, cbData=%u, dwFlags=%u\n", \
1545                NULLWSTR(wszProperty),cbData,dwFlags);
1546        if (!wszProperty) return SCARD_E_INVALID_PARAMETER;
1547        if (!pbData) return SCARD_E_INVALID_PARAMETER;
1548        if (!pdwDataLen) return SCARD_E_INVALID_PARAMETER;
1549
1550        vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
1551
1552        check_reader_status(pCardData);
1553
1554        if (wcscmp(CP_CARD_FREE_SPACE,wszProperty) == 0)
1555        {
1556                PCARD_FREE_SPACE_INFO pCardFreeSpaceInfo = (PCARD_FREE_SPACE_INFO )pbData;
1557                if (pdwDataLen) *pdwDataLen = sizeof(*pCardFreeSpaceInfo);
1558                if (cbData < sizeof(*pCardFreeSpaceInfo)) return SCARD_E_NO_MEMORY;
1559                if (pCardFreeSpaceInfo->dwVersion > CARD_FREE_SPACE_INFO_CURRENT_VERSION )
1560                        return ERROR_REVISION_MISMATCH;
1561
1562                pCardFreeSpaceInfo->dwVersion = CARD_FREE_SPACE_INFO_CURRENT_VERSION;
1563                pCardFreeSpaceInfo->dwBytesAvailable = -1;
1564                pCardFreeSpaceInfo->dwMaxKeyContainers = vs->cert_count;
1565                pCardFreeSpaceInfo->dwKeyContainersAvailable = vs->cert_count;
1566
1567                logprintf(pCardData, 7, "pCardFreeSpaceInfo ");
1568                loghex(pCardData, 7, pbData, *pdwDataLen);
1569
1570                return SCARD_S_SUCCESS;
1571        }
1572        if (wcscmp(CP_CARD_CAPABILITIES,wszProperty) == 0)
1573        {
1574                PCARD_CAPABILITIES pCardCapabilities = (PCARD_CAPABILITIES )pbData;
1575                if (pdwDataLen) *pdwDataLen = sizeof(*pCardCapabilities);
1576                if (cbData < sizeof(*pCardCapabilities)) return ERROR_INSUFFICIENT_BUFFER;
1577                if (pCardCapabilities->dwVersion != CARD_CAPABILITIES_CURRENT_VERSION &&
1578                        pCardCapabilities->dwVersion != 0) return ERROR_REVISION_MISMATCH;
1579
1580                pCardCapabilities->dwVersion = CARD_CAPABILITIES_CURRENT_VERSION;
1581                pCardCapabilities->fCertificateCompression = TRUE;
1582                pCardCapabilities->fKeyGen = FALSE;
1583
1584                logprintf(pCardData, 7, "pCardCapabilities ");
1585                loghex(pCardData, 7, pbData, *pdwDataLen);
1586
1587                return SCARD_S_SUCCESS;
1588        }
1589        if (wcscmp(CP_CARD_KEYSIZES,wszProperty) == 0)
1590        {
1591                PCARD_KEY_SIZES pKeySizes = (PCARD_KEY_SIZES )pbData;
1592                if (pdwDataLen) *pdwDataLen = sizeof(*pKeySizes);
1593                if (cbData < sizeof(*pKeySizes)) return ERROR_INSUFFICIENT_BUFFER;
1594                if (pKeySizes->dwVersion != CARD_KEY_SIZES_CURRENT_VERSION &&
1595                        pKeySizes->dwVersion != 0) return ERROR_REVISION_MISMATCH;
1596
1597                pKeySizes->dwVersion = CARD_KEY_SIZES_CURRENT_VERSION;
1598                pKeySizes->dwMinimumBitlen = 512;
1599                pKeySizes->dwDefaultBitlen = 1024;
1600                pKeySizes->dwMaximumBitlen = 16384;
1601                pKeySizes->dwIncrementalBitlen = 64;
1602
1603                logprintf(pCardData, 7, "pKeySizes ");
1604                loghex(pCardData, 7, pbData, *pdwDataLen);
1605
1606                return SCARD_S_SUCCESS;
1607        }
1608        if (wcscmp(CP_CARD_READ_ONLY,wszProperty) == 0)
1609        {
1610                BOOL *p = (BOOL*)pbData;
1611                if (pdwDataLen) *pdwDataLen = sizeof(*p);
1612                if (cbData < sizeof(*p)) return ERROR_INSUFFICIENT_BUFFER;
1613                *p = TRUE; /* XXX HACK */
1614
1615                logprintf(pCardData, 7, "pcardReadOnly");
1616                loghex(pCardData, 7, pbData, *pdwDataLen);
1617                return SCARD_S_SUCCESS;
1618        }
1619        if (wcscmp(CP_CARD_CACHE_MODE,wszProperty) == 0)
1620        {
1621                DWORD *p = (DWORD *)pbData;
1622                if (pdwDataLen) *pdwDataLen = sizeof(*p);
1623                if (cbData < sizeof(*p)) return ERROR_INSUFFICIENT_BUFFER;
1624                *p = CP_CACHE_MODE_NO_CACHE;
1625
1626                logprintf(pCardData, 7, "pCardCacheMode ");
1627                loghex(pCardData, 7, pbData, *pdwDataLen);
1628                return SCARD_S_SUCCESS;
1629        }
1630        if (wcscmp(CP_SUPPORTS_WIN_X509_ENROLLMENT,wszProperty) == 0)
1631        {
1632                DWORD *p = (DWORD *)pbData;
1633                if (pdwDataLen) *pdwDataLen = sizeof(*p);
1634                if (cbData < sizeof(*p)) return ERROR_INSUFFICIENT_BUFFER;
1635                *p = 0;
1636
1637                logprintf(pCardData, 7, "pSupportsX509Enrolment ");
1638                loghex(pCardData, 7, pbData, *pdwDataLen);
1639                return SCARD_S_SUCCESS;
1640        }
1641        if (wcscmp(CP_CARD_GUID,wszProperty) == 0)
1642        {
1643                if (pdwDataLen) *pdwDataLen = sizeof(vs->cardFiles.file_cardid);
1644                if (cbData < sizeof(vs->cardFiles.file_cardid)) return ERROR_INSUFFICIENT_BUFFER;
1645
1646                CopyMemory(pbData,vs->cardFiles.file_cardid,sizeof(vs->cardFiles.file_cardid));
1647
1648                logprintf(pCardData, 7, "CardGUID ");
1649                loghex(pCardData, 7, pbData, *pdwDataLen);
1650                return SCARD_S_SUCCESS;
1651        }
1652        if (wcscmp(CP_CARD_SERIAL_NO,wszProperty) == 0)
1653        {
1654                if (pdwDataLen) *pdwDataLen = sizeof(vs->p15card->tokeninfo->serial_number);
1655                if (cbData < sizeof(vs->p15card->tokeninfo->serial_number)) return ERROR_INSUFFICIENT_BUFFER;
1656
1657                CopyMemory(pbData,vs->p15card->tokeninfo->serial_number,sizeof(vs->p15card->tokeninfo->serial_number));
1658
1659                logprintf(pCardData, 7, "SerialNumber ");
1660                loghex(pCardData, 7, pbData, *pdwDataLen);
1661                return SCARD_S_SUCCESS;
1662        }
1663        if (wcscmp(CP_CARD_PIN_INFO,wszProperty) == 0)
1664        {
1665                PPIN_INFO p = (PPIN_INFO) pbData;
1666                if (pdwDataLen) *pdwDataLen = sizeof(*p);
1667                if (cbData < sizeof(*p)) return ERROR_INSUFFICIENT_BUFFER;
1668                if (p->dwVersion != PIN_INFO_CURRENT_VERSION) return ERROR_REVISION_MISMATCH;
1669                p->PinType = AlphaNumericPinType;
1670                p->dwFlags = 0;
1671                switch (dwFlags)
1672                {
1673                        case ROLE_USER:
1674                                logprintf(pCardData, 2,"returning info on PIN ROLE_USER ( Auth ) [%u]\n",dwFlags);
1675                                p->PinPurpose = DigitalSignaturePin;
1676                                p->PinCachePolicy.dwVersion = PIN_CACHE_POLICY_CURRENT_VERSION;
1677                                p->PinCachePolicy.dwPinCachePolicyInfo = 0;
1678                                p->PinCachePolicy.PinCachePolicyType = PinCacheNormal;
1679                                p->dwChangePermission = 0;
1680                                p->dwUnblockPermission = 0;
1681                                break;
1682                        default:
1683                                logprintf(pCardData, 0,"Invalid Pin number %u requested\n",dwFlags);
1684                                return SCARD_E_INVALID_PARAMETER;
1685                        }
1686
1687                loghex(pCardData, 7, pbData, *pdwDataLen);
1688
1689
1690                return SCARD_S_SUCCESS;
1691        }
1692        if (wcscmp(CP_CARD_LIST_PINS,wszProperty) == 0)
1693        {
1694                PPIN_SET p = (PPIN_SET) pbData;
1695                if (pdwDataLen) *pdwDataLen = sizeof(*p);
1696                if (cbData < sizeof(*p)) return ERROR_INSUFFICIENT_BUFFER;
1697                SET_PIN(*p, ROLE_USER);
1698                logprintf(pCardData, 7, "CARD_LIST_PINS ");
1699                loghex(pCardData, 7, pbData, *pdwDataLen);
1700
1701                return SCARD_S_SUCCESS;
1702        }
1703        if (wcscmp(CP_CARD_AUTHENTICATED_STATE,wszProperty) == 0)
1704        {
1705                PPIN_SET p = (PPIN_SET) pbData;
1706                if (pdwDataLen) *pdwDataLen = sizeof(*p);
1707                if (cbData < sizeof(*p)) return ERROR_INSUFFICIENT_BUFFER;
1708                logprintf(pCardData, 7, "CARD_AUTHENTICATED_STATE invalid\n");
1709                return SCARD_E_INVALID_PARAMETER;
1710        }
1711        if (wcscmp(CP_CARD_PIN_STRENGTH_VERIFY,wszProperty) == 0)
1712        {
1713                DWORD *p = (DWORD *)pbData;
1714                if (dwFlags != ROLE_USER) return SCARD_E_INVALID_PARAMETER;
1715                if (pdwDataLen) *pdwDataLen = sizeof(*p);
1716                if (cbData < sizeof(*p)) return ERROR_INSUFFICIENT_BUFFER;
1717                *p = CARD_PIN_STRENGTH_PLAINTEXT;
1718
1719                logprintf(pCardData, 7, "CARD_PIN_STRENGTH_VERIFY");
1720                loghex(pCardData, 7, pbData, *pdwDataLen);
1721
1722                return SCARD_S_SUCCESS;
1723        }
1724        if (wcscmp(CP_CARD_PIN_STRENGTH_CHANGE,wszProperty) == 0)
1725        {
1726                return SCARD_E_UNSUPPORTED_FEATURE;
1727        }
1728        if (wcscmp(CP_CARD_PIN_STRENGTH_UNBLOCK,wszProperty)  == 0)
1729        {
1730                return SCARD_E_UNSUPPORTED_FEATURE;
1731        }
1732
1733        logprintf(pCardData, 3, "INVALID PARAMETER\n");
1734        return SCARD_E_INVALID_PARAMETER;
1735}
1736
1737DWORD WINAPI CardSetProperty(__in   PCARD_DATA pCardData,
1738        __in LPCWSTR wszProperty,
1739        __in_bcount(cbDataLen)  PBYTE pbData,
1740        __in DWORD cbDataLen,
1741        __in DWORD dwFlags)
1742{
1743        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
1744        logprintf(pCardData, 1, "CardSetProperty\n");
1745
1746        if (!pCardData) return SCARD_E_INVALID_PARAMETER;
1747
1748        logprintf(pCardData, 2, "CardSetProperty wszProperty=%S, cbDataLen=%u, dwFlags=%u",\
1749                NULLWSTR(wszProperty),cbDataLen,dwFlags);
1750
1751        if (!wszProperty) return SCARD_E_INVALID_PARAMETER;
1752
1753        if (wcscmp(CP_CARD_PIN_STRENGTH_VERIFY, wszProperty) == 0 ||
1754                wcscmp(CP_CARD_PIN_INFO, wszProperty) == 0) return SCARD_E_INVALID_PARAMETER;
1755
1756        if (dwFlags) return SCARD_E_INVALID_PARAMETER;
1757
1758        if (wcscmp(CP_PIN_CONTEXT_STRING, wszProperty) == 0)
1759                return SCARD_S_SUCCESS;
1760
1761        if (wcscmp(CP_CARD_CACHE_MODE, wszProperty) == 0 ||
1762                wcscmp(CP_SUPPORTS_WIN_X509_ENROLLMENT, wszProperty) == 0 ||
1763                wcscmp(CP_CARD_GUID, wszProperty) == 0 ||
1764                wcscmp(CP_CARD_SERIAL_NO, wszProperty) == 0) {
1765                        return SCARD_E_INVALID_PARAMETER;
1766        }
1767
1768        if (!pbData) return SCARD_E_INVALID_PARAMETER;
1769        if (!cbDataLen) return SCARD_E_INVALID_PARAMETER;
1770
1771        if (wcscmp(CP_PARENT_WINDOW, wszProperty) == 0) {
1772                if (cbDataLen != sizeof(DWORD))
1773                        return SCARD_E_INVALID_PARAMETER;
1774                else
1775                {
1776                        HWND cp = *((HWND *) pbData);
1777                        if (cp!=0 && !IsWindow(cp))  return SCARD_E_INVALID_PARAMETER;
1778                }
1779                return SCARD_S_SUCCESS;
1780        }
1781
1782        logprintf(pCardData, 3, "INVALID PARAMETER\n");
1783        return SCARD_E_INVALID_PARAMETER;
1784}
1785
1786#define MINIMUM_VERSION_SUPPORTED (4)
1787#define CURRENT_VERSION_SUPPORTED (6)
1788
1789DWORD WINAPI CardAcquireContext(IN PCARD_DATA pCardData, __in DWORD dwFlags)
1790{
1791        VENDOR_SPECIFIC *vs;
1792        DWORD suppliedVersion = 0;
1793        u8 challenge[8];
1794
1795        if (!pCardData)
1796                return SCARD_E_INVALID_PARAMETER;
1797        if (dwFlags)
1798                return SCARD_E_INVALID_PARAMETER;
1799
1800        suppliedVersion = pCardData->dwVersion;
1801
1802        /* VENDOR SPECIFIC */
1803        vs = pCardData->pvVendorSpecific = \
1804                pCardData->pfnCspAlloc(sizeof(VENDOR_SPECIFIC));
1805        memset(vs, 0, sizeof(VENDOR_SPECIFIC));
1806
1807        logprintf(pCardData, 1, "=================================" \
1808                                        "=================================\n");
1809
1810        logprintf(pCardData, 1, "\nP:%d T:%d pCardData:%p ",GetCurrentProcessId(), GetCurrentThreadId(), pCardData);
1811        logprintf(pCardData, 1, "CardAcquireContext, dwVersion=%u, name=%S," \
1812                        "hScard=0x%08X, hSCardCtx=0x%08X\n", pCardData->dwVersion, \
1813                        NULLWSTR(pCardData->pwszCardName),pCardData->hScard, \
1814                        pCardData->hSCardCtx);
1815
1816        vs->hScard = pCardData->hScard;
1817        vs->hSCardCtx = pCardData->hSCardCtx;
1818
1819        /* The lowest supported version is 4. */
1820        if (pCardData->dwVersion < MINIMUM_VERSION_SUPPORTED)
1821        {
1822                return (DWORD) ERROR_REVISION_MISMATCH;
1823        }
1824
1825        if( pCardData->hScard == 0)
1826        {
1827                logprintf(pCardData, 0, "Invalide handle.\n");
1828                return SCARD_E_INVALID_HANDLE;
1829        }
1830
1831        logprintf(pCardData, 2, "request version pCardData->dwVersion = %d\n", pCardData->dwVersion);
1832
1833        pCardData->dwVersion = min(pCardData->dwVersion, CURRENT_VERSION_SUPPORTED);
1834
1835        logprintf(pCardData, 2, "pCardData->dwVersion = %d\n", pCardData->dwVersion);
1836
1837        if(1)
1838        {
1839                int r;
1840                sc_context_param_t ctx_param;
1841
1842                vs->ctx = NULL;
1843
1844                logprintf(pCardData, 3, "create ctx\n");
1845
1846                memset(&ctx_param, 0, sizeof(ctx_param));
1847                ctx_param.ver = 1;
1848                ctx_param.app_name = "cardmod";
1849
1850                r = sc_context_create(&(vs->ctx), &ctx_param);
1851                logprintf(pCardData, 3, "sc_context_create passed r = %d\n", r);
1852                if (r)
1853                {
1854                        logprintf(pCardData, 0, "Failed to establish context: %s\n", \
1855                                sc_strerror(r));
1856                        return SCARD_F_UNKNOWN_ERROR;
1857                }
1858        }
1859
1860        pCardData->pfnCardDeleteContext = CardDeleteContext;
1861        pCardData->pfnCardQueryCapabilities = CardQueryCapabilities;
1862        pCardData->pfnCardDeleteContainer = CardDeleteContainer;
1863        pCardData->pfnCardCreateContainer = CardCreateContainer;
1864        pCardData->pfnCardGetContainerInfo = CardGetContainerInfo;
1865        pCardData->pfnCardAuthenticatePin = CardAuthenticatePin;
1866        pCardData->pfnCardGetChallenge = CardGetChallenge;
1867        pCardData->pfnCardAuthenticateChallenge = CardAuthenticateChallenge;
1868        pCardData->pfnCardUnblockPin = CardUnblockPin;
1869        pCardData->pfnCardChangeAuthenticator = CardChangeAuthenticator;
1870        pCardData->pfnCardDeauthenticate = CardDeauthenticate; /* NULL */
1871        pCardData->pfnCardCreateDirectory = CardCreateDirectory;
1872        pCardData->pfnCardDeleteDirectory = CardDeleteDirectory;
1873        pCardData->pvUnused3 = NULL;
1874        pCardData->pvUnused4 = NULL;
1875        pCardData->pfnCardCreateFile = CardCreateFile;
1876        pCardData->pfnCardReadFile = CardReadFile;
1877        pCardData->pfnCardWriteFile = CardWriteFile;
1878        pCardData->pfnCardDeleteFile = CardDeleteFile;
1879        pCardData->pfnCardEnumFiles = CardEnumFiles;
1880        pCardData->pfnCardGetFileInfo = CardGetFileInfo;
1881        pCardData->pfnCardQueryFreeSpace = CardQueryFreeSpace;
1882        pCardData->pfnCardQueryKeySizes = CardQueryKeySizes;
1883        pCardData->pfnCardSignData = CardSignData;
1884        pCardData->pfnCardRSADecrypt = CardRSADecrypt;
1885        pCardData->pfnCardConstructDHAgreement = CardConstructDHAgreement;
1886
1887        associate_card(pCardData);
1888
1889        logprintf(pCardData, 1, "OpenSC init done.\n");
1890
1891        if(sc_get_challenge(vs->p15card->card, challenge, sizeof(challenge)))
1892        {
1893                vs->cardFiles.file_cardcf.wContainersFreshness = rand()%30000;
1894                vs->cardFiles.file_cardcf.wFilesFreshness = rand()%30000;
1895        }
1896        else
1897        {
1898                vs->cardFiles.file_cardcf.wContainersFreshness = challenge[0]*256+challenge[1];
1899                vs->cardFiles.file_cardcf.wFilesFreshness = challenge[3]*256+challenge[4];
1900        }
1901
1902        if (suppliedVersion > 4) {
1903                pCardData->pfnCardDeriveKey = CardDeriveKey;
1904                pCardData->pfnCardDestroyDHAgreement = CardDestroyDHAgreement;
1905                pCardData->pfnCspGetDHAgreement = CspGetDHAgreement;
1906
1907                if (suppliedVersion > 5 ) {
1908                        pCardData->pfnCardGetChallengeEx = CardGetChallengeEx;
1909                        pCardData->pfnCardAuthenticateEx = CardAuthenticateEx;
1910                        pCardData->pfnCardChangeAuthenticatorEx = CardChangeAuthenticatorEx;
1911                        pCardData->pfnCardDeauthenticateEx = CardDeauthenticateEx;
1912                        pCardData->pfnCardGetContainerProperty = CardGetContainerProperty;
1913                        pCardData->pfnCardSetContainerProperty = CardSetContainerProperty;
1914                        pCardData->pfnCardGetProperty = CardGetProperty;
1915                        pCardData->pfnCardSetProperty = CardSetProperty;
1916                }
1917        }
1918
1919        return SCARD_S_SUCCESS;
1920}
1921
1922static int associate_card(PCARD_DATA pCardData)
1923{
1924    VENDOR_SPECIFIC *vs;
1925        int  r;
1926        BYTE empty_appdir[] = {1,'m','s','c','p',0,0,0,0};
1927        BYTE empty_cardcf[6]={0,0,0,0,0,0};
1928        BYTE empty_cardid[16]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
1929
1930        logprintf(pCardData, 1, "associate_card\n");
1931        vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
1932        /*
1933         * set the addresses of the reader and card handles
1934         * Our cardmod pcsc code will use these  when we call sc_ctx_use_reader
1935         * We use the address of the handles as provided in the pCardData
1936         */
1937        vs->hSCardCtx = pCardData->hSCardCtx;
1938        vs->hScard = pCardData->hScard;
1939
1940        memcpy(vs->cardFiles.file_appdir, empty_appdir, sizeof(empty_appdir));
1941        memset(&(vs->cardFiles.file_cardcf), 0, sizeof(vs->cardFiles.file_cardcf));
1942        memcpy(vs->cardFiles.file_cardid, empty_cardid, sizeof(empty_cardid));
1943
1944        /* set the provided reader and card handles into ctx */
1945        logprintf(pCardData, 5, "cardmod_use_handles %d\n", \
1946        sc_ctx_use_reader(vs->ctx, &vs->hSCardCtx, &vs->hScard));
1947
1948        /* should be only one reader */
1949        logprintf(pCardData, 5, "sc_ctx_get_reader_count(ctx): %d\n", \
1950                        sc_ctx_get_reader_count(vs->ctx));
1951
1952        vs->reader = sc_ctx_get_reader(vs->ctx, 0);
1953        if(vs->reader)
1954        {
1955                logprintf(pCardData, 3, "%s\n", NULLSTR(vs->reader->name));
1956
1957                r = sc_connect_card(vs->reader, &(vs->card));
1958                logprintf(pCardData, 2, "sc_connect_card result = %d, %s\n", \
1959                                r, sc_strerror(r));
1960                if(!r)
1961                {
1962                        r = sc_pkcs15_bind(vs->card, NULL, &(vs->p15card));
1963                        logprintf(pCardData, 2, "PKCS#15 initialization result: %d, %s\n", \
1964                                r, sc_strerror(r));
1965                }
1966        }
1967
1968        if(vs->card == NULL || vs->p15card == NULL)
1969        {
1970                logprintf(pCardData, 0, "Card unknow.\n");
1971                return SCARD_E_UNKNOWN_CARD;
1972        }
1973
1974        /*
1975         * We want a 16 byte unique serial number
1976         * PKCS15 gives us a char string, that
1977         * appears to have been formated with %02x or %02X
1978         * so as to make it printable.
1979         * So for now we will try and convert back to bin,
1980         * and use the last 32 bytes of the vs-p15card->tokeninfo->serial_number
1981         * TODO needs to be looked at closer
1982         */
1983
1984        if (vs->p15card->tokeninfo && vs->p15card->tokeninfo->serial_number) {
1985                size_t len1, len2;
1986                char * cserial;
1987
1988                len1 = strlen(vs->p15card->tokeninfo->serial_number);
1989                cserial = vs->p15card->tokeninfo->serial_number;
1990                len2 = sizeof(vs->cardFiles.file_cardid) * 2;
1991                if ( len1 > len2) {
1992                        cserial += len1 - len2;
1993                        len1 = len2;
1994                }
1995                len1 /= 2;
1996                r = sc_hex_to_bin(cserial, vs->cardFiles.file_cardid, &len1);
1997                logprintf(pCardData, 7, "serial number r=%d len1=%d len2=%d ",r, len1, len2);
1998                loghex(pCardData, 7, vs->cardFiles.file_cardid, sizeof(vs->cardFiles.file_cardid));
1999        }
2000
2001
2002        r = sc_pkcs15_get_objects(vs->p15card, SC_PKCS15_TYPE_CERT_X509, \
2003                vs->cert_objs, 32);
2004        if (r < 0)
2005        {
2006                logprintf(pCardData, 0, "Certificate enumeration failed: %s\n", \
2007                        sc_strerror(r));
2008                return SCARD_F_UNKNOWN_ERROR;
2009        }
2010
2011        vs->cert_count = r;
2012        logprintf(pCardData, 2, "Found %d certificat(s) in the card.\n", \
2013                vs->cert_count);
2014
2015        r = sc_pkcs15_get_objects(vs->p15card, SC_PKCS15_TYPE_PRKEY_RSA, \
2016                vs->prkey_objs, 32);
2017        if (r < 0)
2018        {
2019                logprintf(pCardData, 0, "Private key enumeration failed: %s\n", \
2020                        sc_strerror(r));
2021                return SCARD_F_UNKNOWN_ERROR;
2022        }
2023
2024        vs->prkey_count = r;
2025        logprintf(pCardData, 2, "Found %d private key(s) in the card.\n", \
2026                vs->prkey_count);
2027
2028        r = sc_pkcs15_get_objects(vs->p15card, SC_PKCS15_TYPE_AUTH_PIN, \
2029                vs->pin_objs, 8);
2030        if (r < 0)
2031        {
2032                logprintf(pCardData, 2, "Pin object enumeration failed: %s\n", \
2033                        sc_strerror(r));
2034                return SCARD_F_UNKNOWN_ERROR;
2035        }
2036
2037        vs->pin_count = r;
2038        logprintf(pCardData, 2, "Found %d pin(s) in the card.\n", \
2039                vs->pin_count);
2040
2041#if 1
2042        dump_objects(pCardData);
2043#endif
2044
2045        return SCARD_S_SUCCESS;
2046
2047}
2048
2049static int disassociate_card(PCARD_DATA pCardData)
2050{
2051
2052    VENDOR_SPECIFIC *vs;
2053        int i;
2054
2055        vs = (VENDOR_SPECIFIC*)(pCardData->pvVendorSpecific);
2056        logprintf(pCardData, 1, "disassociate_card\n");
2057
2058        if(vs->pin != NULL)
2059        {
2060                free(vs->pin);
2061                vs->pin = NULL;
2062        }
2063
2064        for (i = 0; i < vs->cert_count; i++) {
2065                vs->cert_objs[i] = NULL;
2066        }
2067        vs->cert_count = 0;
2068
2069        for (i = 0; i < vs->prkey_count; i++) {
2070                vs->prkey_objs[i] = NULL;
2071        }
2072        vs->prkey_count = 0;
2073
2074        for (i = 0; i < vs->pin_count; i++) {
2075                vs->pin_objs[i] = NULL;
2076        }
2077        vs->pin_count = 0;
2078
2079
2080        if(vs->p15card)
2081        {
2082                logprintf(pCardData, 6, "sc_pkcs15_unbind\n");
2083                sc_pkcs15_unbind(vs->p15card);
2084                vs->p15card = NULL;
2085        }
2086
2087        if(vs->card)
2088        {
2089                logprintf(pCardData, 6, "sc_disconnect_card\n");
2090                sc_disconnect_card(vs->card);
2091                vs->card = NULL;
2092        }
2093
2094        vs->reader = NULL;
2095
2096        vs->hSCardCtx = -1;
2097        vs->hScard = -1;
2098
2099        return SCARD_S_SUCCESS;
2100}
2101
2102
2103BOOL APIENTRY DllMain( HMODULE hModule,
2104        DWORD  ul_reason_for_call,
2105        LPVOID lpReserved
2106)
2107{
2108#ifdef CARDMOD_LOW_LEVEL_DEBUG
2109        logprintf(NULL,8,"\n********** DllMain hModule=0x%08X reason=%d Reserved=%p P:%d T:%d\n",
2110                hModule, ul_reason_for_call, lpReserved, GetCurrentProcessId(), GetCurrentThreadId());
2111#endif
2112        switch (ul_reason_for_call)
2113        {
2114                case DLL_PROCESS_ATTACH:
2115#ifdef CARDMOD_LOW_LEVEL_DEBUG
2116                        {
2117                                CHAR name[MAX_PATH + 1] = "\0";
2118                                GetModuleFileName(GetModuleHandle(NULL),name,MAX_PATH);
2119                                logprintf(NULL,1,"** DllMain Attach ModuleFileName=%s\n",name);
2120                        }
2121#endif
2122                        break;
2123                case DLL_THREAD_ATTACH:
2124                case DLL_THREAD_DETACH:
2125                        break;
2126       case DLL_PROCESS_DETACH:
2127                        break;
2128        }
2129        return TRUE;
2130}
2131
2132#ifdef _MANAGED
2133#pragma managed(pop)
2134#endif
2135#endif
2136
Note: See TracBrowser for help on using the repository browser.