diff options
Diffstat (limited to 'src/network/ssl')
-rw-r--r-- | src/network/ssl/qsslcertificate.cpp | 101 | ||||
-rw-r--r-- | src/network/ssl/qsslcertificate.h | 6 | ||||
-rw-r--r-- | src/network/ssl/qsslcertificate_p.h | 5 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket.cpp | 21 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket.h | 3 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_openssl.cpp | 17 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_openssl_symbols.cpp | 8 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_openssl_symbols_p.h | 3 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_p.h | 2 |
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(); |