]> arthur.barton.de Git - ngircd.git/blobdiff - src/ngircd/conn-ssl.c
S2S-TLS/GnuTLS: Update SSL code for GnuTLS certificate reloading
[ngircd.git] / src / ngircd / conn-ssl.c
index d89c11fe1baa1d2252c856f9e9308e0b756b61d6..cef580f8699dc9c3a0ce82cafdb96f2a48352142 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>
@@ -155,13 +155,13 @@ LogOpenSSL_CertInfo(int level, X509 * cert, const char *msg)
        mem = BIO_new(BIO_s_mem());
        if (!mem)
                return;
-       X509_NAME_print_ex(mem, X509_get_subject_name(cert), 4,
+       X509_NAME_print_ex(mem, X509_get_subject_name(cert), 0,
                           XN_FLAG_ONELINE);
-       X509_NAME_print_ex(mem, X509_get_issuer_name(cert), 4, XN_FLAG_ONELINE);
+       X509_NAME_print_ex(mem, X509_get_issuer_name(cert), 2, XN_FLAG_ONELINE);
        if (BIO_write(mem, "", 1) == 1) {
                len = BIO_get_mem_data(mem, &memptr);
                if (memptr && len > 0)
-                       Log(level, "%s: \"%s\"", msg, memptr);
+                       Log(level, "%s: \"%s\".", msg, memptr);
        }
        (void)BIO_set_close(mem, BIO_CLOSE);
        BIO_free(mem);
@@ -211,14 +211,23 @@ pem_passwd_cb(char *buf, int size, int rwflag, void *password)
 static int
 Verify_openssl(int preverify_ok, X509_STORE_CTX * ctx)
 {
-       int err;
-
+#ifdef DEBUG
        if (!preverify_ok) {
-               err = X509_STORE_CTX_get_error(ctx);
-               Log(LOG_ERR, "Certificate validation failed: %s",
-                   X509_verify_cert_error_string(err));
+               int err = X509_STORE_CTX_get_error(ctx);
+               LogDebug("Certificate validation failed: %s",
+                        X509_verify_cert_error_string(err));
        }
-       return preverify_ok;
+#else
+       (void)preverify_ok;
+       (void)ctx;
+#endif
+
+       /* Always(!) return success as we have to deal with invalid
+        * (self-signed, expired, ...) client certificates and with invalid
+        * server certificates when "SSLVerify" is disabled, which we don't
+        * know at this stage. Therefore we postpone this check, it will be
+        * (and has to be!) handled in cb_connserver_login_ssl(). */
+       return 1;
 }
 #endif
 
@@ -459,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);
@@ -823,9 +835,12 @@ ConnSSL_HandleError(CONNECTION * c, const int code, const char *fname)
                                    "SSL error, client disconnected [in %s()]!",
                                    fname);
                                break;
-                       case -1:        /* low level socket I/O error, check errno */
-                               Log(LOG_ERR, "SSL error: %s [in %s()]!",
-                                   strerror(real_errno), fname);
+                       case -1:
+                               /* Low level socket I/O error, check errno. But
+                                * we don't need to log this here, the generic
+                                * connection layer will take care of it. */
+                               LogDebug("SSL error: %s [in %s()]!",
+                                        strerror(real_errno), fname);
                        }
                }
                break;