Coverage Report

Created: 2021-05-04 09:02

/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
0
   {
24
0
   switch(code)
25
0
      {
26
0
      case 1:
27
0
         return "RSA";
28
0
      case 2:
29
0
         return "DSA";
30
0
      case 64:
31
0
         return "ECDSA";
32
0
      default:
33
0
         return ""; // DH or something else
34
0
      }
35
0
   }
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
   m_names(ca_certs),
59
   m_cert_key_types({ "RSA", "ECDSA", "DSA" })
60
0
   {
61
0
   m_schemes = policy.acceptable_signature_schemes();
62
0
   hash.update(io.send(*this));
63
0
   }
64
65
/**
66
* Deserialize a Certificate Request message
67
*/
68
Certificate_Req::Certificate_Req(const std::vector<uint8_t>& buf)
69
0
   {
70
0
   if(buf.size() < 4)
71
0
      throw Decoding_Error("Certificate_Req: Bad certificate request");
72
73
0
   TLS_Data_Reader reader("CertificateRequest", buf);
74
75
0
   std::vector<uint8_t> cert_type_codes = reader.get_range_vector<uint8_t>(1, 1, 255);
76
77
0
   for(size_t i = 0; i != cert_type_codes.size(); ++i)
78
0
      {
79
0
      const std::string cert_type_name = cert_type_code_to_name(cert_type_codes[i]);
80
81
0
      if(cert_type_name.empty()) // something we don't know
82
0
         continue;
83
84
0
      m_cert_key_types.emplace_back(cert_type_name);
85
0
      }
86
87
0
   const std::vector<uint8_t> algs = reader.get_range_vector<uint8_t>(2, 2, 65534);
88
89
0
   if(algs.size() % 2 != 0)
90
0
      throw Decoding_Error("Bad length for signature IDs in certificate request");
91
92
0
   for(size_t i = 0; i != algs.size(); i += 2)
93
0
      {
94
0
      m_schemes.push_back(static_cast<Signature_Scheme>(make_uint16(algs[i], algs[i+1])));
95
0
      }
96
97
0
   const uint16_t purported_size = reader.get_uint16_t();
98
99
0
   if(reader.remaining_bytes() != purported_size)
100
0
      throw Decoding_Error("Inconsistent length in certificate request");
101
102
0
   while(reader.has_remaining())
103
0
      {
104
0
      std::vector<uint8_t> name_bits = reader.get_range_vector<uint8_t>(2, 0, 65535);
105
106
0
      BER_Decoder decoder(name_bits.data(), name_bits.size());
107
0
      X509_DN name;
108
0
      decoder.decode(name);
109
0
      m_names.emplace_back(name);
110
0
      }
111
0
   }
112
113
/**
114
* Serialize a Certificate Request message
115
*/
116
std::vector<uint8_t> Certificate_Req::serialize() const
117
0
   {
118
0
   std::vector<uint8_t> buf;
119
120
0
   std::vector<uint8_t> cert_types;
121
122
0
   for(size_t i = 0; i != m_cert_key_types.size(); ++i)
123
0
      cert_types.push_back(cert_type_name_to_code(m_cert_key_types[i]));
124
125
0
   append_tls_length_value(buf, cert_types, 1);
126
127
0
   if(m_schemes.size() > 0)
128
0
      buf += Signature_Algorithms(m_schemes).serialize(Connection_Side::SERVER);
129
130
0
   std::vector<uint8_t> encoded_names;
131
132
0
   for(size_t i = 0; i != m_names.size(); ++i)
133
0
      {
134
0
      DER_Encoder encoder;
135
0
      encoder.encode(m_names[i]);
136
137
0
      append_tls_length_value(encoded_names, encoder.get_contents(), 2);
138
0
      }
139
140
0
   append_tls_length_value(buf, encoded_names, 2);
141
142
0
   return buf;
143
0
   }
144
145
}
146
147
}