Skip to content

Commit

Permalink
ssl: add support for ASN.1 boolean values
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
jlaine committed Sep 3, 2014
1 parent c68ef6d commit bdb30ab
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 0 deletions.
23 changes: 23 additions & 0 deletions src/network/ssl/qasn1element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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')) {
Expand Down
12 changes: 12 additions & 0 deletions src/network/ssl/qasn1element_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class Q_AUTOTEST_EXPORT QAsn1Element
public:
enum ElementType {
// universal
BooleanType = 0x01,
IntegerType = 0x02,
BitStringType = 0x03,
OctetStringType = 0x04,
Expand Down Expand Up @@ -91,10 +92,12 @@ class Q_AUTOTEST_EXPORT QAsn1Element
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;
Expand All @@ -106,12 +109,21 @@ class Q_AUTOTEST_EXPORT QAsn1Element
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
60 changes: 60 additions & 0 deletions tests/auto/network/ssl/qasn1element/tst_qasn1element.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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");
Expand Down

0 comments on commit bdb30ab

Please sign in to comment.