Wrong key usage in pkcs15-init tool

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

Wrong key usage in pkcs15-init tool

Stef Hoeben
Hi,

two strange things in pkcs15init with the result that all pkcs15 key usage
bits are set for the private keys on the card:

1) in do_store_private_key() in pkcs15-init.c:

        unsigned int    usage = cert[0]->ex_kusage;

        /* No certificate usage? Assume ordinary
         * user cert */
        usage = 0x1F;

  So the key usage from the ex_kusage field in the X509 stuct is replaced
  by a hardcoded value (0x1F)

  Guess this should be removed?

2) Over here (Win32, OpenSSL 0.9.7d, the ex_kusage field always contains 0,
no matter what key usage bits the cert contains.

Any idea why?

An alternative might be to use OpenSSLs  X509_get_ext_d2i() function (which
seems to work fine) and convert the resulting ASN1_BIT_STRING into an
unsigned int?

Cheers,
Stef


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

Re: Wrong key usage in pkcs15-init tool

Nils Larsch
Stef Hoeben wrote:

> Hi,
>
> two strange things in pkcs15init with the result that all pkcs15 key usage
> bits are set for the private keys on the card:
>
> 1) in do_store_private_key() in pkcs15-init.c:
>
>        unsigned int    usage = cert[0]->ex_kusage;
>
>        /* No certificate usage? Assume ordinary
>         * user cert */
>        usage = 0x1F;
>
>  So the key usage from the ex_kusage field in the X509 stuct is replaced
>  by a hardcoded value (0x1F)
>
>  Guess this should be removed?

I guess it should be
        if (usage == 0)
                usage = 0x1F;

>
> 2) Over here (Win32, OpenSSL 0.9.7d, the ex_kusage field always contains 0,
> no matter what key usage bits the cert contains.
>
> Any idea why?

perhaps because the value is never set ;-) Could you try if it helps
if you insert a
        X509_check_purpose(cert[0], -1, -1);
before the X509::ex_kusage value is used ?

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

Re: Wrong key usage in pkcs15-init tool

Stef Hoeben

> perhaps because the value is never set ;-) Could you try if it helps
> if you insert a
>     X509_check_purpose(cert[0], -1, -1);
> before the X509::ex_kusage value is used ?

Ah, thx! Now it works.

But now the sc_pkcs15init_map_usage() in pkcs15-lib.c doesn't
work (anymore).

For example if the first X509 key usage bit (digitalSignature) in the
cert is set,
key_usage contains (now) the value 0x80. However, sc_pkcs15init_map_usage()
maps this to a pkcs15 key usage of 0 because the function expects a
key_usage
value of 0x01 (if I read the code correctly).

Assuming that adding X509_check_purpose() works everywhere, it may
be best to keep it, and thus change sc_pkcs15init_map_usage()?

But then I'm not sure how e.g. the 9th bit (decipherOnly) will be
represented in key_usage? As 0x0100? Currently, the 8th and 9th
bits are ignored so if we would keep it that way, the function would
become:

Index: pkcs15init/pkcs15-lib.c
===================================================================
--- pkcs15init/pkcs15-lib.c     (revision 2432)
+++ pkcs15init/pkcs15-lib.c     (working copy)
@@ -1623,7 +1623,7 @@
        | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER,    /* cRLSign */
 };

-static unsigned int    x509_to_pkcs15_public_key_usage[16] = {
+static unsigned int    x509_to_pkcs15_public_key_usage[] = {
        SC_PKCS15_PRKEY_USAGE_VERIFY
        | SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER,  /* digitalSignature */
        SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,   /* NonRepudiation */
@@ -1644,9 +1644,10 @@
        bits = _private? x509_to_pkcs15_private_key_usage
                      : x509_to_pkcs15_public_key_usage;
        for (n = p15_usage = 0; n < 16; n++) {
-               if (x509_usage & (1 << n))
+               if (x509_usage & (0x8000 >> n))
                        p15_usage |= bits[n];
        }
+
        return p15_usage;
 }

What do you think?

Cheers,
Stef

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

Re: Wrong key usage in pkcs15-init tool

Nils Larsch
Stef Hoeben wrote:

>
>> perhaps because the value is never set ;-) Could you try if it helps
>> if you insert a
>>     X509_check_purpose(cert[0], -1, -1);
>> before the X509::ex_kusage value is used ?
>
>
> Ah, thx! Now it works.
>
> But now the sc_pkcs15init_map_usage() in pkcs15-lib.c doesn't
> work (anymore).
sc_pkcs15init_map_usage is broken: it assumes a wrong order of bits
in a asn.1 BIT STRING

>
> For example if the first X509 key usage bit (digitalSignature) in the
> cert is set,
> key_usage contains (now) the value 0x80. However, sc_pkcs15init_map_usage()
> maps this to a pkcs15 key usage of 0 because the function expects a
> key_usage
> value of 0x01 (if I read the code correctly).

yep, that's what I meant

>
> Assuming that adding X509_check_purpose() works everywhere, it may
> be best to keep it, and thus change sc_pkcs15init_map_usage()?

yep

>
> But then I'm not sure how e.g. the 9th bit (decipherOnly) will be
> represented in key_usage? As 0x0100? Currently, the 8th and 9th
> bits are ignored so if we would keep it that way, the function would
> become:
>
> Index: pkcs15init/pkcs15-lib.c
> ===================================================================
> --- pkcs15init/pkcs15-lib.c     (revision 2432)
> +++ pkcs15init/pkcs15-lib.c     (working copy)
> @@ -1623,7 +1623,7 @@
>        | SC_PKCS15_PRKEY_USAGE_SIGNRECOVER,    /* cRLSign */
> };
>
> -static unsigned int    x509_to_pkcs15_public_key_usage[16] = {
> +static unsigned int    x509_to_pkcs15_public_key_usage[] = {
>        SC_PKCS15_PRKEY_USAGE_VERIFY
>        | SC_PKCS15_PRKEY_USAGE_VERIFYRECOVER,  /* digitalSignature */
>        SC_PKCS15_PRKEY_USAGE_NONREPUDIATION,   /* NonRepudiation */
> @@ -1644,9 +1644,10 @@
>        bits = _private? x509_to_pkcs15_private_key_usage
>                      : x509_to_pkcs15_public_key_usage;
>        for (n = p15_usage = 0; n < 16; n++) {
> -               if (x509_usage & (1 << n))
> +               if (x509_usage & (0x8000 >> n))
>                        p15_usage |= bits[n];
>        }
> +
>        return p15_usage;
> }
does the attached patch help ?

Nils

Index: src/pkcs15init/pkcs15-lib.c
===================================================================
--- src/pkcs15init/pkcs15-lib.c (Revision 2439)
+++ src/pkcs15init/pkcs15-lib.c (Arbeitskopie)
@@ -1644,7 +1644,7 @@
  bits = _private? x509_to_pkcs15_private_key_usage
       : x509_to_pkcs15_public_key_usage;
  for (n = p15_usage = 0; n < 16; n++) {
- if (x509_usage & (1 << n))
+ if (x509_usage & ((0x80 >> (n % 8)) << (n / 8)))
  p15_usage |= bits[n];
  }
  return p15_usage;
Index: src/tools/pkcs15-init.c
===================================================================
--- src/tools/pkcs15-init.c (Revision 2439)
+++ src/tools/pkcs15-init.c (Arbeitskopie)
@@ -44,6 +44,7 @@
 #include <openssl/dsa.h>
 #include <openssl/bn.h>
 #include <openssl/pkcs12.h>
+#include <openssl/x509v3.h>
 #include <opensc/cardctl.h>
 #include <opensc/pkcs15.h>
 #include <opensc/pkcs15-init.h>
@@ -701,11 +702,16 @@
  if ((r = do_convert_private_key(&args.key, pkey)) < 0)
  return r;
  if (ncerts) {
- unsigned int usage = cert[0]->ex_kusage;
+ unsigned int usage;
 
+ /* tell openssl to cache the extensions */
+ X509_check_purpose(cert[0], -1, -1);
+ usage = cert[0]->ex_kusage;
+
  /* No certificate usage? Assume ordinary
  * user cert */
- usage = 0x1F;
+ if (usage == 0)
+ usage = 0x1F;
 
  /* If the user requested a specific key usage on the
  * command line check if it includes _more_

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

Re: Wrong key usage in pkcs15-init tool

Stef Hoeben

>
> does the attached patch help ?


Yes, works fine. I just added the same X509_check_purpose()
to the CA certs: see attachment.

Cheers,
Stef


Index: pkcs15-init.c
===================================================================
--- pkcs15-init.c (revision 2444)
+++ pkcs15-init.c (working copy)
@@ -44,6 +44,7 @@
 #include <openssl/dsa.h>
 #include <openssl/bn.h>
 #include <openssl/pkcs12.h>
+#include <openssl/x509v3.h>
 #include <opensc/cardctl.h>
 #include <opensc/pkcs15.h>
 #include <opensc/pkcs15-init.h>
@@ -701,11 +702,16 @@
  if ((r = do_convert_private_key(&args.key, pkey)) < 0)
  return r;
  if (ncerts) {
- unsigned int usage = cert[0]->ex_kusage;
+ unsigned int usage;
 
+ /* tell openssl to cache the extensions */
+ X509_check_purpose(cert[0], -1, -1);
+ usage = cert[0]->ex_kusage;
+
  /* No certificate usage? Assume ordinary
  * user cert */
- usage = 0x1F;
+ if (usage == 0)
+ usage = 0x1F;
 
  /* If the user requested a specific key usage on the
  * command line check if it includes _more_
@@ -749,6 +755,7 @@
  if ((r = do_convert_cert(&cargs.der_encoded, cert[i])) < 0)
  return r;
 
+ X509_check_purpose(cert[i], -1, -1);
  cargs.x509_usage = cert[i]->ex_kusage;
  cargs.label = X509_NAME_oneline(cert[i]->cert_info->subject,
  namebuf, sizeof(namebuf));

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

Re: Wrong key usage in pkcs15-init tool

Nils Larsch
Stef Hoeben wrote:
>
>>
>> does the attached patch help ?
>
>
>
> Yes, works fine. I just added the same X509_check_purpose()
> to the CA certs: see attachment.

ok, I've committed this.

Thanks,
Nils
_______________________________________________
opensc-devel mailing list
[hidden email]
http://www.opensc.org/cgi-bin/mailman/listinfo/opensc-devel