Coverage Report

Created: 2020-02-14 15:38

/src/botan/src/lib/tls/msg_cert_req.cpp
Line
Count
Source (jump to first uncovered line)
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
10.6k
   {
24
10.6k
   switch(code)
25
10.6k
      {
26
10.6k
      case 1:
27
1.73k
         return "RSA";
28
10.6k
      case 2:
29
634
         return "DSA";
30
10.6k
      case 64:
31
1.02k
         return "ECDSA";
32
10.6k
      default:
33
7.24k
         return ""; // DH or something else
34
10.6k
      }
35
10.6k
   }
36
37
uint8_t cert_type_name_to_code(const std::string& name)
38
0
   {
39
0
   if(name == "RSA")
40
0
      return 1;
41
0
   if(name == "DSA")
42
0
      return 2;
43
0
   if(name == "ECDSA")
44
0
      return 64;
45
0
46
0
   throw Invalid_Argument("Unknown cert type " + name);
47
0
   }
48
49
}
50
51
/**
52
* Create a new Certificate Request message
53
*/
54
Certificate_Req::Certificate_Req(Handshake_IO& io,
55
                                 Handshake_Hash& hash,
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", "ECDSA", "DSA" })
61
0
   {
62
0
   if(version.supports_negotiable_signature_algorithms())
63
0
      {
64
0
      m_schemes = policy.allowed_signature_schemes();
65
0
      }
66
0
67
0
   hash.update(io.send(*this));
68
0
   }
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
130
   {
76
130
   if(buf.size() < 4)
77
5
      throw Decoding_Error("Certificate_Req: Bad certificate request");
78
125
79
125
   TLS_Data_Reader reader("CertificateRequest", buf);
80
125
81
125
   std::vector<uint8_t> cert_type_codes = reader.get_range_vector<uint8_t>(1, 1, 255);
82
125
83
10.7k
   for(size_t i = 0; i != cert_type_codes.size(); ++i)
84
10.6k
      {
85
10.6k
      const std::string cert_type_name = cert_type_code_to_name(cert_type_codes[i]);
86
10.6k
87
10.6k
      if(cert_type_name.empty()) // something we don't know
88
7.24k
         continue;
89
3.39k
90
3.39k
      m_cert_key_types.emplace_back(cert_type_name);
91
3.39k
      }
92
125
93
125
   if(version.supports_negotiable_signature_algorithms())
94
123
      {
95
123
      const std::vector<uint8_t> algs = reader.get_range_vector<uint8_t>(2, 2, 65534);
96
123
97
123
      if(algs.size() % 2 != 0)
98
4
         throw Decoding_Error("Bad length for signature IDs in certificate request");
99
119
100
5.77k
      for(size_t i = 0; i != algs.size(); i += 2)
101
5.65k
         {
102
5.65k
         m_schemes.push_back(static_cast<Signature_Scheme>(make_uint16(algs[i], algs[i+1])));
103
5.65k
         }
104
119
      }
105
125
106
125
   const uint16_t purported_size = reader.get_uint16_t();
107
121
108
121
   if(reader.remaining_bytes() != purported_size)
109
57
      throw Decoding_Error("Inconsistent length in certificate request");
110
64
111
77
   while(reader.has_remaining())
112
13
      {
113
13
      std::vector<uint8_t> name_bits = reader.get_range_vector<uint8_t>(2, 0, 65535);
114
13
115
13
      BER_Decoder decoder(name_bits.data(), name_bits.size());
116
13
      X509_DN name;
117
13
      decoder.decode(name);
118
13
      m_names.emplace_back(name);
119
13
      }
120
64
   }
121
122
/**
123
* Serialize a Certificate Request message
124
*/
125
std::vector<uint8_t> Certificate_Req::serialize() const
126
0
   {
127
0
   std::vector<uint8_t> buf;
128
0
129
0
   std::vector<uint8_t> cert_types;
130
0
131
0
   for(size_t i = 0; i != m_cert_key_types.size(); ++i)
132
0
      cert_types.push_back(cert_type_name_to_code(m_cert_key_types[i]));
133
0
134
0
   append_tls_length_value(buf, cert_types, 1);
135
0
136
0
   if(m_schemes.size() > 0)
137
0
      buf += Signature_Algorithms(m_schemes).serialize(Connection_Side::SERVER);
138
0
139
0
   std::vector<uint8_t> encoded_names;
140
0
141
0
   for(size_t i = 0; i != m_names.size(); ++i)
142
0
      {
143
0
      DER_Encoder encoder;
144
0
      encoder.encode(m_names[i]);
145
0
146
0
      append_tls_length_value(encoded_names, encoder.get_contents(), 2);
147
0
      }
148
0
149
0
   append_tls_length_value(buf, encoded_names, 2);
150
0
151
0
   return buf;
152
0
   }
153
154
}
155
156
}