As a lot of full CSPs are based on PKCS#11, I want to use our PKCS#11 in the
minidriver. I read the Minidriver Specification, but there were some
functions like Challenge Response authentication or writing files which are
not supported by PKCS#11. We only want to use the cards for certificate
authentication and signing (e.g. outlook, website authentication, logon) and
roll out certificates with certsrv but not to store user data on them.
Has somebody experience with a minidriver based on PKCS#11? Does this work
or are there major problems expected.
By reading the specification there come some questions up.
When rolling out a certificate, a keypair is generated. I think this is done
with CardCreateContainer. Then also the certificate is written to the card.
Which command is therefore used and how is the certificate and keypair
referenced. In PKCS#11 there is the CKA_ID which has the same value to check
the belonging.
To check which function of the minidriver the applications are calling with
the parameters, it would be useful to debug a minidriver. How can I debug it?
Is the driver running in kernel mode or can I debug it like a normal dll.
How can I debug during logon? Do I need to debug in kernel mode with 2 PCs
and a serial cable, or is there a more convenient way?
I also downloded the CNG Sample, but there is no sample for a minidriver. I
read that there is a minidriver sample existing, but how can I get it?
It would be fine if somebody can give me some hints.
regars
Alex
> As a lot of full CSPs are based on PKCS#11, I want to use our PKCS#11 in
> the
> minidriver.
I wouldn't really say that a lot of full CSPs are based on an underlying
PKCS#11 library. My experience is that it's a lot easier to write a CSP
that directly sends APDUs to the smart card using the smart card API, than
trying to map a PKCS#11 library model onto the entirely different CSP model.
> I read the Minidriver Specification, but there were some
> functions like Challenge Response authentication or writing files which
> are
> not supported by PKCS#11. We only want to use the cards for certificate
> authentication and signing (e.g. outlook, website authentication, logon)
> and
> roll out certificates with certsrv but not to store user data on them.
You don't have to support the challenge response authentication, which is
used for administrator 'log on' to the card. However, you won't be able to
e.g. use the pintool.exe tool to unblock a card if you don't have
challenge/response authentication.
You don't need to have a file system physically on your card, however your
smart card minidriver will have to emulate one. E.g., the card ID will be
read from the \cardid file and the container map file (mscp\cmapfile) will
link key container names to key numbers. Your minidriver can translate a
CardReadFile() call for the \cardid file into an APDU that retrieves a
unique card id from the card and then retrurn the card id to the caller,
without the need for a file to actually exist on the card.
> Has somebody experience with a minidriver based on PKCS#11? Does this work
> or are there major problems expected.
It's probably doable; but I wouldn't do it. My guess is you'll lose a lot
of time and encounter a lot of frustration trying to map 3 different
cryptographic token models: (1) the model implicitly assumed by the
minidriver model, (2) the PKCS#11 model and (3) the actual architecture of
your smart card and its APDU command and feature set. Also, you're bound to
be doing some hacks to make those models match, which will negatively affect
the security and maintainability of your solution.
> To check which function of the minidriver the applications are calling
> with
> the parameters, it would be useful to debug a minidriver. How can I debug
> it?
> Is the driver running in kernel mode or can I debug it like a normal dll.
> How can I debug during logon? Do I need to debug in kernel mode with 2 PCs
> and a serial cable, or is there a more convenient way?
A smart card minidriver works entirely in user mode. You can debug it using
a normal debugger. The application that uses the cryptographic functions
will be calling advapi32.dll, which in turn calls basecsp.dll (the Microsoft
Base Smart Card CSP), which in turn calls your minidriver, all in user mode.
Debugging during logon using a live debugger is not possible as far as I
know. However, you can always write logging traces to a log file and
examine that. In my experience; this is sufficient to debug smart card
logon sequences.
Cheers,
Jan.
The intention why we want to set up the minidriver on the PKCS#11 is, that
our PKCS#11 supports a lot of different cards, but if the mapping is not
possible we have to implement more minidrivers for the different cards.
Do you maybe know, what commands are called when creating a keypair (key
container) and installing the certificate to this keypair?
Is there maybe a testapplication? I found the document "Smart Card
Minidriver Certification Requirements for Base CSP and KSP". There are the
command desribed in detail, but not which data are transfered. This will
maybe save a lot of time, because I will not have to debug all applications,
to see how they call the minidriver.
You wrote, that the challenge response authentication is is used in the
pintool.exe to unblock the card. In most cases the PINs are unblocked with a
PUK and not via challenge response. How can this challenge response
authentication which encrypts a challenge with a key (often DES) mapped to a
PUK. The application which encrypts the challenge must hold the key, do I
have to enter this key in the pintool.exe. In case of a DES key it will be a
least 8 bytes and nobody would remember this key. A PUK can not be used to
encrypt the challenge.
regards
Alexander
Hi,
why not using an existing generic CSP?
Stefan
> Do you maybe know, what commands are called when creating a keypair (key
> container) and installing the certificate to this keypair?
Yes, knowing a typical sequence of calls for this kind of operation is quite
useful for making estmations with regards to your minidriver.
So here you go:
- CardAcquireContext
- CardReadFile for the \cardid file
- CardReadFile for the \cardcf file
- CardReadFile for the mscp\cmapfile; to retrieve the free slots from the
minidriver
- CardQueryKeySizes to get the available key lengths, called twice (for
AT_SIGNATURE and AT_KEYEXCHANGE)
- CardReadFile, again for the \cardcf file
- CardQueryFreeSpace
- CardAuthenticatePin
- CardReadFile for the \cardcf file
- CardAuthenticatePin
- CardWriteFile, updating the \cardcf file
- CardWriteFile to the mscp\cmapfile, creating a key container. Typical
data:
30 00 66 00 38 00 38 00 31 00 61 00 36 00 62 00 0.f.8.8. 1.a.6.b.
2D 00 39 00 61 00 36 00 63 00 2D 00 34 00 61 00 -.9.a.6. c.-.4.a.
37 00 36 00 2D 00 38 00 62 00 37 00 38 00 2D 00 7.6.-.8. b.7.8.-.
62 00 37 00 61 00 63 00 36 00 34 00 38 00 38 00 b.7.a.c. 6.4.8.8.
35 00 66 00 33 00 34 00 00 00 00 00 00 00 00 00 5.f.3.4. ........
01 00 00 00 00 00 ......
This creates a key container with container name
'0f881a6b-9a6c-4a76-8b78-b7ac64885f34', bit 0 of the flags is set,
indicating it is a valid container.
- CardWriteFile, updating the \cardcf file
- CardWriteFile to the mscp\cmapfile, updating the key container. Typical
data:
30 00 66 00 38 00 38 00 31 00 61 00 36 00 62 00 0.f.8.8. 1.a.6.b.
2D 00 39 00 61 00 36 00 63 00 2D 00 34 00 61 00 -.9.a.6. c.-.4.a.
37 00 36 00 2D 00 38 00 62 00 37 00 38 00 2D 00 7.6.-.8. b.7.8.-.
62 00 37 00 61 00 63 00 36 00 34 00 38 00 38 00 b.7.a.c. 6.4.8.8.
35 00 66 00 33 00 34 00 00 00 00 00 00 00 00 00 5.f.3.4. ........
03 00 00 00 00 00 ......
Bit 1 is also set on the flags, indicating the new container is a default
container.
- CardQueryCapabilities is called to verify if the card can generate key
pairs on-card, and if it can compress certificates.
Let's assume the minidriver returns that it cannot generate key pairs on
card. The Base Smart Card CSP will then generate a key pair and store it on
the card:
- CardWriteFile, updating the \cardcf file
- CardCreateContainer is called with the CARD_CREATE_CONTAINER_KEY_IMPORT
flag set, i.e. the key material is provided by the Base Smart Card CSP and
passed in pbKeyData
- CardWriteFile, updating the \cardcf file
- CardWriteFile to the mscp\cmapfile, updating the key container. Typical
data:
30 00 66 00 38 00 38 00 31 00 61 00 36 00 62 00 0.f.8.8. 1.a.6.b.
2D 00 39 00 61 00 36 00 63 00 2D 00 34 00 61 00 -.9.a.6. c.-.4.a.
37 00 36 00 2D 00 38 00 62 00 37 00 38 00 2D 00 7.6.-.8. b.7.8.-.
62 00 37 00 61 00 63 00 36 00 34 00 38 00 38 00 b.7.a.c. 6.4.8.8.
35 00 66 00 33 00 34 00 00 00 00 00 00 00 00 00 5.f.3.4. ........
03 00 00 00 00 04 ......
The key length data has now been updated; indicating we have a 1024 bit Key
Exchange key in the container.
- CardGetContainerInfo is called, retrieving back the public key.
- CardSignData is called twice to sign a hash using the private key.
- CardDeauthenticate is called
- CardReadFile for the \cardcf file, twice
- CardAuthenticatePin
- CardWriteFile, updating the \cardcf file
- CardDeleteFile, deleting the privious certuficate in e.g. mscp\kxc00
- CardWriteFile, updating the \cardcf file
- CardCreateFile, to create e.g. the mscp\kxc00 file to write the key
exchange certificate in for key 00
- CardWriteFile, updating the \cardcf file
- CardWriteFile to e.g. mscp\kxc00, writing the certificate
- CardReadFile for the mscp\cmapfile
- CardWriteFile, updating the \cardcf file
- CardWriteFile, updating the mscp\cmapfile
- CardDeauthenticate is called.
> Is there maybe a testapplication? I found the document "Smart Card
> Minidriver Certification Requirements for Base CSP and KSP". There are the
> command desribed in detail, but not which data are transfered. This will
> maybe save a lot of time, because I will not have to debug all
> applications, to see how they call the minidriver.
A smart card minidriver test suite is available from Microsoft. However, it
will still be useful to look at real life use case scenarios, to see what is
expected in practise from the minidriver; especially since you will probably
not be able to fully implement the minidriver specification...
> You wrote, that the challenge response authentication is is used in the
> pintool.exe to unblock the card. In most cases the PINs are unblocked with
> a PUK and not via challenge response. How can this challenge response
> authentication which encrypts a challenge with a key (often DES) mapped to
> a PUK. The application which encrypts the challenge must hold the key, do
> I have to enter this key in the pintool.exe. In case of a DES key it will
> be a least 8 bytes and nobody would remember this key. A PUK can not be
> used to encrypt the challenge.
Exactly. If your card has a PUK instead of a challenge response system for
allowing administrator authentication, you will not be able to implement the
challenge response scheme. This means you will have to provide a card
unblock tool separately, since you will not be able to use the pintool.exe
that comes with the Microsoft Base Smart Card CSP.
Cheers,
Jan.
>
> why not using an existing generic CSP?
>
We tested the CSP from Identity Alliance which is based on PKCS#11. Email
encryption and signing and also the web authenication with IE works fine,
but sometimes it produces an application error.
Do you know some other generic CSPs we can test? This would be fine.
Apart from that, we want to support Windows Vista.
Vista has no Gina and as I understood the credential provider uses the Base
CSP and therefore the Card Mini Driver. The card minidriver should be easier
to implement than a full CSP and I'm now collecting a much information I can
get.
regards
Alex
Thank you for the detailed description. This helps me a lot.
> A smart card minidriver test suite is available from Microsoft. However,
> it will still be useful to look at real life use case scenarios, to see
> what is expected in practise from the minidriver; especially since you
> will probably not be able to fully implement the minidriver
> specification...
Do you know how to get this test suite? We have a MSDN subscripion, but I
didn't find it. Maybe there is also a sample project for a card mini driver,
I have read in an other thread.
> Exactly. If your card has a PUK instead of a challenge response system
> for allowing administrator authentication, you will not be able to
> implement the challenge response scheme. This means you will have to
> provide a card unblock tool separately, since you will not be able to use
> the pintool.exe that comes with the Microsoft Base Smart Card CSP.
In the specification there is also the function CardUnblockPin defined. If
in "pbAuthenticationData" a pointer to a PUK is specified instead of the
response data of CardGetChallenge() as specified, this could probably work.
What do you think?
regards Alex
> Thank you for the detailed description. This helps me a lot.
My pleasure!
>> A smart card minidriver test suite is available from Microsoft. However,
>> it will still be useful to look at real life use case scenarios, to see
>> what is expected in practise from the minidriver; especially since you
>> will probably not be able to fully implement the minidriver
>> specification...
>
> Do you know how to get this test suite? We have a MSDN subscripion, but I
> didn't find it. Maybe there is also a sample project for a card mini
> driver, I have read in an other thread.
I quickly checked and indeed it's not in MSDN, nor available on-line as far
as I can see. We have a beta version; so I'm not sure whether it has been
released yet. You might want to contact Microsoft to check how you can get
hold of the test suite...
>> Exactly. If your card has a PUK instead of a challenge response system
>> for allowing administrator authentication, you will not be able to
>> implement the challenge response scheme. This means you will have to
>> provide a card unblock tool separately, since you will not be able to use
>> the pintool.exe that comes with the Microsoft Base Smart Card CSP.
>
> In the specification there is also the function CardUnblockPin defined. If
> in "pbAuthenticationData" a pointer to a PUK is specified instead of the
> response data of CardGetChallenge() as specified, this could probably
> work. What do you think?
Yes, you can use this to build a tool that uses your minidriver to unblock a
card, however, none of the standard tools (such as the card unblock in the
pintool.exe that's delivered with the Microsoft Base Smart Card CSP) will
support this...
Cheers,
Jan.
Check:
http://www.aloaha.com/wi-software-en/aloaha-cryptographic-service-provider.php
and
http://www.aloaha.de/wi-software/aloaha-cryptographic-service-provider-de.php
Uses this CSP the PKCS#11 API? I only found information about a native CSP
API of the vendor, but this seems how to access the CSP.
regards
Alexander
regards
Alexander
> I tried now to debug my Test Minidriver so see how it is called. When I
> enter the registry key for the card, the driver is loaded. When I want to
> make changes to the file, the access is denied, because winlogon has loaded
> the dll.
You can rename your module to module2.dll, module3.dll, ... and change the
registry key for your card module accordingly...
> Is there a possibility to change the file without rebooting the machine?
> Is there an ohter possibility to test the minidriver, so that winlogon does
> not load it?
I'm not sure. You could try switching off automatic certificate propagation
(set reg key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows
NT\CurrentVersion\Winlogon\Notify\ScCertProp\Enabled to 0 on XP or set the
CertPropSvc service to disabled on Vista) to prevent the card from being used
as soon as it's inserted. But again, I'm not sure if this does the trick...
Cheers,
Jan.
that CSP does not use a PKCS11. Aloahas PKCS11 and CSP access the same
native core. If you need you card supported by them just contact them. They
are pretty fast in supporting new cards.
Stefan
"Alexander" <ac2...@gmx.net> schrieb im Newsbeitrag
news:dd444$46b1d0b5$51dfc6d2$47...@news.inode.at...
In the meantime I also tried to get the testsuite and sample project from
Microsoft, but they do not know what I'm talking about and gave me
phonenumbers, where I can't even get a connection.
Does somebody maybe have a contact?
regards
Alexander
"Jan Spooren" <jspo...@nospam.nospam> wrote in message
news:%23IGfy6t...@TK2MSFTNGP04.phx.gbl...
> It calls CardAcquireContext and then ReadFile for the file "cardid". I
> allocate a buffer with pfnCspAlloc provided within the CardData stucture,
> copy the 16 bytes long ID to that buffer an return 0.
> After that, the certutil seems to deadlock because it is running, but no
> futher function is called.
> Do you have an idea what the problem could be?
I assume you also set *ppbData to the newly allocated data buffer and set
*pcbData to 16?
Is your cardid null-terminated?
> In the meantime I also tried to get the testsuite and sample project from
> Microsoft, but they do not know what I'm talking about and gave me
> phonenumbers, where I can't even get a connection.
The test suite is called the "Card Module Certification Kit (CMCK)" and is
shipped with the Windows Logo Kit. (See also:
http://blogs.msdn.com/shivaram/archive/2007/02/26/card-mini-driver-certification-requirements.aspx)
Cheers,
Jan.
> I assume you also set *ppbData to the newly allocated data buffer and set
> *pcbData to 16?
> Is your cardid null-terminated?
Yes I set the *ppbData to the allocated buffer and set the length (*pcbDat)
to 16.
The buffer is not null terminated, because for the cardid I used the serial
number of the card, which can include 0x00.
I tried it with a hard coded buffer. Here the code:
BYTE pbCardID[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
PFN_CSP_ALLOC pAlloc = pCardData->pfnCspAlloc;
BYTE* pbCardIDAlloc = (BYTE*) pAlloc(sizeof(pbCardID));
memcpy(pbCardIDAlloc, pbCardID, sizeof(pbCardID));
*ppbData = pbCardIDAlloc;
*pcbData = sizeof(pbCardID);
regards
Alexander
> The buffer is not null terminated, because for the cardid I used the
> serial number of the card, which can include 0x00.
>
> I tried it with a hard coded buffer. Here the code:
>
> BYTE pbCardID[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
> 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
[...]
Could you check what happens if you replace pbCardID with:
BYTE pbCardID[] = {0x30, 0x30, 0x30, 0x31, 0x30, 0x32, 0x30, 0x33,
0x30, 0x34, 0x30, 0x35, 0x36, 0x30, 0x37, 0x30, 0x38, 0x30, 0x39,
0x30, 0x41, 0x30, 0x42, 0x30, 0x43, 0x30, 0x44, 0x30, 0x45, 0x30, 0x46,
0x00};
Cheers,
Jan.
Its an old thread, but ive been doing CSP and minidriver development
for a while, and im using this approach ( only in debug builds )
In DllMain, DLL_PROCESS_ATTACH, i do
GetModuleFileName(GetModuleHandle(NULL)..) to figure out the loading
program name, and then compare it against known process .exes that are
eager to load these DLLs, and are annoying to restart:
explorer.exe, lsass.exe, winlogon.exe, and svchost.exe. The last one
should be commented out if you want to test certificate propagation
service, as this one runs under svchost
-kert