#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>
/*!
\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.
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
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.
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()
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)
class QIODevice;
class QSslError;
class QSslKey;
+class QSslCertificateExtension;
class QStringList;
class QSslCertificatePrivate;
QDateTime effectiveDate() const;
QDateTime expiryDate() const;
QSslKey publicKey() const;
+ QList<QSslCertificateExtension> extensions() const;
QByteArray toPem() const;
QByteArray toDer() const;
//
#include "qsslsocket_p.h"
+#include "qsslcertificateextension.h"
#include <QtCore/qdatetime.h>
#include <QtCore/qmap.h>
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);
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;
--- /dev/null
+/****************************************************************************
+**
+** 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;
+}
--- /dev/null
+/****************************************************************************
+**
+** 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
+
+
--- /dev/null
+/****************************************************************************
+**
+** 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
+
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
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)
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)
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)
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
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);
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 \
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