[PATCH GnuPG 0/5] Add ECC support for D-Trust 4.1/4.4

Mario Haustein via Gnupg-devel <[email protected]>
Newsgroups gmane.comp.encryption.gpg.devel
Organization TU Chemnitz
Message-ID <3378651.usfYGdeWWP@localdomain>
Dear Developers,

this series of patches adds ECC support for the D-Trust 4.1/4.4 cards. All the 
code was already there. Just the security environment parameters had to be 
confirmed which I now successfully did with my test cards.

The patches further allow keys with the derive usage-flag to be used for 
decryption and fixes certificate import for duplicate certificate IDs. These 
issues were already addressed in separate threads on this list.

I am unsure whether patch nr. 0003 is necessary. Feel free to either omit it 
or to squash it with 0002.

Mario Haustein (3):
  scd:p15: Take derive usage into account for decryption.
  scd:p15: Fix typo in a comment
  scd:p15: Add ECC support for D-Trust Card 4.1/4.4

Werner Koch (2):
  scd:p15: Handle duplicate certificate ids.
  scd:p15: Take derive usage into account for decryption.

 scd/app-p15.c | 96 +++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 71 insertions(+), 25 deletions(-)

-- 
2.43.0

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-Handle-duplicate-certificate-ids.patch (text/x-patch, 4.1 KB)
>From f7b706b0e78cc7415cd2e512ed4a9731b355078f Mon Sep 17 00:00:00 2001
From: Werner Koch <[email protected]>
Date: Mon, 19 Feb 2024 14:45:06 +0100
Subject: [PATCH GnuPG 1/5] scd:p15: Handle duplicate certificate ids.

* scd/app-p15.c (struct app_local_s): Add field cdf_dup_counter.
(objid_in_cdflist_p): New.
(read_p15_info): Clear the counter.
(read_ef_cdf): Detect and fix duplicate IDs.
--

GnuPG-bug-id: 7001
Reported-by: Mario Haustein <[email protected]>
---
 scd/app-p15.c | 46 ++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 44 insertions(+), 2 deletions(-)

diff --git a/scd/app-p15.c b/scd/app-p15.c
index 2bb90beaa..eb9c53465 100644
--- a/scd/app-p15.c
+++ b/scd/app-p15.c
@@ -520,6 +520,9 @@ struct app_local_s
   /* Information on all useful certificates. */
   cdf_object_t useful_certificate_info;
 
+  /* Counter to make object ids of certificates unique.  */
+  unsigned int cdf_dup_counter;
+
   /* Information on all public keys. */
   prkdf_object_t public_key_info;
 
@@ -2419,6 +2422,22 @@ read_ef_pukdf (app_t app, unsigned short fid, pukdf_object_t *result)
 }
 
 
+/* Return true id CDFLIST has the given object id.  */
+static int
+objid_in_cdflist_p (cdf_object_t cdflist,
+                    const unsigned char *objid, size_t objidlen)
+{
+  cdf_object_t cdf;
+
+  if (!objid || !objidlen)
+    return 0;
+  for (cdf = cdflist; cdf; cdf = cdf->next)
+    if (cdf->objidlen == objidlen && !memcmp (cdf->objid, objid, objidlen))
+      return 1;
+  return 0;
+}
+
+
 /* Read and parse the Certificate Directory Files identified by FID.
    On success a newlist of CDF object gets stored at RESULT and the
    caller is then responsible of releasing this list.  On error a
@@ -2464,6 +2483,7 @@ read_ef_cdf (app_t app, unsigned short fid, int cdftype, cdf_object_t *result)
       unsigned long ul;
       const unsigned char *objid;
       size_t objidlen;
+      int objidextralen;
 
       err = parse_ber_header (&p, &n, &class, &tag, &constructed,
                               &ndef, &objlen, &hdrlen);
@@ -2588,8 +2608,19 @@ read_ef_cdf (app_t app, unsigned short fid, int cdftype, cdf_object_t *result)
           label = NULL;
         }
 
-      cdf->objidlen = objidlen;
-      cdf->objid = xtrymalloc (objidlen);
+      /* Card's have been found in the wild which do not have unique
+       * IDs for their certificate objects.  If we detect this we
+       * append a counter to the ID.  */
+      objidextralen =
+        (objid_in_cdflist_p (cdflist, objid, objidlen)
+         || objid_in_cdflist_p (app->app_local->certificate_info,
+                                objid, objidlen)
+         || objid_in_cdflist_p (app->app_local->trusted_certificate_info,
+                                objid, objidlen)
+         || objid_in_cdflist_p (app->app_local->useful_certificate_info,
+                                objid, objidlen));
+      cdf->objidlen = objidlen + objidextralen;
+      cdf->objid = xtrymalloc (objidlen + objidextralen);
       if (!cdf->objid)
         {
           err = gpg_error_from_syserror ();
@@ -2597,6 +2628,16 @@ read_ef_cdf (app_t app, unsigned short fid, int cdftype, cdf_object_t *result)
           goto leave;
         }
       memcpy (cdf->objid, objid, objidlen);
+      if (objidextralen)
+        {
+          if (app->app_local->cdf_dup_counter == 255)
+            {
+              log_error ("p15: too many duplicate certificate ids\n");
+              err = gpg_error (GPG_ERR_TOO_MANY);
+              goto parse_error;
+            }
+          cdf->objid[objidlen] = ++app->app_local->cdf_dup_counter;
+        }
 
       cdf->pathlen = objlen/2;
       for (i=0; i < cdf->pathlen; i++, pp += 2, nn -= 2)
@@ -3664,6 +3705,7 @@ read_p15_info (app_t app)
   log_assert (!app->app_local->certificate_info);
   log_assert (!app->app_local->trusted_certificate_info);
   log_assert (!app->app_local->useful_certificate_info);
+  app->app_local->cdf_dup_counter = 0;
   err = read_ef_cdf (app, app->app_local->odf.certificates, 'c',
                      &app->app_local->certificate_info);
   if (!err || gpg_err_code (err) == GPG_ERR_NO_DATA)
-- 
2.43.0
0002-scd-p15-Take-derive-usage-into-account-for-decryptio.patch (text/x-patch, 4.1 KB)
>From 057a668a7994dfb4ad3dcde7d40337cd34bded64 Mon Sep 17 00:00:00 2001
From: Werner Koch <[email protected]>
Date: Mon, 19 Feb 2024 13:51:02 +0100
Subject: [PATCH GnuPG 2/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 eb9c53465..8a869279d 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;
@@ -4256,7 +4256,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
@@ -5969,7 +5970,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);
@@ -6012,6 +6014,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);
@@ -6021,17 +6024,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.  */
@@ -6316,7 +6320,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
0004-scd-p15-Fix-typo-in-a-comment.patch (text/x-patch, 877 B)
>From 3c61ac16e8b6a90f3efeb917bd20612660755c54 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 4ad3bc3b7..fb1b67c21 100644
--- a/scd/app-p15.c
+++ b/scd/app-p15.c
@@ -4704,7 +4704,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
0003-scd-p15-Take-derive-usage-into-account-for-decryptio.patch (text/x-patch, 1.5 KB)
>From c944a0cb15a332426105a33bf01d4f301b60cbe7 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 8a869279d..4ad3bc3b7 100644
--- a/scd/app-p15.c
+++ b/scd/app-p15.c
@@ -4726,7 +4726,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;
@@ -4935,7 +4936,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
0005-scd-p15-Add-ECC-support-for-D-Trust-Card-4.1-4.4.patch (text/x-patch, 1.5 KB)
>From 5fecff0baed5d8b7ef0f53a08a75976794dd739e 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 fb1b67c21..877db8bfc 100644
--- a/scd/app-p15.c
+++ b/scd/app-p15.c
@@ -5828,9 +5828,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
         {
@@ -6089,9 +6088,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/gtEp4RcqrdrrMm8sIKEfoFAmXTiUYACgkQrrMm8sIK
EfofOw//Q/Ez0b4uJrQHU6jCpTyXiaU3uk6lv3HXL3jEuj9nS7cLqkzZLMHloPTY
TMS1IATHnDjc0nFlV6DgfL0IItiR8XqPORx/EeIg7mPeuykQG4QpnvMR+8YiscCq
PZ1bNVeEm4FMojIrs1VinnejdM/YoRYCn2ex4WhuBc1XnbV0aQyqMWVjk9ugzxch
D2/80kpt0cHWz/OXye0vJdH2JmUosc390MW4/9KK4uBWNFV9HylXr9SuK4rUKzUW
VFqDhVs/yTHAB8kEhCAWJL1bpaO2o8yX45YnT4Jz/niWHwiCt4SEreZf2G3VU305
WIJD6dzSsRHXaBLO11zZnW2pLcHiGf3wYAEGb9z9R1ud9j5yfzW94MTNFYHP1ojk
r9P6Pcx8CAM/8+2Gdx2GzPqqnJfsZIcNF4ZUnwWZJFOpn60lyvAaOc2Vo05+mF1j
2ojnN+uWCZUNkI6ZjAVlngqGF1q+yTi4e/0Ctm/R2IdDwjRCtN6XflGFylsdEd3e
TEEb04Jbp5Lbz0xyGilUf4ebcREP9miQzc3P1t78MiS3bAHNQoO4dxKeLCKF2bB4
qzLvYhQwRLLA9IeQ2TKtVuCVoMGWfF3+yBOfLxjVhmpb4tjv5IgMsH9CINpzOEEQ
Z/gA3gTfz/4PI3pPVqNL4lQB9vJyrsHIhAoOuZ06AmfWcZY/j8Y=
=+vbq
-----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.