Skip to content

Commit 7b10ad6

Browse files
metsmamrts
authored andcommitted
Move magic enum to local and avoid allocation
WE2-1204, WE2-1057 Signed-off-by: Raul Metsma <raul@metsma.ee>
1 parent 63f99a3 commit 7b10ad6

8 files changed

Lines changed: 339 additions & 210 deletions

File tree

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ add_library(${PROJECT_NAME}
3939
src/electronic-ids/ms-cryptoapi/MsCryptoApiElectronicID.cpp
4040
src/electronic-ids/ms-cryptoapi/MsCryptoApiElectronicID.hpp
4141
>
42+
src/magic_enum/magic_enum.hpp
4243
)
4344

4445
target_include_directories(${PROJECT_NAME}

include/electronic-id/electronic-id.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include <functional>
2828
#include <optional>
29+
#include <set>
2930

3031
namespace electronic_id
3132
{

include/electronic-id/enums.hpp

Lines changed: 49 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424

2525
#include "pcsc-cpp/pcsc-cpp.hpp"
2626

27-
#include <set>
2827
#include <string>
28+
#include <string_view>
2929

3030
namespace electronic_id
3131
{
@@ -35,15 +35,17 @@ class CertificateType
3535
public:
3636
enum CertificateTypeEnum : int8_t { AUTHENTICATION, SIGNING, NONE = -1 };
3737

38-
CertificateType() = default;
39-
constexpr CertificateType(const CertificateTypeEnum _value) : value(_value) {}
38+
constexpr CertificateType() noexcept = default;
39+
constexpr CertificateType(const CertificateTypeEnum _value) noexcept : value(_value) {}
4040

41-
bool isAuthentication() const { return value == AUTHENTICATION; }
41+
constexpr bool isAuthentication() const noexcept { return value == AUTHENTICATION; }
42+
constexpr bool isSigning() const noexcept { return value == SIGNING; }
4243

43-
bool isSigning() const { return value == SIGNING; }
44-
45-
constexpr bool operator==(const CertificateType other) const { return value == other.value; }
46-
operator std::string() const;
44+
constexpr bool operator==(const CertificateType other) const noexcept
45+
{
46+
return value == other.value;
47+
}
48+
operator std::string_view() const noexcept;
4749

4850
private:
4951
CertificateTypeEnum value = NONE;
@@ -66,27 +68,27 @@ class HashAlgorithm
6668
NONE = -1
6769
};
6870

69-
HashAlgorithm() = default;
70-
constexpr HashAlgorithm(const HashAlgorithmEnum _value) : value(_value) {}
71+
constexpr HashAlgorithm() = default;
72+
constexpr HashAlgorithm(const HashAlgorithmEnum _value) noexcept : value(_value) {}
7173
// String conversion constructor.
72-
HashAlgorithm(const std::string&);
74+
explicit HashAlgorithm(const std::string&);
7375

74-
constexpr bool operator==(HashAlgorithmEnum other) const { return value == other; }
75-
constexpr operator HashAlgorithmEnum() const { return value; }
76+
constexpr bool operator==(HashAlgorithmEnum other) const noexcept { return value == other; }
77+
constexpr operator HashAlgorithmEnum() const noexcept { return value; }
7678

77-
operator std::string() const;
79+
operator std::string_view() const noexcept;
7880

79-
constexpr size_t hashByteLength() const
81+
constexpr size_t hashByteLength() const noexcept
8082
{
81-
return size_t(value <= SHA512 ? value / 8 : (value / 10) / 8);
83+
return size_t((value <= SHA512 ? value : (value / 10)) / 8);
8284
}
8385

84-
constexpr bool isSHA2() const
86+
constexpr bool isSHA2() const noexcept
8587
{
8688
return value >= HashAlgorithm::SHA224 && value <= HashAlgorithm::SHA512;
8789
}
8890

89-
constexpr bool isSHA3() const
91+
constexpr bool isSHA3() const noexcept
9092
{
9193
return value >= HashAlgorithm::SHA3_224 && value <= HashAlgorithm::SHA3_512;
9294
}
@@ -136,26 +138,25 @@ class SignatureAlgorithm
136138
NONE = -1
137139
};
138140

139-
constexpr SignatureAlgorithm(const SignatureAlgorithmEnum _value) : value(_value) {}
140-
constexpr SignatureAlgorithm(const SignatureAlgorithmEnum key, const HashAlgorithm hash) :
141+
constexpr SignatureAlgorithm(const SignatureAlgorithmEnum _value) noexcept : value(_value) {}
142+
constexpr SignatureAlgorithm(const SignatureAlgorithmEnum key,
143+
const HashAlgorithm hash) noexcept :
141144
value(SignatureAlgorithmEnum(key | int16_t(hash)))
142145
{
143146
}
144147

145-
constexpr bool operator==(HashAlgorithm other) const
148+
constexpr bool operator==(HashAlgorithm other) const noexcept
146149
{
147150
return other.operator==(operator HashAlgorithm());
148151
}
149-
constexpr bool operator==(SignatureAlgorithmEnum other) const { return value == other; }
150-
151-
constexpr operator HashAlgorithm() const
152+
constexpr operator HashAlgorithm() const noexcept
152153
{
153154
return HashAlgorithm::HashAlgorithmEnum(value & ~(ES | PS | RS));
154155
}
155156

156-
constexpr operator SignatureAlgorithmEnum() const { return value; }
157+
constexpr operator SignatureAlgorithmEnum() const noexcept { return value; }
157158

158-
operator std::string() const;
159+
operator std::string_view() const noexcept;
159160

160161
private:
161162
SignatureAlgorithmEnum value = NONE;
@@ -175,17 +176,16 @@ class JsonWebSignatureAlgorithm
175176
RS256, // RSASSA-PKCS1-v1_5
176177
RS384,
177178
RS512,
178-
NONE = -1
179179
};
180180

181-
constexpr JsonWebSignatureAlgorithm(const JsonWebSignatureAlgorithmEnum _value) : value(_value)
181+
constexpr JsonWebSignatureAlgorithm(const JsonWebSignatureAlgorithmEnum _value) :
182+
value(validate(_value))
182183
{
183184
}
184185

185-
constexpr bool operator==(JsonWebSignatureAlgorithmEnum other) const { return value == other; }
186-
constexpr operator JsonWebSignatureAlgorithmEnum() const { return value; }
186+
constexpr operator JsonWebSignatureAlgorithmEnum() const noexcept { return value; }
187187

188-
operator std::string() const;
188+
operator std::string_view() const noexcept;
189189

190190
constexpr HashAlgorithm hashAlgorithm() const
191191
{
@@ -208,15 +208,31 @@ class JsonWebSignatureAlgorithm
208208
}
209209
}
210210

211-
constexpr bool isRSAWithPKCS1Padding()
211+
constexpr bool isRSAWithPKCS1Padding() const noexcept
212212
{
213213
return value == RS256 || value == RS384 || value == RS512;
214214
}
215215

216216
constexpr size_t hashByteLength() const { return hashAlgorithm().hashByteLength(); }
217217

218218
private:
219-
JsonWebSignatureAlgorithmEnum value = NONE;
219+
static constexpr JsonWebSignatureAlgorithmEnum validate(JsonWebSignatureAlgorithmEnum v)
220+
{
221+
switch (v) {
222+
case ES256:
223+
case ES384:
224+
case ES512:
225+
case PS256:
226+
case PS384:
227+
case PS512:
228+
case RS256:
229+
case RS384:
230+
case RS512:
231+
return v;
232+
}
233+
throw std::logic_error("Invalid JsonWebSignatureAlgorithm value");
234+
}
235+
JsonWebSignatureAlgorithmEnum value;
220236
};
221237

222238
} // namespace electronic_id

lib/libpcsc-cpp/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ add_library(${PROJECT_NAME}
99
include/${PROJECT_NAME}/${PROJECT_NAME}.hpp
1010
include/${PROJECT_NAME}/${PROJECT_NAME}-utils.hpp
1111
include/${PROJECT_NAME}/comp_winscard.hpp
12-
include/magic_enum/magic_enum.hpp
1312
src/Context.hpp
1413
src/SCardCall.hpp
1514
src/SmartCard.cpp

lib/libpcsc-cpp/include/pcsc-cpp/pcsc-cpp-utils.hpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,5 @@ constexpr const char* removeAbsolutePathPrefix(std::string_view filePath)
6969

7070
#define REQUIRE_NON_NULL(val) \
7171
if (!(val)) { \
72-
throw std::logic_error("Null " + std::string(#val) + " in " \
73-
+ pcsc_cpp::removeAbsolutePathPrefix(__FILE__) + ':' \
74-
+ std::to_string(__LINE__) + ':' + __func__); \
72+
THROW(std::logic_error, "Null " #val); \
7573
}

src/electronic-id.cpp

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -209,11 +209,11 @@ const std::vector<MaskedATREntry> MASKED_ATRS = {
209209
constructor<ElectronicID::Type::LuxEID>},
210210
};
211211

212-
const auto SUPPORTED_ALGORITHMS = std::map<std::string, HashAlgorithm> {
213-
{"SHA-224"s, HashAlgorithm::SHA224}, {"SHA-256"s, HashAlgorithm::SHA256},
214-
{"SHA-384"s, HashAlgorithm::SHA384}, {"SHA-512"s, HashAlgorithm::SHA512},
215-
{"SHA3-224"s, HashAlgorithm::SHA3_224}, {"SHA3-256"s, HashAlgorithm::SHA3_256},
216-
{"SHA3-384"s, HashAlgorithm::SHA3_384}, {"SHA3-512"s, HashAlgorithm::SHA3_512},
212+
const auto SUPPORTED_ALGORITHMS = std::map<std::string_view, HashAlgorithm> {
213+
{"SHA-224", HashAlgorithm::SHA224}, {"SHA-256", HashAlgorithm::SHA256},
214+
{"SHA-384", HashAlgorithm::SHA384}, {"SHA-512", HashAlgorithm::SHA512},
215+
{"SHA3-224", HashAlgorithm::SHA3_224}, {"SHA3-256", HashAlgorithm::SHA3_256},
216+
{"SHA3-384", HashAlgorithm::SHA3_384}, {"SHA3-512", HashAlgorithm::SHA3_512},
217217
};
218218

219219
} // namespace
@@ -263,14 +263,14 @@ bool ElectronicID::isSupportedSigningHashAlgorithm(const HashAlgorithm hashAlgo)
263263
}
264264

265265
AutoSelectFailed::AutoSelectFailed(Reason r) :
266-
Error(std::string("Auto-select card failed, reason: ") + std::string(magic_enum::enum_name(r))),
266+
Error(std::string("Auto-select card failed, reason: ").append(magic_enum::enum_name(r))),
267267
_reason(r)
268268
{
269269
}
270270

271271
VerifyPinFailed::VerifyPinFailed(const Status s, const observer_ptr<pcsc_cpp::ResponseApdu> ra,
272272
const int8_t r) :
273-
Error(std::string("Verify PIN failed, status: ") + std::string(magic_enum::enum_name(s))
273+
Error(std::string("Verify PIN failed, status: ").append(magic_enum::enum_name(s))
274274
+ (ra ? ", response: " + *ra : "")),
275275
_status(s), _retries(r)
276276
{
@@ -286,68 +286,71 @@ HashAlgorithm::HashAlgorithm(const std::string& algoName)
286286
value = SUPPORTED_ALGORITHMS.at(algoName);
287287
}
288288

289-
HashAlgorithm::operator std::string() const
289+
HashAlgorithm::operator std::string_view() const noexcept
290290
{
291291
const auto algoNameValuePair =
292292
std::find_if(SUPPORTED_ALGORITHMS.cbegin(), SUPPORTED_ALGORITHMS.cend(),
293293
[this](const auto& pair) { return pair.second == value; });
294-
return algoNameValuePair != SUPPORTED_ALGORITHMS.cend() ? algoNameValuePair->first : "UNKNOWN";
294+
if (algoNameValuePair != SUPPORTED_ALGORITHMS.cend())
295+
return algoNameValuePair->first;
296+
return "UNKNOWN";
295297
}
296298

297299
std::string HashAlgorithm::allSupportedAlgorithmNames()
298300
{
299301
static const auto SUPPORTED_ALGORITHM_NAMES = std::accumulate(
300302
std::next(SUPPORTED_ALGORITHMS.begin()), SUPPORTED_ALGORITHMS.end(),
301303
std::string(SUPPORTED_ALGORITHMS.begin()->first),
302-
[](auto result, const auto& value) { return result + ", "s + std::string(value.first); });
304+
[](auto result, const auto& value) { return (result + ", ").append(value.first); });
303305
return SUPPORTED_ALGORITHM_NAMES;
304306
}
305307

306308
pcsc_cpp::byte_vector HashAlgorithm::rsaOID(const HashAlgorithmEnum hash)
307309
{
308310
switch (hash) {
309-
case HashAlgorithm::SHA224:
311+
using enum HashAlgorithm::HashAlgorithmEnum;
312+
case SHA224:
310313
return {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
311314
0x65, 0x03, 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c};
312-
case HashAlgorithm::SHA256:
315+
case SHA256:
313316
return {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
314317
0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};
315-
case HashAlgorithm::SHA384:
318+
case SHA384:
316319
return {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
317320
0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30};
318-
case HashAlgorithm::SHA512:
321+
case SHA512:
319322
return {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
320323
0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40};
321-
case HashAlgorithm::SHA3_224:
324+
case SHA3_224:
322325
return {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
323326
0x65, 0x03, 0x04, 0x02, 0x07, 0x05, 0x00, 0x04, 0x1c};
324-
case HashAlgorithm::SHA3_256:
327+
case SHA3_256:
325328
return {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
326329
0x65, 0x03, 0x04, 0x02, 0x08, 0x05, 0x00, 0x04, 0x20};
327-
case HashAlgorithm::SHA3_384:
330+
case SHA3_384:
328331
return {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
329332
0x65, 0x03, 0x04, 0x02, 0x09, 0x05, 0x00, 0x04, 0x30};
330-
case HashAlgorithm::SHA3_512:
333+
case SHA3_512:
331334
return {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
332335
0x65, 0x03, 0x04, 0x02, 0x0A, 0x05, 0x00, 0x04, 0x40};
333336
default:
334337
THROW(ArgumentFatalError, "No OID for algorithm " + std::string(HashAlgorithm(hash)));
335338
}
336339
}
337340

338-
CertificateType::operator std::string() const
341+
CertificateType::operator std::string_view() const noexcept
339342
{
340-
return std::string(magic_enum::enum_name(value));
343+
return magic_enum::enum_name(value);
341344
}
342345

343-
JsonWebSignatureAlgorithm::operator std::string() const
346+
JsonWebSignatureAlgorithm::operator std::string_view() const noexcept
344347
{
345-
return std::string(magic_enum::enum_name(value));
348+
return magic_enum::enum_name(value);
346349
}
347350

348-
SignatureAlgorithm::operator std::string() const
351+
SignatureAlgorithm::operator std::string_view() const noexcept
349352
{
350-
return std::string(magic_enum::enum_name(value));
353+
return magic_enum::enum_name(value);
351354
}
352355

353356
} // namespace electronic_id

src/electronic-ids/ms-cryptoapi/MsCryptoApiElectronicID.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ JsonWebSignatureAlgorithm MsCryptoApiElectronicID::authSignatureAlgorithm() cons
3737
byte_vector MsCryptoApiElectronicID::signWithAuthKey(byte_vector&& /* pin */,
3838
const byte_vector& hash) const
3939
{
40-
if (certType != CertificateType::AUTHENTICATION) {
40+
if (!certType.isAuthentication()) {
4141
THROW(WrongCertificateTypeError,
4242
"This electronic ID does not support signing with the authentication key. "
4343
"It contains a "
@@ -59,7 +59,7 @@ ElectronicID::Signature
5959
MsCryptoApiElectronicID::signWithSigningKey(byte_vector&& /* pin */, const byte_vector& hash,
6060
const HashAlgorithm hashAlgo) const
6161
{
62-
if (certType != CertificateType::SIGNING) {
62+
if (!certType.isSigning()) {
6363
THROW(WrongCertificateTypeError,
6464
"This electronic ID does not support signing with the digital signature key. "
6565
"It contains a "

0 commit comments

Comments
 (0)