Botan 3.0.0-alpha0
Crypto and TLS for C&
msg_cert_req.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.h>
11#include <botan/tls_extensions.h>
12#include <botan/internal/tls_reader.h>
13#include <botan/internal/tls_handshake_io.h>
14#include <botan/internal/tls_handshake_hash.h>
15#include <botan/der_enc.h>
16#include <botan/ber_dec.h>
17
18namespace Botan::TLS {
19
21 {
23 }
24
25namespace {
26
27std::string cert_type_code_to_name(uint8_t code)
28 {
29 switch(code)
30 {
31 case 1:
32 return "RSA";
33 case 2:
34 return "DSA";
35 case 64:
36 return "ECDSA";
37 default:
38 return ""; // DH or something else
39 }
40 }
41
42uint8_t cert_type_name_to_code(const std::string& name)
43 {
44 if(name == "RSA")
45 return 1;
46 if(name == "DSA")
47 return 2;
48 if(name == "ECDSA")
49 return 64;
50
51 throw Invalid_Argument("Unknown cert type " + name);
52 }
53
54}
55
56/**
57* Create a new Certificate Request message
58*/
61 const Policy& policy,
62 const std::vector<X509_DN>& ca_certs) :
63 m_names(ca_certs),
64 m_cert_key_types({ "RSA", "ECDSA", "DSA" })
65 {
66 m_schemes = policy.acceptable_signature_schemes();
67 hash.update(io.send(*this));
68 }
69
70/**
71* Deserialize a Certificate Request message
72*/
73Certificate_Request_12::Certificate_Request_12(const std::vector<uint8_t>& buf)
74 {
75 if(buf.size() < 4)
76 throw Decoding_Error("Certificate_Req: Bad certificate request");
77
78 TLS_Data_Reader reader("CertificateRequest", buf);
79
80 const auto cert_type_codes = reader.get_range_vector<uint8_t>(1, 1, 255);
81
82 for(const auto cert_type_code : cert_type_codes)
83 {
84 const std::string cert_type_name = cert_type_code_to_name(cert_type_code);
85
86 if(cert_type_name.empty()) // something we don't know
87 continue;
88
89 m_cert_key_types.emplace_back(cert_type_name);
90 }
91
92 const std::vector<uint8_t> algs = reader.get_range_vector<uint8_t>(2, 2, 65534);
93
94 if(algs.size() % 2 != 0)
95 throw Decoding_Error("Bad length for signature IDs in certificate request");
96
97 for(size_t i = 0; i != algs.size(); i += 2)
98 {
99 m_schemes.emplace_back(make_uint16(algs[i], algs[i+1]));
100 }
101
102 const uint16_t purported_size = reader.get_uint16_t();
103
104 if(reader.remaining_bytes() != purported_size)
105 throw Decoding_Error("Inconsistent length in certificate request");
106
107 while(reader.has_remaining())
108 {
109 std::vector<uint8_t> name_bits = reader.get_range_vector<uint8_t>(2, 0, 65535);
110
111 BER_Decoder decoder(name_bits.data(), name_bits.size());
113 decoder.decode(name);
114 m_names.emplace_back(name);
115 }
116 }
117
118const std::vector<std::string>& Certificate_Request_12::acceptable_cert_types() const
119 {
120 return m_cert_key_types;
121 }
122
123const std::vector<X509_DN>& Certificate_Request_12::acceptable_CAs() const
124 {
125 return m_names;
126 }
127
128const std::vector<Signature_Scheme>& Certificate_Request_12::signature_schemes() const
129 {
130 return m_schemes;
131 }
132
133/**
134* Serialize a Certificate Request message
135*/
136std::vector<uint8_t> Certificate_Request_12::serialize() const
137 {
138 std::vector<uint8_t> buf;
139
140 std::vector<uint8_t> cert_types;
141
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 append_tls_length_value(buf, cert_types, 1);
146
147 if(!m_schemes.empty())
149
150 std::vector<uint8_t> encoded_names;
151
152 for(const auto& name : m_names)
153 {
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}
secure_vector< uint8_t > get_contents()
Definition: der_enc.cpp:155
DER_Encoder & encode(bool b)
Definition: der_enc.cpp:288
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
bool has_remaining() const
Definition: tls_reader.h:40
size_t remaining_bytes() const
Definition: tls_reader.h:38
std::vector< T > get_range_vector(size_t len_bytes, size_t min_elems, size_t max_elems)
Definition: tls_reader.h:130
std::string name
@ CERTIFICATE_REQUEST
Definition: tls_magic.h:75
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:212
constexpr uint16_t make_uint16(uint8_t i0, uint8_t i1)
Definition: loadstor.h:65
MechanismType hash