Botan  2.1.0
Crypto and TLS for C++11
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 */
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 
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 }
Certificate_Req(Handshake_IO &io, Handshake_Hash &hash, const Policy &policy, const std::vector< X509_DN > &allowed_cas, Protocol_Version version)
size_t remaining_bytes() const
Definition: tls_reader.h:38
secure_vector< uint8_t > get_contents()
Definition: der_enc.cpp:124
DER_Encoder & encode(bool b)
Definition: der_enc.cpp:216
std::vector< T > get_range_vector(size_t len_bytes, size_t min_elems, size_t max_elems)
Definition: tls_reader.h:105
std::vector< uint8_t > serialize() const override
bool has_remaining() const
Definition: tls_reader.h:40
Definition: alg_id.cpp:13
static std::string sig_algo_name(uint8_t code)
bool supports_negotiable_signature_algorithms() const
Definition: tls_version.cpp:61
MechanismType hash
static std::string hash_algo_name(uint8_t code)
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