[opensc-devel] Signing with PKCS#11 and Pin Pad Reader

2010-05-13 Thread Jakob Blomer
Hi,

I try to use the pkcs#11 library (actually the respective OpenSSL 
engine) with a pin pad reader on OS X.  The reader is a Gemalto PC 
Pinpad, the card is a Feitian PKI card.  I test using the pkcs11-tool, 
but the behaviour with the OpenSSL engine seems to be the same.  Up to 
hash calculation, everything works fine.  However, signing things with 
an activated pin pad does not work with the error
PKCS11 function C_SignFinal failed: rv = CKR_USER_NOT_LOGGED_IN (0x101)
At that point, I entered a correct pin using the pin pad.

I already tried the possible combinations of cache_pin and lock_login 
options as well as turning the options under "reader_driver pcsc" on and 
off without success.  If I disable the pin pad, everything seems to work 
fine.

Cheers,
Jakob

Below some debug information.

OS X: 10.5.8

opensc-tool -i:
opensc 0.12.0-svn-r4341 [gcc  4.0.1 (Apple Inc. build 5490)]
Enabled features: zlib readline iconv openssl 
pcsc(/System/Library/Frameworks/PCSC.framework/PCSC)

pkcs15-tool --dump:
Using reader with a card: Gemplus GemPC Pinpad 00 00
PKCS#15 Card [CernVM]:
Version: 1
Serial number  : 3089520016010310
Manufacturer ID: EnterSafe
Last update: 20100513140331Z
Flags  : PRN generation, EID compliant

PIN [User PIN]
Com. Flags: 0x3
ID: 01
Flags : [0x30], initialized, needs-padding
Length: min_len:4, max_len:16, stored_len:16
Pad char  : 0x00
Reference : 1
Type  : ascii-numeric
Path  :

Private RSA Key [CernVM Master Key]
Com. Flags  : 3
Usage   : [0x2E], decrypt, sign, signRecover, unwrap
Access Flags: [0x1D], sensitive, alwaysSensitive, neverExtract, local
ModLength   : 2048
Key ref : 1
Native  : yes
Path: 3f005015
Auth ID : 01
ID  : 19e096dd973630c31174206d692d0af624fef41a

Public RSA Key [CernVM Public Key]
Com. Flags  : 2
Usage   : [0xD1], encrypt, wrap, verify, verifyRecover
Access Flags: [0x0]
ModLength   : 2048
Key ref : 0
Native  : no
Path: 3f0050153000
Auth ID :
ID  : 19e096dd973630c31174206d692d0af624fef41a

Pin pad *disabled*, pkcs11-tool -t -l --slot 1:
Please enter User PIN:
C_SeedRandom() and C_GenerateRandom():
   seeding (C_SeedRandom) not supported
   seems to be OK
Digests:
   all 4 digest functions seem to work
   MD5: OK
   SHA-1: OK
   RIPEMD160: OK
Signatures (currently only RSA signatures)
   testing key 0 (CernVM Master Key)
   all 4 signature functions seem to work
   testing signature mechanisms:
 RSA-X-509: OK
 RSA-PKCS: OK
 SHA1-RSA-PKCS: OK
 MD5-RSA-PKCS: OK
 RIPEMD160-RSA-PKCS: OK
Verify (currently only for RSA):
   testing key 0 (CernVM Master Key)
 RSA-X-509: OK
 RSA-PKCS: OK
 SHA1-RSA-PKCS: OK
 MD5-RSA-PKCS: OK
 RIPEMD160-RSA-PKCS: OK
Key unwrap (RSA)
   testing key 0 (CernVM Master Key)
   ERR: C_UnwrapKey failed: CKR_SESSION_READ_ONLY (0xb5)
   ERR: C_UnwrapKey failed: CKR_SESSION_READ_ONLY (0xb5)
   ERR: C_UnwrapKey failed: CKR_SESSION_READ_ONLY (0xb5)
   ERR: C_UnwrapKey failed: CKR_SESSION_READ_ONLY (0xb5)
 DES-CBC: DES-EDE3-CBC: BF-CBC: CAST5-CFB: Decryption (RSA)
   testing key 0 (CernVM Master Key)
 RSA-X-509: OK
 RSA-PKCS: OK

Pin pad *enabled*, pkcs11-tool -t -l --slot 1:
C_SeedRandom() and C_GenerateRandom():
   seeding (C_SeedRandom) not supported
   seems to be OK
Digests:
   all 4 digest functions seem to work
   MD5: OK
   SHA-1: OK
   RIPEMD160: OK
Signatures (currently only RSA signatures)
   testing key 0 (CernVM Master Key)
error: PKCS11 function C_SignFinal failed: rv = CKR_USER_NOT_LOGGED_IN 
(0x101)

Tail of the debug for the above command:
0xa0515720 00:32:29.646 [opensc-pkcs11] iso7816.c:102:iso7816_check_sw: 
Security status not satisfied
0xa0515720 00:32:29.646 [opensc-pkcs11] 
card-entersafe.c:900:entersafe_compute_with_prkey: internal set security 
env failed: Security status not satisfied
0xa0515720 00:32:29.646 [opensc-pkcs11] sec.c:56:sc_compute_signature: 
returning with: -1211
0xa0515720 00:32:29.646 [opensc-pkcs11] 
pkcs15-pin.c:509:sc_pkcs15_pincache_revalidate: called
0xa0515720 00:32:29.646 [opensc-pkcs11] card.c:320:sc_unlock: called
0xa0515720 00:32:29.646 [opensc-pkcs11] 
pkcs15-sec.c:296:sc_pkcs15_compute_signature: sc_compute_signature() 
failed: Security status not satisfied
0xa0515720 00:32:29.646 [opensc-pkcs11] card.c:320:sc_unlock: called
0xa0515720 00:32:29.646 [opensc-pkcs11] 
framework-pkcs15.c:2447:pkcs15_prkey_sign: Sign complete. Result -1211.
0xa0515720 00:32:29.646 [opensc-pkcs11] 
misc.c:59:sc_to_cryptoki_error_common: opensc error: Security status not 
satisfied (-1211)
0xa0515720 00:32:29.646 [opensc-pkcs11] pkcs11-object.c:659:C_SignFinal: 
C_SignFinal() = CKR_USER_NOT_LOGGED_IN
0xa05157

Re: [opensc-devel] opensc 0.11.13 and openssl 1.0 oddity

2010-05-13 Thread Aleksey Samsonov
Hello,

Fix committed to trunk (revision 4347). Could you please test it?

Thanks

Aleksey Samsonov wrote:
> Hello,
> 
> Martin Paljak wrote:
>> Hello,
>>
>> On Apr 22, 2010, at 23:08 , Aleksey Samsonov wrote:
>>
>>> What are you think about solution in attachment? (openssl.cnf isn't 
>>> needed in this case)
>>> Thanks
>>> Index: src/pkcs11/openssl.c
>>>
>>
>>> +#ifndef OPENSSL_NO_ENGINE
>>> +ENGINE *e;
>>> +
>>> +#if !defined(OPENSSL_NO_STATIC_ENGINE) && !defined(OPENSSL_NO_GOST)
>>> +ENGINE_load_gost();
>>> +#else
>>> +/* TODO: try to load dynamic gost engine */
>> Does this mean that the gost engine (and thus software gost 
>> verification) only works if the gost engine is built in and not a 
>> dynamic engine?
> 
> No. This mean that I'm going to do it if concept is true.
> 
> 
>>> +#endif /* !OPENSSL_NO_STATIC_ENGINE && !OPENSSL_NO_GOST */
>>> +
>>> +e = ENGINE_by_id("gost");
>>> +if (e) {
>>> +ENGINE_set_default(e, ENGINE_METHOD_ALL);
>> Doesn't this affect RSA operations?
> 
> Gost engine doesn't have callback for ENGINE_METHOD_RSA. Therefore it 
> doesn't affect.

___
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel


Re: [opensc-devel] C_SignFinal fails when using a pinpad reader

2010-05-13 Thread Viktor TARASOV
Viktor TARASOV wrote:
> Hello Ludovic,
>
>
> Ludovic Rousseau wrote:
>   
>> 2010/5/11 Viktor TARASOV :
>>   
>> 
>>> Ludovic Rousseau wrote:
>>> 
>>>   
 2010/5/11 Viktor TARASOV :

   
 
>> I can send an OpenSC log file level=99 (200 KB uncompressed) if needed.
>> I use the current SVN version of OpenSC.
>>
>>   
>> 
> Please, do it.
>
> 
>   
 Attached. bzip2 compressed.

 I have a Feitian smart card and use the entersafe card driver.

 It may be an entersafe card driver bug.
 log says:
 0xb7b476b0 16:40:59.112 [opensc-pkcs11]
 iso7816.c:102:iso7816_check_sw: Security status not satisfied
 0xb7b476b0 16:40:59.112 [opensc-pkcs11]
 card-entersafe.c:900:entersafe_compute_with_prkey: internal set
 security env failed: Security status not satisfied
 0xb7b476b0 16:40:59.112 [opensc-pkcs11] sec.c:56:sc_compute_signature:
 returning with: -1211

   
 
>>> OK, thanks.
>>>
>>> I have this card and I'll look it before the end of
>>> this week (with 'Gemalto PC PinPad Reader').
>>> 
>>>   
>> I think you will need this patch to use the Gemalto pinpad:
>>
>> Index: src/libopensc/card-entersafe.c
>> ===
>> --- src/libopensc/card-entersafe.c   (revision 4340)
>> +++ src/libopensc/card-entersafe.c   (working copy)
>> @@ -938,7 +938,7 @@
>>  {
>>  pin->encoding   = SC_PIN_ENCODING_ASCII;
>>  pin->min_length = 4;
>> -pin->max_length = 16;
>> +pin->max_length = 8;
>>  pin->pad_length = 16;
>>  pin->offset = 5 + num * 16;
>>  pin->pad_char   = 0x00;
>>
>> The reader does not accept PIN longer than 8. I willl write about that
>> on my blog [1] later.
>>   
>> 
>
> Using actual trunk I cannot sign with Feitian card neither with 
> conventional reader nor with pin pad.
> The reason, afais, in both cases is the same -- after user PIN was 
> validated, the signing key parent DF is selected by full path. Feitian 
> UserPIN is local one, and so its 'validated' flag is lost. (Still to be 
> looked for -- why PKCS#15 pin cache is not working here.)
>
> In fact, there is no real need to select key DF -- it's already selected 
> by the previous operations,
> but the card->cache (that keeps current path) is invalidated and 
> 'compute signature' procedure has to other way to ensure sign key's DF 
> then re-selection.
>
> To keep valid card->cache (and current path) I'll do two small changes 
> to trunk:
> - in entersafe profile for the user PIN add flag 'local' (in fact it's 
> really 'local', but actual profile has no this flag);
> - set default value of 'lock_login' to 'true' (as it stated by the 
> comments in opensc.conf, but not in reality) .
>
> After these changes, the card->cache->current_path will be properly 
> filled up when verifying PKCS#15 PIN,
> and card->cache will not be invalidated between 'C_Login' and 'C_Sign'.
>   

It 'works for me' in trunk r4346 with 'Gemalto PC Pinpad Reader'.

>   
>> Bye
>>
>> [1] http://ludovicrousseau.blogspot.com/
>>   
>> 
>
> Kind wishes,
> Viktor.
>
>   


-- 
Viktor Tarasov  

___
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel


Re: [opensc-devel] C_SignFinal fails when using a pinpad reader

2010-05-13 Thread Viktor TARASOV
Hello Ludovic,


Ludovic Rousseau wrote:
> 2010/5/11 Viktor TARASOV :
>   
>> Ludovic Rousseau wrote:
>> 
>>> 2010/5/11 Viktor TARASOV :
>>>
>>>   
> I can send an OpenSC log file level=99 (200 KB uncompressed) if needed.
> I use the current SVN version of OpenSC.
>
>   
 Please, do it.

 
>>> Attached. bzip2 compressed.
>>>
>>> I have a Feitian smart card and use the entersafe card driver.
>>>
>>> It may be an entersafe card driver bug.
>>> log says:
>>> 0xb7b476b0 16:40:59.112 [opensc-pkcs11]
>>> iso7816.c:102:iso7816_check_sw: Security status not satisfied
>>> 0xb7b476b0 16:40:59.112 [opensc-pkcs11]
>>> card-entersafe.c:900:entersafe_compute_with_prkey: internal set
>>> security env failed: Security status not satisfied
>>> 0xb7b476b0 16:40:59.112 [opensc-pkcs11] sec.c:56:sc_compute_signature:
>>> returning with: -1211
>>>
>>>   
>> OK, thanks.
>>
>> I have this card and I'll look it before the end of
>> this week (with 'Gemalto PC PinPad Reader').
>> 
>
> I think you will need this patch to use the Gemalto pinpad:
>
> Index: src/libopensc/card-entersafe.c
> ===
> --- src/libopensc/card-entersafe.c(revision 4340)
> +++ src/libopensc/card-entersafe.c(working copy)
> @@ -938,7 +938,7 @@
>  {
>   pin->encoding   = SC_PIN_ENCODING_ASCII;
>   pin->min_length = 4;
> - pin->max_length = 16;
> + pin->max_length = 8;
>   pin->pad_length = 16;
>   pin->offset = 5 + num * 16;
>   pin->pad_char   = 0x00;
>
> The reader does not accept PIN longer than 8. I willl write about that
> on my blog [1] later.
>   

Using actual trunk I cannot sign with Feitian card neither with 
conventional reader nor with pin pad.
The reason, afais, in both cases is the same -- after user PIN was 
validated, the signing key parent DF is selected by full path. Feitian 
UserPIN is local one, and so its 'validated' flag is lost. (Still to be 
looked for -- why PKCS#15 pin cache is not working here.)

In fact, there is no real need to select key DF -- it's already selected 
by the previous operations,
but the card->cache (that keeps current path) is invalidated and 
'compute signature' procedure has to other way to ensure sign key's DF 
then re-selection.

To keep valid card->cache (and current path) I'll do two small changes 
to trunk:
- in entersafe profile for the user PIN add flag 'local' (in fact it's 
really 'local', but actual profile has no this flag);
- set default value of 'lock_login' to 'true' (as it stated by the 
comments in opensc.conf, but not in reality) .

After these changes, the card->cache->current_path will be properly 
filled up when verifying PKCS#15 PIN,
and card->cache will not be invalidated between 'C_Login' and 'C_Sign'.

> Bye
>
> [1] http://ludovicrousseau.blogspot.com/
>   

Kind wishes,
Viktor.

-- 
Viktor Tarasov  

___
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel


[opensc-devel] To support a new card

2010-05-13 Thread Xiaoshuo Wu

Hello,
Thanks to OpenSC developers and my colleagues' help, I managed to get a  
new card supported.


I attached a bzip2 compressed patch, it includes following changes:
1.Support PK/13C, a new Feitian PKI card;
Add three driver file "es_pk13c.profile", "pkcs15-es_pk13c.c" and  
"card-es_pk13c.c".
Modified sc_pkcs15_find_prkey_by_reference() so as to generate more than  
one key pair.

2.Remove unnecessary "struct mf" in "sc_entersafe_create_data";

Many thanks to Weitao, he provides the entersafe driver example.
I'd also like to thank Viktor for the inspiring advices and code.

It's a scratch, and will be updated, please review it.

Regards, Xiaoshuo

trunk.4343.pk13c.tar.bz2
Description: application/bzip2
___
opensc-devel mailing list
opensc-devel@lists.opensc-project.org
http://www.opensc-project.org/mailman/listinfo/opensc-devel

Re: [opensc-devel] Question about C_WaitForSlotEvent()

2010-05-13 Thread Viktor TARASOV

Martin Paljak wrote:

On Apr 14, 2010, at 19:28 , Viktor TARASOV wrote:
  

Hi,

I'm testing the OpenSC pkcs11 module with Firefox.

In the logs I see the endless loop of the messages from the 
C_WaitForSlotEvent() and underneath calls,

non interrupted by timeout. CPU usage is considerable.

My question: should it be like this?


No. I've said before that (blocking) C_WaitForSlotEvent is broken (by me) in 
trunk.
  


This patch is 'working for me'.
It was applied to the IAS/ECC branch and tested in WinXP SP3.

If no objections, I'll apply it to the trunk.

Kind wishes,
Viktor.

--
Viktor Tarasov  

Index: opensc.trunk/src/tools/util.c
===
--- opensc.trunk/src/tools/util.c	(révision 4343)
+++ opensc.trunk/src/tools/util.c	(copie de travail)
@@ -23,7 +23,7 @@
 
 		if (sc_ctx_get_reader_count(ctx) == 0) {
 			fprintf(stderr, "Waiting for a reader to be attached...\n");
-			r = sc_wait_for_event(ctx, SC_EVENT_READER_ATTACHED, &found, &event, -1);
+			r = sc_wait_for_event(ctx, SC_EVENT_READER_ATTACHED, &found, &event, -1, NULL);
 			if (r < 0) {
 fprintf(stderr, "Error while waiting for a reader: %s\n", sc_strerror(r));
 return 3;
@@ -35,7 +35,7 @@
 			}
 		}
 		fprintf(stderr, "Waiting for a card to be inserted...\n");
-		r = sc_wait_for_event(ctx, SC_EVENT_CARD_INSERTED, &found, &event, -1);
+		r = sc_wait_for_event(ctx, SC_EVENT_CARD_INSERTED, &found, &event, -1, NULL);
 		if (r < 0) {
 			fprintf(stderr, "Error while waiting for a card: %s\n", sc_strerror(r));
 			return 3;
Index: opensc.trunk/src/pkcs11/pkcs11-global.c
===
--- opensc.trunk/src/pkcs11/pkcs11-global.c	(révision 4343)
+++ opensc.trunk/src/pkcs11/pkcs11-global.c	(copie de travail)
@@ -608,13 +608,14 @@
 			 CK_VOID_PTR pReserved) /* reserved.  Should be NULL_PTR */
 {
 	sc_reader_t *found;
-	int r;
 	unsigned int mask, events;
+	void *reader_states = NULL;
+	CK_SLOT_ID slot_id;
 	CK_RV rv;
+	int ii, r;
 	
-	if (pReserved != NULL_PTR) {
+	if (pReserved != NULL_PTR)
 		return  CKR_ARGUMENTS_BAD;
-	}
 
 	sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_WaitForSlotEvent(block=%d)", !(flags & CKF_DONT_BLOCK));
 #if 0
@@ -633,21 +634,25 @@
 		mask |= SC_EVENT_READER_EVENTS;
 	}
 
-	if ((rv = slot_find_changed(pSlot, mask)) == CKR_OK
-	 || (flags & CKF_DONT_BLOCK))
+	rv = slot_find_changed(&slot_id, mask);
+	if ((rv == CKR_OK) || (flags & CKF_DONT_BLOCK))
 		goto out;
 
 again:
+	sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_WaitForSlotEvent() reader_states:%p", reader_states);
 	sc_pkcs11_unlock();
-	r = sc_wait_for_event(context, mask, &found, &events, -1);
-
+	r = sc_wait_for_event(context, mask, &found, &events, -1, &reader_states);
 	if (sc_pkcs11_conf.plug_and_play && events & SC_EVENT_READER_ATTACHED) {
 		/* NSS/Firefox Triggers a C_GetSlotList(NULL) only if a slot ID is returned that it does not know yet
 		   Change the first hotplug slot id on every call to make this happen.
 		*/
 		sc_pkcs11_slot_t *hotplug_slot = list_get_at(&virtual_slots, 0);
 		*pSlot= hotplug_slot->id -1;
-		rv = CKR_OK;
+	
+		rv = sc_pkcs11_lock();
+		if (rv != CKR_OK)
+			return rv;
+
 		goto out;
 	}
 	/* Was C_Finalize called ? */
@@ -665,10 +670,21 @@
 
 	/* If no changed slot was found (maybe an unsupported card
 	 * was inserted/removed) then go waiting again */
-	if ((rv = slot_find_changed(pSlot, mask)) != CKR_OK)
+	rv = slot_find_changed(&slot_id, mask);
+	if (rv != CKR_OK)
 		goto again;
 
-out:	sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_WaitForSlotEvent() = %s, event in 0x%lx", lookup_enum (RV_T, rv), *pSlot);
+out:	
+	if (pSlot)
+		*pSlot = slot_id;
+
+	/* Free allocated readers states holder */
+	if (reader_states)   {
+		sc_debug(context, SC_LOG_DEBUG_NORMAL, "free reader states");
+		sc_wait_for_event(context, 0, NULL, NULL, -1, &reader_states);
+	}
+
+	sc_debug(context, SC_LOG_DEBUG_NORMAL, "C_WaitForSlotEvent() = %s, event in 0x%lx", lookup_enum (RV_T, rv), *pSlot);
 	sc_pkcs11_unlock();
 	return rv;
 }
Index: opensc.trunk/src/libopensc/reader-pcsc.c
===
--- opensc.trunk/src/libopensc/reader-pcsc.c	(révision 4343)
+++ opensc.trunk/src/libopensc/reader-pcsc.c	(copie de travail)
@@ -953,11 +953,9 @@
 
 /* Wait for an event to occur.
  */
-static int pcsc_wait_for_event(sc_context_t *ctx,
-			   void *reader_data,
-   unsigned int event_mask,
-   sc_reader_t **event_reader,
-			   unsigned int *event, int timeout)
+static int pcsc_wait_for_event(sc_context_t *ctx, void *reader_data,
+   unsigned int event_mask, sc_reader_t **event_reader, unsigned int *event, 
+			   int timeout, void **reader_states)
 {
 	struct pcsc_global_private_data *gpriv = (struct pcsc_global_private_data *)reader_data;
 	LONG rv;
@@ -968,26 +966,40 @@
 
 	SC_FUNC_CALLED(ctx, SC_LOG_DEBUG