summaryrefslogtreecommitdiffstats
path: root/src/network/ssl
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/ssl')
-rw-r--r--src/network/ssl/qsslcertificate.cpp101
-rw-r--r--src/network/ssl/qsslcertificate.h6
-rw-r--r--src/network/ssl/qsslcertificate_p.h5
-rw-r--r--src/network/ssl/qsslsocket.cpp21
-rw-r--r--src/network/ssl/qsslsocket.h3
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp17
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp8
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h3
-rw-r--r--src/network/ssl/qsslsocket_p.h2
9 files changed, 138 insertions, 28 deletions
diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp
index 7403590f8c..839a253b99 100644
--- a/src/network/ssl/qsslcertificate.cpp
+++ b/src/network/ssl/qsslcertificate.cpp
@@ -128,7 +128,7 @@
QT_BEGIN_NAMESPACE
// forward declaration
-static QMap<QString, QString> _q_mapFromX509Name(X509_NAME *name);
+static QMap<QByteArray, QString> _q_mapFromX509Name(X509_NAME *name);
/*!
Constructs a QSslCertificate by reading \a format encoded data
@@ -297,19 +297,19 @@ QByteArray QSslCertificate::digest(QCryptographicHash::Algorithm algorithm) cons
return QCryptographicHash::hash(toDer(), algorithm);
}
-static QString _q_SubjectInfoToString(QSslCertificate::SubjectInfo info)
+static QByteArray _q_SubjectInfoToString(QSslCertificate::SubjectInfo info)
{
- QString str;
+ QByteArray str;
switch (info) {
- case QSslCertificate::Organization: str = QLatin1String("O"); break;
- case QSslCertificate::CommonName: str = QLatin1String("CN"); break;
- case QSslCertificate::LocalityName: str = QLatin1String("L"); break;
- case QSslCertificate::OrganizationalUnitName: str = QLatin1String("OU"); break;
- case QSslCertificate::CountryName: str = QLatin1String("C"); break;
- case QSslCertificate::StateOrProvinceName: str = QLatin1String("ST"); break;
- case QSslCertificate::DistinguishedNameQualifier: str = QLatin1String("dnQualifier"); break;
- case QSslCertificate::SerialNumber: str = QLatin1String("serialNumber"); break;
- case QSslCertificate::EmailAddress: str = QLatin1String("emailAddress"); break;
+ case QSslCertificate::Organization: str = QByteArray("O"); break;
+ case QSslCertificate::CommonName: str = QByteArray("CN"); break;
+ case QSslCertificate::LocalityName: str = QByteArray("L"); break;
+ case QSslCertificate::OrganizationalUnitName: str = QByteArray("OU"); break;
+ case QSslCertificate::CountryName: str = QByteArray("C"); break;
+ case QSslCertificate::StateOrProvinceName: str = QByteArray("ST"); break;
+ case QSslCertificate::DistinguishedNameQualifier: str = QByteArray("dnQualifier"); break;
+ case QSslCertificate::SerialNumber: str = QByteArray("serialNumber"); break;
+ case QSslCertificate::EmailAddress: str = QByteArray("emailAddress"); break;
}
return str;
}
@@ -334,20 +334,20 @@ QStringList QSslCertificate::issuerInfo(SubjectInfo info) const
}
/*!
- Returns the issuer information for \a tag from the certificate,
- or an empty string if there is no information for \a tag in the
+ Returns the issuer information for \a attribute from the certificate,
+ or an empty string if there is no information for \a attribute in the
certificate.
\sa subjectInfo()
*/
-QStringList QSslCertificate::issuerInfo(const QByteArray &tag) const
+QStringList QSslCertificate::issuerInfo(const QByteArray &attribute) const
{
// lazy init
if (d->issuerInfo.isEmpty() && d->x509)
d->issuerInfo =
_q_mapFromX509Name(q_X509_get_issuer_name(d->x509));
- return d->issuerInfo.values(QString::fromLatin1(tag));
+ return d->issuerInfo.values(attribute);
}
/*!
@@ -370,19 +370,57 @@ QStringList QSslCertificate::subjectInfo(SubjectInfo info) const
}
/*!
- Returns the subject information for \a tag, or an empty string if
- there is no information for \a tag in the certificate.
+ Returns the subject information for \a attribute, or an empty string if
+ there is no information for \a attribute in the certificate.
\sa issuerInfo()
*/
-QStringList QSslCertificate::subjectInfo(const QByteArray &tag) const
+QStringList QSslCertificate::subjectInfo(const QByteArray &attribute) const
{
// lazy init
if (d->subjectInfo.isEmpty() && d->x509)
d->subjectInfo =
_q_mapFromX509Name(q_X509_get_subject_name(d->x509));
- return d->subjectInfo.values(QString::fromLatin1(tag));
+ return d->subjectInfo.values(attribute);
+}
+
+/*!
+ Returns a list of the attributes that have values in the subject
+ information of this certificate. The information associated
+ with a given attribute can be accessed using the subjectInfo()
+ method. Note that this list may include the OIDs for any
+ elements that are not known by the SSL backend.
+
+ \sa subjectInfo()
+*/
+QList<QByteArray> QSslCertificate::subjectInfoAttributes() const
+{
+ // lazy init
+ if (d->subjectInfo.isEmpty() && d->x509)
+ d->subjectInfo =
+ _q_mapFromX509Name(q_X509_get_subject_name(d->x509));
+
+ return d->subjectInfo.uniqueKeys();
+}
+
+/*!
+ Returns a list of the attributes that have values in the issuer
+ information of this certificate. The information associated
+ with a given attribute can be accessed using the issuerInfo()
+ method. Note that this list may include the OIDs for any
+ elements that are not known by the SSL backend.
+
+ \sa subjectInfo()
+*/
+QList<QByteArray> QSslCertificate::issuerInfoAttributes() const
+{
+ // lazy init
+ if (d->issuerInfo.isEmpty() && d->x509)
+ d->issuerInfo =
+ _q_mapFromX509Name(q_X509_get_issuer_name(d->x509));
+
+ return d->issuerInfo.uniqueKeys();
}
/*!
@@ -706,17 +744,32 @@ QByteArray QSslCertificatePrivate::text_from_X509(X509 *x509)
return result;
}
-static QMap<QString, QString> _q_mapFromX509Name(X509_NAME *name)
+QByteArray QSslCertificatePrivate::asn1ObjectName(ASN1_OBJECT *object)
{
- QMap<QString, QString> info;
+ int nid = q_OBJ_obj2nid(object);
+ if (nid != NID_undef)
+ return QByteArray(q_OBJ_nid2sn(nid));
+
+ // This is used for unknown info so we get the OID as text
+ char buf[80];
+ q_i2t_ASN1_OBJECT(buf, sizeof(buf), object);
+
+ return QByteArray(buf);
+}
+
+static QMap<QByteArray, QString> _q_mapFromX509Name(X509_NAME *name)
+{
+ QMap<QByteArray, QString> info;
for (int i = 0; i < q_X509_NAME_entry_count(name); ++i) {
X509_NAME_ENTRY *e = q_X509_NAME_get_entry(name, i);
- const char *obj = q_OBJ_nid2sn(q_OBJ_obj2nid(q_X509_NAME_ENTRY_get_object(e)));
+
+ QByteArray name = QSslCertificatePrivate::asn1ObjectName(q_X509_NAME_ENTRY_get_object(e));
unsigned char *data = 0;
int size = q_ASN1_STRING_to_UTF8(&data, q_X509_NAME_ENTRY_get_data(e));
- info.insertMulti(QString::fromUtf8(obj), QString::fromUtf8((char*)data, size));
+ info.insertMulti(name, QString::fromUtf8((char*)data, size));
q_CRYPTO_free(data);
}
+
return info;
}
diff --git a/src/network/ssl/qsslcertificate.h b/src/network/ssl/qsslcertificate.h
index 8abaa3f73e..4de84dd4ba 100644
--- a/src/network/ssl/qsslcertificate.h
+++ b/src/network/ssl/qsslcertificate.h
@@ -100,9 +100,11 @@ public:
QByteArray serialNumber() const;
QByteArray digest(QCryptographicHash::Algorithm algorithm = QCryptographicHash::Md5) const;
QStringList issuerInfo(SubjectInfo info) const;
- QStringList issuerInfo(const QByteArray &tag) const;
+ QStringList issuerInfo(const QByteArray &attribute) const;
QStringList subjectInfo(SubjectInfo info) const;
- QStringList subjectInfo(const QByteArray &tag) const;
+ QStringList subjectInfo(const QByteArray &attribute) const;
+ QList<QByteArray> subjectInfoAttributes() const;
+ QList<QByteArray> issuerInfoAttributes() const;
QMultiMap<QSsl::AlternateNameEntryType, QString> alternateSubjectNames() const;
QDateTime effectiveDate() const;
QDateTime expiryDate() const;
diff --git a/src/network/ssl/qsslcertificate_p.h b/src/network/ssl/qsslcertificate_p.h
index eb192968c5..3cfcef7b57 100644
--- a/src/network/ssl/qsslcertificate_p.h
+++ b/src/network/ssl/qsslcertificate_p.h
@@ -83,8 +83,8 @@ public:
QByteArray versionString;
QByteArray serialNumberString;
- QMap<QString, QString> issuerInfo;
- QMap<QString, QString> subjectInfo;
+ QMap<QByteArray, QString> issuerInfo;
+ QMap<QByteArray, QString> subjectInfo;
QDateTime notValidAfter;
QDateTime notValidBefore;
@@ -92,6 +92,7 @@ public:
void init(const QByteArray &data, QSsl::EncodingFormat format);
+ static QByteArray asn1ObjectName(ASN1_OBJECT *object);
static QByteArray QByteArray_from_X509(X509 *x509, QSsl::EncodingFormat format);
static QByteArray text_from_X509(X509 *x509);
static QSslCertificate QSslCertificate_from_X509(X509 *x509);
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index f191ed9324..294e2508d8 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -1599,6 +1599,27 @@ bool QSslSocket::supportsSsl()
}
/*!
+ Returns the version number of the SSL library in use. Note that
+ this is the version of the library in use at run-time not compile
+ time. If no SSL support is available then this will return an
+ undefined value.
+*/
+long QSslSocket::sslLibraryVersionNumber()
+{
+ return QSslSocketPrivate::sslLibraryVersionNumber();
+}
+
+/*!
+ Returns the version string of the SSL library in use. Note that
+ this is the version of the library in use at run-time not compile
+ time. If no SSL support is available then this will return an empty value.
+*/
+QString QSslSocket::sslLibraryVersionString()
+{
+ return QSslSocketPrivate::sslLibraryVersionString();
+}
+
+/*!
Starts a delayed SSL handshake for a client connection. This
function can be called when the socket is in the \l ConnectedState
but still in the \l UnencryptedMode. If it is not yet connected,
diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h
index f175ffd946..803e79e0c4 100644
--- a/src/network/ssl/qsslsocket.h
+++ b/src/network/ssl/qsslsocket.h
@@ -176,6 +176,9 @@ public:
QList<QSslError> sslErrors() const;
static bool supportsSsl();
+ static long sslLibraryVersionNumber();
+ static QString sslLibraryVersionString();
+
void ignoreSslErrors(const QList<QSslError> &errors);
public Q_SLOTS:
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 479a6bd60e..c7e938a705 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -602,6 +602,23 @@ void QSslSocketPrivate::ensureInitialized()
ensureCiphersAndCertsLoaded();
}
+long QSslSocketPrivate::sslLibraryVersionNumber()
+{
+ return q_SSLeay();
+}
+
+QString QSslSocketPrivate::sslLibraryVersionString()
+{
+ if (!supportsSsl())
+ return QString();
+
+ const char *versionString = q_SSLeay_version(SSLEAY_VERSION);
+ if (!versionString)
+ return QString();
+
+ return QString::fromLatin1(versionString);
+}
+
/*!
\internal
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index b652833b45..31afab003f 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -133,6 +133,10 @@ DEFINEFUNC(EVP_PKEY *, EVP_PKEY_new, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(int, EVP_PKEY_type, int a, a, return NID_undef, return)
DEFINEFUNC2(int, i2d_X509, X509 *a, a, unsigned char **b, b, return -1, return)
DEFINEFUNC(const char *, OBJ_nid2sn, int a, a, return 0, return)
+DEFINEFUNC(const char *, OBJ_nid2ln, int a, a, return 0, return)
+DEFINEFUNC3(int, i2t_ASN1_OBJECT, char *a, a, int b, b, ASN1_OBJECT *c, c, return -1, return)
+
+
DEFINEFUNC(int, OBJ_obj2nid, const ASN1_OBJECT *a, a, return NID_undef, return)
#ifdef SSLEAY_MACROS
DEFINEFUNC6(void *, PEM_ASN1_read_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return 0, return)
@@ -276,6 +280,7 @@ DEFINEFUNC(void, OPENSSL_add_all_algorithms_noconf, void, DUMMYARG, return, DUMM
DEFINEFUNC(void, OPENSSL_add_all_algorithms_conf, void, DUMMYARG, return, DUMMYARG)
DEFINEFUNC3(int, SSL_CTX_load_verify_locations, SSL_CTX *ctx, ctx, const char *CAfile, CAfile, const char *CApath, CApath, return 0, return)
DEFINEFUNC(long, SSLeay, void, DUMMYARG, return 0, return)
+DEFINEFUNC(const char *, SSLeay_version, int a, a, return 0, return)
#ifdef Q_OS_SYMBIAN
#define RESOLVEFUNC(func, ordinal, lib) \
@@ -687,6 +692,8 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(EVP_PKEY_new)
RESOLVEFUNC(EVP_PKEY_type)
RESOLVEFUNC(OBJ_nid2sn)
+ RESOLVEFUNC(OBJ_nid2ln)
+ RESOLVEFUNC(i2t_ASN1_OBJECT)
RESOLVEFUNC(OBJ_obj2nid)
#ifdef SSLEAY_MACROS // ### verify
RESOLVEFUNC(PEM_ASN1_read_bio)
@@ -788,6 +795,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(OPENSSL_add_all_algorithms_conf)
RESOLVEFUNC(SSL_CTX_load_verify_locations)
RESOLVEFUNC(SSLeay)
+ RESOLVEFUNC(SSLeay_version)
#endif // Q_OS_SYMBIAN
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 658aa144a7..cd3aa07bc0 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -237,6 +237,8 @@ int q_EVP_PKEY_type(int a);
EVP_PKEY *q_EVP_PKEY_new();
int q_i2d_X509(X509 *a, unsigned char **b);
const char *q_OBJ_nid2sn(int a);
+const char *q_OBJ_nid2ln(int a);
+int q_i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *obj);
int q_OBJ_obj2nid(const ASN1_OBJECT *a);
#ifdef SSLEAY_MACROS
// ### verify
@@ -426,6 +428,7 @@ void q_OPENSSL_add_all_algorithms_noconf();
void q_OPENSSL_add_all_algorithms_conf();
int q_SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath);
long q_SSLeay();
+const char *q_SSLeay_version(int type);
// Helper function
class QDateTime;
diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h
index 86ecba07ce..b1dc656e88 100644
--- a/src/network/ssl/qsslsocket_p.h
+++ b/src/network/ssl/qsslsocket_p.h
@@ -116,6 +116,8 @@ public:
bool allowRootCertOnDemandLoading;
static bool supportsSsl();
+ static long sslLibraryVersionNumber();
+ static QString sslLibraryVersionString();
static void ensureInitialized();
static void deinitialize();
static QList<QSslCipher> defaultCiphers();