Botan 2.1.0 Crypto and TLS for C++11

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

msg_cert_req.cpp
Go to the documentation of this file.
1 /*
2 * Certificate Request Message
3 * (C) 2004-2006,2012 Jack Lloyd
4 *
5 * Botan is released under the Simplified BSD License (see license.txt)
6 */
7
8 #include <botan/tls_messages.h>
9 #include <botan/tls_extensions.h>
10 #include <botan/internal/tls_reader.h>
11 #include <botan/internal/tls_handshake_io.h>
12 #include <botan/internal/tls_handshake_hash.h>
13 #include <botan/der_enc.h>
14 #include <botan/ber_dec.h>
15 #include <botan/loadstor.h>
16
17 namespace Botan {
18
19 namespace TLS {
20
21 namespace {
22
23 std::string cert_type_code_to_name(uint8_t code)
24 {
25 switch(code)
26 {
27 case 1:
28 return "RSA";
29 case 2:
30 return "DSA";
31 case 64:
32 return "ECDSA";
33 default:
34 return ""; // DH or something else
35 }
36 }
37
38 uint8_t cert_type_name_to_code(const std::string& name)
39 {
40 if(name == "RSA")
41 return 1;
42 if(name == "DSA")
43 return 2;
44 if(name == "ECDSA")
45 return 64;
46
47 throw Invalid_Argument("Unknown cert type " + name);
48 }
49
50 }
51
52 /**
53 * Create a new Certificate Request message
54 */
55 Certificate_Req::Certificate_Req(Handshake_IO& io,
56 Handshake_Hash& hash,
57 const Policy& policy,
58 const std::vector<X509_DN>& ca_certs,
59 Protocol_Version version) :
60 m_names(ca_certs),
61 m_cert_key_types({ "RSA", "DSA", "ECDSA" })
62 {
63 if(version.supports_negotiable_signature_algorithms())
64 {
65 std::vector<std::string> hashes = policy.allowed_signature_hashes();
66 std::vector<std::string> sigs = policy.allowed_signature_methods();
67
68 for(size_t i = 0; i != hashes.size(); ++i)
69 for(size_t j = 0; j != sigs.size(); ++j)
70 m_supported_algos.push_back(std::make_pair(hashes[i], sigs[j]));
71 }
72
73 hash.update(io.send(*this));
74 }
75
76 /**
77 * Deserialize a Certificate Request message
78 */
79 Certificate_Req::Certificate_Req(const std::vector<uint8_t>& buf,
80 Protocol_Version version)
81 {
82 if(buf.size() < 4)
83 throw Decoding_Error("Certificate_Req: Bad certificate request");
84
85 TLS_Data_Reader reader("CertificateRequest", buf);
86
87 std::vector<uint8_t> cert_type_codes = reader.get_range_vector<uint8_t>(1, 1, 255);
88
89 for(size_t i = 0; i != cert_type_codes.size(); ++i)
90 {
91 const std::string cert_type_name = cert_type_code_to_name(cert_type_codes[i]);
92
93 if(cert_type_name.empty()) // something we don't know
94 continue;
95
96 m_cert_key_types.push_back(cert_type_name);
97 }
98
99 if(version.supports_negotiable_signature_algorithms())
100 {
101 std::vector<uint8_t> sig_hash_algs = reader.get_range_vector<uint8_t>(2, 2, 65534);
102
103 if(sig_hash_algs.size() % 2 != 0)
104 throw Decoding_Error("Bad length for signature IDs in certificate request");
105
106 for(size_t i = 0; i != sig_hash_algs.size(); i += 2)
107 {
108 std::string hash = Signature_Algorithms::hash_algo_name(sig_hash_algs[i]);
109 std::string sig = Signature_Algorithms::sig_algo_name(sig_hash_algs[i+1]);
110 m_supported_algos.push_back(std::make_pair(hash, sig));
111 }
112 }
113
114 const uint16_t purported_size = reader.get_uint16_t();
115
116 if(reader.remaining_bytes() != purported_size)
117 throw Decoding_Error("Inconsistent length in certificate request");
118
119 while(reader.has_remaining())
120 {
121 std::vector<uint8_t> name_bits = reader.get_range_vector<uint8_t>(2, 0, 65535);
122
123 BER_Decoder decoder(name_bits.data(), name_bits.size());
124 X509_DN name;
125 decoder.decode(name);
126 m_names.push_back(name);
127 }
128 }
129
130 /**
131 * Serialize a Certificate Request message
132 */
133 std::vector<uint8_t> Certificate_Req::serialize() const
134 {
135 std::vector<uint8_t> buf;
136
137 std::vector<uint8_t> cert_types;
138
139 for(size_t i = 0; i != m_cert_key_types.size(); ++i)
140 cert_types.push_back(cert_type_name_to_code(m_cert_key_types[i]));
141
142 append_tls_length_value(buf, cert_types, 1);
143
144 if(!m_supported_algos.empty())
145 buf += Signature_Algorithms(m_supported_algos).serialize();
146
147 std::vector<uint8_t> encoded_names;
148
149 for(size_t i = 0; i != m_names.size(); ++i)
150 {
151 DER_Encoder encoder;
152 encoder.encode(m_names[i]);
153
154 append_tls_length_value(encoded_names, encoder.get_contents(), 2);
155 }
156
157 append_tls_length_value(buf, encoded_names, 2);
158
159 return buf;
160 }
161
162 }
163
164 }
Botan::Invalid_Argument
Definition: exceptn.h:34
Botan::TLS::Certificate_Req::Certificate_Req
Certificate_Req(Handshake_IO &io, Handshake_Hash &hash, const Policy &policy, const std::vector< X509_DN > &allowed_cas, Protocol_Version version)
Definition: msg_cert_req.cpp:55
Botan::TLS::TLS_Data_Reader::remaining_bytes
size_t remaining_bytes() const
Definition: tls_reader.h:38
Botan::DER_Encoder::get_contents
secure_vector< uint8_t > get_contents()
Definition: der_enc.cpp:124
Botan::TLS::Handshake_Hash
Definition: tls_handshake_hash.h:22
Botan::TLS::Protocol_Version
Definition: tls_version.h:21
Botan::TLS::TLS_Data_Reader::get_uint16_t
uint16_t get_uint16_t()
Definition: tls_reader.h:62
Botan::DER_Encoder::encode
DER_Encoder & encode(bool b)
Definition: der_enc.cpp:216
Botan::DER_Encoder
Definition: der_enc.h:22
Botan::TLS::TLS_Data_Reader::get_range_vector
std::vector< T > get_range_vector(size_t len_bytes, size_t min_elems, size_t max_elems)
Definition: tls_reader.h:105
Botan::TLS::Signature_Algorithms::serialize
std::vector< uint8_t > serialize() const override
Definition: tls_extensions.cpp:495
Botan::Decoding_Error
Definition: exceptn.h:189
Botan::X509_DN
Definition: x509_dn.h:22
Botan::TLS::TLS_Data_Reader::has_remaining
bool has_remaining() const
Definition: tls_reader.h:40
Botan::TLS::Handshake_IO
Definition: tls_handshake_io.h:30
Botan
Definition: alg_id.cpp:13
Botan::TLS::Signature_Algorithms::sig_algo_name
static std::string sig_algo_name(uint8_t code)
Definition: tls_extensions.cpp:466
Botan::TLS::Policy
Definition: tls_policy.h:26
Botan::TLS::TLS_Data_Reader
Definition: tls_reader.h:24
Botan::TLS::Signature_Algorithms
Definition: tls_extensions.h:294
Botan::TLS::Protocol_Version::supports_negotiable_signature_algorithms
bool supports_negotiable_signature_algorithms() const
Definition: tls_version.cpp:61
Botan::BER_Decoder
Definition: ber_dec.h:19
hash
MechanismType hash
Definition: p11_mechanism.cpp:63
Botan::TLS::Signature_Algorithms::hash_algo_name
static std::string hash_algo_name(uint8_t code)
Definition: tls_extensions.cpp:427
Botan::TLS::append_tls_length_value
void append_tls_length_value(std::vector< uint8_t, Alloc > &buf, const T *vals, size_t vals_size, size_t tag_size)
Definition: tls_reader.h:185