diff options
Diffstat (limited to 'src/network/ssl/qasn1element.cpp')
-rw-r--r-- | src/network/ssl/qasn1element.cpp | 391 |
1 files changed, 0 insertions, 391 deletions
diff --git a/src/network/ssl/qasn1element.cpp b/src/network/ssl/qasn1element.cpp deleted file mode 100644 index 65a0e08961..0000000000 --- a/src/network/ssl/qasn1element.cpp +++ /dev/null @@ -1,391 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2014 Jeremy Lainé <jeremy.laine@m4x.org> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtNetwork module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#include "qasn1element_p.h" - -#include <QtCore/qdatastream.h> -#include <QtCore/qdatetime.h> -#include <QtCore/qlist.h> -#include <QDebug> - -#include <limits> - -QT_BEGIN_NAMESPACE - -typedef QMap<QByteArray, QByteArray> OidNameMap; -static OidNameMap createOidMap() -{ - OidNameMap oids; - // used by unit tests - oids.insert(oids.cend(), QByteArrayLiteral("0.9.2342.19200300.100.1.5"), QByteArrayLiteral("favouriteDrink")); - oids.insert(oids.cend(), QByteArrayLiteral("1.2.840.113549.1.9.1"), QByteArrayLiteral("emailAddress")); - oids.insert(oids.cend(), QByteArrayLiteral("1.3.6.1.5.5.7.1.1"), QByteArrayLiteral("authorityInfoAccess")); - oids.insert(oids.cend(), QByteArrayLiteral("1.3.6.1.5.5.7.48.1"), QByteArrayLiteral("OCSP")); - oids.insert(oids.cend(), QByteArrayLiteral("1.3.6.1.5.5.7.48.2"), QByteArrayLiteral("caIssuers")); - oids.insert(oids.cend(), QByteArrayLiteral("2.5.29.14"), QByteArrayLiteral("subjectKeyIdentifier")); - oids.insert(oids.cend(), QByteArrayLiteral("2.5.29.15"), QByteArrayLiteral("keyUsage")); - oids.insert(oids.cend(), QByteArrayLiteral("2.5.29.17"), QByteArrayLiteral("subjectAltName")); - oids.insert(oids.cend(), QByteArrayLiteral("2.5.29.19"), QByteArrayLiteral("basicConstraints")); - oids.insert(oids.cend(), QByteArrayLiteral("2.5.29.35"), QByteArrayLiteral("authorityKeyIdentifier")); - oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.10"), QByteArrayLiteral("O")); - oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.11"), QByteArrayLiteral("OU")); - oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.12"), QByteArrayLiteral("title")); - oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.13"), QByteArrayLiteral("description")); - oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.17"), QByteArrayLiteral("postalCode")); - oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.3"), QByteArrayLiteral("CN")); - oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.4"), QByteArrayLiteral("SN")); - oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.41"), QByteArrayLiteral("name")); - oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.42"), QByteArrayLiteral("GN")); - oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.43"), QByteArrayLiteral("initials")); - oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.46"), QByteArrayLiteral("dnQualifier")); - oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.5"), QByteArrayLiteral("serialNumber")); - oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.6"), QByteArrayLiteral("C")); - oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.7"), QByteArrayLiteral("L")); - oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.8"), QByteArrayLiteral("ST")); - oids.insert(oids.cend(), QByteArrayLiteral("2.5.4.9"), QByteArrayLiteral("street")); - return oids; -} -Q_GLOBAL_STATIC_WITH_ARGS(OidNameMap, oidNameMap, (createOidMap())) - -QAsn1Element::QAsn1Element(quint8 type, const QByteArray &value) - : mType(type) - , mValue(value) -{ -} - -bool QAsn1Element::read(QDataStream &stream) -{ - // type - quint8 tmpType; - stream >> tmpType; - if (!tmpType) - return false; - - // length - quint64 length = 0; - quint8 first; - stream >> first; - if (first & 0x80) { - // long form - const quint8 bytes = (first & 0x7f); - if (bytes > 7) - return false; - - quint8 b; - for (int i = 0; i < bytes; i++) { - stream >> b; - length = (length << 8) | b; - } - } else { - // short form - length = (first & 0x7f); - } - - if (length > quint64(std::numeric_limits<int>::max())) - return false; - // value - QByteArray tmpValue; - tmpValue.resize(length); - int count = stream.readRawData(tmpValue.data(), tmpValue.size()); - if (count != int(length)) - return false; - - mType = tmpType; - mValue.swap(tmpValue); - return true; -} - -bool QAsn1Element::read(const QByteArray &data) -{ - QDataStream stream(data); - return read(stream); -} - -void QAsn1Element::write(QDataStream &stream) const -{ - // type - stream << mType; - - // length - qint64 length = mValue.size(); - if (length >= 128) { - // long form - quint8 encodedLength = 0x80; - QByteArray ba; - while (length) { - ba.prepend(quint8((length & 0xff))); - length >>= 8; - encodedLength += 1; - } - stream << encodedLength; - stream.writeRawData(ba.data(), ba.size()); - } else { - // short form - stream << quint8(length); - } - - // value - stream.writeRawData(mValue.data(), mValue.size()); -} - -QAsn1Element QAsn1Element::fromBool(bool val) -{ - return QAsn1Element(QAsn1Element::BooleanType, - QByteArray(1, val ? 0xff : 0x00)); -} - -QAsn1Element QAsn1Element::fromInteger(unsigned int val) -{ - QAsn1Element elem(QAsn1Element::IntegerType); - while (val > 127) { - elem.mValue.prepend(val & 0xff); - val >>= 8; - } - elem.mValue.prepend(val & 0x7f); - return elem; -} - -QAsn1Element QAsn1Element::fromVector(const QList<QAsn1Element> &items) -{ - QAsn1Element seq; - seq.mType = SequenceType; - QDataStream stream(&seq.mValue, QDataStream::WriteOnly); - for (auto it = items.cbegin(), end = items.cend(); it != end; ++it) - it->write(stream); - return seq; -} - -QAsn1Element QAsn1Element::fromObjectId(const QByteArray &id) -{ - QAsn1Element elem; - elem.mType = ObjectIdentifierType; - const QList<QByteArray> bits = id.split('.'); - Q_ASSERT(bits.size() > 2); - elem.mValue += quint8((bits[0].toUInt() * 40 + bits[1].toUInt())); - for (int i = 2; i < bits.size(); ++i) { - char buffer[std::numeric_limits<unsigned int>::digits / 7 + 2]; - char *pBuffer = buffer + sizeof(buffer); - *--pBuffer = '\0'; - unsigned int node = bits[i].toUInt(); - *--pBuffer = quint8((node & 0x7f)); - node >>= 7; - while (node) { - *--pBuffer = quint8(((node & 0x7f) | 0x80)); - node >>= 7; - } - elem.mValue += pBuffer; - } - return elem; -} - -bool QAsn1Element::toBool(bool *ok) const -{ - if (*this == fromBool(true)) { - if (ok) - *ok = true; - return true; - } else if (*this == fromBool(false)) { - if (ok) - *ok = true; - return false; - } else { - if (ok) - *ok = false; - return false; - } -} - -QDateTime QAsn1Element::toDateTime() const -{ - QDateTime result; - - if (mValue.size() != 13 && mValue.size() != 15) - return result; - - // QDateTime::fromString is lenient and accepts +- signs in front - // of the year; but ASN.1 doesn't allow them. - const auto isAsciiDigit = [](char c) - { - return c >= '0' && c <= '9'; - }; - - if (!isAsciiDigit(mValue[0])) - return result; - - // Timezone must be present, and UTC - if (mValue.back() != 'Z') - return result; - - // In addition, check that we only have digits representing the - // date/time. This should not really be necessary (there's no such - // thing as negative months/days/etc.); it's a workaround for - // QTBUG-84349. - if (!std::all_of(mValue.begin(), mValue.end() - 1, isAsciiDigit)) - return result; - - if (mType == UtcTimeType && mValue.size() == 13) { - result = QDateTime::fromString(QString::fromLatin1(mValue), - QStringLiteral("yyMMddHHmmsst")); - if (!result.isValid()) - return result; - - Q_ASSERT(result.timeSpec() == Qt::UTC); - - QDate date = result.date(); - - // RFC 2459: - // Where YY is greater than or equal to 50, the year shall be - // interpreted as 19YY; and - // - // Where YY is less than 50, the year shall be interpreted as 20YY. - // - // QDateTime interprets the 'yy' format as 19yy, so we may need to adjust - // the year (bring it in the [1950, 2049] range). - if (date.year() < 1950) - result.setDate(date.addYears(100)); - - Q_ASSERT(result.date().year() >= 1950); - Q_ASSERT(result.date().year() <= 2049); - } else if (mType == GeneralizedTimeType && mValue.size() == 15) { - result = QDateTime::fromString(QString::fromLatin1(mValue), - QStringLiteral("yyyyMMddHHmmsst")); - } - - return result; -} - -QMultiMap<QByteArray, QString> QAsn1Element::toInfo() const -{ - QMultiMap<QByteArray, QString> info; - QAsn1Element elem; - QDataStream issuerStream(mValue); - while (elem.read(issuerStream) && elem.mType == QAsn1Element::SetType) { - QAsn1Element issuerElem; - QDataStream setStream(elem.mValue); - if (issuerElem.read(setStream) && issuerElem.mType == QAsn1Element::SequenceType) { - const auto elems = issuerElem.toList(); - if (elems.size() == 2) { - const QByteArray key = elems.front().toObjectName(); - if (!key.isEmpty()) - info.insert(key, elems.back().toString()); - } - } - } - return info; -} - -qint64 QAsn1Element::toInteger(bool *ok) const -{ - if (mType != QAsn1Element::IntegerType || mValue.isEmpty()) { - if (ok) - *ok = false; - return 0; - } - - // NOTE: negative numbers are not handled - if (mValue.at(0) & 0x80) { - if (ok) - *ok = false; - return 0; - } - - qint64 value = mValue.at(0) & 0x7f; - for (int i = 1; i < mValue.size(); ++i) - value = (value << 8) | quint8(mValue.at(i)); - - if (ok) - *ok = true; - return value; -} - -QList<QAsn1Element> QAsn1Element::toList() const -{ - QList<QAsn1Element> items; - if (mType == SequenceType) { - QAsn1Element elem; - QDataStream stream(mValue); - while (elem.read(stream)) - items << elem; - } - return items; -} - -QByteArray QAsn1Element::toObjectId() const -{ - QByteArray key; - if (mType == ObjectIdentifierType && !mValue.isEmpty()) { - quint8 b = mValue.at(0); - key += QByteArray::number(b / 40) + '.' + QByteArray::number (b % 40); - unsigned int val = 0; - for (int i = 1; i < mValue.size(); ++i) { - b = mValue.at(i); - val = (val << 7) | (b & 0x7f); - if (!(b & 0x80)) { - key += '.' + QByteArray::number(val); - val = 0; - } - } - } - return key; -} - -QByteArray QAsn1Element::toObjectName() const -{ - QByteArray key = toObjectId(); - return oidNameMap->value(key, key); -} - -QString QAsn1Element::toString() const -{ - // Detect embedded NULs and reject - if (qstrlen(mValue) < uint(mValue.size())) - return QString(); - - if (mType == PrintableStringType || mType == TeletexStringType - || mType == Rfc822NameType || mType == DnsNameType - || mType == UniformResourceIdentifierType) - return QString::fromLatin1(mValue, mValue.size()); - if (mType == Utf8StringType) - return QString::fromUtf8(mValue, mValue.size()); - - return QString(); -} - -QT_END_NAMESPACE |