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_cert.h>
9 #include <botan/oids.h>
10
11 namespace Botan {
12
get_car() const13 ASN1_Car EAC1_1_CVC::get_car() const
14 {
15 return m_car;
16 }
17
get_ced() const18 ASN1_Ced EAC1_1_CVC::get_ced() const
19 {
20 return m_ced;
21 }
get_cex() const22 ASN1_Cex EAC1_1_CVC::get_cex() const
23 {
24 return m_cex;
25 }
get_chat_value() const26 u32bit EAC1_1_CVC::get_chat_value() const
27 {
28 return m_chat_val;
29 }
30
31 /*
32 * Decode the TBSCertificate data
33 */
force_decode()34 void EAC1_1_CVC::force_decode()
35 {
36 SecureVector<byte> enc_pk;
37 SecureVector<byte> enc_chat_val;
38 size_t cpi;
39 BER_Decoder tbs_cert(tbs_bits);
40 tbs_cert.decode(cpi, ASN1_Tag(41), APPLICATION)
41 .decode(m_car)
42 .start_cons(ASN1_Tag(73))
43 .raw_bytes(enc_pk)
44 .end_cons()
45 .decode(m_chr)
46 .start_cons(ASN1_Tag(76))
47 .decode(m_chat_oid)
48 .decode(enc_chat_val, OCTET_STRING, ASN1_Tag(19), APPLICATION)
49 .end_cons()
50 .decode(m_ced)
51 .decode(m_cex)
52 .verify_end();
53
54 if(enc_chat_val.size() != 1)
55 throw Decoding_Error("CertificateHolderAuthorizationValue was not of length 1");
56
57 if(cpi != 0)
58 throw Decoding_Error("EAC1_1 certificate's cpi was not 0");
59
60 m_pk = decode_eac1_1_key(enc_pk, sig_algo);
61
62 m_chat_val = enc_chat_val[0];
63
64 self_signed = (m_car.iso_8859() == m_chr.iso_8859());
65 }
66
67 /*
68 * CVC Certificate Constructor
69 */
EAC1_1_CVC(DataSource & in)70 EAC1_1_CVC::EAC1_1_CVC(DataSource& in)
71 {
72 init(in);
73 self_signed = false;
74 do_decode();
75 }
76
EAC1_1_CVC(const std::string & in)77 EAC1_1_CVC::EAC1_1_CVC(const std::string& in)
78 {
79 DataSource_Stream stream(in, true);
80 init(stream);
81 self_signed = false;
82 do_decode();
83 }
84
operator ==(EAC1_1_CVC const & rhs) const85 bool EAC1_1_CVC::operator==(EAC1_1_CVC const& rhs) const
86 {
87 return (tbs_data() == rhs.tbs_data()
88 && get_concat_sig() == rhs.get_concat_sig());
89 }
90
decode_eac1_1_key(const MemoryRegion<byte> &,AlgorithmIdentifier &)91 ECDSA_PublicKey* decode_eac1_1_key(const MemoryRegion<byte>&,
92 AlgorithmIdentifier&)
93 {
94 throw Internal_Error("decode_eac1_1_key: Unimplemented");
95 return 0;
96 }
97
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)98 EAC1_1_CVC make_cvc_cert(PK_Signer& signer,
99 MemoryRegion<byte> const& public_key,
100 ASN1_Car const& car,
101 ASN1_Chr const& chr,
102 byte holder_auth_templ,
103 ASN1_Ced ced,
104 ASN1_Cex cex,
105 RandomNumberGenerator& rng)
106 {
107 OID chat_oid(OIDS::lookup("CertificateHolderAuthorizationTemplate"));
108 MemoryVector<byte> enc_chat_val;
109 enc_chat_val.push_back(holder_auth_templ);
110
111 MemoryVector<byte> enc_cpi;
112 enc_cpi.push_back(0x00);
113 MemoryVector<byte> tbs = DER_Encoder()
114 .encode(enc_cpi, OCTET_STRING, ASN1_Tag(41), APPLICATION) // cpi
115 .encode(car)
116 .raw_bytes(public_key)
117 .encode(chr)
118 .start_cons(ASN1_Tag(76), APPLICATION)
119 .encode(chat_oid)
120 .encode(enc_chat_val, OCTET_STRING, ASN1_Tag(19), APPLICATION)
121 .end_cons()
122 .encode(ced)
123 .encode(cex)
124 .get_contents();
125
126 MemoryVector<byte> signed_cert =
127 EAC1_1_CVC::make_signed(signer,
128 EAC1_1_CVC::build_cert_body(tbs),
129 rng);
130
131 DataSource_Memory source(signed_cert);
132 return EAC1_1_CVC(source);
133 }
134
135 }
136