]> arthur.barton.de Git - ngircd.git/blobdiff - src/ngircd/conn-ssl.c
S2S-TLS/GnuTLS: Streamline logging
[ngircd.git] / src / ngircd / conn-ssl.c
index ae864f50852c50db0b5ec1395a5e185060fca938..7fb81839faf62e3e73258c9b25da25b522e7d4e4 100644 (file)
@@ -45,6 +45,8 @@ extern struct SSLOptions Conf_SSLOptions;
 #include <openssl/dh.h>
 #include <openssl/x509v3.h>
 
+#define MAX_CERT_CHAIN_LENGTH  10      /* XXX: do not hardcode */
+
 static SSL_CTX * ssl_ctx;
 static DH *dh_params;
 
@@ -52,8 +54,6 @@ static bool ConnSSL_LoadServerKey_openssl PARAMS(( SSL_CTX *c ));
 static bool ConnSSL_SetVerifyProperties_openssl PARAMS((SSL_CTX * c));
 #endif
 
-#define MAX_CERT_CHAIN_LENGTH  10      /* XXX: do not hardcode */
-
 #ifdef HAVE_LIBGNUTLS
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -468,6 +468,9 @@ ConnSSL_SetVerifyProperties_gnutls(void)
        if (!Conf_SSLOptions.CAFile)
                return true;
 
+       x509_cred_slot *slot = array_get(&x509_creds, sizeof(x509_cred_slot), x509_cred_idx);
+       gnutls_certificate_credentials_t x509_cred = slot->x509_cred;
+
        err = gnutls_certificate_set_x509_trust_file(x509_cred,
                                                     Conf_SSLOptions.CAFile,
                                                     GNUTLS_X509_FMT_PEM);
@@ -744,6 +747,7 @@ ConnSSL_PrepareConnect(CONNECTION * c, CONF_SERVER * s)
 #ifdef HAVE_LIBGNUTLS
        int err;
 
+       (void)s;
        err = gnutls_init(&c->ssl_state.gnutls_session, GNUTLS_CLIENT);
        if (err) {
                Log(LOG_ERR, "Failed to initialize new SSL session: %s",
@@ -865,8 +869,10 @@ ConnSSL_HandleError(CONNECTION * c, const int code, const char *fname)
        default:
                assert(code < 0);
                if (gnutls_error_is_fatal(code)) {
-                       Log(LOG_ERR, "SSL error: %s [%s].",
-                           gnutls_strerror(code), fname);
+                       /* We don't need to log this here, the generic
+                        * connection layer will take care of it. */
+                       LogDebug("SSL error: %s [%s].",
+                                gnutls_strerror(code), fname);
                        ConnSSL_Free(c);
                        return -1;
                }
@@ -910,12 +916,12 @@ LogGnuTLS_CertInfo(int level, gnutls_x509_crt_t cert, const char *msg)
        assert(size);
        issuer_dn = LogMalloc(size);
        if (!issuer_dn) {
-               Log(level, "%s: Distinguished Name: %s", msg, dn);
+               Log(level, "%s: Distinguished Name \"%s\".", msg, dn);
                free(dn);
                return;
        }
        gnutls_x509_crt_get_issuer_dn(cert, issuer_dn, &size);
-       Log(level, "%s: Distinguished Name: \"%s\", Issuer \"%s\"", msg, dn,
+       Log(level, "%s: Distinguished Name \"%s\", Issuer \"%s\".", msg, dn,
            issuer_dn);
        free(dn);
        free(issuer_dn);
@@ -975,7 +981,7 @@ ConnSSL_LogCertInfo( CONNECTION * c, bool connect)
                         * hand we want client certificates, for example for
                         * "CertFP" authentication with services ... */
                        LogOpenSSL_CertInfo(LOG_INFO, peer_cert,
-                                           "Got unchecked client certificate");
+                                           "Got unchecked peer certificate");
                }
 
                X509_free(peer_cert);
@@ -993,29 +999,8 @@ ConnSSL_LogCertInfo( CONNECTION * c, bool connect)
            gnutls_cipher_get_name(cipher),
            gnutls_mac_get_name(gnutls_mac_get(sess)));
        cred = gnutls_auth_get_type(c->ssl_state.gnutls_session);
-       if (cred == GNUTLS_CRD_CERTIFICATE && connect) {
+       if (cred == GNUTLS_CRD_CERTIFICATE) {
                cert_seen = true;
-               int verify =
-                   gnutls_certificate_verify_peers2(c->
-                                                    ssl_state.gnutls_session,
-                                                    &status);
-               if (verify < 0) {
-                       Log(LOG_ERR,
-                           "gnutls_certificate_verify_peers2 failed: %s",
-                           gnutls_strerror(verify));
-                       goto done_cn_validation;
-               } else if (status) {
-                       gnutls_datum_t out;
-
-                       if (gnutls_certificate_verification_status_print
-                           (status, gnutls_certificate_type_get(sess), &out,
-                            0) == GNUTLS_E_SUCCESS) {
-                               Log(LOG_ERR,
-                                   "Certificate validation failed: %s",
-                                   out.data);
-                               gnutls_free(out.data);
-                       }
-               }
 
                gnutls_x509_crt_t cert;
                unsigned cert_list_size;
@@ -1039,17 +1024,46 @@ ConnSSL_LogCertInfo( CONNECTION * c, bool connect)
                            gnutls_strerror(err));
                        goto done_cn_validation;
                }
-               err = gnutls_x509_crt_check_hostname(cert, c->host);
-               if (err == 0)
-                       Log(LOG_ERR,
-                           "Failed to verify the hostname, expected \"%s\"",
-                           c->host);
-               else
-                       cert_ok = verify == 0 && status == 0;
-
-               snprintf(msg, sizeof(msg), "%svalid peer certificate",
-                       cert_ok ? "" : "in");
-               LogGnuTLS_CertInfo(cert_ok ? LOG_DEBUG : LOG_ERR, cert, msg);
+
+               if (connect) {
+                       int verify =
+                           gnutls_certificate_verify_peers2(c->
+                                                            ssl_state.gnutls_session,
+                                                            &status);
+                       if (verify < 0) {
+                               Log(LOG_ERR,
+                                   "gnutls_certificate_verify_peers2 failed: %s",
+                                   gnutls_strerror(verify));
+                               goto done_cn_validation;
+                       } else if (status) {
+                               gnutls_datum_t out;
+
+                               if (gnutls_certificate_verification_status_print
+                                   (status, gnutls_certificate_type_get(sess), &out,
+                                    0) == GNUTLS_E_SUCCESS) {
+                                       Log(LOG_ERR,
+                                           "Certificate validation failed: %s",
+                                           out.data);
+                                       gnutls_free(out.data);
+                               }
+                       }
+
+                       err = gnutls_x509_crt_check_hostname(cert, c->host);
+                       if (err == 0)
+                               Log(LOG_ERR,
+                                   "Failed to verify the hostname, expected \"%s\"",
+                                   c->host);
+                       else
+                               cert_ok = verify == 0 && status == 0;
+
+                       snprintf(msg, sizeof(msg), "Got %svalid server certificate",
+                               cert_ok ? "" : "in");
+                       LogGnuTLS_CertInfo(LOG_INFO, cert, msg);
+               } else {
+                       /* Incoming connection. Please see comments for OpenSSL! */
+                       LogGnuTLS_CertInfo(LOG_INFO, cert,
+                                           "Got unchecked peer certificate");
+               }
 
                gnutls_x509_crt_deinit(cert);
 done_cn_validation: