Botan 1.10.17
cvc_self.cpp
Go to the documentation of this file.
1/*
2 (C) 2007 FlexSecure GmbH
3 2008-2010 Jack Lloyd
4*
5* Distributed under the terms of the Botan license
6*/
7
8#include <botan/cvc_self.h>
9#include <botan/ecc_key.h>
10#include <botan/point_gfp.h>
11#include <botan/time.h>
12#include <botan/oids.h>
13#include <sstream>
14#include <memory>
15
16namespace Botan {
17
18namespace {
19
20/*
21* cvc CHAT values
22*/
23enum CHAT_values{
24 CVCA = 0xC0,
25 DVCA_domestic = 0x80,
26 DVCA_foreign = 0x40,
27 IS = 0x00,
28
29 IRIS = 0x02,
30 FINGERPRINT = 0x01
31};
32
33void encode_eac_bigint(DER_Encoder& der, const BigInt& x, ASN1_Tag tag)
34 {
35 der.encode(BigInt::encode_1363(x, x.bytes()), OCTET_STRING, tag);
36 }
37
38MemoryVector<byte> eac_1_1_encoding(const EC_PublicKey* key,
39 const OID& sig_algo)
40 {
41 if(key->domain_format() == EC_DOMPAR_ENC_OID)
42 throw Encoding_Error("CVC encoder: cannot encode parameters by OID");
43
44 const EC_Group& domain = key->domain();
45
46 // This is why we can't have nice things
47
48 DER_Encoder enc;
50 .encode(sig_algo);
51
52 if(key->domain_format() == EC_DOMPAR_ENC_EXPLICIT)
53 {
54 encode_eac_bigint(enc, domain.get_curve().get_p(), ASN1_Tag(1));
55 encode_eac_bigint(enc, domain.get_curve().get_a(), ASN1_Tag(2));
56 encode_eac_bigint(enc, domain.get_curve().get_b(), ASN1_Tag(3));
57
58 enc.encode(EC2OSP(domain.get_base_point(), PointGFp::UNCOMPRESSED),
60
61 encode_eac_bigint(enc, domain.get_order(), ASN1_Tag(4));
62 }
63
64 enc.encode(EC2OSP(key->public_point(), PointGFp::UNCOMPRESSED),
66
67 if(key->domain_format() == EC_DOMPAR_ENC_EXPLICIT)
68 encode_eac_bigint(enc, domain.get_cofactor(), ASN1_Tag(7));
69
70 enc.end_cons();
71
72 return enc.get_contents();
73 }
74
75std::string padding_and_hash_from_oid(OID const& oid)
76 {
77 std::string padding_and_hash = OIDS::lookup(oid); // use the hash
78
79 if(padding_and_hash.substr(0,6) != "ECDSA/")
80 throw Invalid_State("CVC: Can only use ECDSA, not " + padding_and_hash);
81
82 padding_and_hash.erase(0, padding_and_hash.find("/") + 1);
83 return padding_and_hash;
84 }
85
86}
87
88namespace CVC_EAC {
89
91 EAC1_1_CVC_Options const& opt,
93 {
94 // NOTE: we ignore the value of opt.chr
95
96 const ECDSA_PrivateKey* priv_key = dynamic_cast<const ECDSA_PrivateKey*>(&key);
97
98 if(priv_key == 0)
99 throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type");
100
101 ASN1_Chr chr(opt.car.value());
102
103 AlgorithmIdentifier sig_algo;
104 std::string padding_and_hash("EMSA1_BSI(" + opt.hash_alg + ")");
105 sig_algo.oid = OIDS::lookup(priv_key->algo_name() + "/" + padding_and_hash);
107
108 PK_Signer signer(*priv_key, padding_and_hash);
109
110 MemoryVector<byte> enc_public_key = eac_1_1_encoding(priv_key, sig_algo.oid);
111
112 return make_cvc_cert(signer,
113 enc_public_key,
114 opt.car, chr,
116 opt.ced, opt.cex, rng);
117 }
118
120 ASN1_Chr const& chr,
121 std::string const& hash_alg,
123 {
124
125 ECDSA_PrivateKey const* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&key);
126 if (priv_key == 0)
127 {
128 throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type");
129 }
130 AlgorithmIdentifier sig_algo;
131 std::string padding_and_hash("EMSA1_BSI(" + hash_alg + ")");
132 sig_algo.oid = OIDS::lookup(priv_key->algo_name() + "/" + padding_and_hash);
134
135 PK_Signer signer(*priv_key, padding_and_hash);
136
137 MemoryVector<byte> enc_public_key = eac_1_1_encoding(priv_key, sig_algo.oid);
138
139 MemoryVector<byte> enc_cpi;
140 enc_cpi.push_back(0x00);
142 .encode(enc_cpi, OCTET_STRING, ASN1_Tag(41), APPLICATION)
143 .raw_bytes(enc_public_key)
144 .encode(chr)
145 .get_contents();
146
147 MemoryVector<byte> signed_cert =
150 rng);
151
152 DataSource_Memory source(signed_cert);
153 return EAC1_1_Req(source);
154 }
155
157 EAC1_1_Req const& req,
158 ASN1_Car const& car,
160 {
161
162 ECDSA_PrivateKey const* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&key);
163 if (priv_key == 0)
164 {
165 throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type");
166 }
167 std::string padding_and_hash = padding_and_hash_from_oid(req.signature_algorithm().oid);
168 PK_Signer signer(*priv_key, padding_and_hash);
169 SecureVector<byte> tbs_bits = req.BER_encode();
170 tbs_bits += DER_Encoder().encode(car).get_contents();
171
172 MemoryVector<byte> signed_cert =
173 EAC1_1_ADO::make_signed(signer, tbs_bits, rng);
174
175 DataSource_Memory source(signed_cert);
176 return EAC1_1_ADO(source);
177 }
178
179} // namespace CVC_EAC
180namespace DE_EAC
181{
182
184 std::string const& hash,
185 ASN1_Car const& car, bool iris, bool fingerpr,
186 u32bit cvca_validity_months,
188 {
189 ECDSA_PrivateKey const* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&key);
190 if (priv_key == 0)
191 {
192 throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type");
193 }
195 opts.car = car;
196 const u64bit current_time = system_time();
197
198 opts.ced = ASN1_Ced(current_time);
199 opts.cex = ASN1_Cex(opts.ced);
200 opts.cex.add_months(cvca_validity_months);
201 opts.holder_auth_templ = (CVCA | (iris * IRIS) | (fingerpr * FINGERPRINT));
202 opts.hash_alg = hash;
203 return CVC_EAC::create_self_signed_cert(*priv_key, opts, rng);
204 }
205
206
207
209 Private_Key const& key,
210 EAC1_1_CVC const& signee,
212 {
213 ECDSA_PrivateKey const* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&key);
214 if (priv_key == 0)
215 {
216 throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type");
217 }
218 ASN1_Ced ced(system_time());
219 ASN1_Cex cex(signee.get_cex());
220 if (*static_cast<EAC_Time*>(&ced) > *static_cast<EAC_Time*>(&cex))
221 {
222 std::string detail("link_cvca(): validity periods of provided certificates don't overlap: currend time = ced = ");
223 detail += ced.as_string();
224 detail += ", signee.cex = ";
225 detail += cex.as_string();
226 throw Invalid_Argument(detail);
227 }
228 if (signer.signature_algorithm() != signee.signature_algorithm())
229 {
230 throw Invalid_Argument("link_cvca(): signature algorithms of signer and signee don't match");
231 }
232 AlgorithmIdentifier sig_algo = signer.signature_algorithm();
233 std::string padding_and_hash = padding_and_hash_from_oid(sig_algo.oid);
234 PK_Signer pk_signer(*priv_key, padding_and_hash);
235 std::auto_ptr<Public_Key> pk(signee.subject_public_key());
236 ECDSA_PublicKey* subj_pk = dynamic_cast<ECDSA_PublicKey*>(pk.get());
238
239 MemoryVector<byte> enc_public_key = eac_1_1_encoding(priv_key, sig_algo.oid);
240
241 return make_cvc_cert(pk_signer, enc_public_key,
242 signer.get_car(),
243 signee.get_chr(),
244 signer.get_chat_value(),
245 ced, cex,
246 rng);
247 }
248
250 Private_Key const& key,
251 EAC1_1_Req const& signee,
252 u32bit seqnr,
253 u32bit seqnr_len,
254 bool domestic,
255 u32bit dvca_validity_months,
256 u32bit ca_is_validity_months,
258 {
259 ECDSA_PrivateKey const* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&key);
260 if (priv_key == 0)
261 {
262 throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type");
263 }
264 std::string chr_str = signee.get_chr().value();
265 chr_str += to_string(seqnr, seqnr_len);
266 ASN1_Chr chr(chr_str);
267 std::string padding_and_hash = padding_and_hash_from_oid(signee.signature_algorithm().oid);
268 PK_Signer pk_signer(*priv_key, padding_and_hash);
269 std::auto_ptr<Public_Key> pk(signee.subject_public_key());
270 ECDSA_PublicKey* subj_pk = dynamic_cast<ECDSA_PublicKey*>(pk.get());
271 std::auto_ptr<Public_Key> signer_pk(signer_cert.subject_public_key());
272
273 // for the case that the domain parameters are not set...
274 // (we use those from the signer because they must fit)
275 //subj_pk->set_domain_parameters(priv_key->domain_parameters());
276
278
279 AlgorithmIdentifier sig_algo(signer_cert.signature_algorithm());
280 const u64bit current_time = system_time();
281 ASN1_Ced ced(current_time);
282 u32bit chat_val;
283 u32bit chat_low = signer_cert.get_chat_value() & 0x3; // take the chat rights from signer
284 ASN1_Cex cex(ced);
285 if ((signer_cert.get_chat_value() & CVCA) == CVCA)
286 {
287 // we sign a dvca
288 cex.add_months(dvca_validity_months);
289 if (domestic)
290 chat_val = DVCA_domestic | chat_low;
291 else
292 chat_val = DVCA_foreign | chat_low;
293 }
294 else if ((signer_cert.get_chat_value() & DVCA_domestic) == DVCA_domestic ||
295 (signer_cert.get_chat_value() & DVCA_foreign) == DVCA_foreign)
296 {
297 cex.add_months(ca_is_validity_months);
298 chat_val = IS | chat_low;
299 }
300 else
301 {
302 throw Invalid_Argument("sign_request(): encountered illegal value for CHAT");
303 // (IS cannot sign certificates)
304 }
305
306 MemoryVector<byte> enc_public_key = eac_1_1_encoding(priv_key, sig_algo.oid);
307
308 return make_cvc_cert(pk_signer, enc_public_key,
309 ASN1_Car(signer_cert.get_chr().iso_8859()),
310 chr,
311 chat_val,
312 ced,
313 cex,
314 rng);
315 }
316
318 ASN1_Chr const& chr,
319 std::string const& hash_alg,
321 {
322 ECDSA_PrivateKey const* priv_key = dynamic_cast<ECDSA_PrivateKey const*>(&prkey);
323 if (priv_key == 0)
324 {
325 throw Invalid_Argument("CVC_EAC::create_self_signed_cert(): unsupported key type");
326 }
327 ECDSA_PrivateKey key(*priv_key);
329 return CVC_EAC::create_cvc_req(key, chr, hash_alg, rng);
330 }
331
332} // namespace DE_EAC
333
334}
ASN1_Car(std::string const &str="")
ASN1_Ced(std::string const &str="")
ASN1_Cex(std::string const &str="")
std::string iso_8859() const
std::string value() const
static SecureVector< byte > encode_1363(const BigInt &n, size_t bytes)
Definition big_code.cpp:78
DER_Encoder & start_cons(ASN1_Tag type_tag, ASN1_Tag class_tag=UNIVERSAL)
Definition der_enc.cpp:135
DER_Encoder & raw_bytes(const byte val[], size_t len)
Definition der_enc.cpp:188
SecureVector< byte > get_contents()
Definition der_enc.cpp:122
DER_Encoder & encode(bool b)
Definition der_enc.cpp:209
EAC1_1_ADO(const std::string &str)
Definition cvc_ado.cpp:20
static MemoryVector< byte > make_signed(PK_Signer &signer, const MemoryRegion< byte > &tbs_bits, RandomNumberGenerator &rng)
Definition cvc_ado.cpp:48
ASN1_Cex get_cex() const
Definition cvc_cert.cpp:22
u32bit get_chat_value() const
Definition cvc_cert.cpp:26
ASN1_Car get_car() const
Definition cvc_cert.cpp:13
EAC1_1_Req(DataSource &source)
Definition cvc_req.cpp:38
static SecureVector< byte > build_cert_body(MemoryRegion< byte > const &tbs)
Public_Key * subject_public_key() const
ASN1_Chr get_chr() const
static MemoryVector< byte > make_signed(PK_Signer &signer, const MemoryRegion< byte > &tbs_bits, RandomNumberGenerator &rng)
AlgorithmIdentifier signature_algorithm() const
SecureVector< byte > BER_encode() const
std::string as_string() const
void add_months(u32bit months)
std::string algo_name() const
Definition ecdsa.h:43
void set_parameter_encoding(EC_Group_Encoding enc)
Definition ecc_key.cpp:55
void push_back(T x)
Definition secmem.h:149
EAC1_1_CVC create_self_signed_cert(Private_Key const &key, EAC1_1_CVC_Options const &opt, RandomNumberGenerator &rng)
Definition cvc_self.cpp:90
EAC1_1_ADO create_ado_req(Private_Key const &key, EAC1_1_Req const &req, ASN1_Car const &car, RandomNumberGenerator &rng)
Definition cvc_self.cpp:156
EAC1_1_Req create_cvc_req(Private_Key const &key, ASN1_Chr const &chr, std::string const &hash_alg, RandomNumberGenerator &rng)
Definition cvc_self.cpp:119
EAC1_1_CVC link_cvca(EAC1_1_CVC const &signer, Private_Key const &key, EAC1_1_CVC const &signee, RandomNumberGenerator &rng)
Definition cvc_self.cpp:208
EAC1_1_CVC create_cvca(Private_Key const &key, std::string const &hash, ASN1_Car const &car, bool iris, bool fingerpr, u32bit cvca_validity_months, RandomNumberGenerator &rng)
Definition cvc_self.cpp:183
EAC1_1_CVC sign_request(EAC1_1_CVC const &signer_cert, Private_Key const &key, EAC1_1_Req const &signee, u32bit seqnr, u32bit seqnr_len, bool domestic, u32bit dvca_validity_months, u32bit ca_is_validity_months, RandomNumberGenerator &rng)
Definition cvc_self.cpp:249
EAC1_1_Req create_cvc_req(Private_Key const &prkey, ASN1_Chr const &chr, std::string const &hash_alg, RandomNumberGenerator &rng)
Definition cvc_self.cpp:317
std::string lookup(const OID &oid)
Definition oids.cpp:31
unsigned long long u64bit
Definition types.h:49
std::string to_string(u64bit n, size_t min_len)
Definition parsing.cpp:42
u64bit system_time()
Definition time.cpp:73
std::invalid_argument Invalid_Argument
Definition exceptn.h:20
ASN1_Tag
Definition asn1_int.h:19
@ APPLICATION
Definition asn1_int.h:21
@ OCTET_STRING
Definition asn1_int.h:31
unsigned int u32bit
Definition types.h:32
@ EC_DOMPAR_ENC_EXPLICIT
Definition ec_group.h:23
@ EC_DOMPAR_ENC_OID
Definition ec_group.h:25
@ EC_DOMPAR_ENC_IMPLICITCA
Definition ec_group.h:24
SecureVector< byte > EC2OSP(const PointGFp &point, byte format)
EAC1_1_CVC make_cvc_cert(PK_Signer &signer, MemoryRegion< byte > const &public_key, ASN1_Car const &car, ASN1_Chr const &chr, byte holder_auth_templ, ASN1_Ced ced, ASN1_Cex cex, RandomNumberGenerator &rng)
Definition cvc_cert.cpp:98
Encoding_Error(const std::string &name)
Definition exceptn.h:131
Invalid_State(const std::string &err)
Definition exceptn.h:27