diff options
author | Richard Moore <rich@kde.org> | 2011-11-02 15:07:43 +0100 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-11-06 21:00:39 +0100 |
commit | 6248b869d0e8ae7e0fe566c09f2393278142b547 (patch) | |
tree | f1d8419968a810c0336a74c8539eadefd25b1501 /src/network | |
parent | efe02f9673dc948ef4b48b2abfeb15c978d2b438 (diff) |
SSL certificates: add functionality to read extensions
... by adding a new class QSslCertificateExtension and methods in
QSslCertificate to support extensions. This is needed e.g. for OCSP
(checking revocation status of a certificate) or Extended Validation
certificates.
Change-Id: I5c5d9513fa640cd487786bb9a5af734afebd0828
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/ssl/qsslcertificate.cpp | 245 | ||||
-rw-r--r-- | src/network/ssl/qsslcertificate.h | 2 | ||||
-rw-r--r-- | src/network/ssl/qsslcertificate_p.h | 3 | ||||
-rw-r--r-- | src/network/ssl/qsslcertificateextension.cpp | 200 | ||||
-rw-r--r-- | src/network/ssl/qsslcertificateextension.h | 90 | ||||
-rw-r--r-- | src/network/ssl/qsslcertificateextension_p.h | 68 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_openssl_symbols.cpp | 17 | ||||
-rw-r--r-- | src/network/ssl/qsslsocket_openssl_symbols_p.h | 8 | ||||
-rw-r--r-- | src/network/ssl/ssl.pri | 7 |
9 files changed, 628 insertions, 12 deletions
diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index dd0be205d8..1810270d7c 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -112,6 +112,8 @@ #include "qsslcertificate_p.h" #include "qsslkey.h" #include "qsslkey_p.h" +#include "qsslcertificateextension.h" +#include "qsslcertificateextension_p.h" #include <QtCore/qatomic.h> #include <QtCore/qdatetime.h> @@ -317,7 +319,7 @@ static QByteArray _q_SubjectInfoToString(QSslCertificate::SubjectInfo info) /*! \fn QString QSslCertificate::issuerInfo(SubjectInfo subject) const - + Returns the issuer information for the \a subject from the certificate, or an empty string if there is no information for \a subject in the certificate. @@ -429,12 +431,12 @@ QList<QByteArray> QSslCertificate::issuerInfoAttributes() const certificate. The alternative names typically contain host names, optionally with wildcards, that are valid for this certificate. - + These names are tested against the connected peer's host name, if either the subject information for \l CommonName doesn't define a valid host name, or the subject info name doesn't match the peer's host name. - + \sa subjectInfo() */ QMultiMap<QSsl::AlternativeNameEntryType, QString> QSslCertificate::subjectAlternativeNames() const @@ -542,6 +544,226 @@ QSslKey QSslCertificate::publicKey() const return key; } +/* + * Convert unknown extensions to a QVariant. + */ +static QVariant x509UnknownExtensionToValue(X509_EXTENSION *ext) +{ + // Get the extension specific method object if available + // we cast away the const-ness here because some versions of openssl + // don't use const for the parameters in the functions pointers stored + // in the object. + X509V3_EXT_METHOD *meth = const_cast<X509V3_EXT_METHOD *>(q_X509V3_EXT_get(ext)); + if (!meth) { + ASN1_OCTET_STRING *value = q_X509_EXTENSION_get_data(ext); + QByteArray result( reinterpret_cast<const char *>(q_ASN1_STRING_data(value)), + q_ASN1_STRING_length(value)); + return result; + } + + //const unsigned char *data = ext->value->data; + void *ext_internal = q_X509V3_EXT_d2i(ext); + + // If this extension can be converted + if (meth->i2v && ext_internal) { + STACK_OF(CONF_VALUE) *val = meth->i2v(meth, ext_internal, 0); + + QVariantMap map; + QVariantList list; + bool isMap = false; + + for (int j = 0; j < q_SKM_sk_num(CONF_VALUE, val); j++) { + CONF_VALUE *nval = q_SKM_sk_value(CONF_VALUE, val, j); + if (nval->name && nval->value) { + isMap = true; + map[QString::fromUtf8(nval->name)] = QString::fromUtf8(nval->value); + } else if (nval->name) { + list << QString::fromUtf8(nval->name); + } else if (nval->value) { + list << QString::fromUtf8(nval->value); + } + } + + if (isMap) + return map; + else + return list; + } else if (meth->i2s && ext_internal) { + //qDebug() << meth->i2s(meth, ext_internal); + QVariant result(QString::fromUtf8(meth->i2s(meth, ext_internal))); + return result; + } else if (meth->i2r && ext_internal) { + QByteArray result; + + BIO *bio = q_BIO_new(q_BIO_s_mem()); + if (!bio) + return result; + + meth->i2r(meth, ext_internal, bio, 0); + + char *bio_buffer; + long bio_size = q_BIO_get_mem_data(bio, &bio_buffer); + result = QByteArray(bio_buffer, bio_size); + + q_BIO_free(bio); + return result; + } + + return QVariant(); +} + +/* + * Convert extensions to a variant. The naming of the keys of the map are + * taken from RFC 5280, however we decided the capitalisation in the RFC + * was too silly for the real world. + */ +static QVariant x509ExtensionToValue(X509_EXTENSION *ext) +{ + ASN1_OBJECT *obj = q_X509_EXTENSION_get_object(ext); + int nid = q_OBJ_obj2nid(obj); + + switch (nid) { + case NID_basic_constraints: + { + BASIC_CONSTRAINTS *basic = reinterpret_cast<BASIC_CONSTRAINTS *>(q_X509V3_EXT_d2i(ext)); + + QVariantMap result; + result[QLatin1String("ca")] = basic->ca ? true : false; + if (basic->pathlen) + result[QLatin1String("pathLenConstraint")] = (qlonglong)q_ASN1_INTEGER_get(basic->pathlen); + + q_BASIC_CONSTRAINTS_free(basic); + return result; + } + break; + case NID_info_access: + { + AUTHORITY_INFO_ACCESS *info = reinterpret_cast<AUTHORITY_INFO_ACCESS *>(q_X509V3_EXT_d2i(ext)); + + QVariantMap result; + for (int i=0; i < q_SKM_sk_num(ACCESS_DESCRIPTION, info); i++) { + ACCESS_DESCRIPTION *ad = q_SKM_sk_value(ACCESS_DESCRIPTION, info, i); + + GENERAL_NAME *name = ad->location; + if (name->type == GEN_URI) { + int len = q_ASN1_STRING_length(name->d.uniformResourceIdentifier); + if (len < 0 || len >= 8192) { + // broken name + continue; + } + + const char *uriStr = reinterpret_cast<const char *>(q_ASN1_STRING_data(name->d.uniformResourceIdentifier)); + const QString uri = QString::fromUtf8(uriStr, len); + + result[QString::fromUtf8(QSslCertificatePrivate::asn1ObjectName(ad->method))] = uri; + } else { + qWarning() << "Strange location type" << name->type; + } + } + +#if OPENSSL_VERSION_NUMBER >= 0x10000000L + q_sk_pop_free((_STACK*)info, reinterpret_cast<void(*)(void*)>(q_sk_free)); +#else + q_sk_pop_free((STACK*)info, reinterpret_cast<void(*)(void*)>(q_sk_free)); +#endif + return result; + } + break; + case NID_subject_key_identifier: + { + void *ext_internal = q_X509V3_EXT_d2i(ext); + + // we cast away the const-ness here because some versions of openssl + // don't use const for the parameters in the functions pointers stored + // in the object. + X509V3_EXT_METHOD *meth = const_cast<X509V3_EXT_METHOD *>(q_X509V3_EXT_get(ext)); + + return QVariant(QString::fromUtf8(meth->i2s(meth, ext_internal))); + } + break; + case NID_authority_key_identifier: + { + AUTHORITY_KEYID *auth_key = reinterpret_cast<AUTHORITY_KEYID *>(q_X509V3_EXT_d2i(ext)); + + QVariantMap result; + + // keyid + if (auth_key->keyid) { + QByteArray keyid(reinterpret_cast<const char *>(auth_key->keyid->data), + auth_key->keyid->length); + result[QLatin1String("keyid")] = keyid.toHex(); + } + + // issuer + // TODO: GENERAL_NAMES + + // serial + if (auth_key->serial) + result[QLatin1String("serial")] = (qlonglong)q_ASN1_INTEGER_get(auth_key->serial); + + q_AUTHORITY_KEYID_free(auth_key); + return result; + } + break; + } + + return QVariant(); +} + +QSslCertificateExtension QSslCertificatePrivate::convertExtension(X509_EXTENSION *ext) +{ + QSslCertificateExtension result; + + ASN1_OBJECT *obj = q_X509_EXTENSION_get_object(ext); + QByteArray oid = QSslCertificatePrivate::asn1ObjectId(obj); + QByteArray name = QSslCertificatePrivate::asn1ObjectName(obj); + + result.d->oid = QString::fromUtf8(oid); + result.d->name = QString::fromUtf8(name); + + bool critical = q_X509_EXTENSION_get_critical(ext); + result.d->critical = critical; + + // Lets see if we have custom support for this one + QVariant extensionValue = x509ExtensionToValue(ext); + if (extensionValue.isValid()) { + result.d->value = extensionValue; + result.d->supported = true; + + return result; + } + + extensionValue = x509UnknownExtensionToValue(ext); + if (extensionValue.isValid()) { + result.d->value = extensionValue; + result.d->supported = false; + return result; + } + + return result; +} + +/*! + Returns a list containing the X509 extensions of this certificate. + \since 5.0 + */ +QList<QSslCertificateExtension> QSslCertificate::extensions() const +{ + QList<QSslCertificateExtension> result; + + if (!d->x509) + return result; + + int count = q_X509_get_ext_count(d->x509); + + for (int i=0; i < count; i++) { + X509_EXTENSION *ext = q_X509_get_ext(d->x509, i); + result << QSslCertificatePrivate::convertExtension(ext); + } + + return result; +} + /*! Returns this certificate converted to a PEM (Base64) encoded representation. @@ -581,7 +803,7 @@ QByteArray QSslCertificate::toText() const pattern matching one or more files, as specified by \a syntax. Example: - + \snippet doc/src/snippets/code/src_network_ssl_qsslcertificate.cpp 0 \sa fromData() @@ -760,17 +982,22 @@ QByteArray QSslCertificatePrivate::text_from_X509(X509 *x509) return result; } +QByteArray QSslCertificatePrivate::asn1ObjectId(ASN1_OBJECT *object) +{ + char buf[80]; // The openssl docs a buffer length of 80 should be more than enough + q_OBJ_obj2txt(buf, sizeof(buf), object, 1); // the 1 says always use the oid not the long name + + return QByteArray(buf); +} + + QByteArray QSslCertificatePrivate::asn1ObjectName(ASN1_OBJECT *object) { 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); + return asn1ObjectId(object); } static QMap<QByteArray, QString> _q_mapFromX509Name(X509_NAME *name) diff --git a/src/network/ssl/qsslcertificate.h b/src/network/ssl/qsslcertificate.h index 0498d162c4..07a8df308c 100644 --- a/src/network/ssl/qsslcertificate.h +++ b/src/network/ssl/qsslcertificate.h @@ -65,6 +65,7 @@ class QDateTime; class QIODevice; class QSslError; class QSslKey; +class QSslCertificateExtension; class QStringList; class QSslCertificatePrivate; @@ -114,6 +115,7 @@ public: QDateTime effectiveDate() const; QDateTime expiryDate() const; QSslKey publicKey() const; + QList<QSslCertificateExtension> extensions() const; QByteArray toPem() const; QByteArray toDer() const; diff --git a/src/network/ssl/qsslcertificate_p.h b/src/network/ssl/qsslcertificate_p.h index 3cfcef7b57..c4a833460a 100644 --- a/src/network/ssl/qsslcertificate_p.h +++ b/src/network/ssl/qsslcertificate_p.h @@ -57,6 +57,7 @@ // #include "qsslsocket_p.h" +#include "qsslcertificateextension.h" #include <QtCore/qdatetime.h> #include <QtCore/qmap.h> @@ -92,6 +93,7 @@ public: void init(const QByteArray &data, QSsl::EncodingFormat format); + static QByteArray asn1ObjectId(ASN1_OBJECT *object); static QByteArray asn1ObjectName(ASN1_OBJECT *object); static QByteArray QByteArray_from_X509(X509 *x509, QSsl::EncodingFormat format); static QByteArray text_from_X509(X509 *x509); @@ -99,6 +101,7 @@ public: static QList<QSslCertificate> certificatesFromPem(const QByteArray &pem, int count = -1); static QList<QSslCertificate> certificatesFromDer(const QByteArray &der, int count = -1); static bool isBlacklisted(const QSslCertificate &certificate); + static QSslCertificateExtension convertExtension(X509_EXTENSION *ext); friend class QSslSocketBackendPrivate; diff --git a/src/network/ssl/qsslcertificateextension.cpp b/src/network/ssl/qsslcertificateextension.cpp new file mode 100644 index 0000000000..b154ce70a5 --- /dev/null +++ b/src/network/ssl/qsslcertificateextension.cpp @@ -0,0 +1,200 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Richard J. Moore <rich@kde.org> +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \class QSslCertificateExtension + \brief The QSslCertificateExtension provides an API for accessing the extensions of an X509 certificate. + \since 5.0 + + \rentrant + \ingroup network + \ingroup ssl + \inmodule QtNetwork + + QSslCertificateExtension provides access to an extension stored in + an X509 certificate. The information available depends on the type + of extension being accessed. + + All X509 certificate extensions have the following properties: + + \table + \header + \o Property + \o Description + \row + \o name + \o The human readable name of the extension, eg. 'basicConstraints'. + \row + \o criticality + \o This is a boolean value indicating if the extension is critical + to correctly interpreting the certificate. + \row + \o oid + \o The ASN.1 object identifier that specifies which extension this + is. + \row + \o supported + \o If this is true the structure of the extension's value will not + change between Qt versions. + \row + \o value + \o A QVariant with a structure dependent on the type of extension. + \endtable + + Whilst this class provides access to any type of extension, only + some are guaranteed to be returned in a format that will remain + unchanged between releases. The isSupported() method returns true + for extensions where this is the case. + + The extensions currently supported, and the structure of the value + returned are as follows: + + \table + \header + \o Name + \o OID + \o Details + \row + \o basicConstraints + \o 2.5.29.19 + \o Returned as a QVariantMap. The key 'ca' contains a boolean value, + the optional key 'pathLenConstraint' contains an integer. + \row + \o authorityInfoAccess + \o 1.3.6.1.5.5.7.1.1 + \o Returned as a QVariantMap. There is a key for each access method, + with the value being a URI. + \row + \o subjectKeyIdentifier + \o 2.5.29.14 + \o Returned as a QVariant containing a QString. The string is the key + identifier. + \row + \o authorityKeyIdentifier + \o 2.5.29.35 + \o Returned as a QVariantMap. The optional key 'keyid' contains the key + identifier as a hex string stored in a QByteArray. The optional key + 'serial' contains the authority key serial number as a qlonglong. + Currently there is no support for the general names field of this + extension. + \endtable + + In addition to the supported extensions above, many other common extensions + will be returned in a reasonably structured way. Extensions that the SSL + backend has no support for at all will be returned as a QByteArray. + + Further information about the types of extensions certificates can + contain can be found in RFC 5280. + + \sa QSslCertificate::extensions() + */ + +#include "qsslcertificateextension.h" +#include "qsslcertificateextension_p.h" + +QT_BEGIN_NAMESPACE + +QSslCertificateExtension::QSslCertificateExtension() + : d(new QSslCertificateExtensionPrivate) +{ +} + +QSslCertificateExtension::QSslCertificateExtension(const QSslCertificateExtension &other) + : d(other.d) +{ +} + +QSslCertificateExtension::~QSslCertificateExtension() +{ +} + +QSslCertificateExtension &QSslCertificateExtension::operator=(const QSslCertificateExtension &other) +{ + d = other.d; + return *this; +} + +/*! + Returns the ASN.1 OID of this extension. + */ +QString QSslCertificateExtension::oid() const +{ + return d->oid; +} + +/*! + Returns the name of the extension. If no name is known for the + extension then the OID will be returned. + */ +QString QSslCertificateExtension::name() const +{ + return d->name; +} + +/*! + Returns the value of the extension. The structure of the value + returned depends on the extension type. + */ +QVariant QSslCertificateExtension::value() const +{ + return d->value; +} + +/*! + Returns the criticality of the extension. + */ +bool QSslCertificateExtension::isCritical() const +{ + return d->critical; +} + +/*! + Returns the true if this extension is supported. In this case, + supported simply means that the structure of the QVariant returned + by the value() accessor will remain unchanged between versions. + Unsupported extensions can be freely used, however there is no + guarantee that the returned data will have the same structure + between versions. + */ +bool QSslCertificateExtension::isSupported() const +{ + return d->supported; +} diff --git a/src/network/ssl/qsslcertificateextension.h b/src/network/ssl/qsslcertificateextension.h new file mode 100644 index 0000000000..200ae3e091 --- /dev/null +++ b/src/network/ssl/qsslcertificateextension.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Richard J. Moore <rich@kde.org> +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSSLCERTIFICATEEXTENSION_H +#define QSSLCERTIFICATEEXTENSION_H + +#include <QtCore/qnamespace.h> +#include <QtCore/qshareddata.h> +#include <QtCore/qstring.h> +#include <QtCore/qvariant.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Network) + +#ifndef QT_NO_OPENSSL + +class QSslCertificateExtensionPrivate; + +class Q_NETWORK_EXPORT QSslCertificateExtension +{ +public: + QSslCertificateExtension(); + QSslCertificateExtension(const QSslCertificateExtension &other); + ~QSslCertificateExtension(); + + QSslCertificateExtension &operator=(const QSslCertificateExtension &other); + + QString oid() const; + QString name() const; + QVariant value() const; + bool isCritical() const; + + bool isSupported() const; + +private: + friend class QSslCertificatePrivate; + QSharedDataPointer<QSslCertificateExtensionPrivate> d; +}; + +#endif // QT_NO_OPENSSL + +QT_END_NAMESPACE + +QT_END_HEADER + + +#endif // QSSLCERTIFICATEEXTENSION_H + + diff --git a/src/network/ssl/qsslcertificateextension_p.h b/src/network/ssl/qsslcertificateextension_p.h new file mode 100644 index 0000000000..877175b666 --- /dev/null +++ b/src/network/ssl/qsslcertificateextension_p.h @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Richard J. Moore <rich@kde.org> +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtNetwork module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** GNU Lesser General Public License Usage +** This file may be used under the terms of the GNU Lesser General Public +** License version 2.1 as published by the Free Software Foundation and +** appearing in the file LICENSE.LGPL included in the packaging of this +** file. Please review the following information to ensure the GNU Lesser +** General Public License version 2.1 requirements will be met: +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU General +** Public License version 3.0 as published by the Free Software Foundation +** and appearing in the file LICENSE.GPL included in the packaging of this +** file. Please review the following information to ensure the GNU General +** Public License version 3.0 requirements will be met: +** http://www.gnu.org/copyleft/gpl.html. +** +** Other Usage +** Alternatively, this file may be used in accordance with the terms and +** conditions contained in a signed written agreement between you and Nokia. +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSSLCERTIFICATEEXTESNION_P_H +#define QSSLCERTIFICATEEXTESNION_P_H + +#include "qsslcertificateextension.h" + +QT_BEGIN_NAMESPACE + +class QSslCertificateExtensionPrivate : public QSharedData +{ +public: + inline QSslCertificateExtensionPrivate() + : critical(false), + supported(false) + { + } + + QString oid; + QString name; + QVariant value; + bool critical; + bool supported; +}; + +QT_END_NAMESPACE + +#endif // QSSLCERTIFICATEEXTESNION_P_H + diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp index be8da0eaf0..7696d15542 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols.cpp +++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp @@ -135,7 +135,7 @@ 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) - +DEFINEFUNC4(int, OBJ_obj2txt, char *a, a, int b, b, ASN1_OBJECT *c, c, int d, d, return -1, return) DEFINEFUNC(int, OBJ_obj2nid, const ASN1_OBJECT *a, a, return NID_undef, return) #ifdef SSLEAY_MACROS @@ -259,6 +259,13 @@ DEFINEFUNC(void, X509_free, X509 *a, a, return, DUMMYARG) DEFINEFUNC2(X509_EXTENSION *, X509_get_ext, X509 *a, a, int b, b, return 0, return) DEFINEFUNC(int, X509_get_ext_count, X509 *a, a, return 0, return) DEFINEFUNC4(void *, X509_get_ext_d2i, X509 *a, a, int b, b, int *c, c, int *d, d, return 0, return) +DEFINEFUNC(const X509V3_EXT_METHOD *, X509V3_EXT_get, X509_EXTENSION *a, a, return 0, return) +DEFINEFUNC(void *, X509V3_EXT_d2i, X509_EXTENSION *a, a, return 0, return) +DEFINEFUNC(int, X509_EXTENSION_get_critical, X509_EXTENSION *a, a, return 0, return) +DEFINEFUNC(ASN1_OCTET_STRING *, X509_EXTENSION_get_data, X509_EXTENSION *a, a, return 0, return) +DEFINEFUNC(void, BASIC_CONSTRAINTS_free, BASIC_CONSTRAINTS *a, a, return, DUMMYARG) +DEFINEFUNC(void, AUTHORITY_KEYID_free, AUTHORITY_KEYID *a, a, return, DUMMYARG) +DEFINEFUNC2(int, ASN1_STRING_print, BIO *a, a, const ASN1_STRING *b, b, return 0, return) DEFINEFUNC(X509_NAME *, X509_get_issuer_name, X509 *a, a, return 0, return) DEFINEFUNC(X509_NAME *, X509_get_subject_name, X509 *a, a, return 0, return) DEFINEFUNC(int, X509_verify_cert, X509_STORE_CTX *a, a, return -1, return) @@ -698,6 +705,7 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(OBJ_nid2sn) RESOLVEFUNC(OBJ_nid2ln) RESOLVEFUNC(i2t_ASN1_OBJECT) + RESOLVEFUNC(OBJ_obj2txt) RESOLVEFUNC(OBJ_obj2nid) #ifdef SSLEAY_MACROS // ### verify RESOLVEFUNC(PEM_ASN1_read_bio) @@ -786,6 +794,13 @@ bool q_resolveOpenSslSymbols() RESOLVEFUNC(X509_get_ext) RESOLVEFUNC(X509_get_ext_count) RESOLVEFUNC(X509_get_ext_d2i) + RESOLVEFUNC(X509V3_EXT_get) + RESOLVEFUNC(X509V3_EXT_d2i) + RESOLVEFUNC(X509_EXTENSION_get_critical) + RESOLVEFUNC(X509_EXTENSION_get_data) + RESOLVEFUNC(BASIC_CONSTRAINTS_free) + RESOLVEFUNC(AUTHORITY_KEYID_free) + RESOLVEFUNC(ASN1_STRING_print) RESOLVEFUNC(X509_get_issuer_name) RESOLVEFUNC(X509_get_subject_name) RESOLVEFUNC(X509_verify_cert) diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h index d1705b3680..ad7a0a7557 100644 --- a/src/network/ssl/qsslsocket_openssl_symbols_p.h +++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h @@ -239,6 +239,7 @@ 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_obj2txt(char *buf, int buf_len, ASN1_OBJECT *obj, int no_name); int q_OBJ_obj2nid(const ASN1_OBJECT *a); #ifdef SSLEAY_MACROS // ### verify @@ -369,6 +370,13 @@ void q_X509_free(X509 *a); X509_EXTENSION *q_X509_get_ext(X509 *a, int b); int q_X509_get_ext_count(X509 *a); void *q_X509_get_ext_d2i(X509 *a, int b, int *c, int *d); +const X509V3_EXT_METHOD *q_X509V3_EXT_get(X509_EXTENSION *a); +void *q_X509V3_EXT_d2i(X509_EXTENSION *a); +int q_X509_EXTENSION_get_critical(X509_EXTENSION *a); +ASN1_OCTET_STRING *q_X509_EXTENSION_get_data(X509_EXTENSION *a); +void q_BASIC_CONSTRAINTS_free(BASIC_CONSTRAINTS *a); +void q_AUTHORITY_KEYID_free(AUTHORITY_KEYID *a); +int q_ASN1_STRING_print(BIO *a, const ASN1_STRING *b); X509_NAME *q_X509_get_issuer_name(X509 *a); X509_NAME *q_X509_get_subject_name(X509 *a); int q_X509_verify_cert(X509_STORE_CTX *ctx); diff --git a/src/network/ssl/ssl.pri b/src/network/ssl/ssl.pri index 8b2e2c1917..9ba8d01f51 100644 --- a/src/network/ssl/ssl.pri +++ b/src/network/ssl/ssl.pri @@ -20,7 +20,9 @@ symbian { ssl/qsslsocket.h \ ssl/qsslsocket_openssl_p.h \ ssl/qsslsocket_openssl_symbols_p.h \ - ssl/qsslsocket_p.h + ssl/qsslsocket_p.h \ + ssl/qsslcertificateextension.h \ + ssl/qsslcertificateextension_p.h SOURCES += ssl/qssl.cpp \ ssl/qsslcertificate.cpp \ ssl/qsslconfiguration.cpp \ @@ -29,7 +31,8 @@ symbian { ssl/qsslkey.cpp \ ssl/qsslsocket.cpp \ ssl/qsslsocket_openssl.cpp \ - ssl/qsslsocket_openssl_symbols.cpp + ssl/qsslsocket_openssl_symbols.cpp \ + ssl/qsslcertificateextension.cpp # Add optional SSL libs LIBS_PRIVATE += $$OPENSSL_LIBS |