+#ifdef HAVE_LIBGNUTLS
+static bool check_verification(unsigned output)
+{
+ char errmsg[256] = "";
+
+ if (output & GNUTLS_CERT_SIGNER_NOT_FOUND)
+ strlcpy(errmsg, "No Issuer found", sizeof errmsg);
+ if (output & GNUTLS_CERT_SIGNER_NOT_CA) {
+ if (errmsg[0])
+ strlcat(errmsg, " ,", sizeof errmsg);
+ strlcat(errmsg, "Issuer is not a CA", sizeof errmsg);
+ }
+ if (output & GNUTLS_CERT_INSECURE_ALGORITHM) {
+ if (errmsg[0])
+ strlcat(errmsg, " ,", sizeof errmsg);
+ strlcat(errmsg, "Insecure Algorithm", sizeof errmsg);
+ }
+ if (output & GNUTLS_CERT_REVOKED) {
+ if (errmsg[0])
+ strlcat(errmsg, " ,", sizeof errmsg);
+ strlcat(errmsg, "Certificate Revoked", sizeof errmsg);
+ }
+#ifdef DEBUG
+ if (output & GNUTLS_CERT_INVALID)
+ assert(errmsg[0]); /* check for unhandled error */
+#endif
+ if (!(output & GNUTLS_CERT_INVALID) && !errmsg[0]) {
+ LogDebug("Certificate verified.");
+ return true;
+ }
+ Log(LOG_ERR, "Certificate Validation failed: %s", errmsg);
+ return false;
+}
+
+static void *LogMalloc(size_t s)
+{
+ void *mem = malloc(s);
+ if (!mem)
+ Log(LOG_ERR, "Out of memory: Could not allocate %lu byte", (unsigned long) s);
+ return mem;
+}
+
+static void
+LogGnuTLS_CertInfo(gnutls_x509_crt_t cert, const char *msg)
+{
+ char *dn, *issuer_dn;
+ size_t size = 0;
+ int err = gnutls_x509_crt_get_dn(cert, NULL, &size);
+ if (size == 0 || (err && err != GNUTLS_E_SHORT_MEMORY_BUFFER))
+ goto err_crt_get;
+ dn = LogMalloc(size);
+ if (!dn)
+ return;
+ err = gnutls_x509_crt_get_dn(cert, dn, &size);
+ if (err) {
+ err_crt_get:
+ Log(LOG_ERR, "gnutls_x509_crt_get_dn: %s", err ? gnutls_strerror(err) : "size == 0");
+ return;
+ }
+ gnutls_x509_crt_get_issuer_dn(cert, NULL, &size);
+ assert(size);
+ issuer_dn = LogMalloc(size);
+ if (!issuer_dn) {
+ Log(LOG_INFO, "%s: Distinguished Name: %s", msg, dn);
+ free(dn);
+ return;
+ }
+ gnutls_x509_crt_get_issuer_dn(cert, issuer_dn, &size);
+ Log(LOG_INFO, "%s: Distinguished Name: \"%s\", Issuer \"%s\"", msg, dn, issuer_dn);
+ free(dn);
+ free(issuer_dn);
+}
+#endif
+