diff --git a/sm/ChangeLog b/sm/ChangeLog index 634bb2230..7ab2f9a1f 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,10 @@ +2002-05-03 Werner Koch + + * certpath.c (gpgsm_validate_path): Added EXPTIME arg and changed + all callers. + * verify.c (gpgsm_verify): Tweaked usage of log_debug and + log_error. Return EXPSIG status and add expiretime to VALIDSIG. + 2002-04-26 Werner Koch * gpgsm.h (DBG_AGENT,DBG_AGENT_VALUE): Replaced by DBG_ASSUAN_*. diff --git a/sm/certchain.c b/sm/certchain.c index 978d1f755..1283ce46d 100644 --- a/sm/certchain.c +++ b/sm/certchain.c @@ -305,8 +305,10 @@ gpgsm_is_root_cert (KsbaCert cert) } +/* Validate a path and optionally return the nearest expiration time + in R_EXPTIME */ int -gpgsm_validate_path (KsbaCert cert) +gpgsm_validate_path (KsbaCert cert, time_t *r_exptime) { int rc = 0, depth = 0, maxdepth; char *issuer = NULL; @@ -314,14 +316,17 @@ gpgsm_validate_path (KsbaCert cert) KEYDB_HANDLE kh = keydb_new (0); KsbaCert subject_cert = NULL, issuer_cert = NULL; time_t current_time = time (NULL); + time_t exptime = 0; + + if (r_exptime) + *r_exptime = 0; if ((opt.debug & 4096)) { log_info ("WARNING: bypassing path validation\n"); return 0; } - - + if (!kh) { log_error (_("failed to allocated keyDB handle\n")); @@ -361,7 +366,15 @@ gpgsm_validate_path (KsbaCert cert) goto leave; } - if (current_time < not_before) + if (not_after) + { + if (!exptime) + exptime = not_after; + else if (not_after < exptime) + exptime = not_after; + } + + if (not_before && current_time < not_before) { log_error ("certificate to young; valid from "); gpgsm_dump_time (not_before); @@ -369,7 +382,7 @@ gpgsm_validate_path (KsbaCert cert) rc = GNUPG_Certificate_Too_Young; goto leave; } - if (current_time > not_after) + if (not_after && current_time > not_after) { log_error ("certificate has expired at "); gpgsm_dump_time (not_after); @@ -526,7 +539,8 @@ gpgsm_validate_path (KsbaCert cert) } } - log_info ("certificate is good\n"); + if (opt.verbose) + log_info ("certificate is good\n"); keydb_search_reset (kh); subject_cert = issuer_cert; @@ -539,6 +553,8 @@ gpgsm_validate_path (KsbaCert cert) log_info ("CRLs not checked due to --disable-crl-checks option\n"); leave: + if (r_exptime) + *r_exptime = exptime; xfree (issuer); keydb_release (kh); ksba_cert_release (issuer_cert); diff --git a/sm/certlist.c b/sm/certlist.c index 2d52ada30..177f86725 100644 --- a/sm/certlist.c +++ b/sm/certlist.c @@ -152,7 +152,7 @@ gpgsm_add_to_certlist (const char *name, CERTLIST *listaddr) rc = GNUPG_Ambiguous_Name; } if (!rc) - rc = gpgsm_validate_path (cert); + rc = gpgsm_validate_path (cert, NULL); if (!rc) { CERTLIST cl = xtrycalloc (1, sizeof *cl); diff --git a/sm/certpath.c b/sm/certpath.c index 978d1f755..1283ce46d 100644 --- a/sm/certpath.c +++ b/sm/certpath.c @@ -305,8 +305,10 @@ gpgsm_is_root_cert (KsbaCert cert) } +/* Validate a path and optionally return the nearest expiration time + in R_EXPTIME */ int -gpgsm_validate_path (KsbaCert cert) +gpgsm_validate_path (KsbaCert cert, time_t *r_exptime) { int rc = 0, depth = 0, maxdepth; char *issuer = NULL; @@ -314,14 +316,17 @@ gpgsm_validate_path (KsbaCert cert) KEYDB_HANDLE kh = keydb_new (0); KsbaCert subject_cert = NULL, issuer_cert = NULL; time_t current_time = time (NULL); + time_t exptime = 0; + + if (r_exptime) + *r_exptime = 0; if ((opt.debug & 4096)) { log_info ("WARNING: bypassing path validation\n"); return 0; } - - + if (!kh) { log_error (_("failed to allocated keyDB handle\n")); @@ -361,7 +366,15 @@ gpgsm_validate_path (KsbaCert cert) goto leave; } - if (current_time < not_before) + if (not_after) + { + if (!exptime) + exptime = not_after; + else if (not_after < exptime) + exptime = not_after; + } + + if (not_before && current_time < not_before) { log_error ("certificate to young; valid from "); gpgsm_dump_time (not_before); @@ -369,7 +382,7 @@ gpgsm_validate_path (KsbaCert cert) rc = GNUPG_Certificate_Too_Young; goto leave; } - if (current_time > not_after) + if (not_after && current_time > not_after) { log_error ("certificate has expired at "); gpgsm_dump_time (not_after); @@ -526,7 +539,8 @@ gpgsm_validate_path (KsbaCert cert) } } - log_info ("certificate is good\n"); + if (opt.verbose) + log_info ("certificate is good\n"); keydb_search_reset (kh); subject_cert = issuer_cert; @@ -539,6 +553,8 @@ gpgsm_validate_path (KsbaCert cert) log_info ("CRLs not checked due to --disable-crl-checks option\n"); leave: + if (r_exptime) + *r_exptime = exptime; xfree (issuer); keydb_release (kh); ksba_cert_release (issuer_cert); diff --git a/sm/gpgsm.h b/sm/gpgsm.h index f0630ca38..a9d48c8bf 100644 --- a/sm/gpgsm.h +++ b/sm/gpgsm.h @@ -180,7 +180,7 @@ int gpgsm_create_cms_signature (KsbaCert cert, GCRY_MD_HD md, int mdalgo, /*-- certpath.c --*/ int gpgsm_walk_cert_chain (KsbaCert start, KsbaCert *r_next); int gpgsm_is_root_cert (KsbaCert cert); -int gpgsm_validate_path (KsbaCert cert); +int gpgsm_validate_path (KsbaCert cert, time_t *r_exptime); int gpgsm_basic_cert_check (KsbaCert cert); /*-- certlist.c --*/ diff --git a/sm/server.c b/sm/server.c index 5ebd5477c..beaea803a 100644 --- a/sm/server.c +++ b/sm/server.c @@ -755,6 +755,8 @@ get_status_string ( int no ) case STATUS_INV_RECP : s = "INV_RECP"; break; case STATUS_NO_RECP : s = "NO_RECP"; break; case STATUS_ALREADY_SIGNED : s = "ALREADY_SIGNED"; break; + case STATUS_EXPSIG : s = "EXPSIG"; break; + case STATUS_EXPKEYSIG : s = "EXPKEYSIG"; break; default: s = "?"; break; } return s; diff --git a/sm/verify.c b/sm/verify.c index f4d80393a..5549470c2 100644 --- a/sm/verify.c +++ b/sm/verify.c @@ -153,7 +153,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp) err = ksba_cms_set_reader_writer (cms, reader, writer); if (err) { - log_debug ("ksba_cms_set_reader_writer failed: %s\n", + log_error ("ksba_cms_set_reader_writer failed: %s\n", ksba_strerror (err)); rc = map_ksba_err (err); goto leave; @@ -175,7 +175,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp) err = ksba_cms_parse (cms, &stopreason); if (err) { - log_debug ("ksba_cms_parse failed: %s\n", ksba_strerror (err)); + log_error ("ksba_cms_parse failed: %s\n", ksba_strerror (err)); rc = map_ksba_err (err); goto leave; } @@ -183,7 +183,8 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp) if (stopreason == KSBA_SR_NEED_HASH) { is_detached = 1; - log_debug ("Detached signature\n"); + if (opt.verbose) + log_info ("detached signature\n"); } if (stopreason == KSBA_SR_NEED_HASH @@ -251,7 +252,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp) { char *issuer = NULL; KsbaSexp sigval = NULL; - time_t sigtime; + time_t sigtime, keyexptime; KsbaSexp serial; char *msgdigest = NULL; size_t msgdigestlen; @@ -265,21 +266,27 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp) } if (err) break; - log_debug ("signer %d - issuer: `%s'\n", signer, issuer? issuer:"[NONE]"); - log_debug ("signer %d - serial: ", signer); - gpgsm_dump_serial (serial); - log_printf ("\n"); + if (DBG_X509) + { + log_debug ("signer %d - issuer: `%s'\n", + signer, issuer? issuer:"[NONE]"); + log_debug ("signer %d - serial: ", signer); + gpgsm_dump_serial (serial); + log_printf ("\n"); + } err = ksba_cms_get_signing_time (cms, signer, &sigtime); if (err) { - log_debug ("error getting signing time: %s\n", ksba_strerror (err)); + log_error ("error getting signing time: %s\n", ksba_strerror (err)); sigtime = (time_t)-1; } - log_debug ("signer %d - sigtime: ", signer); - gpgsm_dump_time (sigtime); - log_printf ("\n"); - + if (DBG_X509) + { + log_debug ("signer %d - sigtime: ", signer); + gpgsm_dump_time (sigtime); + log_printf ("\n"); + } err = ksba_cms_get_message_digest (cms, signer, &msgdigest, &msgdigestlen); @@ -288,10 +295,11 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp) algoid = ksba_cms_get_digest_algo (cms, signer); algo = gcry_md_map_name (algoid); - log_debug ("signer %d - digest algo: %d\n", signer, algo); + if (DBG_X509) + log_debug ("signer %d - digest algo: %d\n", signer, algo); if ( !gcry_md_info (data_md, GCRYCTL_IS_ALGO_ENABLED, &algo, NULL) ) { - log_debug ("digest algo %d has not been enabled\n", algo); + log_error ("digest algo %d has not been enabled\n", algo); goto next_signer; } @@ -301,14 +309,15 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp) log_error ("no signature value available\n"); goto next_signer; } - log_debug ("signer %d - signature available", signer); + if (DBG_X509) + log_debug ("signer %d - signature available", signer); /* Find the certificate of the signer */ keydb_search_reset (kh); rc = keydb_search_issuer_sn (kh, issuer, serial); if (rc) { - log_debug ("failed to find the certificate: %s\n", + log_error ("failed to find the certificate: %s\n", gnupg_strerror(rc)); goto next_signer; } @@ -316,7 +325,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp) rc = keydb_get_cert (kh, &cert); if (rc) { - log_debug ("failed to get cert: %s\n", gnupg_strerror (rc)); + log_error ("failed to get cert: %s\n", gnupg_strerror (rc)); goto next_signer; } @@ -351,7 +360,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp) rc = ksba_cms_hash_signed_attrs (cms, signer); if (rc) { - log_debug ("hashing signed attrs failed: %s\n", + log_error ("hashing signed attrs failed: %s\n", ksba_strerror (rc)); gcry_md_close (md); goto next_signer; @@ -371,23 +380,29 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp) goto next_signer; } gpgsm_cert_use_verify_p (cert); /* this displays an info message */ - log_debug ("signature okay - checking certs\n"); - gpgsm_status (ctrl, STATUS_GOODSIG, NULL); + if (DBG_X509) + log_debug ("signature okay - checking certs\n"); + rc = gpgsm_validate_path (cert, &keyexptime); + if (rc == GNUPG_Certificate_Expired) + gpgsm_status (ctrl, STATUS_EXPKEYSIG, NULL); + else + gpgsm_status (ctrl, STATUS_GOODSIG, NULL); + { char *buf, *fpr, *tstr; fpr = gpgsm_get_fingerprint_hexstring (cert, GCRY_MD_SHA1); tstr = strtimestamp (sigtime); - buf = xmalloc ( strlen(fpr) + strlen (tstr) + 100); - sprintf (buf, "%s %s %lu", fpr, tstr, (unsigned long)sigtime ); + buf = xmalloc ( strlen(fpr) + strlen (tstr) + 120); + sprintf (buf, "%s %s %lu %lu", fpr, tstr, + (unsigned long)sigtime, (unsigned long)keyexptime ); xfree (tstr); xfree (fpr); gpgsm_status (ctrl, STATUS_VALIDSIG, buf); xfree (buf); } - rc = gpgsm_validate_path (cert); - if (rc) + if (rc) /* of validate_path */ { log_error ("invalid certification path: %s\n", gnupg_strerror (rc)); if (rc == GNUPG_Bad_Certificate_Path @@ -413,7 +428,7 @@ gpgsm_verify (CTRL ctrl, int in_fd, int data_fd, FILE *out_fp) rc = 0; if (err) { - log_debug ("ksba error: %s\n", ksba_strerror (err)); + log_error ("ksba error: %s\n", ksba_strerror (err)); rc = map_ksba_err (rc); }