blob: b41b78b2cb1834e725533d84180ba16da16a70b9 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
/*
* EAC1_1 objects
* (C) 2008 Falko Strenzke
* strenzke@flexsecure.de
*
* Distributed under the terms of the Botan license
*/
#ifndef BOTAN_EAC_OBJ_H__
#define BOTAN_EAC_OBJ_H__
#include <botan/pubkey.h>
#include <botan/x509_key.h>
#include <botan/signed_obj.h>
#include <botan/pubkey_enums.h>
#include <botan/pubkey.h>
#include <botan/parsing.h>
#include <botan/pem.h>
#include <botan/oids.h>
#include <botan/look_pk.h>
#include <botan/ecdsa_sig.h>
#include <string>
namespace Botan {
const std::string eac_cvc_emsa("EMSA1_BSI");
/*
* TR03110 v1.1 EAC CV Certificate
*/
template<typename Derived> // CRTP is used enable the call sequence:
class BOTAN_DLL EAC1_1_obj : public EAC_Signed_Object
{
// data members first:
protected:
ECDSA_Signature m_sig;
// member functions here:
public:
/**
* Return the signature as a concatenation of the encoded parts.
* @result the concatenated signature
*/
SecureVector<byte> get_concat_sig() const;
/**
* Verify the signature of this objects.
* @param pub_key the public key to verify the signature with
* @result true if the verification succeeded
*/
virtual bool check_signature(Public_Key& pub_key) const;
protected:
void init(SharedPtrConverter<DataSource> in);
static SecureVector<byte> make_signature(PK_Signer& signer,
const MemoryRegion<byte>& tbs_bits,
RandomNumberGenerator& rng);
virtual ~EAC1_1_obj<Derived>(){}
};
template<typename Derived> SecureVector<byte> EAC1_1_obj<Derived>::get_concat_sig() const
{
return m_sig.get_concatenation();
}
template<typename Derived> SecureVector<byte>
EAC1_1_obj<Derived>::make_signature(PK_Signer& signer,
const MemoryRegion<byte>& tbs_bits,
RandomNumberGenerator& rng)
{
// this is the signature as a der sequence
SecureVector<byte> seq_sig = signer.sign_message(tbs_bits, rng);
ECDSA_Signature sig(decode_seq(seq_sig));
SecureVector<byte> concat_sig(sig.get_concatenation());
return concat_sig;
}
template<typename Derived> void EAC1_1_obj<Derived>::init(SharedPtrConverter<DataSource> in)
{
try
{
Derived::decode_info(in.get_shared(), tbs_bits, m_sig);
}
catch(Decoding_Error)
{
throw Decoding_Error(PEM_label_pref + " decoding failed");
}
}
template<typename Derived>
bool EAC1_1_obj<Derived>::check_signature(Public_Key& pub_key) const
{
try
{
std::vector<std::string> sig_info =
split_on(OIDS::lookup(sig_algo.oid), '/');
if(sig_info.size() != 2 || sig_info[0] != pub_key.algo_name())
{
return false;
}
std::string padding = sig_info[1];
Signature_Format format =
(pub_key.message_parts() >= 2) ? DER_SEQUENCE : IEEE_1363;
if(!dynamic_cast<PK_Verifying_wo_MR_Key*>(&pub_key))
return false;
std::unique_ptr<ECDSA_Signature_Encoder> enc(new ECDSA_Signature_Encoder(&m_sig));
SecureVector<byte> seq_sig = enc->signature_bits();
SecureVector<byte> to_sign = tbs_data();
PK_Verifying_wo_MR_Key& sig_key = dynamic_cast<PK_Verifying_wo_MR_Key&>(pub_key);
std::unique_ptr<PK_Verifier> verifier(get_pk_verifier(sig_key, padding, format));
return verifier->verify_message(to_sign, seq_sig);
}
catch(...)
{
return false;
}
}
}
#endif
|