From f5347fbc25aee7adce6244112aae639b0ff00ccd Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 16 Mar 2023 14:52:28 +0100 Subject: [PATCH] dirmngr: Add framework to implement a fake CRL feature. * dirmngr/fakecrl.c: New. * dirmngr/dirmngr.h (opt): Add fake_crl. * dirmngr/dirmngr.c (enum cmd_and_opt_values): Add oFakeCRL. (opts): Add "fake-crl" (parse_rereadable_options): Set opt.fake_crl. * dirmngr/server.c (cmd_isvalid): Take care of fakce CRLs. --- dirmngr/Makefile.am | 1 + dirmngr/crlcache.h | 8 ++++++ dirmngr/dirmngr.c | 10 ++++++- dirmngr/dirmngr.h | 1 + dirmngr/fakecrl.c | 63 +++++++++++++++++++++++++++++++++++++++++++++ dirmngr/server.c | 6 ++++- 6 files changed, 87 insertions(+), 2 deletions(-) create mode 100644 dirmngr/fakecrl.c diff --git a/dirmngr/Makefile.am b/dirmngr/Makefile.am index 1c8065dbb..feee2f5c8 100644 --- a/dirmngr/Makefile.am +++ b/dirmngr/Makefile.am @@ -58,6 +58,7 @@ endif noinst_HEADERS = dirmngr.h crlcache.h crlfetch.h misc.h dirmngr_SOURCES = dirmngr.c dirmngr.h server.c crlcache.c crlfetch.c \ + fakecrl.c \ certcache.c certcache.h \ domaininfo.c \ workqueue.c \ diff --git a/dirmngr/crlcache.h b/dirmngr/crlcache.h index 7db8f01cc..375943462 100644 --- a/dirmngr/crlcache.h +++ b/dirmngr/crlcache.h @@ -45,6 +45,7 @@ crl_sig_result_t; struct crl_cache_entry_s; typedef struct crl_cache_entry_s *crl_cache_entry_t; +/*-- crlcache.c --*/ void crl_cache_init (void); void crl_cache_deinit (void); @@ -68,4 +69,11 @@ gpg_error_t crl_cache_load (ctrl_t ctrl, const char *filename); gpg_error_t crl_cache_reload_crl (ctrl_t ctrl, ksba_cert_t cert); +/*-- fakecrl.c --*/ +crl_cache_result_t fakecrl_isvalid (ctrl_t ctrl, + const char *issuer_hash, + const char *cert_id); + + + #endif /* CRLCACHE_H */ diff --git a/dirmngr/dirmngr.c b/dirmngr/dirmngr.c index 66b7878e5..3c0818af9 100644 --- a/dirmngr/dirmngr.c +++ b/dirmngr/dirmngr.c @@ -158,6 +158,7 @@ enum cmd_and_opt_values { oConnectTimeout, oConnectQuickTimeout, oListenBacklog, + oFakeCRL, aTest }; @@ -274,7 +275,7 @@ static gpgrt_opt_t opts[] = { " points to serverlist")), ARGPARSE_s_i (oLDAPTimeout, "ldaptimeout", N_("|N|set LDAP timeout to N seconds")), - + ARGPARSE_s_s (oFakeCRL, "fake-crl", "@"), ARGPARSE_header ("OCSP", N_("Configuration for OCSP")), @@ -709,6 +710,8 @@ parse_rereadable_options (gpgrt_argparse_t *pargs, int reread) opt.ldaptimeout = DEFAULT_LDAP_TIMEOUT; ldapserver_list_needs_reset = 1; opt.debug_cache_expired_certs = 0; + xfree (opt.fake_crl); + opt.fake_crl = NULL; return 1; } @@ -871,6 +874,11 @@ parse_rereadable_options (gpgrt_argparse_t *pargs, int reread) opt.debug_cache_expired_certs = 0; break; + case oFakeCRL: + xfree (opt.fake_crl); + opt.fake_crl = *pargs->r.ret_str? xstrdup (pargs->r.ret_str) : NULL; + break; + default: return 0; /* Not handled. */ } diff --git a/dirmngr/dirmngr.h b/dirmngr/dirmngr.h index bd4660422..bcb364e8d 100644 --- a/dirmngr/dirmngr.h +++ b/dirmngr/dirmngr.h @@ -104,6 +104,7 @@ struct int force; /* Force loading outdated CRLs. */ + char *fake_crl; /* Name of a file with faked CRL entries. */ unsigned int connect_timeout; /* Timeout for connect. */ unsigned int connect_quick_timeout; /* Shorter timeout for connect. */ diff --git a/dirmngr/fakecrl.c b/dirmngr/fakecrl.c new file mode 100644 index 000000000..43b68a57a --- /dev/null +++ b/dirmngr/fakecrl.c @@ -0,0 +1,63 @@ +/* fakecrl.c - Debug code to test revocations. + * Copyright (C) 2023 g10 Code GmbH + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +/* + * For regression testing it is useful to have a way to claim that + * certain certificates are revoked. We achieve this with the + * --fake-crl option which takes a file name as argument. The format + * of the file is: empty lines and lines starting with a hash sign are + * ignored. A line with the issuer DN in brackets starts entries for + * this issuer. All following lines up to the next line with a + * bracket list revoked certificates. For each revoked certificate + * the hexadecimal encoded serial number is listed, followed by the + * revocation date in ISO 14 byte notation, optionally followed by a + * reason keyword. Example: + *--------------------- + * # Sample Fake CRL + * [CN=Bayern-Softtoken-Issuing-CA-2019,OU=IT-DLZ,O=Freistaat Bayern,C=DE] + * 7FD62B1A9EA5BBC84971183080717004 20221125T074346 + * 11223344556677 20230101T000000 key_compromise + * 0000000000000042 20221206T121200 certificate_hold + * + * [CN=CA IVBB Deutsche Telekom AG 18,OU=Bund,O=PKI-1-Verwaltung,C=DE] + * 735D1B97389F 20230210T083947 + *--------------------- + */ +#include + +#include +#include + +#include "dirmngr.h" +#include "crlcache.h" + + + +/* Returns 0 if the given certificate is not listed in the faked CRL + * or no fake CRL is configured. It is expected that the caller then + * consults the real CRL. */ +gpg_error_t +fakecrl_isvalid (ctrl_t ctrl, const char *issuer_hash, const char *cert_id) +{ + (void)ctrl; + (void)issuer_hash; + (void)cert_id; + return 0; +} diff --git a/dirmngr/server.c b/dirmngr/server.c index cd71592a4..cd0839aad 100644 --- a/dirmngr/server.c +++ b/dirmngr/server.c @@ -1339,6 +1339,10 @@ cmd_isvalid (assuan_context_t ctx, char *line) } else if (only_ocsp) err = gpg_error (GPG_ERR_NO_CRL_KNOWN); + else if (opt.fake_crl && (err = fakecrl_isvalid (ctrl, issuerhash, serialno))) + { + /* We already got the error code. */ + } else { switch (crl_cache_isvalid (ctrl, @@ -1377,7 +1381,7 @@ cmd_isvalid (assuan_context_t ctx, char *line) /* If the line contains a SHA-1 fingerprint as the first argument, - return the FPR vuffer on success. The function checks that the + return the FPR buffer on success. The function checks that the fingerprint consists of valid characters and prints and error message if it does not and returns NULL. Fingerprints are considered optional and thus no explicit error is returned. NULL is