Coverage Report

Created: 2025-04-11 06:34

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