Botan 3.12.0
Crypto and TLS for C&
msg_certificate_req_12.cpp
Go to the documentation of this file.
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
22namespace Botan::TLS {
23
25
29
30namespace {
31
32std::string cert_type_code_to_name(uint8_t code) {
33 switch(code) {
34 case 1:
35 return "RSA";
36 case 64:
37 return "ECDSA";
38 default:
39 return ""; // DH or something else
40 }
41}
42
43uint8_t cert_type_name_to_code(std::string_view name) {
44 if(name == "RSA") {
45 return 1;
46 }
47 if(name == "ECDSA") {
48 return 64;
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*/
60 Handshake_Hash& hash,
61 const Policy& policy,
62 const std::vector<X509_DN>& ca_certs) :
63 m_names(ca_certs), m_cert_key_types({"RSA", "ECDSA"}) {
64 m_schemes = policy.acceptable_signature_schemes();
65 // RFC 5246 7.4.4: supported_signature_algorithms<2..2^16-2>
66 if(m_schemes.empty()) {
67 throw Internal_Error("Policy returned no acceptable signature schemes for CertificateRequest");
68 }
69 hash.update(io.send(*this));
70}
71
72/**
73* Deserialize a Certificate Request message
74*/
75Certificate_Request_12::Certificate_Request_12(const std::vector<uint8_t>& buf) {
76 if(buf.size() < 4) {
77 throw Decoding_Error("Certificate_Req: Bad certificate request");
78 }
79
80 TLS_Data_Reader reader("CertificateRequest", buf);
81
82 const auto cert_type_codes = reader.get_range_vector<uint8_t>(1, 1, 255);
83
84 for(const auto cert_type_code : cert_type_codes) {
85 const std::string cert_type_name = cert_type_code_to_name(cert_type_code);
86
87 if(cert_type_name.empty()) { // something we don't know
88 continue;
89 }
90
91 m_cert_key_types.emplace_back(cert_type_name);
92 }
93
94 const std::vector<uint8_t> algs = reader.get_range_vector<uint8_t>(2, 2, 65534);
95
96 if(algs.size() % 2 != 0) {
97 throw Decoding_Error("Bad length for signature IDs in certificate request");
98 }
99
100 for(size_t i = 0; i != algs.size(); i += 2) {
101 m_schemes.emplace_back(make_uint16(algs[i], algs[i + 1]));
102 }
103
104 const uint16_t purported_size = reader.get_uint16_t();
105
106 if(reader.remaining_bytes() != purported_size) {
107 throw Decoding_Error("Inconsistent length in certificate request");
108 }
109
110 while(reader.has_remaining()) {
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);
113
114 BER_Decoder decoder(name_bits, BER_Decoder::Limits::DER());
115 X509_DN name;
116 decoder.decode(name).verify_end();
117 m_names.emplace_back(name);
118 }
119}
120
121const std::vector<std::string>& Certificate_Request_12::acceptable_cert_types() const {
122 return m_cert_key_types;
123}
124
125const std::vector<X509_DN>& Certificate_Request_12::acceptable_CAs() const {
126 return m_names;
127}
128
129const std::vector<Signature_Scheme>& Certificate_Request_12::signature_schemes() const {
130 return m_schemes;
131}
132
133/**
134* Serialize a Certificate Request message
135*/
136std::vector<uint8_t> Certificate_Request_12::serialize() const {
137 std::vector<uint8_t> buf;
138
139 std::vector<uint8_t> cert_types;
140
141 cert_types.reserve(m_cert_key_types.size());
142 for(const auto& cert_key_type : m_cert_key_types) {
143 cert_types.push_back(cert_type_name_to_code(cert_key_type));
144 }
145
146 append_tls_length_value(buf, cert_types, 1);
147
148 // RFC 5246 7.4.4: supported_signature_algorithms<2..2^16-2>
150
151 std::vector<uint8_t> encoded_names;
152
153 for(const auto& name : m_names) {
154 DER_Encoder encoder;
155 encoder.encode(name);
156
157 append_tls_length_value(encoded_names, encoder.get_contents(), 2);
158 }
159
160 append_tls_length_value(buf, encoded_names, 2);
161
162 return buf;
163}
164} // namespace Botan::TLS
static Limits DER()
Definition ber_dec.h:35
secure_vector< uint8_t > get_contents()
Definition der_enc.cpp:134
DER_Encoder & encode(bool b)
Definition der_enc.cpp:245
const std::vector< std::string > & acceptable_cert_types() const
const std::vector< Signature_Scheme > & signature_schemes() const
std::vector< uint8_t > serialize() const override
const std::vector< X509_DN > & acceptable_CAs() const
Certificate_Request_12(Handshake_IO &io, Handshake_Hash &hash, const Policy &policy, const std::vector< X509_DN > &allowed_cas)
Handshake_Type type() const override
std::vector< uint8_t > serialize(Connection_Side whoami) const override
size_t remaining_bytes() const
Definition tls_reader.h:37
std::vector< T > get_range_vector(size_t len_bytes, size_t min_elems, size_t max_elems)
Definition tls_reader.h:117
void append_tls_length_value(std::vector< uint8_t, Alloc > &buf, const T *vals, size_t vals_size, size_t tag_size)
Definition tls_reader.h:177
std::string fmt(std::string_view format, const T &... args)
Definition fmt.h:53
constexpr uint16_t make_uint16(uint8_t i0, uint8_t i1)
Definition loadstor.h:92