Re: Key usage of ECC keys on PKCS#15 smartcards doesn't allow decryption?

Mario Haustein via Gnupg-devel <[email protected]>
Newsgroups gmane.comp.encryption.gpg.devel
Organization TU Chemnitz
Message-ID <5460453.29KlJPOoH8@localdomain>
Hi Werner,

Am Sonntag, 18. Februar 2024, 17:46:11 CET schrieb Werner Koch:
> On Fri, 16 Feb 2024 15:12, Mario Haustein said:
> > Is it likely that the `derive` check was just forgotten at this place? I
> > cannot judge the consequences of this change, which is the reason for
> > asking
> Well, not forgotten but I have never seen that used by cards.  I'll
> check tomorrow whether I can see any problems with your suggestion.
> 
> FWIW, in gpgsm we had a somewhat related problem with RSA cards:
> 
> /* Telesec RSA cards produced for NRW in 2022 came with only the
>  * keyAgreement bit set.  This flag allows their use for encryption
>  * anyway.  Example cert:
>  *    Issuer: /CN=DOI CA 10a/OU=DOI/O=PKI-1-Verwaltung/C=DE
>  * key usage: digitalSignature nonRepudiation keyAgreement
>  *  policies: 1.3.6.1.4.1.7924.1.1:N:
>  */
> #define COMPAT_ALLOW_KA_TO_ENCR   1
> 
> However, this was clearly wrong.  Thanks for testing with the D-TRUST
> cards. I have had always problems working with the Bundesdruckerei ;-)

thanks for your patch in the PKCS#15 object ID mail thread. I applied it and 
can confirm, it solves the problem. I worked independently on this topic and 
came to a similar solution which just differs in a detail. I was wondering why 
the derive key usage was not considered in do_getattr(). Is there a specific 
reason for it? From my understanding it should allow to use the card for 
OpenPGP keys as well.

You will find my patch as nr. 0003 in the patchset together with my 
preliminary patch for the ECC cards (and a typo). I omitted the patch for the 
PKCS#15 object ID problem, as there are still issues to solve.

If all the issues are solve, I will prepare a final patchset.

Kind regards
-- 
Mario Haustein
Facharbeitsgruppe Anwendungen
Universitätsrechenzentrum

Technische Universität Chemnitz
Straße der Nationen 62 | R. 1/B303 (neu: A11.303)
09111 Chemnitz
Germany

Tel:    +49 371 531-36606
Fax:    +49 371 531-836606

[email protected]
www.tu-chemnitz.de

_______________________________________________
Gnupg-devel mailing list
[email protected]
https://lists.gnupg.org/mailman/listinfo/gnupg-devel
0001-scd-p15-Take-derive-usage-into-account-for-decryptio.patch (text/x-patch, 4.1 KB)
>From 0558faf8bf1a0bfd417c1037bd418575691fbe66 Mon Sep 17 00:00:00 2001
From: Werner Koch <[email protected]>
Date: Mon, 19 Feb 2024 13:51:02 +0100
Subject: [PATCH GnuPG 1/5] scd:p15: Take derive usage into account for
 decryption.

* scd/app-p15.c (set_usage_string): Map usageflags.derive also to 'e'.
(do_auth): Allow usageflags.sign_recover.
(do_decipher): Allow usageflags.derive.
(do_with_keygrip): Take usageflags.derive into account.

(do_decipher): Take a missing AODF for authentication not needed.
--

This is required for D-Trust ECC cards.

The AODF thing is unrelated but seems to be a good idea.

GnuPG-bug-id: 7000
---
 scd/app-p15.c | 33 +++++++++++++++++++--------------
 1 file changed, 19 insertions(+), 14 deletions(-)

diff --git a/scd/app-p15.c b/scd/app-p15.c
index 2bb90beaa..c9ab30fe9 100644
--- a/scd/app-p15.c
+++ b/scd/app-p15.c
@@ -305,7 +305,7 @@ struct prkdf_object_s
   keyaccess_flags_t accessflags;
 
   /* Extended key usage flags.  Only used if .valid is set.  This
-   * information is computed from an associated certificate15.  */
+   * information is computed from an associated certificate.  */
   struct {
     unsigned int valid:1;
     unsigned int sign:1;
@@ -4214,7 +4214,8 @@ set_usage_string (char usage[5], prkdf_object_t prkdf)
           && (!prkdf->extusage.valid || prkdf->extusage.sign))
         usage[usagelen++] = 'c';
       if ((prkdf->usageflags.decrypt
-           || prkdf->usageflags.unwrap)
+           || prkdf->usageflags.unwrap
+           || prkdf->usageflags.derive)
           && (!prkdf->extusage.valid || prkdf->extusage.encr))
         usage[usagelen++] = 'e';
       if ((prkdf->usageflags.sign
@@ -5927,7 +5928,8 @@ do_auth (app_t app, ctrl_t ctrl, const char *keyidstr,
   err = prkdf_object_from_keyidstr (app, keyidstr, &prkdf);
   if (err)
     return err;
-  if (!(prkdf->usageflags.sign || prkdf->gpgusage.auth))
+  if (!(prkdf->usageflags.sign || prkdf->usageflags.sign_recover
+        || prkdf->gpgusage.auth))
     {
       log_error ("p15: key %s may not be used for authentication\n", keyidstr);
       return gpg_error (GPG_ERR_WRONG_KEY_USAGE);
@@ -5970,6 +5972,7 @@ do_decipher (app_t app, ctrl_t ctrl, const char *keyidstr,
     return err;
   if (!(prkdf->usageflags.decrypt
         || prkdf->usageflags.unwrap
+        || prkdf->usageflags.derive
         || prkdf->gpgusage.encr     ))
     {
       log_error ("p15: key %s may not be used for decryption\n", keyidstr);
@@ -5979,17 +5982,18 @@ do_decipher (app_t app, ctrl_t ctrl, const char *keyidstr,
   /* Find the authentication object to this private key object. */
   if (!prkdf->authid)
     {
-      log_error ("p15: no authentication object defined for %s\n", keyidstr);
-      /* fixme: we might want to go ahead and do without PIN
-         verification. */
-      return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION);
+      log_info ("p15: no authentication object defined for %s\n", keyidstr);
+      aodf = NULL;
+    }
+  else
+    {
+      for (aodf = app->app_local->auth_object_info; aodf; aodf = aodf->next)
+        if (aodf->objidlen == prkdf->authidlen
+            && !memcmp (aodf->objid, prkdf->authid, prkdf->authidlen))
+          break;
+      if (!aodf)
+        log_info ("p15: no authentication for %s needed\n", keyidstr);
     }
-  for (aodf = app->app_local->auth_object_info; aodf; aodf = aodf->next)
-    if (aodf->objidlen == prkdf->authidlen
-        && !memcmp (aodf->objid, prkdf->authid, prkdf->authidlen))
-      break;
-  if (!aodf)
-    log_info ("p15: no authentication for %s needed\n", keyidstr);
 
   /* We need some more info about the key - get the keygrip to
    * populate these fields.  */
@@ -6274,7 +6278,8 @@ do_with_keygrip (app_t app, ctrl_t ctrl, int action,
             }
           else if (capability == GCRY_PK_USAGE_ENCR)
             {
-              if (!(prkdf->usageflags.decrypt || prkdf->usageflags.unwrap))
+              if (!(prkdf->usageflags.decrypt || prkdf->usageflags.unwrap
+                    || prkdf->usageflags.derive))
                 continue;
             }
           else if (capability == GCRY_PK_USAGE_AUTH)
-- 
2.43.0
0003-scd-p15-Take-derive-usage-into-account-for-decryptio.patch (text/x-patch, 1.5 KB)
>From 9a962137a1abbff9ae3d8a252ed3d6fcbdbfa7d1 Mon Sep 17 00:00:00 2001
From: Mario Haustein <[email protected]>
Date: Mon, 19 Feb 2024 10:21:24 +0100
Subject: [PATCH GnuPG 3/5] scd:p15: Take derive usage into account for
 decryption.

* scd/app-p15.c (do_getattr): Map usageflags.derive also to 'e'.
---
 scd/app-p15.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/scd/app-p15.c b/scd/app-p15.c
index 9ed51ae04..bd0586f94 100644
--- a/scd/app-p15.c
+++ b/scd/app-p15.c
@@ -4719,7 +4719,8 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
               if ((name[1] == 'A' && (prkdf->usageflags.sign
                                       || prkdf->usageflags.sign_recover))
                   || (name[1] == 'E' && (prkdf->usageflags.decrypt
-                                         || prkdf->usageflags.unwrap))
+                                         || prkdf->usageflags.unwrap
+                                         || prkdf->usageflags.derive))
                   || (name[1] == 'S' && (prkdf->usageflags.sign
                                          || prkdf->usageflags.sign_recover)))
                 break;
@@ -4928,7 +4929,7 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
             }
           else
             {
-              if (prkdf->usageflags.decrypt || prkdf->usageflags.unwrap)
+              if (prkdf->usageflags.decrypt || prkdf->usageflags.unwrap || prkdf->usageflags.derive)
                 break;
             }
         }
-- 
2.43.0
0004-scd-p15-Fix-typo-in-a-comment.patch (text/x-patch, 877 B)
>From aab16c97cab515fe0af759976a1489e88edeee0c Mon Sep 17 00:00:00 2001
From: Mario Haustein <[email protected]>
Date: Mon, 19 Feb 2024 10:22:08 +0100
Subject: [PATCH GnuPG 4/5] scd:p15: Fix typo in a comment

---
 scd/app-p15.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/scd/app-p15.c b/scd/app-p15.c
index bd0586f94..e061d34bc 100644
--- a/scd/app-p15.c
+++ b/scd/app-p15.c
@@ -4697,7 +4697,7 @@ do_getattr (app_t app, ctrl_t ctrl, const char *name)
 
       /* We return the ID of the first private key capable of the
        * requested action.  If any gpgusage flag has been set for the
-       * card we consult the gpgusage flags and not the regualr usage
+       * card we consult the gpgusage flags and not the regular usage
        * flags.
        */
       /* FIXME: This changed: Note that we do not yet return
-- 
2.43.0
0005-scd-p15-Add-ECC-support-for-D-Trust-Card-4.1-4.4.patch (text/x-patch, 1.5 KB)
>From 6f5c2e235cd274fbfd19f0ccfd82c66fe3f124fb Mon Sep 17 00:00:00 2001
From: Mario Haustein <[email protected]>
Date: Mon, 19 Feb 2024 10:22:35 +0100
Subject: [PATCH GnuPG 5/5] scd:p15: Add ECC support for D-Trust Card 4.1/4.4

* scd/app-p15.c (do_sign): Add MSE RESTORE parameters for D-Trust ECC
cards.
(do_decipher): Ditto.
---
 scd/app-p15.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/scd/app-p15.c b/scd/app-p15.c
index e061d34bc..882b891f3 100644
--- a/scd/app-p15.c
+++ b/scd/app-p15.c
@@ -5821,9 +5821,8 @@ do_sign (app_t app, ctrl_t ctrl, const char *keyidstr, int hashalgo,
     {
       if (prkdf->is_ecc)
         {
-          /* Not implemented due to lacking test hardware. */
-          log_info ("Note: ECC is not yet implemented for DTRUST 4 cards\n");
-          err = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
+          err = iso7816_manage_security_env (app_get_slot (app),
+                                             0xf3, 0x21, NULL, 0);
         }
       else
         {
@@ -6082,9 +6081,8 @@ do_decipher (app_t app, ctrl_t ctrl, const char *keyidstr,
     {
       if (prkdf->is_ecc)
         {
-          /* Not implemented due to lacking test hardware. */
-          log_info ("Note: ECC is not yet implemented for DTRUST 4 cards\n");
-          err = gpg_error (GPG_ERR_UNSUPPORTED_ALGORITHM);
+          err = iso7816_manage_security_env (app_get_slot (app),
+                                             0xF3, 0x39, NULL, 0);
         }
       else
         {
-- 
2.43.0
signature.asc (application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE-----

iQIzBAABCAAdFiEE0dWxQ/gtEp4RcqrdrrMm8sIKEfoFAmXTeAoACgkQrrMm8sIK
EfoDLQ//XXe/C3ZCXQRxWVW7xYV45KyfNu8iEF8O2gvZ0UeyiaYZ8NTA8T48xjGH
eh1m5+A7s7SqO5vr3kJA+SSjzWb5797SU5KYSDWG1FQoDaZqF3QxCrWVmM9+dK6n
3RHTeJkc8xxF9vwmChrPciWNG41Jx5g+IRcO9ZbAwNrKjqEweSAAQx2PLmYcp7kU
6/+9iWVzmcBC0xqXiPFqAfLYKf84tD8RKxwY6+drIRtqtPm3f1EeZRAUwlRtNlkJ
AOBE1m5r/T+5Q79zqzqbrhVjF9RUG7vuY6a6C4SyGnvxV3E5e36hwAMyCG4KpHWd
GhwS2zGv68f1Sroj9RZSlJMNZ6itVZzWqWifjcDjNKpjvFkpDdQoiQ7EjfZLPj5V
cdqNnMgDNUUKAbfP9Oq7NddRr4l1F6SwiIveC53WkQDskk6XV9zhiYYXS5Stv+cP
HRnHckjUrt79YRZzcFMEWjDn05D2ktWTKCaYVL9oZx63HogyFbnInVlyNq6xwc6K
ESsrpMAtIoQNEvau3WZ3NLwK1hjNY404XUNrXBi5RiZd2jwQ67tvM31X/M0F3Afe
a61X3s27BujCgmy7zutG1XHntnQU404Ium8H2smz7Q/96x+Tt7vcHNMMSjkY/oQS
g2DFhlZlAkANk+lCrUlR5h6PHviYp0rsD4oL+NEVJatk9LfbrAs=
=uIwO
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.