Coverage Report

Created: 2026-05-16 06:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/botan/build/include/public/botan/credentials_manager.h
Line
Count
Source
1
/*
2
* Credentials Manager
3
* (C) 2011,2012 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#ifndef BOTAN_CREDENTIALS_MANAGER_H_
9
#define BOTAN_CREDENTIALS_MANAGER_H_
10
11
#include <botan/symkey.h>
12
#include <botan/tls_magic.h>
13
#include <memory>
14
#include <optional>
15
#include <string>
16
17
namespace Botan {
18
19
class AlgorithmIdentifier;
20
class Certificate_Store;
21
class Public_Key;
22
class Private_Key;
23
class X509_Certificate;
24
class X509_DN;
25
26
namespace TLS {
27
28
class ExternalPSK;
29
30
}
31
32
/**
33
* Interface for a credentials manager.
34
*
35
* A type is a fairly static value that represents the general nature
36
* of the transaction occurring. Currently used values are "tls-client"
37
* and "tls-server". Context represents a hostname, email address,
38
* username, or other identifier.
39
*/
40
class BOTAN_PUBLIC_API(2, 0) Credentials_Manager /* NOLINT(*-special-member-functions) */ {
41
   public:
42
13.7k
      virtual ~Credentials_Manager() = default;
43
44
      /**
45
      * Return a list of the certificates of CAs that we trust in this
46
      * type/context.
47
      *
48
      * @param type specifies the type of operation occurring
49
      *
50
      * @param context specifies a context relative to type. For instance
51
      *        for type "tls-client", context specifies the servers name.
52
      */
53
      virtual std::vector<Certificate_Store*> trusted_certificate_authorities(const std::string& type,
54
                                                                              const std::string& context);
55
56
      /**
57
      * Return a cert chain we can use, ordered from leaf to root,
58
      * or else an empty vector.
59
      *
60
      * It is assumed that the caller can get the private key of the
61
      * leaf with private_key_for
62
      *
63
      * For a comprehensive write-up of how to select certificates for TLS
64
      * CertificateVerify messages, see RFC 8446 Sections 4.4.2.2 and 4.4.2.3.
65
      *
66
      * @param cert_key_types specifies the key types desired ("RSA",
67
      *                       "DSA", "ECDSA", etc), or empty if there
68
      *                       is no preference by the caller.
69
      * @param cert_signature_schemes specifies the signature types desired
70
      *                               as signatures in the certificate(s) itself,
71
      *                               or empty for no preference by the caller.
72
      *
73
      * @param acceptable_CAs the CAs the requestor will accept (possibly empty)
74
      * @param type specifies the type of operation occurring
75
      * @param context specifies a context relative to type.
76
      */
77
      virtual std::vector<X509_Certificate> find_cert_chain(
78
         const std::vector<std::string>& cert_key_types,
79
         const std::vector<AlgorithmIdentifier>& cert_signature_schemes,
80
         const std::vector<X509_DN>& acceptable_CAs,
81
         const std::string& type,
82
         const std::string& context);
83
84
      /**
85
      * Return a raw public key to be used for authentication or nullptr if no
86
      * public key was found.
87
      *
88
      * It is assumed that the caller can get the private key of the leaf with
89
      * private_key_for().
90
      *
91
      * @param key_types  specifies the key types desired ("RSA", "DSA",
92
      *                   "ECDSA", etc), or empty if there is no preference by
93
      *                   the caller.
94
      * @param type       specifies the type of operation occurring
95
      * @param context    specifies a context relative to type.
96
      */
97
      virtual std::shared_ptr<Public_Key> find_raw_public_key(const std::vector<std::string>& key_types,
98
                                                              const std::string& type,
99
                                                              const std::string& context);
100
101
      /**
102
      * Return a certificate chain we can use to identify ourselves, ordered
103
      * from leaf to root, or else an empty vector.
104
      *
105
      * This virtual function is deprecated, and will be removed in a
106
      * future release. Use (and override) find_cert_chain() instead.
107
      *
108
      * It is assumed that the caller can get the private key of the leaf with
109
      * private_key_for()
110
      *
111
      * @param cert_key_types specifies the key types desired ("RSA", "DSA",
112
      *                       "ECDSA", etc), or empty if there is no preference
113
      *                       by the caller.
114
      * @param cert_signature_schemes specifies the signature types desired as
115
      *                               signatures in the certificate(s) itself,
116
      *                               or empty for no preference by the caller.
117
      * @param type specifies the type of operation occurring
118
      * @param context specifies a context relative to type.
119
      */
120
      BOTAN_DEPRECATED("Do not define or use this function; use find_cert_chain")
121
      virtual std::vector<X509_Certificate> cert_chain(const std::vector<std::string>& cert_key_types,
122
                                                       const std::vector<AlgorithmIdentifier>& cert_signature_schemes,
123
                                                       const std::string& type,
124
                                                       const std::string& context);
125
126
      /**
127
      * Return a certificate chain we can use to identify ourselves, ordered
128
      * from leaf to root, or else an empty vector. Override this if we have one
129
      * certificate of type @p cert_key_type and we would like to use a
130
      * certificate in this type and context.
131
      *
132
      * For servers @p type will be "tls-server" and the @p context will be the
133
      * server name that the client requested via SNI (or empty, if the client
134
      * did not send SNI).
135
      *
136
      * @warning To avoid cross-protocol attacks it is recommended that if a
137
      *          server receives an SNI request for a name it does not expect,
138
      *          it should close the connection with an alert. This can be done
139
      *          by throwing an exception from the implementation of this
140
      *          function.
141
      *
142
      * It is assumed that the caller can get the private key of the leaf with
143
      * private_key_for()
144
      *
145
      * @param cert_key_type specifies the type of key requested ("RSA", "DSA",
146
      *                      "ECDSA", etc)
147
      * @param cert_signature_schemes specifies the signature types desired as
148
      *                               signatures in the certificate(s) itself,
149
      *                               or empty for no preference by the caller.
150
      * @param type specifies the type of operation occurring
151
      * @param context specifies a context relative to type.
152
      */
153
      std::vector<X509_Certificate> cert_chain_single_type(
154
         const std::string& cert_key_type,
155
         const std::vector<AlgorithmIdentifier>& cert_signature_schemes,
156
         const std::string& type,
157
         const std::string& context);
158
159
      /**
160
      * Return a `shared_ptr` to the private key for this certificate. The
161
      * @p cert will be the leaf cert of a chain returned previously by
162
      * find_cert_chain() or cert_chain_single_type().
163
      *
164
      * This function should either return nullptr or throw an exception if
165
      * the matching private key is unavailable.
166
      *
167
      * @return private key associated with this certificate if we should use it
168
      *         in this context.
169
      */
170
      virtual std::shared_ptr<Private_Key> private_key_for(const X509_Certificate& cert,
171
                                                           const std::string& type,
172
                                                           const std::string& context);
173
174
      /**
175
      * This function should either return nullptr or throw an exception if
176
      * the key is unavailable.
177
      *
178
      * @return private key associated with this raw public key if we should
179
      *         use it with this context. @p raw_public_key was returned by
180
      *         find_raw_public_key()
181
      */
182
      virtual std::shared_ptr<Private_Key> private_key_for(const Public_Key& raw_public_key,
183
                                                           const std::string& type,
184
                                                           const std::string& context);
185
186
      /**
187
       * Provides a secret value to encrypt session tickets for stateless
188
       * session resumptions. The default implementation returns an empty
189
       * key that effectively disables session tickets.
190
       *
191
       * @returns a secret value to be used to encrypt session tickets in
192
       *          subclasses of Session_Manager_Stateless.
193
       */
194
      virtual secure_vector<uint8_t> session_ticket_key();
195
196
      /**
197
       * Provides a secret to authenticate DTLS hello cookies. The default
198
       * implementation returns an empty key that effectively disables hello
199
       * cookies. Applications that wish to use DTLS are strongly advised to
200
       * implement this method.
201
       *
202
       * @returns a secret value to authenticate DTLS hello cookies
203
       */
204
      virtual secure_vector<uint8_t> dtls_cookie_secret();
205
206
      /**
207
      * Returns an identity hint which may be provided to the client. This can
208
      * help a client understand what PSK to use.
209
      *
210
      * @param type specifies the type of operation occurring
211
      * @param context specifies a context relative to type.
212
      * @return the PSK identity hint for this type/context
213
      */
214
      virtual std::string psk_identity_hint(const std::string& type, const std::string& context);
215
216
      /**
217
      * Returns the identity we would like to use given this @p type and
218
      * @p context and the optional @p identity_hint. Not all servers or
219
      * protocols will provide a hint.
220
      *
221
      * @param type specifies the type of operation occurring
222
      * @param context specifies a context relative to type.
223
      * @param identity_hint was passed by the server (but may be empty)
224
      * @return the PSK identity we want to use
225
      */
226
      virtual std::string psk_identity(const std::string& type,
227
                                       const std::string& context,
228
                                       const std::string& identity_hint);
229
230
      /**
231
      * Retrieves the PSK with the given @p identity or throws an exception.
232
      * It's default implementation uses find_preshared_keys() with @p identity
233
      * as the single allowed identity.
234
      *
235
      * This method is called by the TLS 1.2 implementation exclusively and will
236
      * eventually be deprecated in favor of find_preshared_keys(). Going
237
      * forward, new applications should implement find_preshared_keys() and
238
      * rely on psk()'s default implementation.
239
      *
240
      * Also, the default implementation delegates @p context "session-ticket"
241
      * and "dtls-cookie-secret" to the methods session_ticket_key() and
242
      * dtls_cookie_secret() respectively. New applications should implement
243
      * those methods and rely on the default implementation of psk().
244
      *
245
      * TODO(Botan4) remove this interface
246
      *
247
      * @param type specifies the type of operation occurring
248
      * @param context specifies a context relative to type.
249
      * @param identity is a PSK identity previously returned by
250
               psk_identity for the same type and context.
251
      * @return the PSK used for identity, or throw an exception if no
252
      *         key exists
253
      */
254
      virtual SymmetricKey psk(const std::string& type, const std::string& context, const std::string& identity);
255
256
      /**
257
       * Filters all available PSKs with the given criterions. Note that omitted
258
       * criterions (like an empty @p identities list or an unspecified @p PRF)
259
       * must be interpreted as "no restriction".
260
       *
261
       * Note that this is used as the underlying API for the legacy psk()
262
       * method currently still used in TLS 1.2. New applications should override
263
       * find_preshared_keys() and leave psk() with the default implementation.
264
       *
265
       * In TLS 1.3 the @p identities might contain opaque session ticket data
266
       * that is not necessarily a printable string, despite the utilized
267
       * std::string type. Implementations must be prepared to ignore identities
268
       * generated via the TLS 1.3 resumption mechanism.
269
       *
270
       * @param host        the host name for which a PSK is requested (may be empty)
271
       * @param whoami      the type of the host (client or server) that is requesting
272
       * @param identities  an optional filter for PSK identities to be returned
273
       *                    (an empty list means: all identities are welcome)
274
       * @param prf         an optional filter for the Pseudo Random Function the PRFs
275
       *                    must be provisioned for
276
       *
277
       * @returns a list of PSKs that meet the defined criterions in preference order
278
       */
279
      virtual std::vector<TLS::ExternalPSK> find_preshared_keys(std::string_view host,
280
                                                                TLS::Connection_Side whoami,
281
                                                                const std::vector<std::string>& identities = {},
282
                                                                const std::optional<std::string>& prf = std::nullopt);
283
284
      /**
285
       * Selects a single PSK identity from the given @p identities and returns
286
       * its details (i.e. the secret value) for it to be used in the handshake.
287
       *
288
       * The default implementation relies on the filtering capabilities
289
       * provided by find_preshared_keys() and simply selects the first PSK
290
       * returned. If applications need finer grained control, they should
291
       * override this method.
292
       *
293
       * In TLS 1.3 the @p identities might contain opaque session ticket data
294
       * that is not necessarily a printable string, despite the utilized
295
       * std::string type. Implementations must be prepared to ignore identities
296
       * generated via the TLS 1.3 resumption mechanism.
297
       *
298
       * @param host        the host name for which a PSK is requested (may be empty)
299
       * @param whoami      the type of the host (client or server) that is requesting
300
       * @param identities  an optional filter for PSK identities to be returned
301
       *                    (an empty list means: all identities are welcome)
302
       * @param prf         an optional filter for the Pseudo Random Function the PRFs
303
       *                    must be provisioned for
304
       *
305
       * @returns the PSK for the selected identity or std::nullopt if no PSK
306
       *          meets the requirements
307
       */
308
      virtual std::optional<TLS::ExternalPSK> choose_preshared_key(
309
         std::string_view host,
310
         TLS::Connection_Side whoami,
311
         const std::vector<std::string>& identities,
312
         const std::optional<std::string>& prf = std::nullopt);
313
};
314
315
}  // namespace Botan
316
317
#endif