• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

randombit / botan / 21848380424

10 Feb 2026 01:47AM UTC coverage: 91.634% (+1.6%) from 90.069%
21848380424

push

github

web-flow
Merge pull request #5296 from randombit/jack/tls-header-patrol

Various changes to reduce header dependencies in TLS

104002 of 113497 relevant lines covered (91.63%)

11230277.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.65
/src/lib/tls/tls12/msg_certificate_req_12.cpp
1
/*
2
* Certificate Request Message
3
* (C) 2004-2006,2012 Jack Lloyd
4
*     2021 Elektrobit Automotive GmbH
5
*     2022 René Meusel, Hannes Rantzsch - neXenio GmbH
6
*
7
* Botan is released under the Simplified BSD License (see license.txt)
8
*/
9

10
#include <botan/tls_messages_12.h>
11

12
#include <botan/ber_dec.h>
13
#include <botan/certstor.h>
14
#include <botan/der_enc.h>
15
#include <botan/pkix_types.h>
16
#include <botan/tls_extensions.h>
17
#include <botan/tls_policy.h>
18
#include <botan/internal/fmt.h>
19
#include <botan/internal/tls_handshake_hash.h>
20
#include <botan/internal/tls_handshake_io.h>
21
#include <botan/internal/tls_reader.h>
22

23
namespace Botan::TLS {
24

25
Certificate_Request_12::~Certificate_Request_12() = default;
930✔
26

27
Handshake_Type Certificate_Request_12::type() const {
731✔
28
   return Handshake_Type::CertificateRequest;
731✔
29
}
30

31
namespace {
32

33
std::string cert_type_code_to_name(uint8_t code) {
400✔
34
   switch(code) {
400✔
35
      case 1:
193✔
36
         return "RSA";
193✔
37
      case 64:
194✔
38
         return "ECDSA";
194✔
39
      default:
13✔
40
         return "";  // DH or something else
13✔
41
   }
42
}
43

44
uint8_t cert_type_name_to_code(std::string_view name) {
552✔
45
   if(name == "RSA") {
552✔
46
      return 1;
276✔
47
   }
48
   if(name == "ECDSA") {
276✔
49
      return 64;
276✔
50
   }
51

52
   throw Invalid_Argument(fmt("Unknown/unhandled TLS cert type {}", name));
×
53
}
54

55
}  // namespace
56

57
/**
58
* Create a new Certificate Request message
59
*/
60
Certificate_Request_12::Certificate_Request_12(Handshake_IO& io,
276✔
61
                                               Handshake_Hash& hash,
62
                                               const Policy& policy,
63
                                               const std::vector<X509_DN>& ca_certs) :
276✔
64
      m_names(ca_certs), m_cert_key_types({"RSA", "ECDSA"}) {
1,380✔
65
   m_schemes = policy.acceptable_signature_schemes();
276✔
66
   hash.update(io.send(*this));
552✔
67
}
828✔
68

69
/**
70
* Deserialize a Certificate Request message
71
*/
72
Certificate_Request_12::Certificate_Request_12(const std::vector<uint8_t>& buf) {
199✔
73
   if(buf.size() < 4) {
199✔
74
      throw Decoding_Error("Certificate_Req: Bad certificate request");
1✔
75
   }
76

77
   TLS_Data_Reader reader("CertificateRequest", buf);
198✔
78

79
   const auto cert_type_codes = reader.get_range_vector<uint8_t>(1, 1, 255);
198✔
80

81
   for(const auto cert_type_code : cert_type_codes) {
598✔
82
      const std::string cert_type_name = cert_type_code_to_name(cert_type_code);
400✔
83

84
      if(cert_type_name.empty()) {  // something we don't know
400✔
85
         continue;
13✔
86
      }
87

88
      m_cert_key_types.emplace_back(cert_type_name);
387✔
89
   }
400✔
90

91
   const std::vector<uint8_t> algs = reader.get_range_vector<uint8_t>(2, 2, 65534);
198✔
92

93
   if(algs.size() % 2 != 0) {
194✔
94
      throw Decoding_Error("Bad length for signature IDs in certificate request");
1✔
95
   }
96

97
   for(size_t i = 0; i != algs.size(); i += 2) {
1,859✔
98
      m_schemes.emplace_back(make_uint16(algs[i], algs[i + 1]));
1,666✔
99
   }
100

101
   const uint16_t purported_size = reader.get_uint16_t();
193✔
102

103
   if(reader.remaining_bytes() != purported_size) {
193✔
104
      throw Decoding_Error("Inconsistent length in certificate request");
3✔
105
   }
106

107
   while(reader.has_remaining()) {
358✔
108
      std::vector<uint8_t> name_bits = reader.get_range_vector<uint8_t>(2, 0, 65535);
168✔
109

110
      BER_Decoder decoder(name_bits.data(), name_bits.size());
168✔
111
      X509_DN name;
168✔
112
      decoder.decode(name);
168✔
113
      m_names.emplace_back(name);
168✔
114
   }
168✔
115
}
229✔
116

117
const std::vector<std::string>& Certificate_Request_12::acceptable_cert_types() const {
190✔
118
   return m_cert_key_types;
190✔
119
}
120

121
const std::vector<X509_DN>& Certificate_Request_12::acceptable_CAs() const {
190✔
122
   return m_names;
190✔
123
}
124

125
const std::vector<Signature_Scheme>& Certificate_Request_12::signature_schemes() const {
256✔
126
   return m_schemes;
256✔
127
}
128

129
/**
130
* Serialize a Certificate Request message
131
*/
132
std::vector<uint8_t> Certificate_Request_12::serialize() const {
276✔
133
   std::vector<uint8_t> buf;
276✔
134

135
   std::vector<uint8_t> cert_types;
276✔
136

137
   cert_types.reserve(m_cert_key_types.size());
276✔
138
   for(const auto& cert_key_type : m_cert_key_types) {
828✔
139
      cert_types.push_back(cert_type_name_to_code(cert_key_type));
552✔
140
   }
141

142
   append_tls_length_value(buf, cert_types, 1);
276✔
143

144
   if(!m_schemes.empty()) {
276✔
145
      buf += Signature_Algorithms(m_schemes).serialize(Connection_Side::Server);
276✔
146
   }
147

148
   std::vector<uint8_t> encoded_names;
276✔
149

150
   for(const auto& name : m_names) {
613✔
151
      DER_Encoder encoder;
337✔
152
      encoder.encode(name);
337✔
153

154
      append_tls_length_value(encoded_names, encoder.get_contents(), 2);
674✔
155
   }
337✔
156

157
   append_tls_length_value(buf, encoded_names, 2);
276✔
158

159
   return buf;
276✔
160
}
276✔
161
}  // namespace Botan::TLS
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc