summaryrefslogtreecommitdiffstats
path: root/src/network
diff options
context:
space:
mode:
authorRichard Moore <rich@kde.org>2013-02-11 22:31:00 +0000
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-02-19 21:37:24 +0100
commit7898080ca78ceec15163976390979631fcbd178d (patch)
tree7cfc458b51addf0a6ddd585700335030e9d2c56e /src/network
parent4a07519877b4b3aad45d1a727487d9e87630973b (diff)
Add support for intermediate certificates to server sockets.
Add intermediate certificates to our server sockets, and to our client certs. Change-Id: Ib5aa575473f9e84f337bebe35099506dd7d7e2ba Task-Number: QTBUG-19825 Task-Number: QTBUG-13281 Reviewed-by: Peter Hartmann <phartmann@rim.com>
Diffstat (limited to 'src/network')
-rw-r--r--src/network/ssl/qsslconfiguration.cpp27
-rw-r--r--src/network/ssl/qsslconfiguration.h1
-rw-r--r--src/network/ssl/qsslcontext.cpp11
-rw-r--r--src/network/ssl/qsslsocket.cpp26
-rw-r--r--src/network/ssl/qsslsocket.h3
5 files changed, 68 insertions, 0 deletions
diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp
index 3d466b85ca..afbd4fac77 100644
--- a/src/network/ssl/qsslconfiguration.cpp
+++ b/src/network/ssl/qsslconfiguration.cpp
@@ -325,6 +325,33 @@ QList<QSslCertificate> QSslConfiguration::localCertificateChain() const
}
/*!
+ Sets the certificate chain to be presented to the peer during the
+ SSL handshake to be \a localChain.
+
+ Setting the certificate chain once the connection has been
+ established has no effect.
+
+ A certificate is the means of identification used in the SSL
+ process. The local certificate is used by the remote end to verify
+ the local user's identity against its list of Certification
+ Authorities. In most cases, such as in HTTP web browsing, only
+ servers identify to the clients, so the client does not send a
+ certificate.
+
+ Unlike QSslConfiguration::setLocalCertificate() this method allows
+ you to specify any intermediate certificates required in order to
+ validate your certificate. The first item in the list must be the
+ leaf certificate.
+
+ \sa localCertificateChain()
+ \since 5.1
+ */
+void QSslConfiguration::setLocalCertificateChain(const QList<QSslCertificate> &localChain)
+{
+ d->localCertificateChain = localChain;
+}
+
+/*!
Returns the certificate to be presented to the peer during the SSL
handshake process.
diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h
index 291f6ead9d..0000382ed5 100644
--- a/src/network/ssl/qsslconfiguration.h
+++ b/src/network/ssl/qsslconfiguration.h
@@ -100,6 +100,7 @@ public:
// Certificate & cipher configuration
QList<QSslCertificate> localCertificateChain() const;
+ void setLocalCertificateChain(const QList<QSslCertificate> &localChain);
QSslCertificate localCertificate() const;
void setLocalCertificate(const QSslCertificate &certificate);
diff --git a/src/network/ssl/qsslcontext.cpp b/src/network/ssl/qsslcontext.cpp
index f75ff3796d..22ad42116b 100644
--- a/src/network/ssl/qsslcontext.cpp
+++ b/src/network/ssl/qsslcontext.cpp
@@ -234,6 +234,17 @@ init_context:
sslContext->errorCode = QSslError::UnspecifiedError;
return sslContext;
}
+
+ // If we have any intermediate certificates then we need to add them to our chain
+ bool first = true;
+ foreach (const QSslCertificate &cert, configuration.d->localCertificateChain) {
+ if (first) {
+ first = false;
+ continue;
+ }
+ q_SSL_CTX_ctrl(sslContext->ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0,
+ q_X509_dup(reinterpret_cast<X509 *>(cert.handle())));
+ }
}
// Initialize peer verification.
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index 421731a174..b1cdef7f29 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -912,6 +912,32 @@ void QSslSocket::setSslConfiguration(const QSslConfiguration &configuration)
}
/*!
+ Sets the certificate chain to be presented to the peer during the
+ SSL handshake to be \a localChain.
+
+ \sa QSslConfiguration::setLocalCertificateChain()
+ \since 5.1
+ */
+void QSslSocket::setLocalCertificateChain(const QList<QSslCertificate> &localChain)
+{
+ Q_D(QSslSocket);
+ d->configuration.localCertificateChain = localChain;
+}
+
+/*!
+ Returns the socket's local \l {QSslCertificate} {certificate} chain,
+ or an empty list if no local certificates have been assigned.
+
+ \sa setLocalCertificateChain()
+ \since 5.1
+*/
+QList<QSslCertificate> QSslSocket::localCertificateChain() const
+{
+ Q_D(const QSslSocket);
+ return d->configuration.localCertificateChain;
+}
+
+/*!
Sets the socket's local certificate to \a certificate. The local
certificate is necessary if you need to confirm your identity to the
peer. It is used together with the private key; if you set the local
diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h
index 55141243ff..d89933efda 100644
--- a/src/network/ssl/qsslsocket.h
+++ b/src/network/ssl/qsslsocket.h
@@ -131,6 +131,9 @@ public:
void setSslConfiguration(const QSslConfiguration &config);
// Certificate & cipher accessors.
+ void setLocalCertificateChain(const QList<QSslCertificate> &localChain);
+ QList<QSslCertificate> localCertificateChain() const;
+
void setLocalCertificate(const QSslCertificate &certificate);
void setLocalCertificate(const QString &fileName, QSsl::EncodingFormat format = QSsl::Pem);
QSslCertificate localCertificate() const;