diff options
author | Thorvald Natvig <slicer@users.sourceforge.net> | 2009-05-22 17:47:20 +0400 |
---|---|---|
committer | Thorvald Natvig <slicer@users.sourceforge.net> | 2009-05-22 17:47:43 +0400 |
commit | 39e2f5a375cdb80cb53d2dbd660ac6fe4eb0699e (patch) | |
tree | 913b094a56f4f0919736529336b7611c1756792a /src/murmur/Cert.cpp | |
parent | e5cdd853d449e8a0b1aea156194ab2c607bf0537 (diff) |
Allow adding CA chain to cert files
Diffstat (limited to 'src/murmur/Cert.cpp')
-rw-r--r-- | src/murmur/Cert.cpp | 107 |
1 files changed, 61 insertions, 46 deletions
diff --git a/src/murmur/Cert.cpp b/src/murmur/Cert.cpp index b16e1677c..618298aec 100644 --- a/src/murmur/Cert.cpp +++ b/src/murmur/Cert.cpp @@ -47,51 +47,76 @@ static int add_ext(X509 * crt, int nid, char *value) { return 1; } +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()); + BIO_set_close(mem, BIO_NOCLOSE); + pkey = d2i_PrivateKey_bio(mem, NULL); + BIO_free(mem); + + mem = BIO_new_mem_buf(qbaCert.data(), qbaCert.size()); + 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; +} + void Server::initializeCert() { QByteArray crt, key, pass; - if (! QSslSocket::supportsSsl()) { - qFatal("Qt without SSL Support"); - } - crt = getConf("certificate", QString()).toByteArray(); key = getConf("key", QString()).toByteArray(); pass = getConf("passphrase", QByteArray()).toByteArray(); - - if (! crt.isEmpty()) { - qscCert = QSslCertificate(crt); - if (qscCert.isNull()) { - log("Failed to parse certificate."); - } else if (qscCert.issuerInfo(QSslCertificate::CommonName) == QLatin1String("Murmur Autogenerated Certificate")) { - log("Old autogenerated certificate is unusable for registration, invalidating it"); - qscCert = QSslCertificate(); - } + + QList<QSslCertificate> ql; + + if (! key.isEmpty()) { + qskKey = QSslKey(key, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, pass); + if (qskKey.isNull()) + qskKey = QSslKey(key, QSsl::Dsa, QSsl::Pem, QSsl::PrivateKey, pass); } - - if (! key.isEmpty() && qscCert.isNull()) { - qscCert = QSslCertificate(key); - if (! qscCert.isNull()) { - log("Using certificate from key."); - } + if (qskKey.isNull() && ! crt.isEmpty()) { + qskKey = QSslKey(crt, QSsl::Rsa, QSsl::Pem, QSsl::PrivateKey, pass); + if (qskKey.isNull()) + qskKey = QSslKey(crt, QSsl::Dsa, QSsl::Pem, QSsl::PrivateKey, pass); } - - if (! qscCert.isNull()) { - QSsl::KeyAlgorithm alg = qscCert.publicKey().algorithm(); - - if (! key.isEmpty()) { - qskKey = QSslKey(key, alg, QSsl::Pem, QSsl::PrivateKey, pass); - if (qskKey.isNull()) { - log("Failed to parse key."); - } - } - - if (! crt.isEmpty() && qskKey.isNull()) { - qskKey = QSslKey(crt, alg, QSsl::Pem, QSsl::PrivateKey, pass); - if (! qskKey.isNull()) { - log("Using key from certificate."); + if (! qskKey.isNull()) { + ql << QSslCertificate::fromData(crt); + ql << QSslCertificate::fromData(key); + for(int i=0;i<ql.size();++i) { + const QSslCertificate &c = ql.at(i); + if (isKeyForCert(qskKey, c)) { + qscCert = c; + ql.removeAt(i); } } + qlCA = ql; + } + if (qscCert.issuerInfo(QSslCertificate::CommonName) == QLatin1String("Murmur Autogenerated Certificate")) { + log("Old autogenerated certificate is unusable for registration, invalidating it"); + qscCert = QSslCertificate(); } if (qscCert.isNull() || qskKey.isNull()) { @@ -107,7 +132,7 @@ void Server::initializeCert() { X509 *x509 = X509_new(); EVP_PKEY *pkey = EVP_PKEY_new(); - RSA *rsa = RSA_generate_key(1024,RSA_F4,NULL,NULL); + RSA *rsa = RSA_generate_key(2048,RSA_F4,NULL,NULL); EVP_PKEY_assign_RSA(pkey, rsa); X509_set_version(x509, 2); @@ -142,21 +167,11 @@ void Server::initializeCert() { qskKey = QSslKey(key, QSsl::Rsa, QSsl::Der); if (qskKey.isNull()) log("Key generation failed"); - + setConf("certificate", qscCert.toPem()); setConf("key", qskKey.toPem()); } } - - QList<QSslCipher> pref; - foreach(QSslCipher c, QSslSocket::defaultCiphers()) { - if (c.usedBits() < 128) - continue; - pref << c; - } - if (pref.isEmpty()) - qFatal("No ciphers of at least 128 bit found"); - QSslSocket::setDefaultCiphers(pref); } const QString Server::getDigest() const { |