Store the local certificate in a QList.

Instead of storing a single QSslCertificate for a the local cert, store
a list of them. This will allow us to handle server sockets that use a
certificate that is not issued directly from the CA root in future.

Change-Id: I9a36b9a99daa9c0bdd17f61b4ce1a7da746f2e96
Reviewed-by: Peter Hartmann <phartmann@rim.com>
This commit is contained in:
Richard Moore 2013-02-11 17:14:25 +00:00 committed by The Qt Project
parent 5dbd42a62e
commit 4a07519877
5 changed files with 47 additions and 11 deletions

View File

@ -173,7 +173,7 @@ bool QSslConfiguration::operator==(const QSslConfiguration &other) const
return true;
return d->peerCertificate == other.d->peerCertificate &&
d->peerCertificateChain == other.d->peerCertificateChain &&
d->localCertificate == other.d->localCertificate &&
d->localCertificateChain == other.d->localCertificateChain &&
d->privateKey == other.d->privateKey &&
d->sessionCipher == other.d->sessionCipher &&
d->ciphers == other.d->ciphers &&
@ -212,7 +212,7 @@ bool QSslConfiguration::isNull() const
d->allowRootCertOnDemandLoading == true &&
d->caCertificates.count() == 0 &&
d->ciphers.count() == 0 &&
d->localCertificate.isNull() &&
d->localCertificateChain.isEmpty() &&
d->privateKey.isNull() &&
d->peerCertificate.isNull() &&
d->peerCertificateChain.count() == 0 &&
@ -312,6 +312,18 @@ void QSslConfiguration::setPeerVerifyDepth(int depth)
d->peerVerifyDepth = depth;
}
/*!
Returns the certificate chain to be presented to the peer during
the SSL handshake process.
\sa localCertificate()
\since 5.1
*/
QList<QSslCertificate> QSslConfiguration::localCertificateChain() const
{
return d->localCertificateChain;
}
/*!
Returns the certificate to be presented to the peer during the SSL
handshake process.
@ -320,7 +332,9 @@ void QSslConfiguration::setPeerVerifyDepth(int depth)
*/
QSslCertificate QSslConfiguration::localCertificate() const
{
return d->localCertificate;
if (d->localCertificateChain.isEmpty())
return QSslCertificate();
return d->localCertificateChain[0];
}
/*!
@ -341,7 +355,8 @@ QSslCertificate QSslConfiguration::localCertificate() const
*/
void QSslConfiguration::setLocalCertificate(const QSslCertificate &certificate)
{
d->localCertificate = certificate;
d->localCertificateChain = QList<QSslCertificate>();
d->localCertificateChain += certificate;
}
/*!

View File

@ -99,6 +99,8 @@ public:
void setPeerVerifyDepth(int depth);
// Certificate & cipher configuration
QList<QSslCertificate> localCertificateChain() const;
QSslCertificate localCertificate() const;
void setLocalCertificate(const QSslCertificate &certificate);

View File

@ -91,7 +91,7 @@ public:
QSslCertificate peerCertificate;
QList<QSslCertificate> peerCertificateChain;
QSslCertificate localCertificate;
QList<QSslCertificate> localCertificateChain;
QSslKey privateKey;
QSslCipher sessionCipher;

View File

@ -895,7 +895,7 @@ QSslConfiguration QSslSocket::sslConfiguration() const
void QSslSocket::setSslConfiguration(const QSslConfiguration &configuration)
{
Q_D(QSslSocket);
d->configuration.localCertificate = configuration.localCertificate();
d->configuration.localCertificateChain = configuration.localCertificateChain();
d->configuration.privateKey = configuration.privateKey();
d->configuration.ciphers = configuration.ciphers();
d->configuration.caCertificates = configuration.caCertificates();
@ -926,7 +926,8 @@ void QSslSocket::setSslConfiguration(const QSslConfiguration &configuration)
void QSslSocket::setLocalCertificate(const QSslCertificate &certificate)
{
Q_D(QSslSocket);
d->configuration.localCertificate = certificate;
d->configuration.localCertificateChain = QList<QSslCertificate>();
d->configuration.localCertificateChain += certificate;
}
/*!
@ -939,10 +940,10 @@ void QSslSocket::setLocalCertificate(const QSslCertificate &certificate)
void QSslSocket::setLocalCertificate(const QString &path,
QSsl::EncodingFormat format)
{
Q_D(QSslSocket);
QFile file(path);
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
d->configuration.localCertificate = QSslCertificate(file.readAll(), format);
setLocalCertificate(QSslCertificate(file.readAll(), format));
}
/*!
@ -954,7 +955,9 @@ void QSslSocket::setLocalCertificate(const QString &path,
QSslCertificate QSslSocket::localCertificate() const
{
Q_D(const QSslSocket);
return d->configuration.localCertificate;
if (d->configuration.localCertificateChain.isEmpty())
return QSslCertificate();
return d->configuration.localCertificateChain[0];
}
/*!
@ -2057,7 +2060,7 @@ void QSslConfigurationPrivate::deepCopyDefaultConfiguration(QSslConfigurationPri
ptr->ref.store(1);
ptr->peerCertificate = global->peerCertificate;
ptr->peerCertificateChain = global->peerCertificateChain;
ptr->localCertificate = global->localCertificate;
ptr->localCertificateChain = global->localCertificateChain;
ptr->privateKey = global->privateKey;
ptr->sessionCipher = global->sessionCipher;
ptr->ciphers = global->ciphers;

View File

@ -142,6 +142,7 @@ private slots:
void protocolServerSide();
void setCaCertificates();
void setLocalCertificate();
void localCertificateChain();
void setPrivateKey();
void setSocketDescriptor();
void setSslConfiguration_data();
@ -1100,6 +1101,21 @@ void tst_QSslSocket::setLocalCertificate()
{
}
void tst_QSslSocket::localCertificateChain()
{
if (!QSslSocket::supportsSsl())
return;
QSslSocket socket;
socket.setLocalCertificate(QLatin1String(SRCDIR "certs/fluke.cert"));
QSslConfiguration conf = socket.sslConfiguration();
QList<QSslCertificate> chain = conf.localCertificateChain();
QCOMPARE(chain.size(), 1);
QCOMPARE(chain[0], conf.localCertificate());
QCOMPARE(chain[0], socket.localCertificate());
}
void tst_QSslSocket::setPrivateKey()
{
}