summaryrefslogtreecommitdiffstats
path: root/src/network/ssl
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/ssl')
-rw-r--r--src/network/ssl/qsslcipher.cpp20
-rw-r--r--src/network/ssl/qsslcipher.h1
-rw-r--r--src/network/ssl/qsslconfiguration.cpp108
-rw-r--r--src/network/ssl/qsslconfiguration.h16
-rw-r--r--src/network/ssl/qsslconfiguration_p.h8
-rw-r--r--src/network/ssl/qsslcontext.cpp60
-rw-r--r--src/network/ssl/qsslcontext_p.h20
-rw-r--r--src/network/ssl/qsslkey.cpp2
-rw-r--r--src/network/ssl/qsslsocket.cpp14
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp15
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp20
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h55
12 files changed, 307 insertions, 32 deletions
diff --git a/src/network/ssl/qsslcipher.cpp b/src/network/ssl/qsslcipher.cpp
index cdb0ed9063..bb5d93e528 100644
--- a/src/network/ssl/qsslcipher.cpp
+++ b/src/network/ssl/qsslcipher.cpp
@@ -79,6 +79,26 @@ QSslCipher::QSslCipher()
/*!
Constructs a QSslCipher object for the cipher determined by \a
+ name. The constructor accepts only supported ciphers (i.e., the
+ \a name must identify a cipher in the list of ciphers returned by
+ QSslSocket::supportedCiphers()).
+
+ You can call isNull() after construction to check if \a name
+ correctly identified a supported cipher.
+*/
+QSslCipher::QSslCipher(const QString &name)
+ : d(new QSslCipherPrivate)
+{
+ foreach (const QSslCipher &cipher, QSslSocket::supportedCiphers()) {
+ if (cipher.name() == name) {
+ *this = cipher;
+ return;
+ }
+ }
+}
+
+/*!
+ Constructs a QSslCipher object for the cipher determined by \a
name and \a protocol. The constructor accepts only supported
ciphers (i.e., the \a name and \a protocol must identify a cipher
in the list of ciphers returned by
diff --git a/src/network/ssl/qsslcipher.h b/src/network/ssl/qsslcipher.h
index e351d7949b..4cebffa7ae 100644
--- a/src/network/ssl/qsslcipher.h
+++ b/src/network/ssl/qsslcipher.h
@@ -57,6 +57,7 @@ class Q_NETWORK_EXPORT QSslCipher
{
public:
QSslCipher();
+ QSslCipher(const QString &name);
QSslCipher(const QString &name, QSsl::SslProtocol protocol);
QSslCipher(const QSslCipher &other);
~QSslCipher();
diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp
index 4aad7c04c5..1e859ae6e6 100644
--- a/src/network/ssl/qsslconfiguration.cpp
+++ b/src/network/ssl/qsslconfiguration.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -52,6 +53,9 @@ const QSsl::SslOptions QSslConfigurationPrivate::defaultSslOptions = QSsl::SslOp
|QSsl::SslOptionDisableCompression
|QSsl::SslOptionDisableSessionPersistence;
+const char QSslConfiguration::NextProtocolSpdy3_0[] = "spdy/3";
+const char QSslConfiguration::NextProtocolHttp1_1[] = "http/1.1";
+
/*!
\class QSslConfiguration
\brief The QSslConfiguration class holds the configuration and state of an SSL connection
@@ -113,6 +117,33 @@ const QSsl::SslOptions QSslConfigurationPrivate::defaultSslOptions = QSsl::SslOp
*/
/*!
+ \enum QSslConfiguration::NextProtocolNegotiationStatus
+
+ Describes the status of the Next Protocol Negotiation (NPN).
+
+ \value NextProtocolNegotiationNone No application protocol
+ has been negotiated (yet).
+
+ \value NextProtocolNegotiationNegotiated A next protocol
+ has been negotiated (see nextNegotiatedProtocol()).
+
+ \value NextProtocolNegotiationUnsupported The client and
+ server could not agree on a common next application protocol.
+*/
+
+/*!
+ \variable QSslConfiguration::NextProtocolSpdy3_0
+ \brief The value used for negotiating SPDY 3.0 during the Next
+ Protocol Negotiation.
+*/
+
+/*!
+ \variable QSslConfiguration::NextProtocolHttp1_1
+ \brief The value used for negotiating HTTP 1.1 during the Next
+ Protocol Negotiation.
+*/
+
+/*!
Constructs an empty SSL configuration. This configuration contains
no valid settings and the state will be empty. isNull() will
return true after this constructor is called.
@@ -185,7 +216,10 @@ bool QSslConfiguration::operator==(const QSslConfiguration &other) const
d->allowRootCertOnDemandLoading == other.d->allowRootCertOnDemandLoading &&
d->sslOptions == other.d->sslOptions &&
d->sslSession == other.d->sslSession &&
- d->sslSessionTicketLifeTimeHint == other.d->sslSessionTicketLifeTimeHint;
+ d->sslSessionTicketLifeTimeHint == other.d->sslSessionTicketLifeTimeHint &&
+ d->nextAllowedProtocols == other.d->nextAllowedProtocols &&
+ d->nextNegotiatedProtocol == other.d->nextNegotiatedProtocol &&
+ d->nextProtocolNegotiationStatus == other.d->nextProtocolNegotiationStatus;
}
/*!
@@ -221,7 +255,10 @@ bool QSslConfiguration::isNull() const
d->peerCertificateChain.count() == 0 &&
d->sslOptions == QSslConfigurationPrivate::defaultSslOptions &&
d->sslSession.isNull() &&
- d->sslSessionTicketLifeTimeHint == -1);
+ d->sslSessionTicketLifeTimeHint == -1 &&
+ d->nextAllowedProtocols.isEmpty() &&
+ d->nextNegotiatedProtocol.isNull() &&
+ d->nextProtocolNegotiationStatus == QSslConfiguration::NextProtocolNegotiationNone);
}
/*!
@@ -653,6 +690,71 @@ int QSslConfiguration::sessionTicketLifeTimeHint() const
}
/*!
+ \since 5.3
+
+ This function returns the protocol negotiated with the server
+ if the Next Protocol Negotiation (NPN) TLS extension was enabled.
+ In order for the NPN extension to be enabled, setAllowedNextProtocols()
+ needs to be called explicitly before connecting to the server.
+
+ If no protocol could be negotiated or the extension was not enabled,
+ this function returns a QByteArray which is null.
+
+ \sa setAllowedNextProtocols(), nextProtocolNegotiationStatus()
+ */
+QByteArray QSslConfiguration::nextNegotiatedProtocol() const
+{
+ return d->nextNegotiatedProtocol;
+}
+
+/*!
+ \since 5.3
+
+ This function sets the allowed \a protocols to be negotiated with the
+ server through the Next Protocol Negotiation (NPN) TLS extension; each
+ element in \a protocols must define one allowed protocol.
+ The function must be called explicitly before connecting to send the NPN
+ extension in the SSL handshake.
+ Whether or not the negotiation succeeded can be queried through
+ nextProtocolNegotiationStatus().
+
+ \sa nextNegotiatedProtocol(), nextProtocolNegotiationStatus(), allowedNextProtocols(), QSslConfiguration::NextProtocolSpdy3_0, QSslConfiguration::NextProtocolHttp1_1
+ */
+void QSslConfiguration::setAllowedNextProtocols(QList<QByteArray> protocols)
+{
+ d->nextAllowedProtocols = protocols;
+}
+
+/*!
+ \since 5.3
+
+ This function returns the allowed protocols to be negotiated with the
+ server through the Next Protocol Negotiation (NPN) TLS extension, as set
+ by setAllowedNextProtocols().
+
+ \sa nextNegotiatedProtocol(), nextProtocolNegotiationStatus(), setAllowedNextProtocols(), QSslConfiguration::NextProtocolSpdy3_0, QSslConfiguration::NextProtocolHttp1_1
+ */
+QList<QByteArray> QSslConfiguration::allowedNextProtocols() const
+{
+ return d->nextAllowedProtocols;
+}
+
+/*!
+ \since 5.3
+
+ This function returns the status of the Next Protocol Negotiation (NPN).
+ If the feature has not been enabled through setAllowedNextProtocols(),
+ this function returns NextProtocolNegotiationNone.
+ The status will be set before emitting the encrypted() signal.
+
+ \sa setAllowedNextProtocols(), allowedNextProtocols(), nextNegotiatedProtocol(), QSslConfiguration::NextProtocolNegotiationStatus
+ */
+QSslConfiguration::NextProtocolNegotiationStatus QSslConfiguration::nextProtocolNegotiationStatus() const
+{
+ return d->nextProtocolNegotiationStatus;
+}
+
+/*!
Returns the default SSL configuration to be used in new SSL
connections.
@@ -663,7 +765,7 @@ int QSslConfiguration::sessionTicketLifeTimeHint() const
\li protocol SecureProtocols (meaning either TLS 1.0 or SSL 3 will be used)
\li the system's default CA certificate list
\li the cipher list equal to the list of the SSL libraries'
- supported SSL ciphers
+ supported SSL ciphers that are 128 bits or more
\endlist
\sa QSslSocket::supportedCiphers(), setDefaultConfiguration()
diff --git a/src/network/ssl/qsslconfiguration.h b/src/network/ssl/qsslconfiguration.h
index a48eceb63e..587187ca06 100644
--- a/src/network/ssl/qsslconfiguration.h
+++ b/src/network/ssl/qsslconfiguration.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -131,6 +132,21 @@ public:
static QSslConfiguration defaultConfiguration();
static void setDefaultConfiguration(const QSslConfiguration &configuration);
+ enum NextProtocolNegotiationStatus {
+ NextProtocolNegotiationNone,
+ NextProtocolNegotiationNegotiated,
+ NextProtocolNegotiationUnsupported
+ };
+
+ void setAllowedNextProtocols(QList<QByteArray> protocols);
+ QList<QByteArray> allowedNextProtocols() const;
+
+ QByteArray nextNegotiatedProtocol() const;
+ NextProtocolNegotiationStatus nextProtocolNegotiationStatus() const;
+
+ static const char NextProtocolSpdy3_0[];
+ static const char NextProtocolHttp1_1[];
+
private:
friend class QSslSocket;
friend class QSslConfigurationPrivate;
diff --git a/src/network/ssl/qsslconfiguration_p.h b/src/network/ssl/qsslconfiguration_p.h
index 71ee8d2bfe..d183c3335c 100644
--- a/src/network/ssl/qsslconfiguration_p.h
+++ b/src/network/ssl/qsslconfiguration_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -86,7 +87,8 @@ public:
allowRootCertOnDemandLoading(true),
peerSessionShared(false),
sslOptions(QSslConfigurationPrivate::defaultSslOptions),
- sslSessionTicketLifeTimeHint(-1)
+ sslSessionTicketLifeTimeHint(-1),
+ nextProtocolNegotiationStatus(QSslConfiguration::NextProtocolNegotiationNone)
{ }
QSslCertificate peerCertificate;
@@ -114,6 +116,10 @@ public:
QByteArray sslSession;
int sslSessionTicketLifeTimeHint;
+ QList<QByteArray> nextAllowedProtocols;
+ QByteArray nextNegotiatedProtocol;
+ QSslConfiguration::NextProtocolNegotiationStatus nextProtocolNegotiationStatus;
+
// in qsslsocket.cpp:
static QSslConfiguration defaultConfiguration();
static void setDefaultConfiguration(const QSslConfiguration &configuration);
diff --git a/src/network/ssl/qsslcontext.cpp b/src/network/ssl/qsslcontext.cpp
index adf42fb79a..551804ec79 100644
--- a/src/network/ssl/qsslcontext.cpp
+++ b/src/network/ssl/qsslcontext.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -263,6 +264,45 @@ init_context:
return sslContext;
}
+#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+
+static int next_proto_cb(SSL *, unsigned char **out, unsigned char *outlen,
+ const unsigned char *in, unsigned int inlen, void *arg)
+{
+ QSslContext::NPNContext *ctx = reinterpret_cast<QSslContext::NPNContext *>(arg);
+
+ // comment out to debug:
+// QList<QByteArray> supportedVersions;
+// for (unsigned int i = 0; i < inlen; ) {
+// QByteArray version(reinterpret_cast<const char *>(&in[i+1]), in[i]);
+// supportedVersions << version;
+// i += in[i] + 1;
+// }
+
+ int proto = q_SSL_select_next_proto(out, outlen, in, inlen, ctx->data, ctx->len);
+ switch (proto) {
+ case OPENSSL_NPN_UNSUPPORTED:
+ ctx->status = QSslConfiguration::NextProtocolNegotiationNone;
+ break;
+ case OPENSSL_NPN_NEGOTIATED:
+ ctx->status = QSslConfiguration::NextProtocolNegotiationNegotiated;
+ break;
+ case OPENSSL_NPN_NO_OVERLAP:
+ ctx->status = QSslConfiguration::NextProtocolNegotiationUnsupported;
+ break;
+ default:
+ qWarning("OpenSSL sent unknown NPN status");
+ }
+
+ return SSL_TLSEXT_ERR_OK;
+}
+
+QSslContext::NPNContext QSslContext::npnContext() const
+{
+ return m_npnContext;
+}
+#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
+
// Needs to be deleted by caller
SSL* QSslContext::createSsl()
{
@@ -283,6 +323,26 @@ SSL* QSslContext::createSsl()
session = 0;
}
}
+
+#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+ QList<QByteArray> protocols = sslConfiguration.d->nextAllowedProtocols;
+ if (!protocols.isEmpty()) {
+ m_supportedNPNVersions.clear();
+ for (int a = 0; a < protocols.count(); ++a) {
+ if (protocols.at(a).size() > 255) {
+ qWarning() << "TLS NPN extension" << protocols.at(a)
+ << "is too long and will be truncated to 255 characters.";
+ protocols[a] = protocols.at(a).left(255);
+ }
+ m_supportedNPNVersions.append(protocols.at(a).size()).append(protocols.at(a));
+ }
+ m_npnContext.data = reinterpret_cast<unsigned char *>(m_supportedNPNVersions.data());
+ m_npnContext.len = m_supportedNPNVersions.count();
+ m_npnContext.status = QSslConfiguration::NextProtocolNegotiationNone;
+ q_SSL_CTX_set_next_proto_select_cb(ctx, next_proto_cb, &m_npnContext);
+ }
+#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
+
return ssl;
}
diff --git a/src/network/ssl/qsslcontext_p.h b/src/network/ssl/qsslcontext_p.h
index 2b596798a6..20b27c1ce7 100644
--- a/src/network/ssl/qsslcontext_p.h
+++ b/src/network/ssl/qsslcontext_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -72,6 +73,21 @@ public:
QByteArray sessionASN1() const;
void setSessionASN1(const QByteArray &sessionASN1);
int sessionTicketLifeTimeHint() const;
+
+#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+ // must be public because we want to use it from an OpenSSL callback
+ struct NPNContext {
+ NPNContext() : data(0),
+ len(0),
+ status(QSslConfiguration::NextProtocolNegotiationNone)
+ { }
+ unsigned char *data;
+ unsigned short len;
+ QSslConfiguration::NextProtocolNegotiationStatus status;
+ };
+ NPNContext npnContext() const;
+#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
+
protected:
QSslContext();
@@ -84,6 +100,10 @@ private:
QSslError::SslError errorCode;
QString errorStr;
QSslConfiguration sslConfiguration;
+#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+ QByteArray m_supportedNPNVersions;
+ NPNContext m_npnContext;
+#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
};
#endif // QT_NO_SSL
diff --git a/src/network/ssl/qsslkey.cpp b/src/network/ssl/qsslkey.cpp
index cf62f44855..95eed6e4b3 100644
--- a/src/network/ssl/qsslkey.cpp
+++ b/src/network/ssl/qsslkey.cpp
@@ -256,7 +256,7 @@ QSslKey::QSslKey(const QByteArray &encoded, QSsl::KeyAlgorithm algorithm,
a valid key.
*/
QSslKey::QSslKey(QIODevice *device, QSsl::KeyAlgorithm algorithm, QSsl::EncodingFormat encoding,
- QSsl::KeyType type, const QByteArray &passPhrase)
+ QSsl::KeyType type, const QByteArray &passPhrase)
: d(new QSslKeyPrivate)
{
QByteArray encoded;
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index 38b493a769..6edf4efae0 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -905,6 +906,9 @@ void QSslSocket::setSslConfiguration(const QSslConfiguration &configuration)
d->configuration.sslOptions = configuration.d->sslOptions;
d->configuration.sslSession = configuration.sessionTicket();
d->configuration.sslSessionTicketLifeTimeHint = configuration.sessionTicketLifeTimeHint();
+ d->configuration.nextAllowedProtocols = configuration.allowedNextProtocols();
+ d->configuration.nextNegotiatedProtocol = configuration.nextNegotiatedProtocol();
+ d->configuration.nextProtocolNegotiationStatus = configuration.nextProtocolNegotiationStatus();
// if the CA certificates were set explicitly (either via
// QSslConfiguration::setCaCertificates() or QSslSocket::setCaCertificates(),
@@ -1195,12 +1199,9 @@ void QSslSocket::setCiphers(const QString &ciphers)
Q_D(QSslSocket);
d->configuration.ciphers.clear();
foreach (const QString &cipherName, ciphers.split(QLatin1String(":"),QString::SkipEmptyParts)) {
- for (int i = 0; i < 3; ++i) {
- // ### Crude
- QSslCipher cipher(cipherName, QSsl::SslProtocol(i));
- if (!cipher.isNull())
- d->configuration.ciphers << cipher;
- }
+ QSslCipher cipher(cipherName);
+ if (!cipher.isNull())
+ d->configuration.ciphers << cipher;
}
}
@@ -1953,6 +1954,7 @@ void QSslSocketPrivate::init()
*/
QList<QSslCipher> QSslSocketPrivate::defaultCiphers()
{
+ QSslSocketPrivate::ensureInitialized();
QMutexLocker locker(&globalData()->mutex);
return globalData()->config->ciphers;
}
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 69b9e53884..3421154114 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -596,6 +596,7 @@ void QSslSocketPrivate::resetDefaultCiphers()
SSL *mySsl = q_SSL_new(myCtx);
QList<QSslCipher> ciphers;
+ QList<QSslCipher> defaultCiphers;
STACK_OF(SSL_CIPHER) *supportedCiphers = q_SSL_get_ciphers(mySsl);
for (int i = 0; i < q_sk_SSL_CIPHER_num(supportedCiphers); ++i) {
@@ -603,8 +604,11 @@ void QSslSocketPrivate::resetDefaultCiphers()
if (cipher->valid) {
QSslCipher ciph = QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(cipher);
if (!ciph.isNull()) {
+ // Unconditionally exclude ADH ciphers since they offer no MITM protection
if (!ciph.name().toLower().startsWith(QLatin1String("adh")))
ciphers << ciph;
+ if (ciph.usedBits() >= 128)
+ defaultCiphers << ciph;
}
}
}
@@ -614,7 +618,7 @@ void QSslSocketPrivate::resetDefaultCiphers()
q_SSL_free(mySsl);
setDefaultSupportedCiphers(ciphers);
- setDefaultCiphers(ciphers);
+ setDefaultCiphers(defaultCiphers);
}
QList<QSslCertificate> QSslSocketPrivate::systemCaCertificates()
@@ -1482,6 +1486,15 @@ void QSslSocketBackendPrivate::continueHandshake()
}
}
+#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+ const unsigned char *proto;
+ unsigned int proto_len;
+ q_SSL_get0_next_proto_negotiated(ssl, &proto, &proto_len);
+ QByteArray nextProtocol(reinterpret_cast<const char *>(proto), proto_len);
+ configuration.nextNegotiatedProtocol = nextProtocol;
+ configuration.nextProtocolNegotiationStatus = sslContextPointer->npnContext().status;
+#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
+
connectionEncrypted = true;
emit q->encrypted();
if (autoStartHandshake && pendingClose) {
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index ddf53f18f4..79bce22b0d 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -346,6 +347,20 @@ DEFINEFUNC(long, SSLeay, void, DUMMYARG, return 0, return)
DEFINEFUNC(const char *, SSLeay_version, int a, a, return 0, return)
DEFINEFUNC2(int, i2d_SSL_SESSION, SSL_SESSION *in, in, unsigned char **pp, pp, return 0, return)
DEFINEFUNC3(SSL_SESSION *, d2i_SSL_SESSION, SSL_SESSION **a, a, const unsigned char **pp, pp, long length, length, return 0, return)
+#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+DEFINEFUNC6(int, SSL_select_next_proto, unsigned char **out, out, unsigned char *outlen, outlen,
+ const unsigned char *in, in, unsigned int inlen, inlen,
+ const unsigned char *client, client, unsigned int client_len, client_len,
+ return -1, return)
+DEFINEFUNC3(void, SSL_CTX_set_next_proto_select_cb, SSL_CTX *s, s,
+ int (*cb) (SSL *ssl, unsigned char **out,
+ unsigned char *outlen,
+ const unsigned char *in,
+ unsigned int inlen, void *arg), cb,
+ void *arg, arg, return, DUMMYARG)
+DEFINEFUNC3(void, SSL_get0_next_proto_negotiated, const SSL *s, s,
+ const unsigned char **data, data, unsigned *len, len, return, DUMMYARG)
+#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
#define RESOLVEFUNC(func) \
if (!(_q_##func = _q_PTR_##func(libs.first->resolve(#func))) \
@@ -815,6 +830,11 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(SSLeay_version)
RESOLVEFUNC(i2d_SSL_SESSION)
RESOLVEFUNC(d2i_SSL_SESSION)
+#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+ RESOLVEFUNC(SSL_select_next_proto)
+ RESOLVEFUNC(SSL_CTX_set_next_proto_select_cb)
+ RESOLVEFUNC(SSL_get0_next_proto_negotiated)
+#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
symbolsResolved = true;
delete libs.first;
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index 7e1a1c983c..500fe9493b 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtNetwork module of the Qt Toolkit.
@@ -79,13 +80,13 @@ QT_BEGIN_NAMESPACE
// **************** Shared declarations ******************
// ret func(arg)
-# define DEFINEFUNC(ret, func, arg, a, err, funcret) \
- typedef ret (*_q_PTR_##func)(arg); \
- static _q_PTR_##func _q_##func = 0; \
- ret q_##func(arg) { \
+# define DEFINEFUNC(ret, func, arg, a, err, funcret) \
+ typedef ret (*_q_PTR_##func)(arg); \
+ static _q_PTR_##func _q_##func = 0; \
+ ret q_##func(arg) { \
if (Q_UNLIKELY(!_q_##func)) { \
qsslSocketUnresolvedSymbolWarning(#func); \
- err; \
+ err; \
} \
funcret _q_##func(a); \
}
@@ -180,8 +181,8 @@ QT_BEGIN_NAMESPACE
// **************** Static declarations ******************
// ret func(arg)
-# define DEFINEFUNC(ret, func, arg, a, err, funcret) \
- ret q_##func(arg) { funcret func(a); }
+# define DEFINEFUNC(ret, func, arg, a, err, funcret) \
+ ret q_##func(arg) { funcret func(a); }
// ret func(arg1, arg2)
# define DEFINEFUNC2(ret, func, arg1, a, arg2, b, err, funcret) \
@@ -384,7 +385,7 @@ int q_X509_cmp(X509 *a, X509 *b);
#ifdef SSLEAY_MACROS
void *q_ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, char *x);
#define q_X509_dup(x509) (X509 *)q_ASN1_dup((i2d_of_void *)q_i2d_X509, \
- (d2i_of_void *)q_d2i_X509,(char *)x509)
+ (d2i_of_void *)q_d2i_X509,(char *)x509)
#else
X509 *q_X509_dup(X509 *a);
#endif
@@ -429,22 +430,22 @@ STACK_OF(X509) *q_X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx);
#define q_BIO_get_mem_data(b, pp) (int)q_BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp)
#define q_BIO_pending(b) (int)q_BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL)
#ifdef SSLEAY_MACROS
-int q_i2d_DSAPrivateKey(const DSA *a, unsigned char **pp);
-int q_i2d_RSAPrivateKey(const RSA *a, unsigned char **pp);
+int q_i2d_DSAPrivateKey(const DSA *a, unsigned char **pp);
+int q_i2d_RSAPrivateKey(const RSA *a, unsigned char **pp);
RSA *q_d2i_RSAPrivateKey(RSA **a, unsigned char **pp, long length);
DSA *q_d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length);
-#define q_PEM_read_bio_RSAPrivateKey(bp, x, cb, u) \
+#define q_PEM_read_bio_RSAPrivateKey(bp, x, cb, u) \
(RSA *)q_PEM_ASN1_read_bio( \
(void *(*)(void**, const unsigned char**, long int))q_d2i_RSAPrivateKey, PEM_STRING_RSA, bp, (void **)x, cb, u)
-#define q_PEM_read_bio_DSAPrivateKey(bp, x, cb, u) \
+#define q_PEM_read_bio_DSAPrivateKey(bp, x, cb, u) \
(DSA *)q_PEM_ASN1_read_bio( \
(void *(*)(void**, const unsigned char**, long int))q_d2i_DSAPrivateKey, PEM_STRING_DSA, bp, (void **)x, cb, u)
-#define q_PEM_write_bio_RSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
- PEM_ASN1_write_bio((int (*)(void*, unsigned char**))q_i2d_RSAPrivateKey,PEM_STRING_RSA,\
- bp,(char *)x,enc,kstr,klen,cb,u)
-#define q_PEM_write_bio_DSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
- PEM_ASN1_write_bio((int (*)(void*, unsigned char**))q_i2d_DSAPrivateKey,PEM_STRING_DSA,\
- bp,(char *)x,enc,kstr,klen,cb,u)
+#define q_PEM_write_bio_RSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
+ PEM_ASN1_write_bio((int (*)(void*, unsigned char**))q_i2d_RSAPrivateKey,PEM_STRING_RSA,\
+ bp,(char *)x,enc,kstr,klen,cb,u)
+#define q_PEM_write_bio_DSAPrivateKey(bp,x,enc,kstr,klen,cb,u) \
+ PEM_ASN1_write_bio((int (*)(void*, unsigned char**))q_i2d_DSAPrivateKey,PEM_STRING_DSA,\
+ bp,(char *)x,enc,kstr,klen,cb,u)
#endif
#define q_SSL_CTX_set_options(ctx,op) q_SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL)
#define q_SSL_CTX_set_mode(ctx,op) q_SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL)
@@ -461,9 +462,9 @@ DSA *q_d2i_DSAPrivateKey(DSA **a, unsigned char **pp, long length);
#define q_X509_get_notAfter(x) X509_get_notAfter(x)
#define q_X509_get_notBefore(x) X509_get_notBefore(x)
#define q_EVP_PKEY_assign_RSA(pkey,rsa) q_EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\
- (char *)(rsa))
+ (char *)(rsa))
#define q_EVP_PKEY_assign_DSA(pkey,dsa) q_EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\
- (char *)(dsa))
+ (char *)(dsa))
#define q_OpenSSL_add_all_algorithms() q_OPENSSL_add_all_algorithms_conf()
void q_OPENSSL_add_all_algorithms_noconf();
void q_OPENSSL_add_all_algorithms_conf();
@@ -473,6 +474,20 @@ const char *q_SSLeay_version(int type);
int q_i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp);
SSL_SESSION *q_d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, long length);
+#if OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG)
+int q_SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
+ const unsigned char *in, unsigned int inlen,
+ const unsigned char *client, unsigned int client_len);
+void q_SSL_CTX_set_next_proto_select_cb(SSL_CTX *s,
+ int (*cb) (SSL *ssl, unsigned char **out,
+ unsigned char *outlen,
+ const unsigned char *in,
+ unsigned int inlen, void *arg),
+ void *arg);
+void q_SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data,
+ unsigned *len);
+#endif // OPENSSL_VERSION_NUMBER >= 0x1000100fL ...
+
// Helper function
class QDateTime;
QDateTime q_getTimeFromASN1(const ASN1_TIME *aTime);