Botan  2.6.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 
16 namespace Botan {
17 
18 namespace TLS {
19 
20 namespace {
21 
22 std::string cert_type_code_to_name(uint8_t code)
23  {
24  switch(code)
25  {
26  case 1:
27  return "RSA";
28  case 2:
29  return "DSA";
30  case 64:
31  return "ECDSA";
32  default:
33  return ""; // DH or something else
34  }
35  }
36 
37 uint8_t cert_type_name_to_code(const std::string& name)
38  {
39  if(name == "RSA")
40  return 1;
41  if(name == "DSA")
42  return 2;
43  if(name == "ECDSA")
44  return 64;
45 
46  throw Invalid_Argument("Unknown cert type " + name);
47  }
48 
49 }
50 
51 /**
52 * Create a new Certificate Request message
53 */
56  const Policy& policy,
57  const std::vector<X509_DN>& ca_certs,
58  Protocol_Version version) :
59  m_names(ca_certs),
60  m_cert_key_types({ "RSA", "DSA", "ECDSA" })
61  {
62  if(version.supports_negotiable_signature_algorithms())
63  {
64  m_schemes = policy.allowed_signature_schemes();
65  }
66 
67  hash.update(io.send(*this));
68  }
69 
70 /**
71 * Deserialize a Certificate Request message
72 */
73 Certificate_Req::Certificate_Req(const std::vector<uint8_t>& buf,
74  Protocol_Version version)
75  {
76  if(buf.size() < 4)
77  throw Decoding_Error("Certificate_Req: Bad certificate request");
78 
79  TLS_Data_Reader reader("CertificateRequest", buf);
80 
81  std::vector<uint8_t> cert_type_codes = reader.get_range_vector<uint8_t>(1, 1, 255);
82 
83  for(size_t i = 0; i != cert_type_codes.size(); ++i)
84  {
85  const std::string cert_type_name = cert_type_code_to_name(cert_type_codes[i]);
86 
87  if(cert_type_name.empty()) // something we don't know
88  continue;
89 
90  m_cert_key_types.push_back(cert_type_name);
91  }
92 
94  {
95  const std::vector<uint8_t> algs = reader.get_range_vector<uint8_t>(2, 2, 65534);
96 
97  if(algs.size() % 2 != 0)
98  throw Decoding_Error("Bad length for signature IDs in certificate request");
99 
100  for(size_t i = 0; i != algs.size(); i += 2)
101  {
102  m_schemes.push_back(static_cast<Signature_Scheme>(make_uint16(algs[i], algs[i+1])));
103  }
104  }
105 
106  const uint16_t purported_size = reader.get_uint16_t();
107 
108  if(reader.remaining_bytes() != purported_size)
109  throw Decoding_Error("Inconsistent length in certificate request");
110 
111  while(reader.has_remaining())
112  {
113  std::vector<uint8_t> name_bits = reader.get_range_vector<uint8_t>(2, 0, 65535);
114 
115  BER_Decoder decoder(name_bits.data(), name_bits.size());
116  X509_DN name;
117  decoder.decode(name);
118  m_names.push_back(name);
119  }
120  }
121 
122 /**
123 * Serialize a Certificate Request message
124 */
125 std::vector<uint8_t> Certificate_Req::serialize() const
126  {
127  std::vector<uint8_t> buf;
128 
129  std::vector<uint8_t> cert_types;
130 
131  for(size_t i = 0; i != m_cert_key_types.size(); ++i)
132  cert_types.push_back(cert_type_name_to_code(m_cert_key_types[i]));
133 
134  append_tls_length_value(buf, cert_types, 1);
135 
136  if(m_schemes.size() > 0)
137  buf += Signature_Algorithms(m_schemes).serialize();
138 
139  std::vector<uint8_t> encoded_names;
140 
141  for(size_t i = 0; i != m_names.size(); ++i)
142  {
143  DER_Encoder encoder;
144  encoder.encode(m_names[i]);
145 
146  append_tls_length_value(encoded_names, encoder.get_contents(), 2);
147  }
148 
149  append_tls_length_value(buf, encoded_names, 2);
150 
151  return buf;
152  }
153 
154 }
155 
156 }
Certificate_Req(Handshake_IO &io, Handshake_Hash &hash, const Policy &policy, const std::vector< X509_DN > &allowed_cas, Protocol_Version version)
secure_vector< uint8_t > get_contents()
Definition: der_enc.cpp:123
bool supports_negotiable_signature_algorithms() const
Definition: tls_version.cpp:60
DER_Encoder & encode(bool b)
Definition: der_enc.cpp:202
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
Definition: alg_id.cpp:13
uint16_t make_uint16(uint8_t i0, uint8_t i1)
Definition: loadstor.h:52
size_t remaining_bytes() const
Definition: tls_reader.h:38
MechanismType hash
bool has_remaining() const
Definition: tls_reader.h:40
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