示例#1
0
QSsl::KeyType QSslKeyProto::type() const
{
  QSslKey *item = qscriptvalue_cast<QSslKey*>(thisObject());
  if (item)
    return item->type();
  return QSsl::KeyType();
}
示例#2
0
bool Server::isKeyForCert(const QSslKey &key, const QSslCertificate &cert) {
	if (key.isNull() || cert.isNull() || (key.type() != QSsl::PrivateKey))
		return false;

	QByteArray qbaKey = key.toDer();
	QByteArray qbaCert = cert.toDer();

	X509 *x509 = NULL;
	EVP_PKEY *pkey = NULL;
	BIO *mem = NULL;

	mem = BIO_new_mem_buf(qbaKey.data(), qbaKey.size());
	Q_UNUSED(BIO_set_close(mem, BIO_NOCLOSE));
	pkey = d2i_PrivateKey_bio(mem, NULL);
	BIO_free(mem);

	mem = BIO_new_mem_buf(qbaCert.data(), qbaCert.size());
	Q_UNUSED(BIO_set_close(mem, BIO_NOCLOSE));
	x509 = d2i_X509_bio(mem, NULL);
	BIO_free(mem);
	mem = NULL;

	if (x509 && pkey && X509_check_private_key(x509, pkey)) {
		EVP_PKEY_free(pkey);
		X509_free(x509);
		return true;
	}

	if (pkey)
		EVP_PKEY_free(pkey);
	if (x509)
		X509_free(x509);
	return false;
}
示例#3
0
int QSslKeyProto::length() const
{
  QSslKey *item = qscriptvalue_cast<QSslKey*>(thisObject());
  if (item)
    return item->length();
  return 0;
}
示例#4
0
QByteArray QSslKeyProto::toPem(const QByteArray & passPhrase) const
{
  QSslKey *item = qscriptvalue_cast<QSslKey*>(thisObject());
  if (item)
    return item->toPem(passPhrase);
  return QByteArray();
}
示例#5
0
bool QSslKeyProto::isNull() const
{
  QSslKey *item = qscriptvalue_cast<QSslKey*>(thisObject());
  if (item)
    return item->isNull();
  return false;
}
示例#6
0
QSsl::KeyAlgorithm QSslKeyProto::algorithm() const
{
  QSslKey *item = qscriptvalue_cast<QSslKey*>(thisObject());
  if (item)
    return item->algorithm();
  return QSsl::KeyAlgorithm();
}
示例#7
0
文件: Cert.cpp 项目: CarlsonER/mumble
Settings::KeyPair CertWizard::importCert(QByteArray data, const QString &pw) {
	X509 *x509 = NULL;
	EVP_PKEY *pkey = NULL;
	PKCS12 *pkcs = NULL;
	BIO *mem = NULL;
	STACK_OF(X509) *certs = NULL;
	Settings::KeyPair kp;
	int ret = 0;

	mem = BIO_new_mem_buf(data.data(), data.size());
	Q_UNUSED(BIO_set_close(mem, BIO_NOCLOSE));
	pkcs = d2i_PKCS12_bio(mem, NULL);
	if (pkcs) {
		ret = PKCS12_parse(pkcs, NULL, &pkey, &x509, &certs);
		if (pkcs && !pkey && !x509 && ! pw.isEmpty()) {
			if (certs) {
				if (ret)
					sk_X509_free(certs);
				certs = NULL;
			}
			ret = PKCS12_parse(pkcs, pw.toUtf8().constData(), &pkey, &x509, &certs);
		}
		if (pkey && x509 && X509_check_private_key(x509, pkey)) {
			unsigned char *dptr;
			QByteArray key, crt;

			key.resize(i2d_PrivateKey(pkey, NULL));
			dptr=reinterpret_cast<unsigned char *>(key.data());
			i2d_PrivateKey(pkey, &dptr);

			crt.resize(i2d_X509(x509, NULL));
			dptr=reinterpret_cast<unsigned char *>(crt.data());
			i2d_X509(x509, &dptr);

			QSslCertificate qscCert = QSslCertificate(crt, QSsl::Der);
			QSslKey qskKey = QSslKey(key, QSsl::Rsa, QSsl::Der);

			QList<QSslCertificate> qlCerts;
			qlCerts << qscCert;

			if (certs) {
				for (int i=0;i<sk_X509_num(certs);++i) {
					X509 *c = sk_X509_value(certs, i);

					crt.resize(i2d_X509(c, NULL));
					dptr=reinterpret_cast<unsigned char *>(crt.data());
					i2d_X509(c, &dptr);

					QSslCertificate cert = QSslCertificate(crt, QSsl::Der);
					qlCerts << cert;
				}
			}
			bool valid = ! qskKey.isNull();
			foreach(const QSslCertificate &cert, qlCerts)
				valid = valid && ! cert.isNull();
			if (valid)
				kp = Settings::KeyPair(qlCerts, qskKey);
		}
	}
示例#8
0
void QgsPkiBundle::setClientKey( const QSslKey &certkey )
{
  mCertKey.clear();
  if ( !certkey.isNull() && certkey.type() == QSsl::PrivateKey )
  {
    mCertKey = certkey;
  }
}
示例#9
0
QDebug operator<<(QDebug debug, const QSslKey &key)
{
    debug << "QSslKey("
          << (key.type() == QSsl::PublicKey ? "PublicKey" : "PrivateKey")
          << ", " << (key.algorithm() == QSsl::Rsa ? "RSA" : "DSA")
          << ", " << key.length()
          << ")";
    return debug;
}
示例#10
0
int CertificateDialogPrivate::keyLenght( const QSslKey &key ) const
{
	switch( key.algorithm() )
	{
	case QSsl::Dsa: return DSA_size( (DSA*)key.handle() ) * 8;
	case QSsl::Rsa: return RSA_size( (RSA*)key.handle() ) * 8;
	}
	return key.length();
}
示例#11
0
QSslKey Server::privateKeyFromPEM(const QByteArray &buf, const QByteArray &pass) {
	QSslKey key;
	key = QSslKey(buf, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, pass);
	if (key.isNull())
		key = QSslKey(buf, QSsl::Dsa, QSsl::Pem, QSsl::PrivateKey, pass);
#if QT_VERSION >= 0x050500
	if (key.isNull())
		key = QSslKey(buf, QSsl::Ec, QSsl::Pem, QSsl::PrivateKey, pass);
#endif
	return key;
}
示例#12
0
QDebug operator<<(QDebug debug, const QSslKey &key)
{
    QDebugStateSaver saver(debug);
    debug.resetFormat().nospace();
    debug << "QSslKey("
          << (key.type() == QSsl::PublicKey ? "PublicKey" : "PrivateKey")
          << ", " << (key.algorithm() == QSsl::Opaque ? "OPAQUE" :
                      (key.algorithm() == QSsl::Rsa ? "RSA" : ((key.algorithm() == QSsl::Dsa) ? "DSA" : "EC")))
          << ", " << key.length()
          << ')';
    return debug;
}
void CertIdentity::setSslKey(const QSslKey &key)
{
    if (key.toPem() == _sslKey.toPem())
        return;
    _sslKey = key;
    _isDirty = true;
}
示例#14
0
const QgsPkiBundle QgsPkiBundle::fromPemPaths( const QString &certPath,
    const QString &keyPath,
    const QString &keyPass,
    const QList<QSslCertificate> &caChain )
{
  QgsPkiBundle pkibundle;
  if ( !certPath.isEmpty() && !keyPath.isEmpty()
       && ( certPath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive )
            || certPath.endsWith( QLatin1String( ".der" ), Qt::CaseInsensitive ) )
       && ( keyPath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive )
            || keyPath.endsWith( QLatin1String( ".der" ), Qt::CaseInsensitive ) )
       && QFile::exists( certPath ) && QFile::exists( keyPath )
     )
  {
    // client cert
    bool pem = certPath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive );
    QSslCertificate clientcert( fileData_( certPath, pem ), pem ? QSsl::Pem : QSsl::Der );
    pkibundle.setClientCert( clientcert );

    // client key
    bool pem_key = keyPath.endsWith( QLatin1String( ".pem" ), Qt::CaseInsensitive );
    QByteArray keydata( fileData_( keyPath, pem_key ) );

    QSslKey clientkey;
    clientkey = QSslKey( keydata,
                         QSsl::Rsa,
                         pem_key ? QSsl::Pem : QSsl::Der,
                         QSsl::PrivateKey,
                         !keyPass.isNull() ? keyPass.toUtf8() : QByteArray() );
    if ( clientkey.isNull() )
    {
      // try DSA algorithm, since Qt can't seem to determine it otherwise
      clientkey = QSslKey( keydata,
                           QSsl::Dsa,
                           pem_key ? QSsl::Pem : QSsl::Der,
                           QSsl::PrivateKey,
                           !keyPass.isNull() ? keyPass.toUtf8() : QByteArray() );
    }
    pkibundle.setClientKey( clientkey );
    if ( !caChain.isEmpty() )
    {
      pkibundle.setCaChain( caChain );
    }
  }
  return pkibundle;
}
示例#15
0
  void KeyShare::CheckPath()
  {
    QDir key_path(_path, "*.pub");
    foreach(const QString &key_name, key_path.entryList()) {
      QString path = _path + "/" + key_name;
      QFile key_file(path);
      key_file.open(QIODevice::ReadOnly);
      QSharedPointer<QSslCertificate> cert(new QSslCertificate(&key_file, QSsl::Der));
      QSslKey pubkey = cert->publicKey();
      QSharedPointer<AsymmetricKey> key(new DsaPublicKey(pubkey.toDer()));
      if(!key->IsValid()) {
        qDebug() << "Invalid key:" << path;
        continue;
      }

      QString name = key_name.left(key_name.length() - 4);
      AddCertificate(name, cert);
    }
  }
QSslKey IdentityEditWidget::keyByFilename(const QString &filename)
{
    QSslKey key;

    QFile keyFile(filename);
    keyFile.open(QIODevice::ReadOnly);
    QByteArray keyRaw = keyFile.read(2 << 20);
    keyFile.close();

    for (int i = 0; i < 2; i++) {
        for (int j = 0; j < 2; j++) {
            key = QSslKey(keyRaw, (QSsl::KeyAlgorithm)j, (QSsl::EncodingFormat)i);
            if (!key.isNull())
                goto returnKey;
        }
    }
    QMessageBox::information(this, tr("Failed to read key"), tr("Failed to read the key file. It is either incompatible or invalid. Note that the key file must not have a passphrase."));
returnKey:
    return key;
}
void IdentityEditWidget::showKeyState(const QSslKey &key)
{
    if (key.isNull()) {
        ui.keyTypeLabel->setText(tr("No Key loaded"));
        ui.clearOrLoadKeyButton->setText(tr("Load"));
    }
    else {
        switch (key.algorithm()) {
        case QSsl::Rsa:
            ui.keyTypeLabel->setText(tr("RSA"));
            break;
        case QSsl::Dsa:
            ui.keyTypeLabel->setText(tr("DSA"));
            break;
        default:
            ui.keyTypeLabel->setText(tr("No Key loaded"));
        }
        ui.clearOrLoadKeyButton->setText(tr("Clear"));
    }
    ui.keyTypeLabel->setProperty("sslKey", key.toPem());
    ui.keyTypeLabel->setProperty("sslKeyType", (int)key.algorithm());
}
// static
const QByteArray QgsAuthProviderPkiPaths::keyAsPem( const QString &keypath,
    const QString &keypass,
    QString *algtype,
    bool reencrypt )
{
  bool pem = keypath.endsWith( ".pem", Qt::CaseInsensitive );
  QByteArray keydata( fileData_( keypath, pem ) );

  QSslKey clientkey;
  clientkey = QSslKey( keydata,
                       QSsl::Rsa,
                       pem ? QSsl::Pem : QSsl::Der,
                       QSsl::PrivateKey,
                       !keypass.isEmpty() ? keypass.toUtf8() : QByteArray() );
  if ( clientkey.isNull() )
  {
    // try DSA algorithm, since Qt can't seem to determine it otherwise
    clientkey = QSslKey( keydata,
                         QSsl::Dsa,
                         pem ? QSsl::Pem : QSsl::Der,
                         QSsl::PrivateKey,
                         !keypass.isEmpty() ? keypass.toUtf8() : QByteArray() );
    if ( clientkey.isNull() )
    {
      return QByteArray();
    }
    if ( algtype )
      *algtype = "dsa";
  }
  else
  {
    if ( algtype )
      *algtype = "rsa";
  }

  // reapply passphrase if protection is requested and passphrase exists
  return ( clientkey.toPem( reencrypt && !keypass.isEmpty() ? keypass.toUtf8() : QByteArray() ) );
}
void IdentityEditWidget::sslDropEvent(QDropEvent *event, bool isCert)
{
    QByteArray rawUris;
    if (event->mimeData()->hasFormat("text/uri-list"))
        rawUris = event->mimeData()->data("text/uri-list");
    else
        rawUris = event->mimeData()->data("text/uri");

    QTextStream uriStream(rawUris);
    QString filename = QUrl(uriStream.readLine()).toLocalFile();

    if (isCert) {
        QSslCertificate cert = certByFilename(filename);
        if (!cert.isNull())
            showCertState(cert);
    }
    else {
        QSslKey key = keyByFilename(filename);
        if (!key.isNull())
            showKeyState(key);
    }
    event->accept();
    emit widgetHasChanged();
}
示例#20
0
/*!
    Returns \c true if this key is equal to \a other; otherwise returns \c false.
*/
bool QSslKey::operator==(const QSslKey &other) const
{
    if (isNull())
        return other.isNull();
    if (other.isNull())
        return isNull();
    if (algorithm() != other.algorithm())
        return false;
    if (type() != other.type())
        return false;
    if (length() != other.length())
        return false;
    if (algorithm() == QSsl::Opaque)
        return handle() == other.handle();
    return toDer() == other.toDer();
}
示例#21
0
void
PlaydarApi::start()
{
    Q_D( PlaydarApi );
    if ( !d->session.isNull() )
    {
        tLog() << "HTTPd session already exists, returning";
        return;
    }

    d->session.reset( new QxtHttpSessionManager() );
    d->connector.reset( new QxtHttpServerConnector() );
    d->tlsSession.reset( new QxtHttpSessionManager() );
    d->tlsConnector.reset( new QxtHttpsServerConnector() );
    if ( d->session.isNull() || d->connector.isNull()
         || d->tlsSession.isNull() || d->tlsConnector.isNull() )
    {
        if ( !d->session.isNull() )
            d->session.reset();
        if ( !d->connector.isNull() )
            d->connector.reset();
        if ( !d->tlsSession.isNull() )
            d->tlsSession.reset();
        if ( !d->tlsConnector.isNull() )
            d->tlsConnector.reset();
        tLog() << "Failed to start HTTPd, could not create object";
        return;
    }

    d->session->setListenInterface( d->ha );
    d->session->setPort( d->port );
    d->session->setConnector( d->connector.data() );

    d->instance.reset( new Api_v1( d->session.data() ) );
    d->session->setStaticContentService( d->instance.data() );

    tLog() << "Starting HTTPd on" << d->session->listenInterface().toString() << d->session->port();
    d->session->start();

    d->tlsSession->setListenInterface( d->ha );
    d->tlsSession->setPort( d->sport );
    d->tlsSession->setConnector( d->tlsConnector.data() );

    d->tlsInstance.reset( new Api_v1( d->tlsSession.data() ) );
    d->tlsSession->setStaticContentService( d->tlsInstance.data() );

    QByteArray settingsKey = TomahawkSettings::instance()->playdarKey();
    QSslKey key;
    if ( settingsKey.isNull() || settingsKey.isEmpty() )
    {
        // Generate a SSL key
        key = KeyBuilder::generate( QSsl::Rsa, KeyBuilder::StrengthNormal );
        TomahawkSettings::instance()->setPlaydarKey( key.toPem() );
    }
    else
    {
        // Restore key
        key = QSslKey( settingsKey, QSsl::Rsa );
    }

    QByteArray settingsCert = TomahawkSettings::instance()->playdarCertificate();
    QSslCertificate cert;
    if ( settingsCert.isNull() || settingsCert.isEmpty() )
    {
        // Generate a SSL certificate
        CertificateRequestBuilder reqbuilder;
        reqbuilder.setVersion( 1 );
        reqbuilder.setKey( key );
        reqbuilder.addNameEntry( Certificate::EntryCountryName, "GB" );
        reqbuilder.addNameEntry( Certificate::EntryOrganizationName, "Tomahawk Player (Desktop)" );
        reqbuilder.addNameEntry( Certificate::EntryCommonName, "localhost" );

        // Sign the request
        CertificateRequest req = reqbuilder.signedRequest(key);

        // Now make a certificate
        CertificateBuilder builder;
        builder.setRequest( req );

        builder.setVersion( 3 );
        builder.setSerial( uuid().toLatin1() );
        builder.setActivationTime( QDateTime::currentDateTimeUtc());
        builder.setExpirationTime( QDateTime::currentDateTimeUtc().addYears( 10 ) );
        builder.setBasicConstraints( false );
        builder.addKeyPurpose( CertificateBuilder::PurposeWebServer );
        builder.setKeyUsage( CertificateBuilder::UsageKeyAgreement|CertificateBuilder::UsageKeyEncipherment );
        builder.addSubjectKeyIdentifier();

        cert = builder.signedCertificate( key );
        TomahawkSettings::instance()->setPlaydarCertificate( cert.toPem() );
    }
    else
    {
        cert = QSslCertificate( settingsCert );
    }

    QxtSslServer* sslServer = d->tlsConnector->tcpServer();
    sslServer->setPrivateKey( key );
    sslServer->setLocalCertificate( cert );

    tLog() << "Starting HTTPSd on" << d->tlsSession->listenInterface().toString() << d->tlsSession->port();
    tLog() << Q_FUNC_INFO << d->tlsSession->start();
}
示例#22
0
void QSslKeyProto::clear()
{
  QSslKey *item = qscriptvalue_cast<QSslKey*>(thisObject());
  if (item)
    item->clear();
}
示例#23
0
void QSslKeyProto::swap(QSslKey & other)
{
  QSslKey *item = qscriptvalue_cast<QSslKey*>(thisObject());
  if (item)
    item->swap(other);
}
示例#24
0
文件: webui.cpp 项目: 0ly/qBittorrent
void WebUI::init()
{
    Preferences* const pref = Preferences::instance();
    Logger* const logger = Logger::instance();

    if (pref->isWebUiEnabled()) {
        const quint16 port = pref->getWebUiPort();
        if (m_port != port) {
            Net::PortForwarder::instance()->deletePort(port);
            m_port = port;
        }

        if (httpServer_) {
            if (httpServer_->serverPort() != m_port)
                httpServer_->close();
        }
        else {
            webapp_ = new WebApplication(this);
            httpServer_ = new Http::Server(webapp_, this);
        }

#ifndef QT_NO_OPENSSL
        if (pref->isWebUiHttpsEnabled()) {
            QList<QSslCertificate> certs = QSslCertificate::fromData(pref->getWebUiHttpsCertificate());
            QSslKey key;
            key = QSslKey(pref->getWebUiHttpsKey(), QSsl::Rsa);
            bool certsIsNull = std::any_of(certs.begin(), certs.end(), [](QSslCertificate c) { return c.isNull(); });
            if (!certsIsNull && !certs.empty() && !key.isNull())
                httpServer_->enableHttps(certs, key);
            else
                httpServer_->disableHttps();
        }
        else {
            httpServer_->disableHttps();
        }
#endif

        if (!httpServer_->isListening()) {
            bool success = httpServer_->listen(QHostAddress::Any, m_port);
            if (success)
                logger->addMessage(tr("The Web UI is listening on port %1").arg(m_port));
            else
                logger->addMessage(tr("Web UI Error - Unable to bind Web UI to port %1").arg(m_port), Log::CRITICAL);
        }

        // DynDNS
        if (pref->isDynDNSEnabled()) {
            if (!dynDNSUpdater_)
                dynDNSUpdater_ = new Net::DNSUpdater(this);
            else
                dynDNSUpdater_->updateCredentials();
        }
        else {
            if (dynDNSUpdater_)
                delete dynDNSUpdater_;
        }

        // Use UPnP/NAT-PMP for Web UI
        if (pref->useUPnPForWebUIPort())
            Net::PortForwarder::instance()->addPort(m_port);
        else
            Net::PortForwarder::instance()->deletePort(m_port);
    }
    else {
        if (httpServer_)
            delete httpServer_;
        if (webapp_)
            delete webapp_;
        if (dynDNSUpdater_)
            delete dynDNSUpdater_;
        Net::PortForwarder::instance()->deletePort(m_port);
    }
}
示例#25
0
void DataPlaneServer::start() {
    server_addr.s6.sin6_family = AF_INET6;
    // we listen on public IP, which is the one stored in the DB.
    struct in6_addr servIp;
    inet_pton(AF_INET6, qSql->getLocalIP().toUtf8().data(), &servIp);
    server_addr.s6.sin6_addr = servIp; //in6addr_any;
    server_addr.s6.sin6_port = htons(DATAPLANEPORT);

    const int on = 1, off = 0;

    OpenSSL_add_ssl_algorithms();

    SSL_load_error_strings();
    ctx = SSL_CTX_new(DTLSv1_server_method());

    SSL_CTX_set_cipher_list(ctx, DTLS_ENCRYPT);
    SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);

    // get certificate and key from SQL & use them
    ConnectionInitiator* i = ConnectionInitiator::getInstance();
    QSslCertificate cert = i->getLocalCertificate();
    QByteArray certBytesPEM = cert.toPem();
    char* x509buffer = certBytesPEM.data();

    BIO *bi;
    bi = BIO_new_mem_buf(x509buffer, certBytesPEM.length());
    X509 *x;
    x = PEM_read_bio_X509(bi, NULL, NULL, NULL);

    if (!SSL_CTX_use_certificate(ctx,x)) {
        qWarning() << "ERROR: no certificate found!";
        UnixSignalHandler::termSignalHandler(0);
    }

    if (x != NULL) X509_free(x);
    if (bi != NULL) BIO_free(bi);

    QSslKey key = i->getPrivateKey();
    QByteArray keyBytesPEM = key.toPem();
    char* keyBuffer = keyBytesPEM.data();

    bi = BIO_new_mem_buf(keyBuffer, keyBytesPEM.length());
    EVP_PKEY *pkey;
    pkey = PEM_read_bio_PrivateKey(bi, NULL, NULL, NULL);

    if (!SSL_CTX_use_PrivateKey(ctx, pkey)) {
        qWarning() << "ERROR: no private key found!";
        UnixSignalHandler::termSignalHandler(0);
    }

    if (pkey != NULL) EVP_PKEY_free(pkey);
    if (bi != NULL) BIO_free(bi);

    if (!SSL_CTX_check_private_key (ctx)) {
        qWarning() << "ERROR: invalid private key!";
        UnixSignalHandler::termSignalHandler(0);
    }
    /* Client has to authenticate */
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, dtls_verify_callback);

    SSL_CTX_set_read_ahead(ctx, 1);
    SSL_CTX_set_cookie_generate_cb(ctx, generate_cookie);
    SSL_CTX_set_cookie_verify_cb(ctx, verify_cookie);

    fd = socket(server_addr.ss.ss_family, SOCK_DGRAM, 0);
    if (fd < 0) {
        qWarning() << "Could not open SOCK_DGRAM";
        UnixSignalHandler::termSignalHandler(0);
    }

#ifdef WIN32
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char*) &on, (socklen_t) sizeof(on));
#else
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void*) &on, (socklen_t) sizeof(on));
#ifdef SO_REUSEPORT
    setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, (const void*) &on, (socklen_t) sizeof(on));
#endif
#endif

    setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&off, sizeof(off));
    bind(fd, (const struct sockaddr *) &server_addr, sizeof(struct sockaddr_in6));

    notif = new QSocketNotifier(fd, QSocketNotifier::Read);
    connect(notif, SIGNAL(activated(int)), this, SLOT(readyRead(int)));
}
示例#26
0
bool SslServer::setCertificate(const QString &path, const QString &keyPath)
{
    // Don't reset _isCertValid here, in case an older but valid certificate is still loaded.
    // Use temporary variables in order to avoid overwriting the existing certificates until
    // everything is confirmed good.
    QSslCertificate untestedCert;
    QList<QSslCertificate> untestedCA;
    QSslKey untestedKey;

    if (path.isEmpty())
        return false;

    QFile certFile(path);
    if (!certFile.exists()) {
        quWarning() << "SslServer: Certificate file" << qPrintable(path) << "does not exist";
        return false;
    }

    if (!certFile.open(QIODevice::ReadOnly)) {
        quWarning()
        << "SslServer: Failed to open certificate file" << qPrintable(path)
        << "error:" << certFile.error();
        return false;
    }

    QList<QSslCertificate> certList = QSslCertificate::fromDevice(&certFile);

    if (certList.isEmpty()) {
        quWarning() << "SslServer: Certificate file doesn't contain a certificate";
        return false;
    }

    untestedCert = certList[0];
    certList.removeFirst(); // remove server cert

    // store CA and intermediates certs
    untestedCA = certList;

    if (!certFile.reset()) {
        quWarning() << "SslServer: IO error reading certificate file";
        return false;
    }

    // load key from keyPath if it differs from path, otherwise load key from path
    if(path != keyPath) {
        QFile keyFile(keyPath);
        if(!keyFile.exists()) {
            quWarning() << "SslServer: Key file" << qPrintable(keyPath) << "does not exist";
            return false;
        }

        if (!keyFile.open(QIODevice::ReadOnly)) {
            quWarning()
            << "SslServer: Failed to open key file" << qPrintable(keyPath)
            << "error:" << keyFile.error();
            return false;
        }

        untestedKey = QSslKey(&keyFile, QSsl::Rsa);
        keyFile.close();
    } else {
        untestedKey = QSslKey(&certFile, QSsl::Rsa);
    }

    certFile.close();

    if (untestedCert.isNull()) {
        quWarning() << "SslServer:" << qPrintable(path) << "contains no certificate data";
        return false;
    }

    // We allow the core to offer SSL anyway, so no "return false" here. Client will warn about the cert being invalid.
    const QDateTime now = QDateTime::currentDateTime();
    if (now < untestedCert.effectiveDate())
        quWarning() << "SslServer: Certificate won't be valid before" << untestedCert.effectiveDate().toString();

    else if (now > untestedCert.expiryDate())
        quWarning() << "SslServer: Certificate expired on" << untestedCert.expiryDate().toString();

    else { // Qt4's isValid() checks for time range and blacklist; avoid a double warning, hence the else block
#if QT_VERSION < 0x050000
        if (!untestedCert.isValid())
#else
        if (untestedCert.isBlacklisted())
#endif
            quWarning() << "SslServer: Certificate blacklisted";
    }
    if (untestedKey.isNull()) {
        quWarning() << "SslServer:" << qPrintable(keyPath) << "contains no key data";
        return false;
    }

    _isCertValid = true;

    // All keys are valid, update the externally visible copy used for new connections.
    _cert = untestedCert;
    _ca = untestedCA;
    _key = untestedKey;

    return _isCertValid;
}