Skip to content

Commit 2d2ab20

Browse files
metsmamrts
authored andcommitted
Derive sign and auth algorithms from certificate and add additional BelEID ATR-s
WE2-808 Signed-off-by: Raul Metsma <[email protected]>
1 parent 47d4602 commit 2d2ab20

File tree

9 files changed

+167
-194
lines changed

9 files changed

+167
-194
lines changed

include/electronic-id/electronic-id.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,7 @@ class ElectronicID
4545
LatEID,
4646
LitEID,
4747
HrvEID,
48-
BelEIDV1_7,
49-
BelEIDV1_8,
48+
BelEID,
5049
CzeEID,
5150
#ifdef _WIN32
5251
MsCryptoApiEID,

src/electronic-id.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ constexpr auto constructor(const Reader& reader)
4949
return std::make_unique<T>(reader.connectToCard());
5050
}
5151

52-
template <Pkcs11ElectronicIDType value>
52+
template <ElectronicID::Type value>
5353
constexpr auto constructor(const Reader& /*reader*/)
5454
{
5555
return std::make_unique<Pkcs11ElectronicID>(value);
@@ -84,26 +84,32 @@ const std::map<byte_vector, ElectronicIDConstructor> SUPPORTED_ATRS {
8484
// LitEID
8585
{{0x3B, 0x9D, 0x18, 0x81, 0x31, 0xFC, 0x35, 0x80, 0x31, 0xC0, 0x69,
8686
0x4D, 0x54, 0x43, 0x4F, 0x53, 0x73, 0x02, 0x05, 0x05, 0xD3},
87-
constructor<Pkcs11ElectronicIDType::LitEIDv3>},
87+
constructor<ElectronicID::Type::LitEID>},
8888
// LitEID v2.0
8989
{{0x3B, 0x9D, 0x18, 0x81, 0x31, 0xFC, 0x35, 0x80, 0x31, 0xC0, 0x69,
9090
0x4D, 0x54, 0x43, 0x4F, 0x53, 0x73, 0x02, 0x06, 0x04, 0xD1},
91-
constructor<Pkcs11ElectronicIDType::LitEIDv3>},
91+
constructor<ElectronicID::Type::LitEID>},
9292
// HrvEID
9393
{{0x3b, 0xff, 0x13, 0x00, 0x00, 0x81, 0x31, 0xfe, 0x45, 0x00, 0x31, 0xb9, 0x64,
9494
0x04, 0x44, 0xec, 0xc1, 0x73, 0x94, 0x01, 0x80, 0x82, 0x90, 0x00, 0x12},
95-
constructor<Pkcs11ElectronicIDType::HrvEID>},
96-
// BelEIDV1_7
95+
constructor<ElectronicID::Type::HrvEID>},
96+
// BelEID
9797
{{0x3b, 0x98, 0x13, 0x40, 0x0a, 0xa5, 0x03, 0x01, 0x01, 0x01, 0xad, 0x13, 0x11},
98-
constructor<Pkcs11ElectronicIDType::BelEIDV1_7>},
99-
// BelEIDV1_8
98+
constructor<ElectronicID::Type::BelEID>},
99+
// BelEID
100+
{{0x3B, 0x98, 0x94, 0x40, 0x0A, 0xA5, 0x03, 0x01, 0x01, 0x01, 0xAD, 0x13, 0x10},
101+
constructor<ElectronicID::Type::BelEID>},
102+
// BelEID
103+
{{0x3B, 0x98, 0x94, 0x40, 0xFF, 0xA5, 0x03, 0x01, 0x01, 0x01, 0xAD, 0x13, 0x10},
104+
constructor<ElectronicID::Type::BelEID>},
105+
// BelEID - https://github.com/Fedict/eid-mw/wiki/Applet-1.8
100106
{{0x3b, 0x7f, 0x96, 0x00, 0x00, 0x80, 0x31, 0x80, 0x65, 0xb0,
101107
0x85, 0x04, 0x01, 0x20, 0x12, 0x0f, 0xff, 0x82, 0x90, 0x00},
102-
constructor<Pkcs11ElectronicIDType::BelEIDV1_8>},
108+
constructor<ElectronicID::Type::BelEID>},
103109
// CzeEID
104110
{{0x3b, 0x7e, 0x94, 0x00, 0x00, 0x80, 0x25, 0xd2, 0x03, 0x10, 0x01, 0x00, 0x56, 0x00, 0x00,
105111
0x00, 0x02, 0x02, 0x00},
106-
constructor<Pkcs11ElectronicIDType::CzeEID>},
112+
constructor<ElectronicID::Type::CzeEID>},
107113
};
108114

109115
inline std::string byteVectorToHexString(const byte_vector& bytes)

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

Lines changed: 41 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -21,49 +21,60 @@
2121
*/
2222

2323
#include "MsCryptoApiElectronicID.hpp"
24-
#include "../scope.hpp"
25-
26-
#include <openssl/x509v3.h>
27-
#include <openssl/err.h>
24+
#include "../x509.hpp"
2825

2926
using namespace pcsc_cpp;
3027

31-
namespace
28+
namespace electronic_id
3229
{
3330

34-
using namespace electronic_id;
31+
JsonWebSignatureAlgorithm MsCryptoApiElectronicID::authSignatureAlgorithm() const
32+
{
33+
// TODO: PS256
34+
return getAuthAlgorithmFromCert(certData);
35+
}
3536

36-
JsonWebSignatureAlgorithm getESAlgorithmFromCert(const byte_vector& cert)
37+
byte_vector MsCryptoApiElectronicID::signWithAuthKey(const byte_vector& /* pin */,
38+
const byte_vector& hash) const
3739
{
38-
const unsigned char* certPtr = cert.data();
39-
auto x509 = SCOPE_GUARD(X509, d2i_X509(nullptr, &certPtr, long(cert.size())));
40-
if (!x509) {
41-
THROW(MsCryptoApiError, "Failed to create X509 object from certificate");
40+
if (certType != CertificateType::AUTHENTICATION) {
41+
THROW(WrongCertificateTypeError,
42+
"This electronic ID does not support signing with the authentication key. "
43+
"It contains a "
44+
+ std::string(certType) + " certificate.");
4245
}
4346

44-
EVP_PKEY* key = X509_get0_pubkey(x509.get());
45-
if (EVP_PKEY_base_id(key) != EVP_PKEY_EC) {
46-
THROW(MsCryptoApiError, "EVP_PKEY_base_id() reports non-EC key where EC key expected");
47-
}
47+
validateAuthHashLength(authSignatureAlgorithm(), name(), hash);
4848

49-
auto keyBitLength = EVP_PKEY_bits(key);
50-
switch (keyBitLength) {
51-
case 256:
52-
return JsonWebSignatureAlgorithm::ES256;
53-
case 384:
54-
return JsonWebSignatureAlgorithm::ES384;
55-
case 512:
56-
case 521: // secp521r1
57-
return JsonWebSignatureAlgorithm::ES512;
58-
default:
59-
THROW(MsCryptoApiError,
60-
"EVP_PKEY_bits() returned an unsupported key size: " + std::to_string(keyBitLength));
49+
auto signature = sign(hash, authSignatureAlgorithm().hashAlgorithm());
50+
return std::move(signature.first);
51+
}
52+
53+
const std::set<SignatureAlgorithm>& MsCryptoApiElectronicID::supportedSigningAlgorithms() const
54+
{
55+
return getSignAlgorithmFromCert(certData);
56+
}
57+
58+
ElectronicID::Signature
59+
MsCryptoApiElectronicID::signWithSigningKey(const byte_vector& /* pin */, const byte_vector& hash,
60+
const HashAlgorithm hashAlgo) const
61+
{
62+
if (certType != CertificateType::SIGNING) {
63+
THROW(WrongCertificateTypeError,
64+
"This electronic ID does not support signing with the digital signature key. "
65+
"It contains a "
66+
+ std::string(certType) + " certificate.");
6167
}
68+
69+
validateSigningHash(*this, hashAlgo, hash);
70+
71+
return sign(hash, hashAlgo);
6272
}
6373

64-
ElectronicID::Signature sign(const byte_vector& hash, HashAlgorithm hashAlgo,
65-
const HCRYPTPROV_OR_NCRYPT_KEY_HANDLE key, const bool isRSA)
74+
ElectronicID::Signature MsCryptoApiElectronicID::sign(const byte_vector& hash,
75+
HashAlgorithm hashAlgo) const
6676
{
77+
bool isRSA = signatureAlgo != SignatureAlgorithm::ES;
6778
BCRYPT_PKCS1_PADDING_INFO padInfo {};
6879
switch (hashAlgo) {
6980
case HashAlgorithm::SHA224:
@@ -114,51 +125,7 @@ ElectronicID::Signature sign(const byte_vector& hash, HashAlgorithm hashAlgo,
114125
THROW(MsCryptoApiError, "Signing failed with error: " + std::to_string(err));
115126
}
116127

117-
return {signature,
118-
SignatureAlgorithm {isRSA ? SignatureAlgorithm::RS : SignatureAlgorithm::ES, hashAlgo}};
119-
}
120-
121-
} // namespace
122-
123-
namespace electronic_id
124-
{
125-
126-
JsonWebSignatureAlgorithm MsCryptoApiElectronicID::authSignatureAlgorithm() const
127-
{
128-
// TODO: PS256
129-
return isRSA() ? JsonWebSignatureAlgorithm::RS256 : getESAlgorithmFromCert(certData);
130-
}
131-
132-
byte_vector MsCryptoApiElectronicID::signWithAuthKey(const byte_vector& /* pin */,
133-
const byte_vector& hash) const
134-
{
135-
if (certType != CertificateType::AUTHENTICATION) {
136-
THROW(WrongCertificateTypeError,
137-
"This electronic ID does not support sigining with the authentication key. "
138-
"It contains a "
139-
+ std::string(certType) + " certificate.");
140-
}
141-
142-
validateAuthHashLength(authSignatureAlgorithm(), name(), hash);
143-
144-
const auto signature = sign(hash, authSignatureAlgorithm().hashAlgorithm(), key, isRSA());
145-
return signature.first;
146-
}
147-
148-
ElectronicID::Signature
149-
MsCryptoApiElectronicID::signWithSigningKey(const byte_vector& /* pin */, const byte_vector& hash,
150-
const HashAlgorithm hashAlgo) const
151-
{
152-
if (certType != CertificateType::SIGNING) {
153-
THROW(WrongCertificateTypeError,
154-
"This electronic ID does not support sigining with the digital signature key. "
155-
"It contains a "
156-
+ std::string(certType) + " certificate.");
157-
}
158-
159-
validateSigningHash(*this, hashAlgo, hash);
160-
161-
return sign(hash, hashAlgo, key, isRSA());
128+
return {signature, {signatureAlgo, hashAlgo}};
162129
}
163130

164131
} // namespace electronic_id

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

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424

2525
#include "electronic-id/electronic-id.hpp"
2626
#include "pcsc-cpp/pcsc-cpp-utils.hpp"
27-
#include "../common.hpp"
2827

2928
#include <windows.h>
3029
#include <wincrypt.h>
@@ -35,9 +34,8 @@ namespace electronic_id
3534
class MsCryptoApiElectronicID : public ElectronicID
3635
{
3736
public:
38-
MsCryptoApiElectronicID(PCCERT_CONTEXT certCtx, pcsc_cpp::byte_vector&& cert,
39-
CertificateType cType, bool isRsa, HCRYPTPROV_OR_NCRYPT_KEY_HANDLE k,
40-
bool freeK) :
37+
MsCryptoApiElectronicID(PCCERT_CONTEXT certCtx, byte_vector&& cert, CertificateType cType,
38+
bool isRsa, HCRYPTPROV_OR_NCRYPT_KEY_HANDLE k, bool freeK) :
4139
ElectronicID {std::make_unique<pcsc_cpp::SmartCard>()}, certContext {certCtx},
4240
certData {cert}, certType {cType},
4341
// TODO: SignatureAlgorithm::PS?
@@ -65,7 +63,7 @@ class MsCryptoApiElectronicID : public ElectronicID
6563
// Use the external dialog provided by the CryptoAPI cryptographic service provider.
6664
bool providesExternalPinDialog() const override { return true; }
6765

68-
pcsc_cpp::byte_vector getCertificate(const CertificateType typ) const override
66+
byte_vector getCertificate(const CertificateType typ) const override
6967
{
7068
if (typ != certType) {
7169
THROW(WrongCertificateTypeError,
@@ -86,13 +84,9 @@ class MsCryptoApiElectronicID : public ElectronicID
8684
return {uint8_t(PIN_RETRY_COUNT_PLACEHOLDER), PIN_RETRY_COUNT_PLACEHOLDER};
8785
}
8886

89-
pcsc_cpp::byte_vector signWithAuthKey(const pcsc_cpp::byte_vector& pin,
90-
const pcsc_cpp::byte_vector& hash) const override;
87+
byte_vector signWithAuthKey(const byte_vector& pin, const byte_vector& hash) const override;
9188

92-
const std::set<SignatureAlgorithm>& supportedSigningAlgorithms() const override
93-
{
94-
return isRSA() ? RSA_SIGNATURE_ALGOS() : ELLIPTIC_CURVE_SIGNATURE_ALGOS();
95-
}
89+
const std::set<SignatureAlgorithm>& supportedSigningAlgorithms() const override;
9690

9791
PinMinMaxLength signingPinMinMaxLength() const override
9892
{
@@ -104,8 +98,7 @@ class MsCryptoApiElectronicID : public ElectronicID
10498
return {uint8_t(PIN_RETRY_COUNT_PLACEHOLDER), PIN_RETRY_COUNT_PLACEHOLDER};
10599
}
106100

107-
Signature signWithSigningKey(const pcsc_cpp::byte_vector& pin,
108-
const pcsc_cpp::byte_vector& hash,
101+
Signature signWithSigningKey(const byte_vector& pin, const byte_vector& hash,
109102
const HashAlgorithm hashAlgo) const override;
110103

111104
std::string name() const override
@@ -115,10 +108,10 @@ class MsCryptoApiElectronicID : public ElectronicID
115108
}
116109
Type type() const override { return Type::MsCryptoApiEID; }
117110

118-
bool isRSA() const { return signatureAlgo != SignatureAlgorithm::ES; }
111+
ElectronicID::Signature sign(const byte_vector& hash, HashAlgorithm hashAlgo) const;
119112

120113
PCCERT_CONTEXT certContext;
121-
const pcsc_cpp::byte_vector certData;
114+
const byte_vector certData;
122115
const CertificateType certType;
123116
const SignatureAlgorithm signatureAlgo;
124117
const HCRYPTPROV_OR_NCRYPT_KEY_HANDLE key;

src/electronic-ids/pkcs11/PKCS11CardManager.hpp

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,8 @@
3030

3131
#include "electronic-id/electronic-id.hpp"
3232

33-
#include "../common.hpp"
34-
#include "../scope.hpp"
3533
#include "../x509.hpp"
3634

37-
#include <cstring>
38-
#include <string>
39-
#include <vector>
4035
#include <unordered_map>
4136
#include <algorithm>
4237
#include <filesystem>
@@ -51,11 +46,8 @@
5146

5247
#define C(API, ...) Call(__func__, __FILE__, __LINE__, "C_" #API, fl->C_##API, __VA_ARGS__)
5348

54-
// HANDLE is captured by copy into the lambda, so the auto* function argument is unused,
55-
// it is only required for satisfying std::unique_ptr constructor requirements.
5649
#define SCOPE_GUARD_SESSION(HANDLE, CLOSE) \
57-
std::unique_ptr<decltype(HANDLE), std::function<void(decltype(HANDLE)*)>>( \
58-
&HANDLE, [HANDLE, this](auto*) { C(CLOSE, HANDLE); })
50+
make_unique_ptr(&(HANDLE), [this](auto* h) { C(CLOSE, *h); });
5951

6052
namespace electronic_id
6153
{

0 commit comments

Comments
 (0)