[PATCH gnupg 1/4] sm: select unexpired certificates skipping exipired  ones

Ramón García ramon.garcia.f at gmail.com
Sun Feb 16 23:00:04 CET 2025


This enables the user to select a certificate by subject, and keep
old expired certificates in the store in case he wishes to decrypt
or verify an old file. This makes renewal of certificate smoother.

* sm/certchain.c sm/gpgsm.h: publish the function
  check_validity_period_cm

* sm/certlist.h: if a expired certificate is found,
  continue looking for another one
---
 sm/certchain.c |  2 +-
 sm/certlist.c  | 47 +++++++++++++++++++++++++++++++++++++++--------
 sm/gpgsm.h     |  5 +++++
 3 files changed, 45 insertions(+), 9 deletions(-)

diff --git a/sm/certchain.c b/sm/certchain.c
index 16449fb02..01ccac907 100644
--- a/sm/certchain.c
+++ b/sm/certchain.c
@@ -1433,7 +1433,7 @@ check_validity_period (ksba_isotime_t current_time,
    model.  The extra constraint here is that notBefore and notAfter
    must exists and if the additional argument CHECK_TIME is given this
    time is used to check the validity period of SUBJECT_CERT.  */
-static gpg_error_t
+gpg_error_t
 check_validity_period_cm (ksba_isotime_t current_time,
                           ksba_isotime_t check_time,
                           ksba_cert_t subject_cert,
diff --git a/sm/certlist.c b/sm/certlist.c
index 53d90ac30..6c5080a69 100644
--- a/sm/certlist.c
+++ b/sm/certlist.c
@@ -337,6 +337,9 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char
*name, int secret,
   KEYDB_SEARCH_DESC desc;
   KEYDB_HANDLE kh = NULL;
   ksba_cert_t cert = NULL;
+  ksba_isotime_t current_time = {0, };
+  ksba_isotime_t exp_time = {0, };
+  int current_time_loaded = 0;

   rc = classify_user_id (name, &desc, 0);
   if (!rc)
@@ -364,7 +367,18 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char
*name, int secret,
                   first_issuer = ksba_cert_get_issuer (cert, 0);
                 }
               rc = secret? gpgsm_cert_use_sign_p (cert, 0)
-                         : gpgsm_cert_use_encrypt_p (cert);
+                         :
+                      gpgsm_cert_use_encrypt_p (cert);
+              if (!rc)
+                {
+                  if (!current_time_loaded)
+                    {
+                      gnupg_get_isotime (current_time);
+                      current_time_loaded = 1;
+                    }
+                  rc = check_validity_period_cm (current_time, current_time,
+                                                 cert, exp_time, 0, NULL, 0);
+                }
               if (gpg_err_code (rc) == GPG_ERR_WRONG_KEY_USAGE)
                 {
                   /* There might be another certificate with the
@@ -383,6 +397,13 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char
*name, int secret,
                     wrong_usage = rc;

                 }
+              else if (gpg_err_code (rc) == GPG_ERR_CERT_EXPIRED)
+                {
+                  ksba_cert_release (cert);
+                  cert = NULL;
+                  log_info (_("looking for another certificate\n"));
+                  goto get_next;
+                }
             }
           /* We want the error code from the first match in this case. */
           if (rc && wrong_usage)
@@ -416,17 +437,27 @@ gpgsm_add_to_certlist (ctrl_t ctrl, const char
*name, int secret,
                      keybox).  */
                   if (!keydb_get_cert (kh, &cert2))
                     {
+                      if (!current_time_loaded)
+                        {
+                          gnupg_get_isotime (current_time);
+                          current_time_loaded = 1;
+                        }
                       int tmp = (same_subject_issuer (first_subject,
                                                       first_issuer,
                                                       cert2)
-                                 && ((gpg_err_code (
-                                      secret? gpgsm_cert_use_sign_p (cert2,0)
-                                            : gpgsm_cert_use_encrypt_p (cert2)
-                                      )
-                                     )  == GPG_ERR_WRONG_KEY_USAGE));
+                                 && (((gpg_err_code (
+                                     secret ?
+                                         gpgsm_cert_use_sign_p (cert2, 0) :
+                                         gpgsm_cert_use_encrypt_p (cert2)))
+                                     == GPG_ERR_WRONG_KEY_USAGE)
+                                   || gpg_err_code (
+                                       check_validity_period_cm (current_time,
+
current_time, cert,
+
exp_time, 0, NULL,
+                                                                 0))
+                                       == GPG_ERR_CERT_EXPIRED));
                       if (tmp)
-                        gpgsm_add_cert_to_certlist (ctrl, cert2,
-                                                    &dup_certs, 0);
+                        gpgsm_add_cert_to_certlist (ctrl, cert2,
&dup_certs, 0);
                       else
                         {
                           if (is_cert_in_certlist (cert2, dup_certs))
diff --git a/sm/gpgsm.h b/sm/gpgsm.h
index 78efe2379..36d5b99e7 100644
--- a/sm/gpgsm.h
+++ b/sm/gpgsm.h
@@ -441,6 +441,11 @@ int gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert,
                           ksba_isotime_t r_exptime,
                           int listmode, estream_t listfp,
                           unsigned int flags, unsigned int *retflags);
+gpg_error_t check_validity_period_cm (ksba_isotime_t current_time,
+                          ksba_isotime_t check_time,
+                          ksba_cert_t subject_cert,
+                          ksba_isotime_t exptime,
+                          int listmode, estream_t listfp, int depth);
 int gpgsm_basic_cert_check (ctrl_t ctrl, ksba_cert_t cert);

 /*-- certlist.c --*/
-- 
2.43.0



More information about the Gnupg-devel mailing list