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

randombit / botan / 5079590438

25 May 2023 12:28PM UTC coverage: 92.228% (+0.5%) from 91.723%
5079590438

Pull #3502

github

Pull Request #3502: Apply clang-format to the codebase

75589 of 81959 relevant lines covered (92.23%)

12139530.51 hits per line

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

90.74
/src/lib/tls/tls_extensions_cert_status_req.cpp
1
/*
2
* TLS Extension Certificate_Status_Request
3
* (C) 2011,2012,2015,2016,2022 Jack Lloyd
4
*     2016 Juraj Somorovsky
5
*     2021 Elektrobit Automotive GmbH
6
*     2022 Hannes Rantzsch, René Meusel, neXenio GmbH
7
*
8
* Botan is released under the Simplified BSD License (see license.txt)
9
*/
10

11
#include <botan/tls_extensions.h>
12

13
#include <botan/tls_exceptn.h>
14
#include <botan/tls_messages.h>
15
#include <botan/internal/tls_reader.h>
16

17
namespace Botan::TLS {
18

19
namespace {
20
class RFC6066_Empty_Certificate_Status_Request {
21
   public:
22
      RFC6066_Empty_Certificate_Status_Request() = default;
23

24
      RFC6066_Empty_Certificate_Status_Request(uint16_t extension_size) {
238✔
25
         if(extension_size != 0) {
238✔
26
            throw Decoding_Error("Received an unexpectedly non-empty Certificate_Status_Request");
×
27
         }
28
      }
238✔
29

30
      std::vector<uint8_t> serialize() const { return {}; }
187✔
31
};
32

33
class RFC6066_Certificate_Status_Request {
4,485✔
34
   public:
35
      RFC6066_Certificate_Status_Request(std::vector<uint8_t> names, std::vector<std::vector<uint8_t>> keys) :
2,257✔
36
            ocsp_names(std::move(names)), ocsp_keys(std::move(keys)) {}
2,257✔
37

38
      RFC6066_Certificate_Status_Request(TLS_Data_Reader& reader, uint16_t extension_size) {
2,228✔
39
         if(extension_size == 0) {
2,228✔
40
            throw Decoding_Error("Received an unexpectedly empty Certificate_Status_Request");
×
41
         }
42

43
         const uint8_t type = reader.get_byte();
2,228✔
44
         if(type == 1 /* ocsp */) {
2,228✔
45
            const size_t len_resp_id_list = reader.get_uint16_t();
2,228✔
46
            ocsp_names = reader.get_fixed<uint8_t>(len_resp_id_list);
2,228✔
47
            const size_t len_requ_ext = reader.get_uint16_t();
2,228✔
48
            extension_bytes = reader.get_fixed<uint8_t>(len_requ_ext);
2,228✔
49
         } else {
50
            // RFC 6066 does not specify anything but 'ocsp' and we
51
            // don't support anything else either.
52
            reader.discard_next(extension_size - 1);
×
53
         }
54
      }
2,228✔
55

56
      std::vector<uint8_t> serialize() const {
2,370✔
57
         // Serialization is hard-coded as we don't support advanced features
58
         // of this extension anyway.
59
         return {
2,370✔
60
            1,  // status_type = ocsp
61
            0,
62
            0,  // empty responder_id_list
63
            0,
64
            0,  // no extensions
65
         };
4,740✔
66
      }
67

68
      std::vector<uint8_t> ocsp_names;
69
      std::vector<std::vector<uint8_t>> ocsp_keys;
70
      std::vector<uint8_t> extension_bytes;
71
};
72

73
}
74

75
class Certificate_Status_Request_Internal {
9,900✔
76
   private:
77
      using Contents =
78
         std::variant<RFC6066_Empty_Certificate_Status_Request, RFC6066_Certificate_Status_Request, Certificate_Status>;
79

80
   public:
81
      Certificate_Status_Request_Internal(Contents c) : content(std::move(c)) {}
4,953✔
82

83
      Contents content;
84
};
85

86
Certificate_Status_Request::Certificate_Status_Request(TLS_Data_Reader& reader,
2,493✔
87
                                                       uint16_t extension_size,
88
                                                       Handshake_Type message_type,
89
                                                       Connection_Side from) {
4,986✔
90
   // This parser needs to take TLS 1.2 and TLS 1.3 into account. The
91
   // extension's content and structure is dependent on the context it
92
   // was sent in (i.e. the enclosing handshake message). Below is a list
93
   // of handshake messages this can appear in.
94
   //
95
   // TLS 1.2
96
   //  * Client Hello
97
   //  * Server Hello
98
   //
99
   // TLS 1.3
100
   //  * Client Hello
101
   //  * Certificate Request
102
   //  * Certificate (Entry)
103

104
   // RFC 6066 8.
105
   //    In order to indicate their desire to receive certificate status
106
   //    information, clients MAY include an extension of type "status_request"
107
   //    in the (extended) client hello.
108
   if(message_type == Handshake_Type::ClientHello) {
2,493✔
109
      m_impl = std::make_unique<Certificate_Status_Request_Internal>(
2,228✔
110
         RFC6066_Certificate_Status_Request(reader, extension_size));
4,456✔
111
   }
112

113
   // RFC 6066 8.
114
   //    If a server returns a "CertificateStatus" message, then the server MUST
115
   //    have included an extension of type "status_request" with empty
116
   //    "extension_data" in the extended server hello.
117
   //
118
   // RFC 8446 4.4.2.1
119
   //    A server MAY request that a client present an OCSP response with its
120
   //    certificate by sending an empty "status_request" extension in its
121
   //    CertificateRequest message.
122
   else if(message_type == Handshake_Type::ServerHello || message_type == Handshake_Type::CertificateRequest) {
265✔
123
      m_impl = std::make_unique<Certificate_Status_Request_Internal>(
238✔
124
         RFC6066_Empty_Certificate_Status_Request(extension_size));
476✔
125
   }
126

127
   // RFC 8446 4.4.2.1
128
   //    In TLS 1.3, the server's OCSP information is carried in an extension
129
   //    in the CertificateEntry [in a Certificate handshake message] [...].
130
   //    Specifically, the body of the "status_request" extension from the
131
   //    server MUST be a CertificateStatus structure as defined in [RFC6066]
132
   //    [...].
133
   //
134
   // RFC 8446 4.4.2.1
135
   //    If the client opts to send an OCSP response, the body of its
136
   //    "status_request" extension MUST be a CertificateStatus structure as
137
   //    defined in [RFC6066].
138
   else if(message_type == Handshake_Type::Certificate) {
27✔
139
      m_impl = std::make_unique<Certificate_Status_Request_Internal>(
54✔
140
         Certificate_Status(reader.get_fixed<uint8_t>(extension_size), from));
108✔
141
   }
142

143
   // all other contexts are not allowed for this extension
144
   else {
145
      throw TLS_Exception(Alert::UnsupportedExtension,
×
146
                          "Server sent a Certificate_Status_Request extension in an unsupported context");
×
147
   }
148
}
2,493✔
149

150
Certificate_Status_Request::Certificate_Status_Request() :
187✔
151
      m_impl(std::make_unique<Certificate_Status_Request_Internal>(RFC6066_Empty_Certificate_Status_Request())) {}
187✔
152

153
Certificate_Status_Request::Certificate_Status_Request(std::vector<uint8_t> ocsp_responder_ids,
2,257✔
154
                                                       std::vector<std::vector<uint8_t>> ocsp_key_ids) :
2,257✔
155
      m_impl(std::make_unique<Certificate_Status_Request_Internal>(
2,257✔
156
         RFC6066_Certificate_Status_Request(std::move(ocsp_responder_ids), std::move(ocsp_key_ids)))) {}
2,257✔
157

158
Certificate_Status_Request::Certificate_Status_Request(std::vector<uint8_t> response) :
16✔
159
      m_impl(std::make_unique<Certificate_Status_Request_Internal>(Certificate_Status(std::move(response)))) {}
32✔
160

161
Certificate_Status_Request::~Certificate_Status_Request() = default;
9,900✔
162

163
const std::vector<uint8_t>& Certificate_Status_Request::get_ocsp_response() const {
24✔
164
   BOTAN_ASSERT_NONNULL(m_impl);
24✔
165
   BOTAN_STATE_CHECK(std::holds_alternative<Certificate_Status>(m_impl->content));
24✔
166
   return std::get<Certificate_Status>(m_impl->content).response();
24✔
167
}
168

169
std::vector<uint8_t> Certificate_Status_Request::serialize(Connection_Side) const {
2,573✔
170
   BOTAN_ASSERT_NONNULL(m_impl);
2,573✔
171
   return std::visit([](const auto& c) { return c.serialize(); }, m_impl->content);
4,959✔
172
}
173

174
}
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