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

randombit / botan / 20579846577

29 Dec 2025 06:24PM UTC coverage: 90.415% (+0.2%) from 90.243%
20579846577

push

github

web-flow
Merge pull request #5167 from randombit/jack/src-size-reductions

Changes to reduce unnecessary inclusions

101523 of 112285 relevant lines covered (90.42%)

12817276.56 hits per line

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

98.63
/src/lib/tls/msg_cert_req.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.h>
11

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

20
namespace Botan::TLS {
21

22
Handshake_Type Certificate_Request_12::type() const {
732✔
23
   return Handshake_Type::CertificateRequest;
732✔
24
}
25

26
namespace {
27

28
std::string cert_type_code_to_name(uint8_t code) {
404✔
29
   switch(code) {
404✔
30
      case 1:
195✔
31
         return "RSA";
195✔
32
      case 64:
196✔
33
         return "ECDSA";
196✔
34
      default:
13✔
35
         return "";  // DH or something else
13✔
36
   }
37
}
38

39
uint8_t cert_type_name_to_code(std::string_view name) {
556✔
40
   if(name == "RSA") {
556✔
41
      return 1;
278✔
42
   }
43
   if(name == "ECDSA") {
278✔
44
      return 64;
278✔
45
   }
46

47
   throw Invalid_Argument(fmt("Unknown/unhandled TLS cert type {}", name));
×
48
}
49

50
}  // namespace
51

52
/**
53
* Create a new Certificate Request message
54
*/
55
Certificate_Request_12::Certificate_Request_12(Handshake_IO& io,
278✔
56
                                               Handshake_Hash& hash,
57
                                               const Policy& policy,
58
                                               const std::vector<X509_DN>& ca_certs) :
278✔
59
      m_names(ca_certs), m_cert_key_types({"RSA", "ECDSA"}) {
1,390✔
60
   m_schemes = policy.acceptable_signature_schemes();
278✔
61
   hash.update(io.send(*this));
556✔
62
}
834✔
63

64
/**
65
* Deserialize a Certificate Request message
66
*/
67
Certificate_Request_12::Certificate_Request_12(const std::vector<uint8_t>& buf) {
201✔
68
   if(buf.size() < 4) {
201✔
69
      throw Decoding_Error("Certificate_Req: Bad certificate request");
1✔
70
   }
71

72
   TLS_Data_Reader reader("CertificateRequest", buf);
200✔
73

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

76
   for(const auto cert_type_code : cert_type_codes) {
604✔
77
      const std::string cert_type_name = cert_type_code_to_name(cert_type_code);
404✔
78

79
      if(cert_type_name.empty()) {  // something we don't know
404✔
80
         continue;
13✔
81
      }
82

83
      m_cert_key_types.emplace_back(cert_type_name);
391✔
84
   }
404✔
85

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

88
   if(algs.size() % 2 != 0) {
196✔
89
      throw Decoding_Error("Bad length for signature IDs in certificate request");
1✔
90
   }
91

92
   for(size_t i = 0; i != algs.size(); i += 2) {
1,879✔
93
      m_schemes.emplace_back(make_uint16(algs[i], algs[i + 1]));
1,688✔
94
   }
95

96
   const uint16_t purported_size = reader.get_uint16_t();
195✔
97

98
   if(reader.remaining_bytes() != purported_size) {
195✔
99
      throw Decoding_Error("Inconsistent length in certificate request");
3✔
100
   }
101

102
   while(reader.has_remaining()) {
364✔
103
      std::vector<uint8_t> name_bits = reader.get_range_vector<uint8_t>(2, 0, 65535);
172✔
104

105
      BER_Decoder decoder(name_bits.data(), name_bits.size());
172✔
106
      X509_DN name;
172✔
107
      decoder.decode(name);
172✔
108
      m_names.emplace_back(name);
172✔
109
   }
344✔
110
}
415✔
111

112
const std::vector<std::string>& Certificate_Request_12::acceptable_cert_types() const {
192✔
113
   return m_cert_key_types;
192✔
114
}
115

116
const std::vector<X509_DN>& Certificate_Request_12::acceptable_CAs() const {
192✔
117
   return m_names;
192✔
118
}
119

120
const std::vector<Signature_Scheme>& Certificate_Request_12::signature_schemes() const {
256✔
121
   return m_schemes;
256✔
122
}
123

124
/**
125
* Serialize a Certificate Request message
126
*/
127
std::vector<uint8_t> Certificate_Request_12::serialize() const {
278✔
128
   std::vector<uint8_t> buf;
278✔
129

130
   std::vector<uint8_t> cert_types;
278✔
131

132
   cert_types.reserve(m_cert_key_types.size());
278✔
133
   for(const auto& cert_key_type : m_cert_key_types) {
834✔
134
      cert_types.push_back(cert_type_name_to_code(cert_key_type));
556✔
135
   }
136

137
   append_tls_length_value(buf, cert_types, 1);
278✔
138

139
   if(!m_schemes.empty()) {
278✔
140
      buf += Signature_Algorithms(m_schemes).serialize(Connection_Side::Server);
556✔
141
   }
142

143
   std::vector<uint8_t> encoded_names;
278✔
144

145
   for(const auto& name : m_names) {
619✔
146
      DER_Encoder encoder;
341✔
147
      encoder.encode(name);
341✔
148

149
      append_tls_length_value(encoded_names, encoder.get_contents(), 2);
682✔
150
   }
341✔
151

152
   append_tls_length_value(buf, encoded_names, 2);
278✔
153

154
   return buf;
278✔
155
}
556✔
156
}  // 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