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

randombit / botan / 25139258422

29 Apr 2026 08:02PM UTC coverage: 89.37% (-0.02%) from 89.385%
25139258422

push

github

web-flow
Merge pull request #5550 from randombit/jack/tls-misc

TLS conformance, hardening, and performance fixes

107055 of 119789 relevant lines covered (89.37%)

11415549.66 hits per line

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

97.33
/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/der_enc.h>
14
#include <botan/pkix_types.h>
15
#include <botan/tls_extensions.h>
16
#include <botan/tls_policy.h>
17
#include <botan/internal/fmt.h>
18
#include <botan/internal/tls_handshake_hash.h>
19
#include <botan/internal/tls_handshake_io.h>
20
#include <botan/internal/tls_reader.h>
21

22
namespace Botan::TLS {
23

24
Certificate_Request_12::~Certificate_Request_12() = default;
974✔
25

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

30
namespace {
31

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

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

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

54
}  // namespace
55

56
/**
57
* Create a new Certificate Request message
58
*/
59
Certificate_Request_12::Certificate_Request_12(Handshake_IO& io,
297✔
60
                                               Handshake_Hash& hash,
61
                                               const Policy& policy,
62
                                               const std::vector<X509_DN>& ca_certs) :
297✔
63
      m_names(ca_certs), m_cert_key_types({"RSA", "ECDSA"}) {
1,485✔
64
   m_schemes = policy.acceptable_signature_schemes();
297✔
65
   // RFC 5246 7.4.4: supported_signature_algorithms<2..2^16-2>
66
   if(m_schemes.empty()) {
297✔
67
      throw Internal_Error("Policy returned no acceptable signature schemes for CertificateRequest");
×
68
   }
69
   hash.update(io.send(*this));
594✔
70
}
891✔
71

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

80
   TLS_Data_Reader reader("CertificateRequest", buf);
200✔
81

82
   const auto cert_type_codes = reader.get_range_vector<uint8_t>(1, 1, 255);
200✔
83

84
   for(const auto cert_type_code : cert_type_codes) {
605✔
85
      const std::string cert_type_name = cert_type_code_to_name(cert_type_code);
405✔
86

87
      if(cert_type_name.empty()) {  // something we don't know
405✔
88
         continue;
13✔
89
      }
90

91
      m_cert_key_types.emplace_back(cert_type_name);
392✔
92
   }
405✔
93

94
   const std::vector<uint8_t> algs = reader.get_range_vector<uint8_t>(2, 2, 65534);
200✔
95

96
   if(algs.size() % 2 != 0) {
196✔
97
      throw Decoding_Error("Bad length for signature IDs in certificate request");
1✔
98
   }
99

100
   for(size_t i = 0; i != algs.size(); i += 2) {
1,878✔
101
      m_schemes.emplace_back(make_uint16(algs[i], algs[i + 1]));
1,688✔
102
   }
103

104
   const uint16_t purported_size = reader.get_uint16_t();
195✔
105

106
   if(reader.remaining_bytes() != purported_size) {
195✔
107
      throw Decoding_Error("Inconsistent length in certificate request");
4✔
108
   }
109

110
   while(reader.has_remaining()) {
367✔
111
      // RFC 5246 7.4.4: opaque DistinguishedName<1..2^16-1>
112
      std::vector<uint8_t> name_bits = reader.get_range_vector<uint8_t>(2, 1, 65535);
176✔
113

114
      BER_Decoder decoder(name_bits, BER_Decoder::Limits::DER());
176✔
115
      X509_DN name;
176✔
116
      decoder.decode(name).verify_end();
176✔
117
      m_names.emplace_back(name);
176✔
118
   }
352✔
119
}
417✔
120

121
const std::vector<std::string>& Certificate_Request_12::acceptable_cert_types() const {
191✔
122
   return m_cert_key_types;
191✔
123
}
124

125
const std::vector<X509_DN>& Certificate_Request_12::acceptable_CAs() const {
191✔
126
   return m_names;
191✔
127
}
128

129
const std::vector<Signature_Scheme>& Certificate_Request_12::signature_schemes() const {
268✔
130
   return m_schemes;
268✔
131
}
132

133
/**
134
* Serialize a Certificate Request message
135
*/
136
std::vector<uint8_t> Certificate_Request_12::serialize() const {
297✔
137
   std::vector<uint8_t> buf;
297✔
138

139
   std::vector<uint8_t> cert_types;
297✔
140

141
   cert_types.reserve(m_cert_key_types.size());
297✔
142
   for(const auto& cert_key_type : m_cert_key_types) {
891✔
143
      cert_types.push_back(cert_type_name_to_code(cert_key_type));
594✔
144
   }
145

146
   append_tls_length_value(buf, cert_types, 1);
297✔
147

148
   // RFC 5246 7.4.4: supported_signature_algorithms<2..2^16-2>
149
   buf += Signature_Algorithms(m_schemes).serialize(Connection_Side::Server);
594✔
150

151
   std::vector<uint8_t> encoded_names;
297✔
152

153
   for(const auto& name : m_names) {
659✔
154
      DER_Encoder encoder;
362✔
155
      encoder.encode(name);
362✔
156

157
      append_tls_length_value(encoded_names, encoder.get_contents(), 2);
724✔
158
   }
362✔
159

160
   append_tls_length_value(buf, encoded_names, 2);
297✔
161

162
   return buf;
297✔
163
}
594✔
164
}  // 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