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

randombit / botan / 5111374265

29 May 2023 11:19AM UTC coverage: 92.227% (+0.5%) from 91.723%
5111374265

push

github

randombit
Next release will be 3.1.0. Update release notes

75588 of 81959 relevant lines covered (92.23%)

11886470.91 hits per line

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

80.39
/src/lib/tls/tls13/msg_certificate_req_13.cpp
1
/*
2
* (C) 2022 Jack Lloyd
3
* (C) 2022 Hannes Rantzsch, René Meusel - neXenio GmbH
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7

8
#include <botan/tls_messages.h>
9

10
#include <botan/credentials_manager.h>
11
#include <botan/tls_callbacks.h>
12
#include <botan/tls_exceptn.h>
13
#include <botan/internal/tls_reader.h>
14

15
namespace Botan::TLS {
16

17
Handshake_Type Certificate_Request_13::type() const { return TLS::Handshake_Type::CertificateRequest; }
369✔
18

19
Certificate_Request_13::Certificate_Request_13(const std::vector<uint8_t>& buf, const Connection_Side side) {
59✔
20
   TLS_Data_Reader reader("Certificate_Request_13", buf);
59✔
21

22
   // RFC 8446 4.3.2
23
   //    A server which is authenticating with a certificate MAY optionally
24
   //    request a certificate from the client.
25
   if(side != Connection_Side::Server) {
59✔
26
      throw TLS_Exception(Alert::UnexpectedMessage, "Received a Certificate_Request message from a client");
×
27
   }
28

29
   m_context = reader.get_tls_length_value(1);
118✔
30
   m_extensions.deserialize(reader, side, type());
59✔
31

32
   // RFC 8446 4.3.2
33
   //    The "signature_algorithms" extension MUST be specified, and other
34
   //    extensions may optionally be included if defined for this message.
35
   //    Clients MUST ignore unrecognized extensions.
36

37
   if(!m_extensions.has<Signature_Algorithms>()) {
57✔
38
      throw TLS_Exception(Alert::MissingExtension,
1✔
39
                          "Certificate_Request message did not provide a signature_algorithms extension");
2✔
40
   }
41

42
   // RFC 8446 4.2.
43
   //    The table below indicates the messages where a given extension may
44
   //    appear [...].  If an implementation receives an extension which it
45
   //    recognizes and which is not specified for the message in which it
46
   //    appears, it MUST abort the handshake with an "illegal_parameter" alert.
47
   //
48
   // For Certificate Request said table states:
49
   //    "status_request", "signature_algorithms", "signed_certificate_timestamp",
50
   //     "certificate_authorities", "oid_filters", "signature_algorithms_cert",
51
   std::set<Extension_Code> allowed_extensions = {
56✔
52
      Extension_Code::CertificateStatusRequest,
53
      Extension_Code::SignatureAlgorithms,
54
      // Extension_Code::SignedCertificateTimestamp,  // NYI
55
      Extension_Code::CertificateAuthorities,
56
      // Extension_Code::OidFilters,                   // NYI
57
      Extension_Code::CertSignatureAlgorithms,
58
   };
56✔
59

60
   if(m_extensions.contains_implemented_extensions_other_than(allowed_extensions)) {
56✔
61
      throw TLS_Exception(Alert::IllegalParameter, "Certificate Request contained an extension that is not allowed");
×
62
   }
63
}
59✔
64

65
Certificate_Request_13::Certificate_Request_13(std::vector<X509_DN> acceptable_CAs, const Policy& policy, Callbacks&) {
100✔
66
   // RFC 8446 4.3.2
67
   //    The certificate_request_context [here: m_context] MUST be unique within
68
   //    the scope of this connection (thus preventing replay of client
69
   //    CertificateVerify messages).  This field SHALL be zero length unless
70
   //    used for the post-handshake authentication exchanges described in
71
   //    Section 4.6.2.
72
   //
73
   // TODO: Post-Handshake auth must fill m_context in an unpredictable way
74

75
   // RFC 8446 4.3.2
76
   //    [Supported signature algorithms are] expressed by sending the
77
   //    "signature_algorithms" and optionally "signature_algorithms_cert"
78
   //    extensions. [A list of certificate authorities which the server would
79
   //    accept] is expressed by sending the "certificate_authorities" extension.
80
   //
81
   //    The "signature_algorithms" extension MUST be specified, and other
82
   //    extensions may optionally be included if defined for this message.
83
   m_extensions.add(std::make_unique<Signature_Algorithms>(policy.acceptable_signature_schemes()));
200✔
84
   if(auto cert_signing_prefs = policy.acceptable_certificate_signature_schemes()) {
100✔
85
      // RFC 8446 4.2.3
86
      //    Implementations which have the same policy in both cases MAY omit
87
      //    the "signature_algorithms_cert" extension.
88
      m_extensions.add(std::make_unique<Signature_Algorithms_Cert>(std::move(cert_signing_prefs.value())));
×
89
   }
×
90

91
   if(!acceptable_CAs.empty()) {
100✔
92
      m_extensions.add(std::make_unique<Certificate_Authorities>(std::move(acceptable_CAs)));
×
93
   }
94

95
   // TODO: Support cert_status_request for OCSP stapling
96

97
   // TODO: give the application a chance to modifying extensions
98
   //       (after GH #2988 is merged)
99
   // callbacks.tls_modify_extensions(m_extensions, Connection_Side::Server);
100
}
100✔
101

102
std::optional<Certificate_Request_13> Certificate_Request_13::maybe_create(const Client_Hello_13& client_hello,
260✔
103
                                                                           Credentials_Manager& cred_mgr,
104
                                                                           Callbacks& callbacks,
105
                                                                           const Policy& policy) {
106
   const auto trusted_CAs = cred_mgr.trusted_certificate_authorities("tls-server", client_hello.sni_hostname());
520✔
107

108
   std::vector<X509_DN> client_auth_CAs;
260✔
109
   for(const auto store : trusted_CAs) {
260✔
110
      const auto subjects = store->all_subjects();
×
111
      client_auth_CAs.insert(client_auth_CAs.end(), subjects.begin(), subjects.end());
×
112
   }
×
113

114
   if(client_auth_CAs.empty() && !policy.request_client_certificate_authentication()) {
260✔
115
      return std::nullopt;
160✔
116
   }
117

118
   return Certificate_Request_13(std::move(client_auth_CAs), policy, callbacks);
200✔
119
}
260✔
120

121
std::vector<X509_DN> Certificate_Request_13::acceptable_CAs() const {
53✔
122
   if(m_extensions.has<Certificate_Authorities>())
53✔
123
      return m_extensions.get<Certificate_Authorities>()->distinguished_names();
3✔
124
   return {};
50✔
125
}
126

127
const std::vector<Signature_Scheme>& Certificate_Request_13::signature_schemes() const {
196✔
128
   // RFC 8446 4.3.2
129
   //    The "signature_algorithms" extension MUST be specified
130
   BOTAN_ASSERT_NOMSG(m_extensions.has<Signature_Algorithms>());
196✔
131

132
   return m_extensions.get<Signature_Algorithms>()->supported_schemes();
196✔
133
}
134

135
const std::vector<Signature_Scheme>& Certificate_Request_13::certificate_signature_schemes() const {
53✔
136
   // RFC 8446 4.2.3
137
   //   If no "signature_algorithms_cert" extension is present, then the
138
   //   "signature_algorithms" extension also applies to signatures appearing
139
   //   in certificates.
140
   if(auto sig_schemes_cert = m_extensions.get<Signature_Algorithms_Cert>()) {
53✔
141
      return sig_schemes_cert->supported_schemes();
×
142
   } else {
143
      return signature_schemes();
53✔
144
   }
145
}
146

147
std::vector<uint8_t> Certificate_Request_13::serialize() const {
102✔
148
   std::vector<uint8_t> buf;
102✔
149
   append_tls_length_value(buf, m_context, 1);
102✔
150
   buf += m_extensions.serialize(Connection_Side::Server);
102✔
151
   return buf;
102✔
152
}
×
153

154
}  // 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