ssl: common certificate parser support for extensions
This makes non-OpenSSL backends able to handle to certificate extensions. This also converts the Q_OS_WINRT #ifdef's in the unit test to QT_NO_OPENSSL as the behavior is the same for any non-OpenSSL backend. Change-Id: I6a8306dc5c97a659ec96063d5a59cee2ee9a63a9 Reviewed-by: Richard J. Moore <rich@kde.org>
This commit is contained in:
parent
2e667c9171
commit
070fcf9ce1
@ -56,6 +56,14 @@ static OidNameMap createOidMap()
|
||||
// used by unit tests
|
||||
oids.insert(oids.end(), QByteArrayLiteral("0.9.2342.19200300.100.1.5"), QByteArrayLiteral("favouriteDrink"));
|
||||
oids.insert(oids.end(), QByteArrayLiteral("1.2.840.113549.1.9.1"), QByteArrayLiteral("emailAddress"));
|
||||
oids.insert(oids.end(), QByteArrayLiteral("1.3.6.1.5.5.7.1.1"), QByteArrayLiteral("authorityInfoAccess"));
|
||||
oids.insert(oids.end(), QByteArrayLiteral("1.3.6.1.5.5.7.48.1"), QByteArrayLiteral("OCSP"));
|
||||
oids.insert(oids.end(), QByteArrayLiteral("1.3.6.1.5.5.7.48.2"), QByteArrayLiteral("caIssuers"));
|
||||
oids.insert(oids.end(), QByteArrayLiteral("2.5.29.14"), QByteArrayLiteral("subjectKeyIdentifier"));
|
||||
oids.insert(oids.end(), QByteArrayLiteral("2.5.29.15"), QByteArrayLiteral("keyUsage"));
|
||||
oids.insert(oids.end(), QByteArrayLiteral("2.5.29.17"), QByteArrayLiteral("subjectAltName"));
|
||||
oids.insert(oids.end(), QByteArrayLiteral("2.5.29.19"), QByteArrayLiteral("basicConstraints"));
|
||||
oids.insert(oids.end(), QByteArrayLiteral("2.5.29.35"), QByteArrayLiteral("authorityKeyIdentifier"));
|
||||
oids.insert(oids.end(), QByteArrayLiteral("2.5.4.10"), QByteArrayLiteral("O"));
|
||||
oids.insert(oids.end(), QByteArrayLiteral("2.5.4.11"), QByteArrayLiteral("OU"));
|
||||
oids.insert(oids.end(), QByteArrayLiteral("2.5.4.12"), QByteArrayLiteral("title"));
|
||||
|
@ -59,6 +59,9 @@
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
#define RSA_ENCRYPTION_OID QByteArrayLiteral("1.2.840.113549.1.1.1")
|
||||
#define DSA_ENCRYPTION_OID QByteArrayLiteral("1.2.840.10040.4.1")
|
||||
|
||||
class Q_AUTOTEST_EXPORT QAsn1Element
|
||||
{
|
||||
public:
|
||||
@ -78,10 +81,6 @@ public:
|
||||
SequenceType = 0x30,
|
||||
SetType = 0x31,
|
||||
|
||||
// application
|
||||
Rfc822NameType = 0x81,
|
||||
DnsNameType = 0x82,
|
||||
|
||||
// context specific
|
||||
Context0Type = 0xA0,
|
||||
Context3Type = 0xA3
|
||||
|
@ -122,7 +122,6 @@
|
||||
|
||||
#include "qsslcertificate.h"
|
||||
#include "qsslcertificate_p.h"
|
||||
#include "qasn1element_p.h"
|
||||
#include "qsslkey_p.h"
|
||||
|
||||
#include <QtCore/qdir.h>
|
||||
@ -642,155 +641,6 @@ static const char *certificate_blacklist[] = {
|
||||
0
|
||||
};
|
||||
|
||||
bool QSslCertificatePrivate::parse(const QByteArray &data)
|
||||
{
|
||||
#ifndef QT_NO_OPENSSL
|
||||
Q_UNUSED(data);
|
||||
#else
|
||||
QAsn1Element root;
|
||||
|
||||
QDataStream dataStream(data);
|
||||
if (!root.read(dataStream) || root.type() != QAsn1Element::SequenceType)
|
||||
return false;
|
||||
|
||||
QDataStream rootStream(root.value());
|
||||
QAsn1Element cert;
|
||||
if (!cert.read(rootStream) || cert.type() != QAsn1Element::SequenceType)
|
||||
return false;
|
||||
|
||||
// version or serial number
|
||||
QAsn1Element elem;
|
||||
QDataStream certStream(cert.value());
|
||||
if (!elem.read(certStream))
|
||||
return false;
|
||||
|
||||
if (elem.type() == QAsn1Element::Context0Type) {
|
||||
QDataStream versionStream(elem.value());
|
||||
if (!elem.read(versionStream) || elem.type() != QAsn1Element::IntegerType)
|
||||
return false;
|
||||
|
||||
versionString = QByteArray::number(elem.value()[0] + 1);
|
||||
if (!elem.read(certStream))
|
||||
return false;
|
||||
} else {
|
||||
versionString = QByteArray::number(1);
|
||||
}
|
||||
|
||||
// serial number
|
||||
if (elem.type() != QAsn1Element::IntegerType)
|
||||
return false;
|
||||
|
||||
QByteArray hexString;
|
||||
hexString.reserve(elem.value().size() * 3);
|
||||
for (int a = 0; a < elem.value().size(); ++a) {
|
||||
const quint8 b = elem.value().at(a);
|
||||
if (b || !hexString.isEmpty()) { // skip leading zeros
|
||||
hexString += QByteArray::number(b, 16).rightJustified(2, '0');
|
||||
hexString += ':';
|
||||
}
|
||||
}
|
||||
hexString.chop(1);
|
||||
serialNumberString = hexString;
|
||||
|
||||
// algorithm ID
|
||||
if (!elem.read(certStream) || elem.type() != QAsn1Element::SequenceType)
|
||||
return false;
|
||||
|
||||
//qDebug() << "algorithm ID" << elem.type() << elem.length << elem.value().toHex();
|
||||
|
||||
// issuer info
|
||||
if (!elem.read(certStream) || elem.type() != QAsn1Element::SequenceType)
|
||||
return false;
|
||||
|
||||
QByteArray issuerDer = data.mid(dataStream.device()->pos() - elem.value().length(), elem.value().length());
|
||||
issuerInfo = elem.toInfo();
|
||||
|
||||
// validity period
|
||||
if (!elem.read(certStream) || elem.type() != QAsn1Element::SequenceType)
|
||||
return false;
|
||||
|
||||
QDataStream validityStream(elem.value());
|
||||
if (!elem.read(validityStream) || (elem.type() != QAsn1Element::UtcTimeType && elem.type() != QAsn1Element::GeneralizedTimeType))
|
||||
return false;
|
||||
|
||||
notValidBefore = elem.toDateTime();
|
||||
if (!elem.read(validityStream) || (elem.type() != QAsn1Element::UtcTimeType && elem.type() != QAsn1Element::GeneralizedTimeType))
|
||||
return false;
|
||||
|
||||
notValidAfter = elem.toDateTime();
|
||||
|
||||
// subject name
|
||||
if (!elem.read(certStream) || elem.type() != QAsn1Element::SequenceType)
|
||||
return false;
|
||||
|
||||
QByteArray subjectDer = data.mid(dataStream.device()->pos() - elem.value().length(), elem.value().length());
|
||||
subjectInfo = elem.toInfo();
|
||||
subjectMatchesIssuer = issuerDer == subjectDer;
|
||||
|
||||
// public key
|
||||
qint64 keyStart = certStream.device()->pos();
|
||||
if (!elem.read(certStream) || elem.type() != QAsn1Element::SequenceType)
|
||||
return false;
|
||||
|
||||
publicKeyDerData.resize(certStream.device()->pos() - keyStart);
|
||||
QDataStream keyStream(elem.value());
|
||||
if (!elem.read(keyStream) || elem.type() != QAsn1Element::SequenceType)
|
||||
return false;
|
||||
|
||||
|
||||
// key algorithm
|
||||
if (!elem.read(elem.value()) || elem.type() != QAsn1Element::ObjectIdentifierType)
|
||||
return false;
|
||||
|
||||
const QByteArray oid = elem.toObjectId();
|
||||
if (oid == "1.2.840.113549.1.1.1")
|
||||
publicKeyAlgorithm = QSsl::Rsa;
|
||||
else if (oid == "1.2.840.10040.4.1")
|
||||
publicKeyAlgorithm = QSsl::Dsa;
|
||||
else
|
||||
publicKeyAlgorithm = QSsl::Opaque;
|
||||
|
||||
certStream.device()->seek(keyStart);
|
||||
certStream.readRawData(publicKeyDerData.data(), publicKeyDerData.size());
|
||||
|
||||
// extensions
|
||||
while (elem.read(certStream)) {
|
||||
if (elem.type() == QAsn1Element::Context3Type) {
|
||||
if (elem.read(elem.value()) && elem.type() == QAsn1Element::SequenceType) {
|
||||
QDataStream extStream(elem.value());
|
||||
while (elem.read(extStream) && elem.type() == QAsn1Element::SequenceType) {
|
||||
QAsn1Element oidElem, valElem;
|
||||
QDataStream seqStream(elem.value());
|
||||
if (oidElem.read(seqStream) && oidElem.type() == QAsn1Element::ObjectIdentifierType &&
|
||||
valElem.read(seqStream) && valElem.type() == QAsn1Element::OctetStringType) {
|
||||
// alternative name
|
||||
if (oidElem.toObjectId() == QByteArray("2.5.29.17")) {
|
||||
QAsn1Element sanElem;
|
||||
if (sanElem.read(valElem.value()) && sanElem.type() == QAsn1Element::SequenceType) {
|
||||
QDataStream nameStream(sanElem.value());
|
||||
QAsn1Element nameElem;
|
||||
while (nameElem.read(nameStream)) {
|
||||
if (nameElem.type() == QAsn1Element::Rfc822NameType) {
|
||||
subjectAlternativeNames.insert(QSsl::EmailEntry, QString::fromLatin1(nameElem.value(), nameElem.value().size()));
|
||||
} else if (nameElem.type() == QAsn1Element::DnsNameType) {
|
||||
subjectAlternativeNames.insert(QSsl::DnsEntry, QString::fromLatin1(nameElem.value(), nameElem.value().size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
derData = data.left(dataStream.device()->pos());
|
||||
null = false;
|
||||
|
||||
#endif // QT_NO_OPENSSL
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QSslCertificatePrivate::isBlacklisted(const QSslCertificate &certificate)
|
||||
{
|
||||
for (int a = 0; certificate_blacklist[a] != 0; a++) {
|
||||
|
@ -109,13 +109,16 @@ public:
|
||||
QSsl::KeyAlgorithm publicKeyAlgorithm;
|
||||
QByteArray publicKeyDerData;
|
||||
QMultiMap<QSsl::AlternativeNameEntryType, QString> subjectAlternativeNames;
|
||||
QList<QSslCertificateExtension> extensions;
|
||||
|
||||
QByteArray derData;
|
||||
|
||||
bool parse(const QByteArray &data);
|
||||
bool parseExtension(const QByteArray &data, QSslCertificateExtension *extension);
|
||||
#endif
|
||||
X509 *x509;
|
||||
|
||||
void init(const QByteArray &data, QSsl::EncodingFormat format);
|
||||
bool parse(const QByteArray &data);
|
||||
|
||||
static QByteArray asn1ObjectId(ASN1_OBJECT *object);
|
||||
static QByteArray asn1ObjectName(ASN1_OBJECT *object);
|
||||
|
@ -47,9 +47,17 @@
|
||||
#include "qsslkey_p.h"
|
||||
#include "qsslcertificateextension.h"
|
||||
#include "qsslcertificateextension_p.h"
|
||||
#include "qasn1element_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
enum GeneralNameType
|
||||
{
|
||||
Rfc822NameType = 0x81,
|
||||
DnsNameType = 0x82,
|
||||
UniformResourceIdentifierType = 0x86
|
||||
};
|
||||
|
||||
bool QSslCertificate::operator==(const QSslCertificate &other) const
|
||||
{
|
||||
if (d == other.d)
|
||||
@ -150,8 +158,7 @@ QSslKey QSslCertificate::publicKey() const
|
||||
|
||||
QList<QSslCertificateExtension> QSslCertificate::extensions() const
|
||||
{
|
||||
Q_UNIMPLEMENTED();
|
||||
return QList<QSslCertificateExtension>();
|
||||
return d->extensions;
|
||||
}
|
||||
|
||||
#define BEGINCERTSTRING "-----BEGIN CERTIFICATE-----"
|
||||
@ -263,4 +270,249 @@ QList<QSslCertificate> QSslCertificatePrivate::certificatesFromDer(const QByteAr
|
||||
return certificates;
|
||||
}
|
||||
|
||||
static QByteArray colonSeparatedHex(const QByteArray &value)
|
||||
{
|
||||
QByteArray hexString;
|
||||
hexString.reserve(value.size() * 3);
|
||||
for (int a = 0; a < value.size(); ++a) {
|
||||
const quint8 b = value.at(a);
|
||||
if (b || !hexString.isEmpty()) { // skip leading zeros
|
||||
hexString += QByteArray::number(b, 16).rightJustified(2, '0');
|
||||
hexString += ':';
|
||||
}
|
||||
}
|
||||
hexString.chop(1);
|
||||
return hexString;
|
||||
}
|
||||
|
||||
bool QSslCertificatePrivate::parse(const QByteArray &data)
|
||||
{
|
||||
QAsn1Element root;
|
||||
|
||||
QDataStream dataStream(data);
|
||||
if (!root.read(dataStream) || root.type() != QAsn1Element::SequenceType)
|
||||
return false;
|
||||
|
||||
QDataStream rootStream(root.value());
|
||||
QAsn1Element cert;
|
||||
if (!cert.read(rootStream) || cert.type() != QAsn1Element::SequenceType)
|
||||
return false;
|
||||
|
||||
// version or serial number
|
||||
QAsn1Element elem;
|
||||
QDataStream certStream(cert.value());
|
||||
if (!elem.read(certStream))
|
||||
return false;
|
||||
|
||||
if (elem.type() == QAsn1Element::Context0Type) {
|
||||
QDataStream versionStream(elem.value());
|
||||
if (!elem.read(versionStream) || elem.type() != QAsn1Element::IntegerType)
|
||||
return false;
|
||||
|
||||
versionString = QByteArray::number(elem.value()[0] + 1);
|
||||
if (!elem.read(certStream))
|
||||
return false;
|
||||
} else {
|
||||
versionString = QByteArray::number(1);
|
||||
}
|
||||
|
||||
// serial number
|
||||
if (elem.type() != QAsn1Element::IntegerType)
|
||||
return false;
|
||||
serialNumberString = colonSeparatedHex(elem.value());
|
||||
|
||||
// algorithm ID
|
||||
if (!elem.read(certStream) || elem.type() != QAsn1Element::SequenceType)
|
||||
return false;
|
||||
|
||||
// issuer info
|
||||
if (!elem.read(certStream) || elem.type() != QAsn1Element::SequenceType)
|
||||
return false;
|
||||
|
||||
QByteArray issuerDer = data.mid(dataStream.device()->pos() - elem.value().length(), elem.value().length());
|
||||
issuerInfo = elem.toInfo();
|
||||
|
||||
// validity period
|
||||
if (!elem.read(certStream) || elem.type() != QAsn1Element::SequenceType)
|
||||
return false;
|
||||
|
||||
QDataStream validityStream(elem.value());
|
||||
if (!elem.read(validityStream) || (elem.type() != QAsn1Element::UtcTimeType && elem.type() != QAsn1Element::GeneralizedTimeType))
|
||||
return false;
|
||||
|
||||
notValidBefore = elem.toDateTime();
|
||||
if (!elem.read(validityStream) || (elem.type() != QAsn1Element::UtcTimeType && elem.type() != QAsn1Element::GeneralizedTimeType))
|
||||
return false;
|
||||
|
||||
notValidAfter = elem.toDateTime();
|
||||
|
||||
// subject name
|
||||
if (!elem.read(certStream) || elem.type() != QAsn1Element::SequenceType)
|
||||
return false;
|
||||
|
||||
QByteArray subjectDer = data.mid(dataStream.device()->pos() - elem.value().length(), elem.value().length());
|
||||
subjectInfo = elem.toInfo();
|
||||
subjectMatchesIssuer = issuerDer == subjectDer;
|
||||
|
||||
// public key
|
||||
qint64 keyStart = certStream.device()->pos();
|
||||
if (!elem.read(certStream) || elem.type() != QAsn1Element::SequenceType)
|
||||
return false;
|
||||
|
||||
publicKeyDerData.resize(certStream.device()->pos() - keyStart);
|
||||
QDataStream keyStream(elem.value());
|
||||
if (!elem.read(keyStream) || elem.type() != QAsn1Element::SequenceType)
|
||||
return false;
|
||||
|
||||
|
||||
// key algorithm
|
||||
if (!elem.read(elem.value()) || elem.type() != QAsn1Element::ObjectIdentifierType)
|
||||
return false;
|
||||
|
||||
const QByteArray oid = elem.toObjectId();
|
||||
if (oid == RSA_ENCRYPTION_OID)
|
||||
publicKeyAlgorithm = QSsl::Rsa;
|
||||
else if (oid == RSA_ENCRYPTION_OID)
|
||||
publicKeyAlgorithm = QSsl::Dsa;
|
||||
else
|
||||
publicKeyAlgorithm = QSsl::Opaque;
|
||||
|
||||
certStream.device()->seek(keyStart);
|
||||
certStream.readRawData(publicKeyDerData.data(), publicKeyDerData.size());
|
||||
|
||||
// extensions
|
||||
while (elem.read(certStream)) {
|
||||
if (elem.type() == QAsn1Element::Context3Type) {
|
||||
if (elem.read(elem.value()) && elem.type() == QAsn1Element::SequenceType) {
|
||||
QDataStream extStream(elem.value());
|
||||
while (elem.read(extStream) && elem.type() == QAsn1Element::SequenceType) {
|
||||
QSslCertificateExtension extension;
|
||||
if (!parseExtension(elem.value(), &extension))
|
||||
return false;
|
||||
extensions << extension;
|
||||
|
||||
if (extension.oid() == QLatin1String("2.5.29.17")) {
|
||||
// subjectAltName
|
||||
QAsn1Element sanElem;
|
||||
if (sanElem.read(extension.value().toByteArray()) && sanElem.type() == QAsn1Element::SequenceType) {
|
||||
QDataStream nameStream(sanElem.value());
|
||||
QAsn1Element nameElem;
|
||||
while (nameElem.read(nameStream)) {
|
||||
if (nameElem.type() == Rfc822NameType) {
|
||||
subjectAlternativeNames.insert(QSsl::EmailEntry, QString::fromLatin1(nameElem.value(), nameElem.value().size()));
|
||||
} else if (nameElem.type() == DnsNameType) {
|
||||
subjectAlternativeNames.insert(QSsl::DnsEntry, QString::fromLatin1(nameElem.value(), nameElem.value().size()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
derData = data.left(dataStream.device()->pos());
|
||||
null = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QSslCertificatePrivate::parseExtension(const QByteArray &data, QSslCertificateExtension *extension)
|
||||
{
|
||||
bool ok;
|
||||
bool critical = false;
|
||||
QAsn1Element oidElem, valElem;
|
||||
|
||||
QDataStream seqStream(data);
|
||||
|
||||
// oid
|
||||
if (!oidElem.read(seqStream) || oidElem.type() != QAsn1Element::ObjectIdentifierType)
|
||||
return false;
|
||||
const QByteArray oid = oidElem.toObjectId();
|
||||
|
||||
// critical and value
|
||||
if (!valElem.read(seqStream))
|
||||
return false;
|
||||
if (valElem.type() == QAsn1Element::BooleanType) {
|
||||
critical = valElem.toBool(&ok);
|
||||
if (!ok || !valElem.read(seqStream))
|
||||
return false;
|
||||
}
|
||||
if (valElem.type() != QAsn1Element::OctetStringType)
|
||||
return false;
|
||||
|
||||
// interpret value
|
||||
QAsn1Element val;
|
||||
bool supported = true;
|
||||
QVariant value;
|
||||
if (oid == QByteArrayLiteral("1.3.6.1.5.5.7.1.1")) {
|
||||
// authorityInfoAccess
|
||||
if (!val.read(valElem.value()) || val.type() != QAsn1Element::SequenceType)
|
||||
return false;
|
||||
QVariantMap result;
|
||||
foreach (const QAsn1Element &el, val.toVector()) {
|
||||
QVector<QAsn1Element> items = el.toVector();
|
||||
if (items.size() != 2)
|
||||
return false;
|
||||
const QString key = QString::fromLatin1(items.at(0).toObjectName());
|
||||
switch (items.at(1).type()) {
|
||||
case Rfc822NameType:
|
||||
case DnsNameType:
|
||||
case UniformResourceIdentifierType:
|
||||
result[key] = QString::fromLatin1(items.at(1).value(), items.at(1).value().size());
|
||||
break;
|
||||
}
|
||||
}
|
||||
value = result;
|
||||
} else if (oid == QByteArrayLiteral("2.5.29.14")) {
|
||||
// subjectKeyIdentifier
|
||||
if (!val.read(valElem.value()) || val.type() != QAsn1Element::OctetStringType)
|
||||
return false;
|
||||
value = colonSeparatedHex(val.value()).toUpper();
|
||||
} else if (oid == QByteArrayLiteral("2.5.29.19")) {
|
||||
// basicConstraints
|
||||
if (!val.read(valElem.value()) || val.type() != QAsn1Element::SequenceType)
|
||||
return false;
|
||||
|
||||
QVariantMap result;
|
||||
QVector<QAsn1Element> items = val.toVector();
|
||||
if (items.size() > 0) {
|
||||
result[QStringLiteral("ca")] = items.at(0).toBool(&ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
} else {
|
||||
result[QStringLiteral("ca")] = false;
|
||||
}
|
||||
if (items.size() > 1) {
|
||||
result[QStringLiteral("pathLenConstraint")] = items.at(1).toInteger(&ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
}
|
||||
value = result;
|
||||
} else if (oid == QByteArrayLiteral("2.5.29.35")) {
|
||||
// authorityKeyIdentifier
|
||||
if (!val.read(valElem.value()) || val.type() != QAsn1Element::SequenceType)
|
||||
return false;
|
||||
QVariantMap result;
|
||||
foreach (const QAsn1Element &el, val.toVector()) {
|
||||
if (el.type() == 0x80) {
|
||||
result[QStringLiteral("keyid")] = el.value().toHex();
|
||||
} else if (el.type() == 0x82) {
|
||||
result[QStringLiteral("serial")] = colonSeparatedHex(el.value());
|
||||
}
|
||||
}
|
||||
value = result;
|
||||
} else {
|
||||
supported = false;
|
||||
value = valElem.value();
|
||||
}
|
||||
|
||||
extension->d->critical = critical;
|
||||
extension->d->supported = supported;
|
||||
extension->d->oid = QString::fromLatin1(oid);
|
||||
extension->d->name = QString::fromLatin1(oidElem.toObjectName());
|
||||
extension->d->value = value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
@ -133,7 +133,7 @@ void QSslKeyPrivate::decodeDer(const QByteArray &der, bool deepClear)
|
||||
if (infoItems.size() < 2 || infoItems[0].type() != QAsn1Element::ObjectIdentifierType)
|
||||
return;
|
||||
if (algorithm == QSsl::Rsa) {
|
||||
if (infoItems[0].toObjectId() != "1.2.840.113549.1.1.1")
|
||||
if (infoItems[0].toObjectId() != RSA_ENCRYPTION_OID)
|
||||
return;
|
||||
// key data
|
||||
if (!elem.read(keyStream) || elem.type() != QAsn1Element::BitStringType || elem.value().isEmpty())
|
||||
@ -144,7 +144,7 @@ void QSslKeyPrivate::decodeDer(const QByteArray &der, bool deepClear)
|
||||
return;
|
||||
keyLength = numberOfBits(elem.value());
|
||||
} else if (algorithm == QSsl::Dsa) {
|
||||
if (infoItems[0].toObjectId() != "1.2.840.10040.4.1")
|
||||
if (infoItems[0].toObjectId() != DSA_ENCRYPTION_OID)
|
||||
return;
|
||||
if (infoItems[1].type() != QAsn1Element::SequenceType)
|
||||
return;
|
||||
|
@ -928,7 +928,7 @@ void tst_QSslCertificate::toText()
|
||||
|
||||
QString txtcert = cert.toText();
|
||||
|
||||
#ifdef Q_OS_WINRT
|
||||
#ifdef QT_NO_OPENSSL
|
||||
QEXPECT_FAIL("", "QTBUG-40884: QSslCertificate::toText is not implemented on WinRT", Continue);
|
||||
#endif
|
||||
QVERIFY(QString::fromLatin1(txt098) == txtcert ||
|
||||
@ -976,7 +976,7 @@ void tst_QSslCertificate::verify()
|
||||
qPrintable(QString("errors: %1").arg(toString(errors))) \
|
||||
)
|
||||
|
||||
#ifdef Q_OS_WINRT
|
||||
#ifdef QT_NO_OPENSSL
|
||||
QEXPECT_FAIL("", "QTBUG-40884: WinRT API does not yet support verifying a chain", Abort);
|
||||
#endif
|
||||
// Empty chain is unspecified error
|
||||
@ -1060,9 +1060,6 @@ void tst_QSslCertificate::extensions()
|
||||
|
||||
QSslCertificate cert = certList[0];
|
||||
QList<QSslCertificateExtension> extensions = cert.extensions();
|
||||
#ifdef Q_OS_WINRT
|
||||
QEXPECT_FAIL("", "QTBUG-40884: WinRT API does not support extensions information", Abort);
|
||||
#endif
|
||||
QVERIFY(extensions.count() == 9);
|
||||
|
||||
int unknown_idx = -1;
|
||||
@ -1161,9 +1158,6 @@ void tst_QSslCertificate::extensionsCritical()
|
||||
|
||||
QSslCertificate cert = certList[0];
|
||||
QList<QSslCertificateExtension> extensions = cert.extensions();
|
||||
#ifdef Q_OS_WINRT
|
||||
QEXPECT_FAIL("", "QTBUG-40884: WinRT API does not support extensions information", Abort);
|
||||
#endif
|
||||
QVERIFY(extensions.count() == 9);
|
||||
|
||||
int basic_constraints_idx = -1;
|
||||
@ -1314,7 +1308,7 @@ void tst_QSslCertificate::pkcs12()
|
||||
QSslCertificate cert;
|
||||
QList<QSslCertificate> caCerts;
|
||||
|
||||
#ifdef Q_OS_WINRT
|
||||
#ifdef QT_NO_OPENSSL
|
||||
QEXPECT_FAIL("", "QTBUG-40884: WinRT API does not support pkcs12 imports", Abort);
|
||||
#endif
|
||||
ok = QSslCertificate::importPKCS12(&f, &key, &cert, &caCerts);
|
||||
|
Loading…
Reference in New Issue
Block a user