ssl: add support for ASN.1 boolean values

This adds support for reading and writing ASN.1 boolean
values. It also adds an operator to test two ASN.1 elements
for equality.

Change-Id: I4a22cbf9808533d593fc59d27b63caaf650b1f57
Reviewed-by: Richard J. Moore <rich@kde.org>
bb10
Jeremy Lainé 2014-09-03 10:44:02 +02:00
parent c68ef6d2c0
commit bdb30abcd2
3 changed files with 95 additions and 0 deletions

View File

@ -155,6 +155,12 @@ void QAsn1Element::write(QDataStream &stream) const
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);
@ -199,6 +205,23 @@ QAsn1Element QAsn1Element::fromObjectId(const QByteArray &id)
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
{
if (mValue.endsWith('Z')) {

View File

@ -64,6 +64,7 @@ class Q_AUTOTEST_EXPORT QAsn1Element
public:
enum ElementType {
// universal
BooleanType = 0x01,
IntegerType = 0x02,
BitStringType = 0x03,
OctetStringType = 0x04,
@ -91,10 +92,12 @@ public:
bool read(const QByteArray &data);
void write(QDataStream &data) const;
static QAsn1Element fromBool(bool val);
static QAsn1Element fromInteger(unsigned int val);
static QAsn1Element fromVector(const QVector<QAsn1Element> &items);
static QAsn1Element fromObjectId(const QByteArray &id);
bool toBool(bool *ok = 0) const;
QDateTime toDateTime() const;
QMultiMap<QByteArray, QString> toInfo() const;
qint64 toInteger(bool *ok = 0) const;
@ -106,12 +109,21 @@ public:
quint8 type() const { return mType; }
QByteArray value() const { return mValue; }
friend inline bool operator==(const QAsn1Element &, const QAsn1Element &);
friend inline bool operator!=(const QAsn1Element &, const QAsn1Element &);
private:
quint8 mType;
QByteArray mValue;
};
Q_DECLARE_TYPEINFO(QAsn1Element, Q_MOVABLE_TYPE);
inline bool operator==(const QAsn1Element &e1, const QAsn1Element &e2)
{ return e1.mType == e2.mType && e1.mValue == e2.mValue; }
inline bool operator!=(const QAsn1Element &e1, const QAsn1Element &e2)
{ return e1.mType != e2.mType || e1.mValue != e2.mValue; }
QT_END_NAMESPACE
#endif

View File

@ -49,6 +49,10 @@ class tst_QAsn1Element : public QObject
private slots:
void emptyConstructor();
void equals_data();
void equals();
void toBool_data();
void toBool();
void dateTime_data();
void dateTime();
void integer_data();
@ -68,6 +72,62 @@ void tst_QAsn1Element::emptyConstructor()
QCOMPARE(elem.value(), QByteArray());
}
Q_DECLARE_METATYPE(QAsn1Element)
void tst_QAsn1Element::equals_data()
{
QTest::addColumn<QAsn1Element>("a");
QTest::addColumn<QAsn1Element>("b");
QTest::addColumn<bool>("equals");
QTest::newRow("equal")
<< QAsn1Element(QAsn1Element::BooleanType, QByteArray("\0", 1))
<< QAsn1Element(QAsn1Element::BooleanType, QByteArray("\0", 1))
<< true;
QTest::newRow("different type")
<< QAsn1Element(QAsn1Element::BooleanType, QByteArray("\0", 1))
<< QAsn1Element(QAsn1Element::IntegerType, QByteArray("\0", 1))
<< false;
QTest::newRow("different value")
<< QAsn1Element(QAsn1Element::BooleanType, QByteArray("\0", 1))
<< QAsn1Element(QAsn1Element::BooleanType, QByteArray("\xff", 1))
<< false;
}
void tst_QAsn1Element::equals()
{
QFETCH(QAsn1Element, a);
QFETCH(QAsn1Element, b);
QFETCH(bool, equals);
QCOMPARE(a == b, equals);
QCOMPARE(a != b, !equals);
}
void tst_QAsn1Element::toBool_data()
{
QTest::addColumn<QByteArray>("encoded");
QTest::addColumn<bool>("value");
QTest::addColumn<bool>("valid");
QTest::newRow("bad type") << QByteArray::fromHex("0201ff") << false << false;
QTest::newRow("bad value") << QByteArray::fromHex("010102") << false << false;
QTest::newRow("false") << QByteArray::fromHex("010100") << false << true;
QTest::newRow("true") << QByteArray::fromHex("0101ff") << true << true;
}
void tst_QAsn1Element::toBool()
{
QFETCH(QByteArray, encoded);
QFETCH(bool, value);
QFETCH(bool, valid);
bool ok;
QAsn1Element elem;
QVERIFY(elem.read(encoded));
QCOMPARE(elem.toBool(&ok), value);
QCOMPARE(ok, valid);
}
void tst_QAsn1Element::dateTime_data()
{
QTest::addColumn<QByteArray>("encoded");