PIN not always requested?

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

PIN not always requested?

Geoffrey Elgey-2
G'day,

[not sure if this is a muscle, opensc, or heimdal problem, so
cross-posting to multiple lists]

I'm having a problem when using Heimdal pkinit with opensc's
pkcs11-enabled crypto engine and the pkcs#11 library provided with muscle.

When I do a kinit using the gemplus PKCS#11 library and a gemsafe card,
I get asked for a PIN to access the private key on the card:

   $ pkcs11-tool --module /usr/lib/gemsafe/libgemsafe.so --show-info
   Cryptoki version 2.1
   Manufacturer     Gemplus
   Library          PKCS#11 Cryptoki (ver 4.0)

   $ pkcs11-tool --module /usr/lib/gemsafe/libgemsafe.so --list-slots
   Available slots:
   Slot 0           Twin 00 00
   token state:   uninitialized

   $ /usr/heimdal/bin/kinit -C ENGINE:CERT=slot_0,KEY=slot_0
   initializing engine
   Found 1 slot
   [0] Twin 00 00                 uninitialized, login
                                  (GemSAFE-D808250F240D)
   Found slot:  Twin 00 00
   Found token: GemSAFE-D808250F240D
   Found 1 cert:
   Found 1 slot
   [0] Twin 00 00                 uninitialized, login
                                  (GemSAFE-D808250F240D)
   Found slot:  Twin 00 00
   Found token: GemSAFE-D808250F240D
   Found 1 certificate:
      1     (/DC=vas/DC=sc/CN=Users/CN=Matlock)
   PKCS#11 token PIN:
   Found 1 key:
      1 P

However, when I replace the gemsafe PKCS#11 library with the muscle
pkcs#11 library abd a cyberflex card, there is no prompt for the PIN:

   $ pkcs11-tool --module /usr/local/lib/libmusclepkcs11.so --show-info
   Cryptoki version 2.11
   Manufacturer     SCHLUMBERGER
   Library          SLB PKCS #11 module (ver 1.0)

   $ pkcs11-tool --module /usr/local/lib/libmusclepkcs11.so --list-slots
   Available slots:
   Slot 1           SCR 331 00 00
     token label:   MuscleCard Applet
     token manuf:   Unknown MFR
     token model:   Unknown Model
     token flags:   rng, login required, PIN initialized, token
                    initialized
     serial num  :  1

   $ /usr/heimdal/bin/kinit -C ENGINE:CERT=slot_0,KEY=slot_0
   initializing engine
   Found 1 slot
   [0] SCR 331 00 00              login             (MuscleCard Applet)
   Found slot:  SCR 331 00 00
   Found token: MuscleCard Applet
   Found 1 cert:
   Found 1 slot
   [0] SCR 331 00 00              login             (MuscleCard Applet)
   Found slot:  SCR 331 00 00
   Found token: MuscleCard Applet
   Found 1 certificate:
      1    DC=vas, DC=sc, CN=Users, CN=Matlock
           (/DC=vas/DC=sc/CN=Users/CN=Matlock)
   Found 1 key:
      1 P  DC=vas, DC=sc, CN=Users, CN=Matlock \
    kinit: krb5_get_init_creds: PKINIT: failed to sign with private key:
    error:2A00A101:PKCS11 library:PKCS11_rsa_sign:User not logged in


I suspect that deep within the crypto engine, code is looking at the
token flags and deciding if asking for a PIN is necessary. The token
flags seem a bit strange for the gemsafe card, but a PIN is requested.
However, no PIN is requested for the muscle card, even though the token
flags specify that login is required.

Can anyone explain what is happenning here?

-- Geoff
_______________________________________________
opensc-user mailing list
[hidden email]
http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-user
Reply | Threaded
Open this post in threaded view
|

Re: PIN not always requested?

Stef Hoeben
Hi,

not sure where the problem is: "pkcs11-tool --show-info" and
"pkcs11-tool --list-slots"
don't ask for a PIN because they don't look for keys.

If you use other tools, like kinit, you may have to enter your PIN if
those tools are programmed to ask your PIN..

(Sorry if I overlooked something..)

Stef

Geoffrey Elgey wrote:

> G'day,
>
> [not sure if this is a muscle, opensc, or heimdal problem, so
> cross-posting to multiple lists]
>
> I'm having a problem when using Heimdal pkinit with opensc's
> pkcs11-enabled crypto engine and the pkcs#11 library provided with
> muscle.
>
> When I do a kinit using the gemplus PKCS#11 library and a gemsafe card,
> I get asked for a PIN to access the private key on the card:
>
>   $ pkcs11-tool --module /usr/lib/gemsafe/libgemsafe.so --show-info
>   Cryptoki version 2.1
>   Manufacturer     Gemplus
>   Library          PKCS#11 Cryptoki (ver 4.0)
>
>   $ pkcs11-tool --module /usr/lib/gemsafe/libgemsafe.so --list-slots
>   Available slots:
>   Slot 0           Twin 00 00
>   token state:   uninitialized
>
>   $ /usr/heimdal/bin/kinit -C ENGINE:CERT=slot_0,KEY=slot_0
>   initializing engine
>   Found 1 slot
>   [0] Twin 00 00                 uninitialized, login
>                                  (GemSAFE-D808250F240D)
>   Found slot:  Twin 00 00
>   Found token: GemSAFE-D808250F240D
>   Found 1 cert:
>   Found 1 slot
>   [0] Twin 00 00                 uninitialized, login
>                                  (GemSAFE-D808250F240D)
>   Found slot:  Twin 00 00
>   Found token: GemSAFE-D808250F240D
>   Found 1 certificate:
>      1     (/DC=vas/DC=sc/CN=Users/CN=Matlock)
>   PKCS#11 token PIN:
>   Found 1 key:
>      1 P
>
> However, when I replace the gemsafe PKCS#11 library with the muscle
> pkcs#11 library abd a cyberflex card, there is no prompt for the PIN:
>
>   $ pkcs11-tool --module /usr/local/lib/libmusclepkcs11.so --show-info
>   Cryptoki version 2.11
>   Manufacturer     SCHLUMBERGER
>   Library          SLB PKCS #11 module (ver 1.0)
>
>   $ pkcs11-tool --module /usr/local/lib/libmusclepkcs11.so --list-slots
>   Available slots:
>   Slot 1           SCR 331 00 00
>     token label:   MuscleCard Applet
>     token manuf:   Unknown MFR
>     token model:   Unknown Model
>     token flags:   rng, login required, PIN initialized, token
>                    initialized
>     serial num  :  1
>
>   $ /usr/heimdal/bin/kinit -C ENGINE:CERT=slot_0,KEY=slot_0
>   initializing engine
>   Found 1 slot
>   [0] SCR 331 00 00              login             (MuscleCard Applet)
>   Found slot:  SCR 331 00 00
>   Found token: MuscleCard Applet
>   Found 1 cert:
>   Found 1 slot
>   [0] SCR 331 00 00              login             (MuscleCard Applet)
>   Found slot:  SCR 331 00 00
>   Found token: MuscleCard Applet
>   Found 1 certificate:
>      1    DC=vas, DC=sc, CN=Users, CN=Matlock
>           (/DC=vas/DC=sc/CN=Users/CN=Matlock)
>   Found 1 key:
>      1 P  DC=vas, DC=sc, CN=Users, CN=Matlock \
>    kinit: krb5_get_init_creds: PKINIT: failed to sign with private key:
>    error:2A00A101:PKCS11 library:PKCS11_rsa_sign:User not logged in
>
>
> I suspect that deep within the crypto engine, code is looking at the
> token flags and deciding if asking for a PIN is necessary. The token
> flags seem a bit strange for the gemsafe card, but a PIN is requested.
> However, no PIN is requested for the muscle card, even though the token
> flags specify that login is required.
>
> Can anyone explain what is happenning here?
>
> -- Geoff
> _______________________________________________
> opensc-user mailing list
> [hidden email]
> http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-user
>

_______________________________________________
opensc-user mailing list
[hidden email]
http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-user
Reply | Threaded
Open this post in threaded view
|

Re: PIN not always requested?

Geoffrey Elgey-2
G'day,

Stef Hoeben wrote:
> not sure where the problem is: "pkcs11-tool --show-info" and
> "pkcs11-tool --list-slots" don't ask for a PIN because they don't
> look for keys.

I included the output of pkcs11-tool to provide further info on the
reader and the card used in each case.

> If you use other tools, like kinit, you may have to enter your PIN if
>  those tools are programmed to ask your PIN..
>
> (Sorry if I overlooked something..)

The problem is the engine_pkcs11.c will prompt for a PIN if I use one
library/card, but not prompt for a PIN if I use a different
library/card, even though a PIN is required in both cases.

A little debugging shows that the pkcs11_load_key function [*] in
engine_pkcs11.c has the following loop:

   while (1) {
     if (PKCS11_enumerate_keys(tok, &keys, &count))
       fail("unable to enumerate keys\n");
     if (count)
       break;
     ...
     ... ask for pin and login ...
     ...
   }

This loop checks if any private keys can be found -- if so, there's no
need to ask for a PIN since private information is already obtainable.
The problem here is that I have not yet provided a PIN, so it looks like
the muscle PKCS11 library is returning handles to private objects during
searches, which means that a PIN is never requested.

This can be demonstrated by using pkcs11-tool:

(a) gemsafe PKCS#11 library, no PIN specified

$ pkcs11-tool --module /usr/lib/gemsafe/libgemsafe.so --slot 0 \
               --list-objects
Certificate Object, type = X.509 cert
   label:
   ID:         1234


(b) gemsafe PKCS#11 library, PIN specified
$ pkcs11-tool --module /usr/lib/gemsafe/libgemsafe.so --slot 0 \
               --pin 1234 --list-objects
Certificate Object, type = X.509 cert
   label:
   ID:         1234
Private Key Object; RSA
   label:
   ID:         1234
   Usage:      decrypt, sign, unwrap


(c) muscle PKCS#11 library, no PIN specified

$ pkcs11-tool --module /usr/local/lib/libmusclepkcs11.so \
               --slot 1 --list-objects
Certificate Object, type = X.509 cert
   label:      DC=vas, DC=sc, CN=Users, CN=Matlock
   ID:         49cb2686266fbb61b612bc3950bdc3099a1e5354

Private Key Object; RSA
   label:      DC=vas, DC=sc, CN=Users, CN=Matlock
   ID:         49cb2686266fbb61b612bc3950bdc3099a1e5354
   Usage:      decrypt, sign, unwrap


(d) muscle PKCS#11 library, PIN specified

$ pkcs11-tool --module /usr/local/lib/libmusclepkcs11.so \
               --slot 1 --pin 00000000 --list-objects
Certificate Object, type = X.509 cert
   label:      DC=vas, DC=sc, CN=Users, CN=Matlock
   ID:         49cb2686266fbb61b612bc3950bdc3099a1e5354

Private Key Object; RSA
   label:      DC=vas, DC=sc, CN=Users, CN=Matlock
   ID:         49cb2686266fbb61b612bc3950bdc3099a1e5354
   Usage:      decrypt, sign, unwrap


For the gemsafe PKCS#11 library, if the PIN is not specified, then a a
search returns no private keys at all. For the muscle PKCS#11 library, a
search returns a handle to the private key, whether the PIN is specified
or not (note, however, that the values of this private object are not
visible, even if the existence of the private object itself is exposed).

Section 10.4 of the PKCS#11 version 2.2 standard mentions the following
for the CKA_PRIVATE attribute:

   "When the CKA_PRIVATE attribute is CK_TRUE, a user may not access
    the object until the user has been authenticated to the token."

This is kinda vague, but I understand it to mean that, until a PIN has
been specified, any private object is hidden from the application. It is
not returned in any searches, and its attribute values are not revealed.
Until a PIN is presented, private objects effectively are not visible to
the application.

This is consistent with how the gemsafe PKCS#11 library operates, and in
what the opensc PKCS#11-enabled crypto engine expects.

My thoughts are that muscle PKCS#11 should be modified to not return any
private objects in searches until a PIN has been presented. Does anyone
disagree?


-- Geoff


[*] Oddly, the pkcs11_load_key function (used for both public and
private keys) has code that enumerates the *certificates* on the token,
and fails if a problem occurs:

   if (PKCS11_enumerate_certs(tok, &certs, &count))
     fail("unable to enumerate certificates\n");

   if(verbose) {
     fprintf(stderr,"Found %u certificate%s:\n", count,
             (count <= 1) ? "" : "s");

     for (n = 0; n < count; n++) {
       ... dump certificate info ...
     }
   }

Why certificates should be searched when loading a private key, and
causing the pkcs11_load_key function to fail if a problem occurs doing
this, is not explained.
_______________________________________________
opensc-user mailing list
[hidden email]
http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-user
Reply | Threaded
Open this post in threaded view
|

Re: PIN not always requested?

Stef Hoeben
Hi,

don't know if the muscle pkcs11 shows info on private keys without
logging in first.

On opensc we've considered it as well: there's nothing secret about the
info on private
keys, it can be a nuissance to enter your PIN too much and it's even
better for security
to enter your PIN (and hence open your card) only when it's realy needed.

But there's of course the problem with the part in the pkcs11 standard,
as you quoted,
allthough IMHO it depends on how to interprete "access" (is providing
non-sensitive
info about the private key the same as accessing it?)

About the certs: it's a nice way to overcome the above problem: user
certs on a
pkcs11 token have most often the same ID as the corresponding private
key (not
enforced by the standard, but everyone does it) so it's a nice
work-around to get info
on private keys without having to log in. (Not sure if that's why it's
used in
pkcs11_load_key function())

Cheers,
Stef

Geoffrey Elgey wrote:

> G'day,
>
> Stef Hoeben wrote:
>
>> not sure where the problem is: "pkcs11-tool --show-info" and
>> "pkcs11-tool --list-slots" don't ask for a PIN because they don't
>> look for keys.
>
>
> I included the output of pkcs11-tool to provide further info on the
> reader and the card used in each case.
>
>> If you use other tools, like kinit, you may have to enter your PIN if
>>  those tools are programmed to ask your PIN..
>>
>> (Sorry if I overlooked something..)
>
>
> The problem is the engine_pkcs11.c will prompt for a PIN if I use one
> library/card, but not prompt for a PIN if I use a different
> library/card, even though a PIN is required in both cases.
>
> A little debugging shows that the pkcs11_load_key function [*] in
> engine_pkcs11.c has the following loop:
>
>   while (1) {
>     if (PKCS11_enumerate_keys(tok, &keys, &count))
>       fail("unable to enumerate keys\n");
>     if (count)
>       break;
>     ...
>     ... ask for pin and login ...
>     ...
>   }
>
> This loop checks if any private keys can be found -- if so, there's no
> need to ask for a PIN since private information is already obtainable.
> The problem here is that I have not yet provided a PIN, so it looks like
> the muscle PKCS11 library is returning handles to private objects during
> searches, which means that a PIN is never requested.
>
> This can be demonstrated by using pkcs11-tool:
>
> (a) gemsafe PKCS#11 library, no PIN specified
>
> $ pkcs11-tool --module /usr/lib/gemsafe/libgemsafe.so --slot 0 \
>               --list-objects
> Certificate Object, type = X.509 cert
>   label:
>   ID:         1234
>
>
> (b) gemsafe PKCS#11 library, PIN specified
> $ pkcs11-tool --module /usr/lib/gemsafe/libgemsafe.so --slot 0 \
>               --pin 1234 --list-objects
> Certificate Object, type = X.509 cert
>   label:
>   ID:         1234
> Private Key Object; RSA
>   label:
>   ID:         1234
>   Usage:      decrypt, sign, unwrap
>
>
> (c) muscle PKCS#11 library, no PIN specified
>
> $ pkcs11-tool --module /usr/local/lib/libmusclepkcs11.so \
>               --slot 1 --list-objects
> Certificate Object, type = X.509 cert
>   label:      DC=vas, DC=sc, CN=Users, CN=Matlock
>   ID:         49cb2686266fbb61b612bc3950bdc3099a1e5354
>
> Private Key Object; RSA
>   label:      DC=vas, DC=sc, CN=Users, CN=Matlock
>   ID:         49cb2686266fbb61b612bc3950bdc3099a1e5354
>   Usage:      decrypt, sign, unwrap
>
>
> (d) muscle PKCS#11 library, PIN specified
>
> $ pkcs11-tool --module /usr/local/lib/libmusclepkcs11.so \
>               --slot 1 --pin 00000000 --list-objects
> Certificate Object, type = X.509 cert
>   label:      DC=vas, DC=sc, CN=Users, CN=Matlock
>   ID:         49cb2686266fbb61b612bc3950bdc3099a1e5354
>
> Private Key Object; RSA
>   label:      DC=vas, DC=sc, CN=Users, CN=Matlock
>   ID:         49cb2686266fbb61b612bc3950bdc3099a1e5354
>   Usage:      decrypt, sign, unwrap
>
>
> For the gemsafe PKCS#11 library, if the PIN is not specified, then a a
> search returns no private keys at all. For the muscle PKCS#11 library, a
> search returns a handle to the private key, whether the PIN is specified
> or not (note, however, that the values of this private object are not
> visible, even if the existence of the private object itself is exposed).
>
> Section 10.4 of the PKCS#11 version 2.2 standard mentions the following
> for the CKA_PRIVATE attribute:
>
>   "When the CKA_PRIVATE attribute is CK_TRUE, a user may not access
>    the object until the user has been authenticated to the token."
>
> This is kinda vague, but I understand it to mean that, until a PIN has
> been specified, any private object is hidden from the application. It is
> not returned in any searches, and its attribute values are not revealed.
> Until a PIN is presented, private objects effectively are not visible to
> the application.
>
> This is consistent with how the gemsafe PKCS#11 library operates, and in
> what the opensc PKCS#11-enabled crypto engine expects.
>
> My thoughts are that muscle PKCS#11 should be modified to not return any
> private objects in searches until a PIN has been presented. Does anyone
> disagree?
>
>
> -- Geoff
>
>
> [*] Oddly, the pkcs11_load_key function (used for both public and
> private keys) has code that enumerates the *certificates* on the token,
> and fails if a problem occurs:
>
>   if (PKCS11_enumerate_certs(tok, &certs, &count))
>     fail("unable to enumerate certificates\n");
>
>   if(verbose) {
>     fprintf(stderr,"Found %u certificate%s:\n", count,
>             (count <= 1) ? "" : "s");
>
>     for (n = 0; n < count; n++) {
>       ... dump certificate info ...
>     }
>   }
>
> Why certificates should be searched when loading a private key, and
> causing the pkcs11_load_key function to fail if a problem occurs doing
> this, is not explained.
> _______________________________________________
> opensc-user mailing list
> [hidden email]
> http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-user
>

_______________________________________________
opensc-user mailing list
[hidden email]
http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-user
Reply | Threaded
Open this post in threaded view
|

Re: PIN not always requested?

Geoffrey Elgey-2
G'day,

Stef Hoeben wrote:

> don't know if the muscle pkcs11 shows info on private keys without
> logging in first.

Muscle PKCS#11 appears to reveal non-sensitive attribute values if the
PIN has not been presented. After the call to PKCS11_enumerate_keys in
pkc11_load_key, I can get various private key attribute values (such as
CKA_SENSITIVE, etc) without error, before a PIN is presented.

> On opensc we've considered it as well: there's nothing secret about
> the info on private keys, it can be a nuissance to enter your PIN too
>  much and it's even better for security to enter your PIN (and hence
> open your card) only when it's realy needed.
>
> But there's of course the problem with the part in the pkcs11
> standard, as you quoted, allthough IMHO it depends on how to
> interprete "access" (is providing non-sensitive info about the
> private key the same as accessing it?)

But the pkcs11_load_key function assumes that if you can get a private
key via the PKCS11_enumerate_keys function, then you do not need to
provide a PIN. So "access" has been interpreted in the code to mean that
the private key is visible to the application.

I'm now not sure what is the correct interpretation of CKA_PRIVATE. All
I know is that opensc PKCS#11 wrapper and libmusclepkcs11 do not agree
on whether a PIN is required.

> About the certs: it's a nice way to overcome the above problem: user
> certs on a pkcs11 token have most often the same ID as the
> corresponding private key (not enforced by the standard, but everyone
>  does it) so it's a nice work-around to get info on private keys
> without having to log in. (Not sure if that's why it's used in
> pkcs11_load_key function())

The only benefit I can see is in verbose mode: get the certificates, and
print out the IDs. You can assume that there is a corresponding private
key on the token with the same ID.

However, two changes should be made here:

   * The pkcs11_load_key function should not fail if certificates cannot
     be enumerated. If enumerating certificates fails, then there's a
     good chance that enumerating keys will also fail, but I still like
     to keep the distinction, just in case.

   * The certificate enumeration itself should only be performed if
    'verbose' is true.

-- Geoff
_______________________________________________
opensc-user mailing list
[hidden email]
http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-user
Reply | Threaded
Open this post in threaded view
|

Re: PIN not always requested?

Geoffrey Elgey-2
In reply to this post by Stef Hoeben
G'day,

Stef Hoeben wrote:
> But there's of course the problem with the part in the pkcs11
> standard, as you quoted, allthough IMHO it depends on how to
> interprete "access" (is providing non-sensitive info about the
> private key the same as accessing it?)

I've been thinking about how to determine a priori if access to private
keys has already been granted.

The pkcs11_load_key function checks if private keys can be enumerated,
and if so, assumes that the user has presented the PIN. But, as shown by
the muscle PKCS#11 library, private keys may be enumerated (and their
non-sensitive values fetched) even if a PIN has not been presented. So
merely checking for the existence of a fetched private key is insufficient.

In addition, my understanding is that there aren't any particular
attributes whose presence or value would indicate that a PIN has been
presented. Attributes such as CKA_PRIVATE and CKA_MODULUS may (or may
not be) fetched, depending on the implementation. There are attributes
that are marked as sensitive, but the value of those attributes is
restricted regardless of login state.

This seems to me to make the "if you can get a private key, you must
have performed a PIN login" test quite useless. I suspect that if you
can get a key, then a cryptographic operation using that key (such as
signing) may need to be performed to test if the card will allow that
operation (assuming that the key supports the given operation).

Or is there a simpler method to test the login state that I'm unaware of?

-- Geoff




_______________________________________________
opensc-user mailing list
[hidden email]
http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-user
Reply | Threaded
Open this post in threaded view
|

Re: PIN not always requested?

Stef Hoeben
Hi Geoff,

there's the CKF_LOGIN_REQUIRED flag in CK_TOKEN_INFO to
see if a pin is needed at all.
And there's the flags in CK_SESSION_INFO as explained in chapter 6.6
of the standard.

A simple and safe way IMHO to check if you can use a key, would be to simply
try it; if you get back a CKR_USER_NOT_LOGGED_IN, you log in
and then try again.

Stef

Geoffrey Elgey wrote:

> G'day,
>
> Stef Hoeben wrote:
>
>> But there's of course the problem with the part in the pkcs11
>> standard, as you quoted, allthough IMHO it depends on how to
>> interprete "access" (is providing non-sensitive info about the
>> private key the same as accessing it?)
>
>
> I've been thinking about how to determine a priori if access to
> private keys has already been granted.
>
> The pkcs11_load_key function checks if private keys can be enumerated,
> and if so, assumes that the user has presented the PIN. But, as shown
> by the muscle PKCS#11 library, private keys may be enumerated (and
> their non-sensitive values fetched) even if a PIN has not been
> presented. So merely checking for the existence of a fetched private
> key is insufficient.
>
> In addition, my understanding is that there aren't any particular
> attributes whose presence or value would indicate that a PIN has been
> presented. Attributes such as CKA_PRIVATE and CKA_MODULUS may (or may
> not be) fetched, depending on the implementation. There are attributes
> that are marked as sensitive, but the value of those attributes is
> restricted regardless of login state.
>
> This seems to me to make the "if you can get a private key, you must
> have performed a PIN login" test quite useless. I suspect that if you
> can get a key, then a cryptographic operation using that key (such as
> signing) may need to be performed to test if the card will allow that
> operation (assuming that the key supports the given operation).
>
> Or is there a simpler method to test the login state that I'm unaware of?
>
> -- Geoff
>
>
>
>

_______________________________________________
opensc-user mailing list
[hidden email]
http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-user