AusweisApp2
EcUtil.h
gehe zur Dokumentation dieser Datei
1 
7 #pragma once
8 
9 #include <QByteArray>
10 #include <QLoggingCategory>
11 #include <QSharedPointer>
12 
13 #include <openssl/bn.h>
14 #include <openssl/ec.h>
15 #include <openssl/ecdsa.h>
16 #include <openssl/evp.h>
17 
18 
19 Q_DECLARE_LOGGING_CATEGORY(card)
20 
21 
22 namespace governikus
23 {
24 
25 class EcUtil
26 {
27  public:
28  static QByteArray point2oct(const QSharedPointer<const EC_GROUP>& pCurve, const EC_POINT* pPoint);
29 
30  static QSharedPointer<EC_POINT> oct2point(const QSharedPointer<const EC_GROUP>& pCurve, const QByteArray& pCompressedData);
31 
32  static QSharedPointer<EC_GROUP> create(EC_GROUP* pEcGroup);
33 
34  static QSharedPointer<EC_KEY> create(EC_KEY* pEcKey);
35 
36  static QSharedPointer<EC_POINT> create(EC_POINT* pEcPoint);
37 
38  static QSharedPointer<BIGNUM> create(BIGNUM* pBigNum);
39 
40  static QSharedPointer<ECDSA_SIG> create(ECDSA_SIG* pEcdsaSignature);
41 
42  static QSharedPointer<EVP_PKEY> create(EVP_PKEY* pEcGroup);
43 
44  static QSharedPointer<EVP_PKEY_CTX> create(EVP_PKEY_CTX* pEcGroup);
45 };
46 
47 inline QByteArray EcUtil::point2oct(const QSharedPointer<const EC_GROUP>& pCurve, const EC_POINT* pPoint)
48 {
49  if (pCurve.isNull() || pPoint == nullptr)
50  {
51  qCCritical(card) << "Invalid input data, cannot encode elliptic curve point";
52  return QByteArray();
53  }
54 
55  size_t buf_size = EC_POINT_point2oct(pCurve.data(), pPoint, POINT_CONVERSION_UNCOMPRESSED, nullptr, 0, nullptr);
56 
57  if (buf_size == 0)
58  {
59  qCCritical(card) << "Cannot encode elliptic curve point";
60  Q_ASSERT(buf_size != 0);
61  return QByteArray();
62  }
63  if (buf_size > INT_MAX)
64  {
65  qCCritical(card) << "Cannot encode elliptic curve point";
66  Q_ASSERT(buf_size <= INT_MAX);
67  return QByteArray();
68  }
69 
70  QVector<uchar> buf(static_cast<int>(buf_size));
71  if (!EC_POINT_point2oct(pCurve.data(), pPoint, POINT_CONVERSION_UNCOMPRESSED, buf.data(), buf_size, nullptr))
72  {
73  qCCritical(card) << "Cannot encode elliptic curve point";
74  return QByteArray();
75  }
76 
77  QByteArray uncompressed(reinterpret_cast<char*>(buf.data()), static_cast<int>(buf_size));
78  return uncompressed;
79 }
80 
81 
82 inline QSharedPointer<EC_POINT> EcUtil::oct2point(const QSharedPointer<const EC_GROUP>& pCurve, const QByteArray& pCompressedData)
83 {
84  QSharedPointer<EC_POINT> point = EcUtil::create(EC_POINT_new(pCurve.data()));
85  if (!EC_POINT_oct2point(pCurve.data(), point.data(), reinterpret_cast<const uchar*>(pCompressedData.constData()), static_cast<size_t>(pCompressedData.size()), nullptr))
86  {
87  qCCritical(card) << "Cannot decode elliptic curve point";
88  return QSharedPointer<EC_POINT>();
89  }
90  if (!EC_POINT_is_on_curve(pCurve.data(), point.data(), nullptr))
91  {
92  qCCritical(card) << "Decoded point is not on curve";
93  return QSharedPointer<EC_POINT>();
94  }
95  return point;
96 }
97 
98 
99 inline QSharedPointer<EC_GROUP> EcUtil::create(EC_GROUP* pEcGroup)
100 {
101  static auto deleter = [](EC_GROUP* ecCurve)
102  {
103  EC_GROUP_free(ecCurve);
104  };
105 
106  return QSharedPointer<EC_GROUP>(pEcGroup, deleter);
107 }
108 
109 
110 inline QSharedPointer<EC_KEY> EcUtil::create(EC_KEY* pEcKey)
111 {
112  static auto deleter = [](EC_KEY* ecKey)
113  {
114  EC_KEY_free(ecKey);
115  };
116 
117  return QSharedPointer<EC_KEY>(pEcKey, deleter);
118 }
119 
120 
121 inline QSharedPointer<EC_POINT> EcUtil::create(EC_POINT* pEcPoint)
122 {
123  static auto deleter = [](EC_POINT* ecPoint)
124  {
125  EC_POINT_clear_free(ecPoint);
126  };
127 
128  return QSharedPointer<EC_POINT>(pEcPoint, deleter);
129 }
130 
131 
132 inline QSharedPointer<BIGNUM> EcUtil::create(BIGNUM* pBigNum)
133 {
134  static auto deleter = [](BIGNUM* bigNum)
135  {
136  BN_clear_free(bigNum);
137  };
138 
139  return QSharedPointer<BIGNUM>(pBigNum, deleter);
140 }
141 
142 
143 inline QSharedPointer<ECDSA_SIG> EcUtil::create(ECDSA_SIG* pEcdsaSignature)
144 {
145  static auto deleter = [](ECDSA_SIG* ecdsaSignature)
146  {
147  ECDSA_SIG_free(ecdsaSignature);
148  };
149 
150  return QSharedPointer<ECDSA_SIG>(pEcdsaSignature, deleter);
151 }
152 
153 
154 inline QSharedPointer<EVP_PKEY> EcUtil::create(EVP_PKEY* pKey)
155 {
156  static auto deleter = [](EVP_PKEY* key)
157  {
158  EVP_PKEY_free(key);
159  };
160 
161  return QSharedPointer<EVP_PKEY>(pKey, deleter);
162 }
163 
164 
165 inline QSharedPointer<EVP_PKEY_CTX> EcUtil::create(EVP_PKEY_CTX* pCtx)
166 {
167  static auto deleter = [](EVP_PKEY_CTX* ctx)
168  {
169  EVP_PKEY_CTX_free(ctx);
170  };
171 
172  return QSharedPointer<EVP_PKEY_CTX>(pCtx, deleter);
173 }
174 
175 
176 } // namespace governikus
governikus::EcUtil::point2oct
static QByteArray point2oct(const QSharedPointer< const EC_GROUP > &pCurve, const EC_POINT *pPoint)
Definition: EcUtil.h:47
governikus::EcUtil::oct2point
static QSharedPointer< EC_POINT > oct2point(const QSharedPointer< const EC_GROUP > &pCurve, const QByteArray &pCompressedData)
Definition: EcUtil.h:82
governikus::EcUtil
Definition: EcUtil.h:26
governikus
Implementation of ActivationContext for Intent based activation on Android systems.
Definition: ActivationContext.h:15
governikus::EcUtil::create
static QSharedPointer< EC_GROUP > create(EC_GROUP *pEcGroup)
Definition: EcUtil.h:99