+ ServerInstance->Logs->Log("m_ssl_gnutls", LOG_DEBUG, "m_ssl_gnutls.so: Failed to set X.509 CRL file '%s': %s", crlfile.c_str(), gnutls_strerror(ret));
+
+ FileReader reader;
+
+ reader.LoadFile(certfile);
+ std::string cert_string = reader.Contents();
+ gnutls_datum_t cert_datum = { (unsigned char*)cert_string.data(), static_cast<unsigned int>(cert_string.length()) };
+
+ reader.LoadFile(keyfile);
+ std::string key_string = reader.Contents();
+ gnutls_datum_t key_datum = { (unsigned char*)key_string.data(), static_cast<unsigned int>(key_string.length()) };
+
+ // If this fails, no SSL port will work. At all. So, do the smart thing - throw a ModuleException
+ unsigned int certcount = 3;
+ x509_certs.resize(certcount);
+ ret = gnutls_x509_crt_list_import(&x509_certs[0], &certcount, &cert_datum, GNUTLS_X509_FMT_PEM, GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
+ if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER)
+ {
+ // the buffer wasn't big enough to hold all certs but gnutls updated certcount to the number of available certs, try again with a bigger buffer
+ x509_certs.resize(certcount);
+ ret = gnutls_x509_crt_list_import(&x509_certs[0], &certcount, &cert_datum, GNUTLS_X509_FMT_PEM, GNUTLS_X509_CRT_LIST_IMPORT_FAIL_IF_EXCEED);
+ }
+
+ if (ret <= 0)
+ {
+ // clear the vector so we won't call gnutls_x509_crt_deinit() on the (uninited) certs later
+ x509_certs.clear();
+ throw ModuleException("Unable to load GnuTLS server certificate (" + certfile + "): " + ((ret < 0) ? (std::string(gnutls_strerror(ret))) : "No certs could be read"));
+ }
+ x509_certs.resize(ret);
+
+ if((ret = gnutls_x509_privkey_import(x509_key, &key_datum, GNUTLS_X509_FMT_PEM)) < 0)
+ throw ModuleException("Unable to load GnuTLS server private key (" + keyfile + "): " + std::string(gnutls_strerror(ret)));
+
+ if((ret = gnutls_certificate_set_x509_key(x509_cred, &x509_certs[0], certcount, x509_key)) < 0)
+ throw ModuleException("Unable to set GnuTLS cert/key pair: " + std::string(gnutls_strerror(ret)));
+
+ #ifdef GNUTLS_NEW_PRIO_API
+ // It's safe to call this every time as we cannot have this uninitialized, see constructor and below.
+ gnutls_priority_deinit(priority);
+
+ // Try to set the priorities for ciphers, kex methods etc. to the user supplied string
+ // If the user did not supply anything then the string is already set to "NORMAL"
+ const char* priocstr = priorities.c_str();
+ const char* prioerror;