QDnsLookup: add support for TLSA records
[ChangeLog][QtNetwork][QDnsLookup] Added support for querying records of type TLSA, which are useful in DNS-based Authentication of Named Entities (DANE). Change-Id: I455fe22ef4ad4b2f9b01fffd17c723aa6ab7f278 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
parent
503fd60988
commit
4503dabfbd
@ -124,6 +124,11 @@
|
|||||||
\title RFC 6724
|
\title RFC 6724
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\externalpage https://datatracker.ietf.org/doc/html/rfc6698
|
||||||
|
\title RFC 6698
|
||||||
|
*/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\externalpage https://datatracker.ietf.org/doc/html/rfc7049
|
\externalpage https://datatracker.ietf.org/doc/html/rfc7049
|
||||||
\title RFC 7049
|
\title RFC 7049
|
||||||
|
@ -257,6 +257,8 @@ static void qt_qdnsservicerecord_sort(QList<QDnsServiceRecord> &records)
|
|||||||
|
|
||||||
\value SRV service records.
|
\value SRV service records.
|
||||||
|
|
||||||
|
\value[since 6.8] TLSA TLS association records.
|
||||||
|
|
||||||
\value TXT text records.
|
\value TXT text records.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -704,6 +706,21 @@ QList<QDnsTextRecord> QDnsLookup::textRecords() const
|
|||||||
return d_func()->reply.textRecords;
|
return d_func()->reply.textRecords;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\since 6.8
|
||||||
|
Returns the list of TLS association records associated with this lookup.
|
||||||
|
|
||||||
|
According to the standards relating to DNS-based Authentication of Named
|
||||||
|
Entities (DANE), this field should be ignored and must not be used for
|
||||||
|
verifying the authentity of a given server if the authenticity of the DNS
|
||||||
|
reply cannot itself be confirmed. See isAuthenticData() for more
|
||||||
|
information.
|
||||||
|
*/
|
||||||
|
QList<QDnsTlsAssociationRecord> QDnsLookup::tlsAssociationRecords() const
|
||||||
|
{
|
||||||
|
return d_func()->reply.tlsAssociationRecords;
|
||||||
|
}
|
||||||
|
|
||||||
#if QT_CONFIG(ssl)
|
#if QT_CONFIG(ssl)
|
||||||
/*!
|
/*!
|
||||||
\since 6.8
|
\since 6.8
|
||||||
@ -1261,6 +1278,223 @@ QDnsTextRecord &QDnsTextRecord::operator=(const QDnsTextRecord &other)
|
|||||||
very fast and never fails.
|
very fast and never fails.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class QDnsTlsAssociationRecord
|
||||||
|
\since 6.8
|
||||||
|
\brief The QDnsTlsAssociationRecord class stores information about a DNS TLSA record.
|
||||||
|
|
||||||
|
\inmodule QtNetwork
|
||||||
|
\ingroup network
|
||||||
|
\ingroup shared
|
||||||
|
|
||||||
|
When performing a text lookup, zero or more records will be returned. Each
|
||||||
|
record is represented by a QDnsTlsAssociationRecord instance.
|
||||||
|
|
||||||
|
The meaning of the fields is defined in \l{RFC 6698}.
|
||||||
|
|
||||||
|
\sa QDnsLookup
|
||||||
|
*/
|
||||||
|
|
||||||
|
QT_DEFINE_QSDP_SPECIALIZATION_DTOR(QDnsTlsAssociationRecordPrivate)
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\enum QDnsTlsAssociationRecord::CertificateUsage
|
||||||
|
|
||||||
|
This enumeration contains valid values for the certificate usage field of
|
||||||
|
TLS Association queries. The following list is up-to-date with \l{RFC 6698}
|
||||||
|
section 2.1.1 and RFC 7218 section 2.1. Please refer to those documents for
|
||||||
|
authoritative instructions on interpreting this enumeration.
|
||||||
|
|
||||||
|
\value CertificateAuthorityConstrait
|
||||||
|
Indicates the record includes an association to a specific Certificate
|
||||||
|
Authority that must be found in the TLS server's certificate chain and
|
||||||
|
must pass PKIX validation.
|
||||||
|
|
||||||
|
\value ServiceCertificateConstraint
|
||||||
|
Indicates the record includes an association to a certificate that must
|
||||||
|
match the end entity certificate provided by the TLS server and must
|
||||||
|
pass PKIX validation.
|
||||||
|
|
||||||
|
\value TrustAnchorAssertion
|
||||||
|
Indicates the record includes an association to a certificate that MUST
|
||||||
|
be used as the ultimate trust anchor to validate the TLS server's
|
||||||
|
certificate and must pass PKIX validation.
|
||||||
|
|
||||||
|
\value DomainIssuedCertificate
|
||||||
|
Indicates the record includes an association to a certificate that must
|
||||||
|
match the end entity certificate provided by the TLS server. PKIX
|
||||||
|
validation is not tested.
|
||||||
|
|
||||||
|
\value PrivateUse
|
||||||
|
No standard meaning applied.
|
||||||
|
|
||||||
|
\value PKIX_TA
|
||||||
|
Alias; mnemonic for Public Key Infrastructure Trust Anchor
|
||||||
|
|
||||||
|
\value PKIX_EE
|
||||||
|
Alias; mnemonic for Public Key Infrastructure End Entity
|
||||||
|
|
||||||
|
\value DANE_TA
|
||||||
|
Alias; mnemonic for DNS-based Authentication of Named Entities Trust Anchor
|
||||||
|
|
||||||
|
\value DANE_EE
|
||||||
|
Alias; mnemonic for DNS-based Authentication of Named Entities End Entity
|
||||||
|
|
||||||
|
\value PrivCert
|
||||||
|
Alias
|
||||||
|
|
||||||
|
Other values are currently reserved, but may be unreserved by future
|
||||||
|
standards. This enumeration can be used for those values even if no
|
||||||
|
enumerator is provided.
|
||||||
|
|
||||||
|
\sa certificateUsage()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\enum QDnsTlsAssociationRecord::Selector
|
||||||
|
|
||||||
|
This enumeration contains valid values for the selector field of TLS
|
||||||
|
Association queries. The following list is up-to-date with \l{RFC 6698}
|
||||||
|
section 2.1.2 and RFC 7218 section 2.2. Please refer to those documents for
|
||||||
|
authoritative instructions on interpreting this enumeration.
|
||||||
|
|
||||||
|
\value FullCertificate
|
||||||
|
Indicates this record refers to the full certificate in its binary
|
||||||
|
structure form.
|
||||||
|
|
||||||
|
\value SubjectPublicKeyInfo
|
||||||
|
Indicates the record refers to the certificate's subject and public
|
||||||
|
key information, in DER-encoded binary structure form.
|
||||||
|
|
||||||
|
\value PrivateUse
|
||||||
|
No standard meaning applied.
|
||||||
|
|
||||||
|
\value Cert
|
||||||
|
Alias
|
||||||
|
|
||||||
|
\value SPKI
|
||||||
|
Alias
|
||||||
|
|
||||||
|
\value PrivSel
|
||||||
|
Alias
|
||||||
|
|
||||||
|
Other values are currently reserved, but may be unreserved by future
|
||||||
|
standards. This enumeration can be used for those values even if no
|
||||||
|
enumerator is provided.
|
||||||
|
|
||||||
|
\sa selector()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\enum QDnsTlsAssociationRecord::MatchingType
|
||||||
|
|
||||||
|
This enumeration contains valid values for the matching type field of TLS
|
||||||
|
Association queries. The following list is up-to-date with \l{RFC 6698}
|
||||||
|
section 2.1.3 and RFC 7218 section 2.3. Please refer to those documents for
|
||||||
|
authoritative instructions on interpreting this enumeration.
|
||||||
|
|
||||||
|
\value Exact
|
||||||
|
Indicates this the certificate or SPKI data is stored verbatim in this
|
||||||
|
record.
|
||||||
|
|
||||||
|
\value Sha256
|
||||||
|
Indicates this a SHA-256 checksum of the the certificate or SPKI data
|
||||||
|
present in this record.
|
||||||
|
|
||||||
|
\value Sha512
|
||||||
|
Indicates this a SHA-512 checksum of the the certificate or SPKI data
|
||||||
|
present in this record.
|
||||||
|
|
||||||
|
\value PrivateUse
|
||||||
|
No standard meaning applied.
|
||||||
|
|
||||||
|
\value PrivMatch
|
||||||
|
Alias
|
||||||
|
|
||||||
|
Other values are currently reserved, but may be unreserved by future
|
||||||
|
standards. This enumeration can be used for those values even if no
|
||||||
|
enumerator is provided.
|
||||||
|
|
||||||
|
\sa matchingType()
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs an empty TLS Association record.
|
||||||
|
*/
|
||||||
|
QDnsTlsAssociationRecord::QDnsTlsAssociationRecord()
|
||||||
|
: d(new QDnsTlsAssociationRecordPrivate)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Constructs a copy of \a other.
|
||||||
|
*/
|
||||||
|
QDnsTlsAssociationRecord::QDnsTlsAssociationRecord(const QDnsTlsAssociationRecord &other) = default;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Moves the content of \a other into this object.
|
||||||
|
*/
|
||||||
|
QDnsTlsAssociationRecord &
|
||||||
|
QDnsTlsAssociationRecord::operator=(const QDnsTlsAssociationRecord &other) = default;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Destroys this TLS Association record object.
|
||||||
|
*/
|
||||||
|
QDnsTlsAssociationRecord::~QDnsTlsAssociationRecord() = default;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the name of this record.
|
||||||
|
*/
|
||||||
|
QString QDnsTlsAssociationRecord::name() const
|
||||||
|
{
|
||||||
|
return d->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the duration in seconds for which this record is valid.
|
||||||
|
*/
|
||||||
|
quint32 QDnsTlsAssociationRecord::timeToLive() const
|
||||||
|
{
|
||||||
|
return d->timeToLive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the certificate usage field for this record.
|
||||||
|
*/
|
||||||
|
QDnsTlsAssociationRecord::CertificateUsage QDnsTlsAssociationRecord::usage() const
|
||||||
|
{
|
||||||
|
return d->usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the selector field for this record.
|
||||||
|
*/
|
||||||
|
QDnsTlsAssociationRecord::Selector QDnsTlsAssociationRecord::selector() const
|
||||||
|
{
|
||||||
|
return d->selector;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the match type field for this record.
|
||||||
|
*/
|
||||||
|
QDnsTlsAssociationRecord::MatchingType QDnsTlsAssociationRecord::matchType() const
|
||||||
|
{
|
||||||
|
return d->matchType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
Returns the binary data field for this record. The interpretation of this
|
||||||
|
binary data depends on the three numeric fields provided by
|
||||||
|
certificateUsage(), selector(), and matchType().
|
||||||
|
|
||||||
|
Do note this is a binary field, even for the checksums, similar to what
|
||||||
|
QCyrptographicHash::result() returns.
|
||||||
|
*/
|
||||||
|
QByteArray QDnsTlsAssociationRecord::value() const
|
||||||
|
{
|
||||||
|
return d->value;
|
||||||
|
}
|
||||||
|
|
||||||
static QDnsLookupRunnable::EncodedLabel encodeLabel(const QString &label)
|
static QDnsLookupRunnable::EncodedLabel encodeLabel(const QString &label)
|
||||||
{
|
{
|
||||||
QDnsLookupRunnable::EncodedLabel::value_type rootDomain = u'.';
|
QDnsLookupRunnable::EncodedLabel::value_type rootDomain = u'.';
|
||||||
|
@ -22,8 +22,11 @@ class QDnsHostAddressRecordPrivate;
|
|||||||
class QDnsMailExchangeRecordPrivate;
|
class QDnsMailExchangeRecordPrivate;
|
||||||
class QDnsServiceRecordPrivate;
|
class QDnsServiceRecordPrivate;
|
||||||
class QDnsTextRecordPrivate;
|
class QDnsTextRecordPrivate;
|
||||||
|
class QDnsTlsAssociationRecordPrivate;
|
||||||
class QSslConfiguration;
|
class QSslConfiguration;
|
||||||
|
|
||||||
|
QT_DECLARE_QSDP_SPECIALIZATION_DTOR(QDnsTlsAssociationRecordPrivate)
|
||||||
|
|
||||||
class Q_NETWORK_EXPORT QDnsDomainNameRecord
|
class Q_NETWORK_EXPORT QDnsDomainNameRecord
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -138,6 +141,78 @@ private:
|
|||||||
|
|
||||||
Q_DECLARE_SHARED(QDnsTextRecord)
|
Q_DECLARE_SHARED(QDnsTextRecord)
|
||||||
|
|
||||||
|
class Q_NETWORK_EXPORT QDnsTlsAssociationRecord
|
||||||
|
{
|
||||||
|
Q_GADGET
|
||||||
|
public:
|
||||||
|
enum class CertificateUsage : quint8 {
|
||||||
|
// https://www.iana.org/assignments/dane-parameters/dane-parameters.xhtml#certificate-usages
|
||||||
|
// RFC 6698
|
||||||
|
CertificateAuthorityConstrait = 0,
|
||||||
|
ServiceCertificateConstraint = 1,
|
||||||
|
TrustAnchorAssertion = 2,
|
||||||
|
DomainIssuedCertificate = 3,
|
||||||
|
PrivateUse = 255,
|
||||||
|
|
||||||
|
// Aliases by RFC 7218
|
||||||
|
PKIX_TA = 0,
|
||||||
|
PKIX_EE = 1,
|
||||||
|
DANE_TA = 2,
|
||||||
|
DANE_EE = 3,
|
||||||
|
PrivCert = 255,
|
||||||
|
};
|
||||||
|
Q_ENUM(CertificateUsage)
|
||||||
|
|
||||||
|
enum class Selector : quint8 {
|
||||||
|
// https://www.iana.org/assignments/dane-parameters/dane-parameters.xhtml#selectors
|
||||||
|
// RFC 6698
|
||||||
|
FullCertificate = 0,
|
||||||
|
SubjectPublicKeyInfo = 1,
|
||||||
|
PrivateUse = 255,
|
||||||
|
|
||||||
|
// Aliases by RFC 7218
|
||||||
|
Cert = FullCertificate,
|
||||||
|
SPKI = SubjectPublicKeyInfo,
|
||||||
|
PrivSel = PrivateUse,
|
||||||
|
};
|
||||||
|
Q_ENUM(Selector)
|
||||||
|
|
||||||
|
enum class MatchingType : quint8 {
|
||||||
|
// https://www.iana.org/assignments/dane-parameters/dane-parameters.xhtml#matching-types
|
||||||
|
// RFC 6698
|
||||||
|
Exact = 0,
|
||||||
|
Sha256 = 1,
|
||||||
|
Sha512 = 2,
|
||||||
|
PrivateUse = 255,
|
||||||
|
PrivMatch = PrivateUse,
|
||||||
|
};
|
||||||
|
Q_ENUM(MatchingType)
|
||||||
|
|
||||||
|
QDnsTlsAssociationRecord();
|
||||||
|
QDnsTlsAssociationRecord(const QDnsTlsAssociationRecord &other);
|
||||||
|
QDnsTlsAssociationRecord(QDnsTlsAssociationRecord &&other)
|
||||||
|
: d(std::move(other.d))
|
||||||
|
{}
|
||||||
|
QDnsTlsAssociationRecord &operator=(QDnsTlsAssociationRecord &&other) noexcept { swap(other); return *this; }
|
||||||
|
QDnsTlsAssociationRecord &operator=(const QDnsTlsAssociationRecord &other);
|
||||||
|
~QDnsTlsAssociationRecord();
|
||||||
|
|
||||||
|
void swap(QDnsTlsAssociationRecord &other) noexcept { d.swap(other.d); }
|
||||||
|
|
||||||
|
QString name() const;
|
||||||
|
quint32 timeToLive() const;
|
||||||
|
CertificateUsage usage() const;
|
||||||
|
Selector selector() const;
|
||||||
|
MatchingType matchType() const;
|
||||||
|
QByteArray value() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QSharedDataPointer<QDnsTlsAssociationRecordPrivate> d;
|
||||||
|
friend class QDnsLookupRunnable;
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_SHARED(QDnsTlsAssociationRecord)
|
||||||
|
|
||||||
class Q_NETWORK_EXPORT QDnsLookup : public QObject
|
class Q_NETWORK_EXPORT QDnsLookup : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -178,6 +253,7 @@ public:
|
|||||||
NS = 2,
|
NS = 2,
|
||||||
PTR = 12,
|
PTR = 12,
|
||||||
SRV = 33,
|
SRV = 33,
|
||||||
|
TLSA = 52,
|
||||||
TXT = 16
|
TXT = 16
|
||||||
};
|
};
|
||||||
Q_ENUM(Type)
|
Q_ENUM(Type)
|
||||||
@ -230,7 +306,7 @@ public:
|
|||||||
QList<QDnsDomainNameRecord> pointerRecords() const;
|
QList<QDnsDomainNameRecord> pointerRecords() const;
|
||||||
QList<QDnsServiceRecord> serviceRecords() const;
|
QList<QDnsServiceRecord> serviceRecords() const;
|
||||||
QList<QDnsTextRecord> textRecords() const;
|
QList<QDnsTextRecord> textRecords() const;
|
||||||
|
QList<QDnsTlsAssociationRecord> tlsAssociationRecords() const;
|
||||||
|
|
||||||
#if QT_CONFIG(ssl)
|
#if QT_CONFIG(ssl)
|
||||||
void setSslConfiguration(const QSslConfiguration &sslConfiguration);
|
void setSslConfiguration(const QSslConfiguration &sslConfiguration);
|
||||||
|
@ -57,6 +57,7 @@ public:
|
|||||||
QList<QDnsDomainNameRecord> nameServerRecords;
|
QList<QDnsDomainNameRecord> nameServerRecords;
|
||||||
QList<QDnsDomainNameRecord> pointerRecords;
|
QList<QDnsDomainNameRecord> pointerRecords;
|
||||||
QList<QDnsServiceRecord> serviceRecords;
|
QList<QDnsServiceRecord> serviceRecords;
|
||||||
|
QList<QDnsTlsAssociationRecord> tlsAssociationRecords;
|
||||||
QList<QDnsTextRecord> textRecords;
|
QList<QDnsTextRecord> textRecords;
|
||||||
|
|
||||||
#if QT_CONFIG(ssl)
|
#if QT_CONFIG(ssl)
|
||||||
@ -296,6 +297,15 @@ public:
|
|||||||
QList<QByteArray> values;
|
QList<QByteArray> values;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class QDnsTlsAssociationRecordPrivate : public QDnsRecordPrivate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QDnsTlsAssociationRecord::CertificateUsage usage;
|
||||||
|
QDnsTlsAssociationRecord::Selector selector;
|
||||||
|
QDnsTlsAssociationRecord::MatchingType matchType;
|
||||||
|
QByteArray value;
|
||||||
|
};
|
||||||
|
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
#endif // QDNSLOOKUP_P_H
|
#endif // QDNSLOOKUP_P_H
|
||||||
|
@ -406,6 +406,23 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
|
|||||||
if (status < 0)
|
if (status < 0)
|
||||||
return reply->makeInvalidReplyError(QDnsLookup::tr("Invalid service record"));
|
return reply->makeInvalidReplyError(QDnsLookup::tr("Invalid service record"));
|
||||||
reply->serviceRecords.append(record);
|
reply->serviceRecords.append(record);
|
||||||
|
} else if (type == QDnsLookup::TLSA) {
|
||||||
|
// https://datatracker.ietf.org/doc/html/rfc6698#section-2.1
|
||||||
|
if (size < 3)
|
||||||
|
return reply->makeInvalidReplyError(QDnsLookup::tr("Invalid TLS association record"));
|
||||||
|
|
||||||
|
const quint8 usage = response[offset];
|
||||||
|
const quint8 selector = response[offset + 1];
|
||||||
|
const quint8 matchType = response[offset + 2];
|
||||||
|
|
||||||
|
QDnsTlsAssociationRecord record;
|
||||||
|
record.d->name = name;
|
||||||
|
record.d->timeToLive = ttl;
|
||||||
|
record.d->usage = QDnsTlsAssociationRecord::CertificateUsage(usage);
|
||||||
|
record.d->selector = QDnsTlsAssociationRecord::Selector(selector);
|
||||||
|
record.d->matchType = QDnsTlsAssociationRecord::MatchingType(matchType);
|
||||||
|
record.d->value.assign(response + offset + 3, response + offset + size);
|
||||||
|
reply->tlsAssociationRecords.append(std::move(record));
|
||||||
} else if (type == QDnsLookup::TXT) {
|
} else if (type == QDnsLookup::TXT) {
|
||||||
QDnsTextRecord record;
|
QDnsTextRecord record;
|
||||||
record.d->name = name;
|
record.d->name = name;
|
||||||
|
@ -224,6 +224,25 @@ void QDnsLookupRunnable::query(QDnsLookupReply *reply)
|
|||||||
record.d->timeToLive = ptr->dwTtl;
|
record.d->timeToLive = ptr->dwTtl;
|
||||||
record.d->weight = ptr->Data.Srv.wWeight;
|
record.d->weight = ptr->Data.Srv.wWeight;
|
||||||
reply->serviceRecords.append(record);
|
reply->serviceRecords.append(record);
|
||||||
|
} else if (ptr->wType == QDnsLookup::TLSA) {
|
||||||
|
// Note: untested, because the DNS_RECORD reply appears to contain
|
||||||
|
// no records relating to TLSA. Maybe WinDNS filters them out of
|
||||||
|
// zones without DNSSEC.
|
||||||
|
QDnsTlsAssociationRecord record;
|
||||||
|
record.d->name = name;
|
||||||
|
record.d->timeToLive = ptr->dwTtl;
|
||||||
|
|
||||||
|
const auto &tlsa = ptr->Data.Tlsa;
|
||||||
|
const quint8 usage = tlsa.bCertUsage;
|
||||||
|
const quint8 selector = tlsa.bSelector;
|
||||||
|
const quint8 matchType = tlsa.bMatchingType;
|
||||||
|
|
||||||
|
record.d->usage = QDnsTlsAssociationRecord::CertificateUsage(usage);
|
||||||
|
record.d->selector = QDnsTlsAssociationRecord::Selector(selector);
|
||||||
|
record.d->matchType = QDnsTlsAssociationRecord::MatchingType(matchType);
|
||||||
|
record.d->value.assign(tlsa.bCertificateAssociationData,
|
||||||
|
tlsa.bCertificateAssociationData + tlsa.bCertificateAssociationDataLength);
|
||||||
|
reply->tlsAssociationRecords.append(std::move(record));
|
||||||
} else if (ptr->wType == QDnsLookup::TXT) {
|
} else if (ptr->wType == QDnsLookup::TXT) {
|
||||||
QDnsTextRecord record;
|
QDnsTextRecord record;
|
||||||
record.d->name = name;
|
record.d->name = name;
|
||||||
|
@ -374,6 +374,14 @@ QStringList tst_QDnsLookup::formatReply(const QDnsLookup *lookup) const
|
|||||||
result.append(std::move(entry));
|
result.append(std::move(entry));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const QDnsTlsAssociationRecord &rr : lookup->tlsAssociationRecords()) {
|
||||||
|
QString entry = u"TLSA %1 %2 %3 %4"_s.arg(int(rr.usage())).arg(int(rr.selector()))
|
||||||
|
.arg(int(rr.matchType())).arg(rr.value().toHex().toUpper());
|
||||||
|
if (rr.name() != domain)
|
||||||
|
entry = "TLSA unexpected label to "_L1 + rr.name();
|
||||||
|
result.append(std::move(entry));
|
||||||
|
}
|
||||||
|
|
||||||
result.sort();
|
result.sort();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -504,6 +512,10 @@ void tst_QDnsLookup::lookup_data()
|
|||||||
"SRV 2 50 7 aaaa-single;"
|
"SRV 2 50 7 aaaa-single;"
|
||||||
"SRV 3 50 7 a-multi";
|
"SRV 3 50 7 a-multi";
|
||||||
|
|
||||||
|
QTest::newRow("tlsa") << QDnsLookup::Type::TLSA << "_25._tcp.multi"
|
||||||
|
<< "TLSA 3 1 1 0123456789ABCDEFFEDCBA9876543210"
|
||||||
|
"0123456789ABCDEFFEDCBA9876543210";
|
||||||
|
|
||||||
QTest::newRow("txt-single") << QDnsLookup::TXT << "txt-single"
|
QTest::newRow("txt-single") << QDnsLookup::TXT << "txt-single"
|
||||||
<< "TXT \"Hello\"";
|
<< "TXT \"Hello\"";
|
||||||
QTest::newRow("txt-multi-onerr") << QDnsLookup::TXT << "txt-multi-onerr"
|
QTest::newRow("txt-multi-onerr") << QDnsLookup::TXT << "txt-multi-onerr"
|
||||||
@ -522,8 +534,12 @@ void tst_QDnsLookup::lookup()
|
|||||||
if (!lookup)
|
if (!lookup)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
QCOMPARE(lookup->error(), QDnsLookup::NoError);
|
#ifdef Q_OS_WIN
|
||||||
|
if (QTest::currentDataTag() == "tlsa"_L1)
|
||||||
|
QSKIP("WinDNS doesn't work properly with TLSA records and we don't know why");
|
||||||
|
#endif
|
||||||
QCOMPARE(lookup->errorString(), QString());
|
QCOMPARE(lookup->errorString(), QString());
|
||||||
|
QCOMPARE(lookup->error(), QDnsLookup::NoError);
|
||||||
QCOMPARE(lookup->type(), type);
|
QCOMPARE(lookup->type(), type);
|
||||||
QCOMPARE(lookup->name(), domainName(domain));
|
QCOMPARE(lookup->name(), domainName(domain));
|
||||||
|
|
||||||
|
@ -37,10 +37,18 @@ static QDnsLookup::Type typeFromString(QString str)
|
|||||||
return QDnsLookup::Type(value);
|
return QDnsLookup::Type(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Enum> [[maybe_unused]] static const char *enumToKey(Enum e)
|
template <typename Enum> QByteArray enumToString(Enum value)
|
||||||
{
|
{
|
||||||
QMetaEnum me = QMetaEnum::fromType<Enum>();
|
QMetaEnum me = QMetaEnum::fromType<Enum>();
|
||||||
return me.valueToKey(int(e));
|
QByteArray keys = me.valueToKeys(int(value));
|
||||||
|
if (keys.isEmpty())
|
||||||
|
return QByteArrayLiteral("<unknown>");
|
||||||
|
|
||||||
|
// return the last one
|
||||||
|
qsizetype idx = keys.lastIndexOf('|');
|
||||||
|
if (idx > 0)
|
||||||
|
return std::move(keys).sliced(idx + 1);
|
||||||
|
return keys;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int showHelp(const char *argv0, int exitcode)
|
static int showHelp(const char *argv0, int exitcode)
|
||||||
@ -113,6 +121,14 @@ static void printAnswers(const QDnsLookup &lookup)
|
|||||||
printf("%s ", qPrintable(QDebug::toString(data)));
|
printf("%s ", qPrintable(QDebug::toString(data)));
|
||||||
puts("");
|
puts("");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const QDnsTlsAssociationRecord &rr : lookup.tlsAssociationRecords()) {
|
||||||
|
printRecordCommon(rr, "TLSA");
|
||||||
|
printf("( %u %u %u ; %s %s %s\n\t%s )\n", quint8(rr.usage()), quint8(rr.selector()),
|
||||||
|
quint8(rr.matchType()), enumToString(rr.usage()).constData(),
|
||||||
|
enumToString(rr.selector()).constData(), enumToString(rr.matchType()).constData(),
|
||||||
|
rr.value().toHex().toUpper().constData());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void printResults(const QDnsLookup &lookup, QElapsedTimer::Duration duration)
|
static void printResults(const QDnsLookup &lookup, QElapsedTimer::Duration duration)
|
||||||
@ -143,7 +159,7 @@ static void printResults(const QDnsLookup &lookup, QElapsedTimer::Duration durat
|
|||||||
#if QT_CONFIG(ssl)
|
#if QT_CONFIG(ssl)
|
||||||
if (lookup.nameserverProtocol() != QDnsLookup::Standard) {
|
if (lookup.nameserverProtocol() != QDnsLookup::Standard) {
|
||||||
if (QSslConfiguration conf = lookup.sslConfiguration(); !conf.isNull()) {
|
if (QSslConfiguration conf = lookup.sslConfiguration(); !conf.isNull()) {
|
||||||
printf(" (%s %s)", enumToKey(conf.sessionProtocol()),
|
printf(" (%s %s)", enumToString(conf.sessionProtocol()).constData(),
|
||||||
qPrintable(conf.sessionCipher().name()));
|
qPrintable(conf.sessionCipher().name()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user