10 #include <QLoggingCategory>
11 #include <QSharedPointer>
13 #include <openssl/ec.h>
14 #include <openssl/ecdsa.h>
15 #include <openssl/evp.h>
18 Q_DECLARE_LOGGING_CATEGORY(card)
27 static QByteArray point2oct(
const QSharedPointer<const EC_GROUP>& pCurve,
const EC_POINT* pPoint);
29 static QSharedPointer<EC_POINT> oct2point(
const QSharedPointer<const EC_GROUP>& pCurve,
const QByteArray& pCompressedData);
31 static QSharedPointer<EC_GROUP> create(EC_GROUP* pEcGroup);
33 static QSharedPointer<EC_KEY> create(EC_KEY* pEcKey);
35 static QSharedPointer<EC_POINT> create(EC_POINT* pEcPoint);
37 static QSharedPointer<BIGNUM> create(BIGNUM* pBigNum);
39 static QSharedPointer<ECDSA_SIG> create(ECDSA_SIG* pEcdsaSignature);
43 inline QByteArray EcUtil::point2oct(
const QSharedPointer<const EC_GROUP>& pCurve,
const EC_POINT* pPoint)
45 if (pCurve.isNull() || pPoint ==
nullptr)
47 qCCritical(card) <<
"Invalid input data, cannot encode elliptic curve point";
51 size_t buf_size = EC_POINT_point2oct(pCurve.data(), pPoint, POINT_CONVERSION_UNCOMPRESSED,
nullptr, 0,
nullptr);
55 qCCritical(card) <<
"Cannot encode elliptic curve point";
56 Q_ASSERT(buf_size != 0);
59 if (buf_size > INT_MAX)
61 qCCritical(card) <<
"Cannot encode elliptic curve point";
62 Q_ASSERT(buf_size <= INT_MAX);
66 QVector<uchar> buf(static_cast<int>(buf_size));
67 if (!EC_POINT_point2oct(pCurve.data(), pPoint, POINT_CONVERSION_UNCOMPRESSED, buf.data(), buf_size,
nullptr))
69 qCCritical(card) <<
"Cannot encode elliptic curve point";
73 QByteArray uncompressed(reinterpret_cast<char*>(buf.data()), static_cast<int>(buf_size));
78 inline QSharedPointer<EC_POINT> EcUtil::oct2point(
const QSharedPointer<const EC_GROUP>& pCurve,
const QByteArray& pCompressedData)
80 QSharedPointer<EC_POINT> point = EcUtil::create(EC_POINT_new(pCurve.data()));
81 if (!EC_POINT_oct2point(pCurve.data(), point.data(),
reinterpret_cast<const uchar*
>(pCompressedData.constData()), static_cast<size_t>(pCompressedData.size()),
nullptr))
83 qCCritical(card) <<
"Cannot decode elliptic curve point";
84 return QSharedPointer<EC_POINT>();
86 if (!EC_POINT_is_on_curve(pCurve.data(), point.data(),
nullptr))
88 qCCritical(card) <<
"Decoded point is not on curve";
89 return QSharedPointer<EC_POINT>();
95 inline QSharedPointer<EC_GROUP> EcUtil::create(EC_GROUP* pEcGroup)
97 static auto deleter = [](EC_GROUP* ecCurve)
99 EC_GROUP_clear_free(ecCurve);
102 return QSharedPointer<EC_GROUP>(pEcGroup, deleter);
106 inline QSharedPointer<EC_KEY> EcUtil::create(EC_KEY* pEcKey)
108 static auto deleter = [](EC_KEY* ecKey)
113 return QSharedPointer<EC_KEY>(pEcKey, deleter);
117 inline QSharedPointer<EC_POINT> EcUtil::create(EC_POINT* pEcPoint)
119 static auto deleter = [](EC_POINT* ecPoint)
121 EC_POINT_clear_free(ecPoint);
124 return QSharedPointer<EC_POINT>(pEcPoint, deleter);
128 inline QSharedPointer<BIGNUM> EcUtil::create(BIGNUM* pBigNum)
130 static auto deleter = [](BIGNUM* bigNum)
132 BN_clear_free(bigNum);
135 return QSharedPointer<BIGNUM>(pBigNum, deleter);
139 inline QSharedPointer<ECDSA_SIG> EcUtil::create(ECDSA_SIG* pEcdsaSignature)
141 static auto deleter = [](ECDSA_SIG* ecdsaSignature)
143 ECDSA_SIG_free(ecdsaSignature);
146 return QSharedPointer<ECDSA_SIG>(pEcdsaSignature, deleter);