summaryrefslogtreecommitdiffstats
path: root/dirmngr/certcache.c
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2017-02-17 16:39:48 +0100
committerWerner Koch <wk@gnupg.org>2017-02-17 16:41:02 +0100
commit070211eb990f5ea41271eba432b6a6b485cef7c7 (patch)
treedf547fb8197e445666906f4a0ee5f37fda512e9d /dirmngr/certcache.c
parentdirmngr: Remove use of hardcoded numbers in validate. (diff)
downloadgnupg2-070211eb990f5ea41271eba432b6a6b485cef7c7.tar.xz
gnupg2-070211eb990f5ea41271eba432b6a6b485cef7c7.zip
dirmngr: Add options --tls and --systrust to the VALIDATE cmd.
* dirmngr/certcache.h (certlist_s, certlist_t): New. * dirmngr/certcache.c (read_certlist_from_stream): New. (release_certlist): New. * dirmngr/server.c (MAX_CERTLIST_LENGTH): New. (cmd_validate): Add options --tls and --systrust. Implement them using a kludge for now. * dirmngr/validate.c (validate_cert_chain): Support systrust checking. Add kludge to disable the CRL checking for tls mode. -- This can now be used to test a list of certificates as returned by TLS. Put the certs PEM encoded into a a file certlist.pem with the target certificate being the first. Then run gpg-connect-agent --dirmngr \ '/definqfile CERTLIST wiki-gnupg-chain.pem' \ 'validate --systrust --tls' /bye CRLS check has been disabled becuase we can't yet pass the systrust flag to the CRL checking code. Signed-off-by: Werner Koch <wk@gnupg.org>
Diffstat (limited to 'dirmngr/certcache.c')
-rw-r--r--dirmngr/certcache.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/dirmngr/certcache.c b/dirmngr/certcache.c
index cd026c2d5..ff86f61b7 100644
--- a/dirmngr/certcache.c
+++ b/dirmngr/certcache.c
@@ -225,6 +225,7 @@ cert_compute_fpr (ksba_cert_t cert, unsigned char *digest)
}
+
/* Cleanup one slot. This releases all resourses but keeps the actual
slot in the cache marked for reuse. */
static void
@@ -1669,3 +1670,92 @@ find_issuing_cert (ctrl_t ctrl, ksba_cert_t cert, ksba_cert_t *r_cert)
return err;
}
+
+
+
+/* Read a list of certificates in PEM format from stream FP and store
+ * them on success at R_CERTLIST. On error NULL is stored at R_CERT
+ * list and an error code returned. Note that even on success an
+ * empty list of certificates can be returned (i.e. NULL stored at
+ * R_CERTLIST) iff the input stream has no certificates. */
+gpg_error_t
+read_certlist_from_stream (certlist_t *r_certlist, estream_t fp)
+{
+ gpg_error_t err;
+ gnupg_ksba_io_t ioctx = NULL;
+ ksba_reader_t reader;
+ ksba_cert_t cert = NULL;
+ certlist_t certlist = NULL;
+ certlist_t cl, *cltail;
+
+ *r_certlist = NULL;
+
+ err = gnupg_ksba_create_reader (&ioctx,
+ (GNUPG_KSBA_IO_PEM | GNUPG_KSBA_IO_MULTIPEM),
+ fp, &reader);
+ if (err)
+ goto leave;
+
+ /* Loop to read all certificates from the stream. */
+ cltail = &certlist;
+ do
+ {
+ ksba_cert_release (cert);
+ cert = NULL;
+ err = ksba_cert_new (&cert);
+ if (!err)
+ err = ksba_cert_read_der (cert, reader);
+ if (err)
+ {
+ if (gpg_err_code (err) == GPG_ERR_EOF)
+ err = 0;
+ goto leave;
+ }
+
+ /* Append the certificate to the list. We also store the
+ * fingerprint and check whether we have a cached certificate;
+ * in that case the cached certificate is put into the list to
+ * take advantage of a validation result which might be stored
+ * in the cached certificate. */
+ cl = xtrycalloc (1, sizeof *cl);
+ if (!cl)
+ {
+ err = gpg_error_from_syserror ();
+ goto leave;
+ }
+ cert_compute_fpr (cert, cl->fpr);
+ cl->cert = get_cert_byfpr (cl->fpr);
+ if (!cl->cert)
+ {
+ cl->cert = cert;
+ cert = NULL;
+ }
+ *cltail = cl;
+ cltail = &cl->next;
+ ksba_reader_clear (reader, NULL, NULL);
+ }
+ while (!gnupg_ksba_reader_eof_seen (ioctx));
+
+ leave:
+ ksba_cert_release (cert);
+ gnupg_ksba_destroy_reader (ioctx);
+ if (err)
+ release_certlist (certlist);
+ else
+ *r_certlist = certlist;
+
+ return err;
+}
+
+
+/* Release the certificate list CL. */
+void
+release_certlist (certlist_t cl)
+{
+ while (cl)
+ {
+ certlist_t next = cl->next;
+ ksba_cert_release (cl->cert);
+ cl = next;
+ }
+}