Coverage Report

Created: 2021-01-13 07:05

/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
7.38k
   {
24
7.38k
   switch(code)
25
7.38k
      {
26
479
      case 1:
27
479
         return "RSA";
28
798
      case 2:
29
798
         return "DSA";
30
449
      case 64:
31
449
         return "ECDSA";
32
5.66k
      default:
33
5.66k
         return ""; // DH or something else
34
7.38k
      }
35
7.38k
   }
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
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.acceptable_signature_schemes();
65
0
      }
66
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
129
   {
76
129
   if(buf.size() < 4)
77
1
      throw Decoding_Error("Certificate_Req: Bad certificate request");
78
79
128
   TLS_Data_Reader reader("CertificateRequest", buf);
80
81
128
   std::vector<uint8_t> cert_type_codes = reader.get_range_vector<uint8_t>(1, 1, 255);
82
83
7.51k
   for(size_t i = 0; i != cert_type_codes.size(); ++i)
84
7.38k
      {
85
7.38k
      const std::string cert_type_name = cert_type_code_to_name(cert_type_codes[i]);
86
87
7.38k
      if(cert_type_name.empty()) // something we don't know
88
5.66k
         continue;
89
90
1.72k
      m_cert_key_types.emplace_back(cert_type_name);
91
1.72k
      }
92
93
128
   if(version.supports_negotiable_signature_algorithms())
94
127
      {
95
127
      const std::vector<uint8_t> algs = reader.get_range_vector<uint8_t>(2, 2, 65534);
96
97
127
      if(algs.size() % 2 != 0)
98
3
         throw Decoding_Error("Bad length for signature IDs in certificate request");
99
100
4.86k
      for(size_t i = 0; i != algs.size(); i += 2)
101
4.74k
         {
102
4.74k
         m_schemes.push_back(static_cast<Signature_Scheme>(make_uint16(algs[i], algs[i+1])));
103
4.74k
         }
104
124
      }
105
106
125
   const uint16_t purported_size = reader.get_uint16_t();
107
108
125
   if(reader.remaining_bytes() != purported_size)
109
31
      throw Decoding_Error("Inconsistent length in certificate request");
110
111
8.12k
   while(reader.has_remaining())
112
8.02k
      {
113
8.02k
      std::vector<uint8_t> name_bits = reader.get_range_vector<uint8_t>(2, 0, 65535);
114
115
8.02k
      BER_Decoder decoder(name_bits.data(), name_bits.size());
116
8.02k
      X509_DN name;
117
8.02k
      decoder.decode(name);
118
8.02k
      m_names.emplace_back(name);
119
8.02k
      }
120
94
   }
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
129
0
   std::vector<uint8_t> cert_types;
130
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
134
0
   append_tls_length_value(buf, cert_types, 1);
135
136
0
   if(m_schemes.size() > 0)
137
0
      buf += Signature_Algorithms(m_schemes).serialize(Connection_Side::SERVER);
138
139
0
   std::vector<uint8_t> encoded_names;
140
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
146
0
      append_tls_length_value(encoded_names, encoder.get_contents(), 2);
147
0
      }
148
149
0
   append_tls_length_value(buf, encoded_names, 2);
150
151
0
   return buf;
152
0
   }
153
154
}
155
156
}