• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 //
3 // Copyright 2015 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18 
19 #ifndef GRPC_SRC_CORE_TSI_SSL_TRANSPORT_SECURITY_H
20 #define GRPC_SRC_CORE_TSI_SSL_TRANSPORT_SECURITY_H
21 
22 #include <grpc/grpc_crl_provider.h>
23 #include <grpc/grpc_security_constants.h>
24 #include <grpc/support/port_platform.h>
25 #include <openssl/x509.h>
26 
27 #include <memory>
28 
29 #include "absl/strings/string_view.h"
30 #include "src/core/tsi/ssl/key_logging/ssl_key_logging.h"
31 #include "src/core/tsi/ssl_transport_security_utils.h"
32 #include "src/core/tsi/transport_security_interface.h"
33 
34 // Value for the TSI_CERTIFICATE_TYPE_PEER_PROPERTY property for X509 certs.
35 #define TSI_X509_CERTIFICATE_TYPE "X509"
36 
37 // This property is of type TSI_PEER_PROPERTY_STRING.
38 #define TSI_X509_SUBJECT_PEER_PROPERTY "x509_subject"
39 #define TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY "x509_subject_common_name"
40 #define TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY \
41   "x509_subject_alternative_name"
42 #define TSI_SSL_SESSION_REUSED_PEER_PROPERTY "ssl_session_reused"
43 #define TSI_X509_PEM_CERT_PROPERTY "x509_pem_cert"
44 #define TSI_X509_PEM_CERT_CHAIN_PROPERTY "x509_pem_cert_chain"
45 #define TSI_SSL_ALPN_SELECTED_PROTOCOL "ssl_alpn_selected_protocol"
46 #define TSI_X509_DNS_PEER_PROPERTY "x509_dns"
47 #define TSI_X509_URI_PEER_PROPERTY "x509_uri"
48 #define TSI_X509_EMAIL_PEER_PROPERTY "x509_email"
49 #define TSI_X509_IP_PEER_PROPERTY "x509_ip"
50 #define TSI_X509_VERIFIED_ROOT_CERT_SUBECT_PEER_PROPERTY \
51   "x509_verified_root_cert_subject"
52 
53 // --- tsi_ssl_root_certs_store object ---
54 
55 // This object stores SSL root certificates. It can be shared by multiple SSL
56 // context.
57 typedef struct tsi_ssl_root_certs_store tsi_ssl_root_certs_store;
58 
59 // Given a NULL-terminated string containing the PEM encoding of the root
60 // certificates, creates a tsi_ssl_root_certs_store object.
61 tsi_ssl_root_certs_store* tsi_ssl_root_certs_store_create(
62     const char* pem_roots);
63 
64 // Destroys the tsi_ssl_root_certs_store object.
65 void tsi_ssl_root_certs_store_destroy(tsi_ssl_root_certs_store* self);
66 
67 // --- tsi_ssl_session_cache object ---
68 
69 // Cache for SSL sessions for sessions resumption.
70 
71 typedef struct tsi_ssl_session_cache tsi_ssl_session_cache;
72 
73 // Create LRU cache for SSL sessions with \a capacity.
74 tsi_ssl_session_cache* tsi_ssl_session_cache_create_lru(size_t capacity);
75 
76 // Increment reference counter of \a cache.
77 void tsi_ssl_session_cache_ref(tsi_ssl_session_cache* cache);
78 
79 // Decrement reference counter of \a cache.
80 void tsi_ssl_session_cache_unref(tsi_ssl_session_cache* cache);
81 
82 // --- tsi_ssl_key_logger object ---
83 
84 // Experimental SSL Key logging functionality to enable decryption of
85 // packet captures.
tsi_tls_session_key_logging_supported()86 static constexpr bool tsi_tls_session_key_logging_supported() {
87 // Supported only for open-ssl versions >= 1.1.1
88 #if OPENSSL_VERSION_NUMBER >= 0x10101000 && !defined(LIBRESSL_VERSION_NUMBER)
89   return true;
90 #else
91   return false;
92 #endif
93 }
94 
95 // --- tsi_ssl_client_handshaker_factory object ---
96 
97 // This object creates a client tsi_handshaker objects implemented in terms of
98 // the TLS 1.2 specification.
99 
100 typedef struct tsi_ssl_client_handshaker_factory
101     tsi_ssl_client_handshaker_factory;
102 
103 // Object that holds a private key / certificate chain pair in PEM format.
104 struct tsi_ssl_pem_key_cert_pair {
105   // private_key is the NULL-terminated string containing the PEM encoding of
106   // the client's private key.
107   const char* private_key;
108 
109   // cert_chain is the NULL-terminated string containing the PEM encoding of
110   // the client's certificate chain.
111   const char* cert_chain;
112 };
113 // TO BE DEPRECATED.
114 // Creates a client handshaker factory.
115 // - pem_key_cert_pair is a pointer to the object containing client's private
116 //   key and certificate chain. This parameter can be NULL if the client does
117 //   not have such a key/cert pair.
118 // - pem_roots_cert is the NULL-terminated string containing the PEM encoding of
119 //   the server root certificates.
120 // - cipher_suites contains an optional list of the ciphers that the client
121 //   supports. The format of this string is described in:
122 //   https://www.openssl.org/docs/apps/ciphers.html.
123 //   This parameter can be set to NULL to use the default set of ciphers.
124 //   TODO(jboeuf): Revisit the format of this parameter.
125 // - alpn_protocols is an array containing the NULL terminated protocol names
126 //   that the handshakers created with this factory support. This parameter can
127 //   be NULL.
128 // - num_alpn_protocols is the number of alpn protocols and associated lengths
129 //   specified. If this parameter is 0, the other alpn parameters must be NULL.
130 // - factory is the address of the factory pointer to be created.
131 
132 // - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case
133 //   where a parameter is invalid.
134 tsi_result tsi_create_ssl_client_handshaker_factory(
135     const tsi_ssl_pem_key_cert_pair* pem_key_cert_pair,
136     const char* pem_root_certs, const char* cipher_suites,
137     const char** alpn_protocols, uint16_t num_alpn_protocols,
138     tsi_ssl_client_handshaker_factory** factory);
139 
140 struct tsi_ssl_client_handshaker_options {
141   // pem_key_cert_pair is a pointer to the object containing client's private
142   // key and certificate chain. This parameter can be NULL if the client does
143   // not have such a key/cert pair.
144   const tsi_ssl_pem_key_cert_pair* pem_key_cert_pair;
145   // pem_roots_cert is the NULL-terminated string containing the PEM encoding of
146   // the client root certificates.
147   const char* pem_root_certs;
148   // root_store is a pointer to the ssl_root_certs_store object. If root_store
149   // is not nullptr and SSL implementation permits, root_store will be used as
150   // root certificates. Otherwise, pem_roots_cert will be used to load server
151   // root certificates.
152   const tsi_ssl_root_certs_store* root_store;
153   // cipher_suites contains an optional list of the ciphers that the client
154   // supports. The format of this string is described in:
155   // https://www.openssl.org/docs/apps/ciphers.html.
156   // This parameter can be set to NULL to use the default set of ciphers.
157   // TODO(jboeuf): Revisit the format of this parameter.
158   const char* cipher_suites;
159   // alpn_protocols is an array containing the NULL terminated protocol names
160   // that the handshakers created with this factory support. This parameter can
161   // be NULL.
162   const char** alpn_protocols;
163   // num_alpn_protocols is the number of alpn protocols and associated lengths
164   // specified. If this parameter is 0, the other alpn parameters must be
165   // NULL.
166   size_t num_alpn_protocols;
167   // ssl_session_cache is a cache for reusable client-side sessions.
168   tsi_ssl_session_cache* session_cache;
169   // tsi_ssl_key_logger is an instance used to log SSL keys to a file.
170   tsi::TlsSessionKeyLoggerCache::TlsSessionKeyLogger* key_logger;
171 
172   // skip server certificate verification.
173   bool skip_server_certificate_verification;
174 
175   // The min and max TLS versions that will be negotiated by the handshaker.
176   tsi_tls_version min_tls_version;
177   tsi_tls_version max_tls_version;
178 
179   // The directory where all hashed CRL files enforced by the handshaker are
180   // located. If the directory is invalid, CRL checking will fail open and just
181   // log. An empty directory will not enable crl checking. Only OpenSSL version
182   // >= 1.1 is supported for CRL checking. Cannot be used in conjunction with
183   // `crl_provider`.
184   const char* crl_directory;
185 
186   // A provider of CRLs. If set, when doing handshakes the `CrlProvider`'s
187   // `GetCrl` function will be called to find CRLs when checking certificates
188   // for revocation. Cannot be used in conjunction with `crl_directory`.
189   // This provider is created and owned by the user and passed in through
190   // options as a shared_ptr.
191   std::shared_ptr<grpc_core::experimental::CrlProvider> crl_provider;
192 
tsi_ssl_client_handshaker_optionstsi_ssl_client_handshaker_options193   tsi_ssl_client_handshaker_options()
194       : pem_key_cert_pair(nullptr),
195         pem_root_certs(nullptr),
196         root_store(nullptr),
197         cipher_suites(nullptr),
198         alpn_protocols(nullptr),
199         num_alpn_protocols(0),
200         session_cache(nullptr),
201         key_logger(nullptr),
202         skip_server_certificate_verification(false),
203         min_tls_version(tsi_tls_version::TSI_TLS1_2),
204         max_tls_version(tsi_tls_version::TSI_TLS1_3),
205         crl_directory(nullptr) {}
206 };
207 
208 // Creates a client handshaker factory.
209 // - options is the options used to create a factory.
210 // - factory is the address of the factory pointer to be created.
211 
212 // - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case
213 //   where a parameter is invalid.
214 tsi_result tsi_create_ssl_client_handshaker_factory_with_options(
215     const tsi_ssl_client_handshaker_options* options,
216     tsi_ssl_client_handshaker_factory** factory);
217 
218 // Creates a client handshaker.
219 //- factory is the factory from which the handshaker will be created.
220 //- server_name_indication indicates the name of the server the client is
221 //  trying to connect to which will be relayed to the server using the SNI
222 //  extension.
223 //- network_bio_buf_size and ssl_bio_buf_size represent BIO pair buffers used in
224 //  SSL. The buffer size being 0 translates to 17KB in boringSSL.
225 //- handshaker is the address of the handshaker pointer to be created.
226 
227 //- This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case
228 //  where a parameter is invalid.
229 tsi_result tsi_ssl_client_handshaker_factory_create_handshaker(
230     tsi_ssl_client_handshaker_factory* factory,
231     const char* server_name_indication, size_t network_bio_buf_size,
232     size_t ssl_bio_buf_size, tsi_handshaker** handshaker);
233 
234 // Increments reference count of the client handshaker factory.
235 tsi_ssl_client_handshaker_factory* tsi_ssl_client_handshaker_factory_ref(
236     tsi_ssl_client_handshaker_factory* client_factory);
237 
238 // Decrements reference count of the handshaker factory. Handshaker factory will
239 // be destroyed once no references exist.
240 void tsi_ssl_client_handshaker_factory_unref(
241     tsi_ssl_client_handshaker_factory* factory);
242 
243 // --- tsi_ssl_server_handshaker_factory object ---
244 
245 // This object creates a client tsi_handshaker objects implemented in terms of
246 // the TLS 1.2 specification.
247 
248 typedef struct tsi_ssl_server_handshaker_factory
249     tsi_ssl_server_handshaker_factory;
250 
251 // TO BE DEPRECATED.
252 // Creates a server handshaker factory.
253 // - pem_key_cert_pairs is an array private key / certificate chains of the
254 //   server.
255 // - num_key_cert_pairs is the number of items in the pem_key_cert_pairs array.
256 // - pem_root_certs is the NULL-terminated string containing the PEM encoding
257 //   of the client root certificates. This parameter may be NULL if the server
258 //   does not want the client to be authenticated with SSL.
259 // - cipher_suites contains an optional list of the ciphers that the server
260 //   supports. The format of this string is described in:
261 //   https://www.openssl.org/docs/apps/ciphers.html.
262 //   This parameter can be set to NULL to use the default set of ciphers.
263 //   TODO(jboeuf): Revisit the format of this parameter.
264 // - alpn_protocols is an array containing the NULL terminated protocol names
265 //   that the handshakers created with this factory support. This parameter can
266 //   be NULL.
267 // - num_alpn_protocols is the number of alpn protocols and associated lengths
268 //   specified. If this parameter is 0, the other alpn parameters must be NULL.
269 // - factory is the address of the factory pointer to be created.
270 
271 // - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case
272 //   where a parameter is invalid.
273 tsi_result tsi_create_ssl_server_handshaker_factory(
274     const tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs,
275     size_t num_key_cert_pairs, const char* pem_client_root_certs,
276     int force_client_auth, const char* cipher_suites,
277     const char** alpn_protocols, uint16_t num_alpn_protocols,
278     tsi_ssl_server_handshaker_factory** factory);
279 
280 // TO BE DEPRECATED.
281 // Same as tsi_create_ssl_server_handshaker_factory method except uses
282 // tsi_client_certificate_request_type to support more ways to handle client
283 // certificate authentication.
284 // - client_certificate_request, if set to non-zero will force the client to
285 //   authenticate with an SSL cert. Note that this option is ignored if
286 //   pem_client_root_certs is NULL or pem_client_roots_certs_size is 0
287 tsi_result tsi_create_ssl_server_handshaker_factory_ex(
288     const tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs,
289     size_t num_key_cert_pairs, const char* pem_client_root_certs,
290     tsi_client_certificate_request_type client_certificate_request,
291     const char* cipher_suites, const char** alpn_protocols,
292     uint16_t num_alpn_protocols, tsi_ssl_server_handshaker_factory** factory);
293 
294 struct tsi_ssl_server_handshaker_options {
295   // pem_key_cert_pairs is an array private key / certificate chains of the
296   // server.
297   const tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs;
298   // num_key_cert_pairs is the number of items in the pem_key_cert_pairs
299   // array.
300   size_t num_key_cert_pairs;
301   // pem_root_certs is the NULL-terminated string containing the PEM encoding
302   // of the server root certificates. This parameter may be NULL if the server
303   // does not want the client to be authenticated with SSL.
304   const char* pem_client_root_certs;
305   // client_certificate_request, if set to non-zero will force the client to
306   // authenticate with an SSL cert. Note that this option is ignored if
307   // pem_client_root_certs is NULL or pem_client_roots_certs_size is 0.
308   tsi_client_certificate_request_type client_certificate_request;
309   // cipher_suites contains an optional list of the ciphers that the server
310   // supports. The format of this string is described in:
311   // https://www.openssl.org/docs/apps/ciphers.html.
312   // This parameter can be set to NULL to use the default set of ciphers.
313   // TODO(jboeuf): Revisit the format of this parameter.
314   const char* cipher_suites;
315   // alpn_protocols is an array containing the NULL terminated protocol names
316   // that the handshakers created with this factory support. This parameter can
317   // be NULL.
318   const char** alpn_protocols;
319   // num_alpn_protocols is the number of alpn protocols and associated lengths
320   // specified. If this parameter is 0, the other alpn parameters must be
321   // NULL.
322   uint16_t num_alpn_protocols;
323   // session_ticket_key is optional key for encrypting session keys. If
324   // parameter is not specified it must be NULL.
325   const char* session_ticket_key;
326   // session_ticket_key_size is a size of session ticket encryption key.
327   size_t session_ticket_key_size;
328   // The min and max TLS versions that will be negotiated by the handshaker.
329   tsi_tls_version min_tls_version;
330   tsi_tls_version max_tls_version;
331   // tsi_ssl_key_logger is an instance used to log SSL keys to a file.
332   tsi::TlsSessionKeyLoggerCache::TlsSessionKeyLogger* key_logger;
333 
334   // The directory where all hashed CRL files are cached in the x.509 store and
335   // enforced by the handshaker are located. If the directory is invalid, CRL
336   // checking will fail open and just log. An empty directory will not enable
337   // crl checking. Only OpenSSL version > 1.1 is supported for CRL checking
338   const char* crl_directory;
339 
340   // A provider of CRLs. If set, when doing handshakes the `CrlProvider`'s
341   // `GetCrl` function will be called to find CRLs when checking certificates
342   // for revocation. Cannot be used in conjunction with `crl_directory`.
343   // This provider is created and owned by the user and passed in through
344   // options as a shared_ptr.
345   std::shared_ptr<grpc_core::experimental::CrlProvider> crl_provider;
346 
347   // If true, the SSL server sends a list of CA names to the client in the
348   // ServerHello. This list of CA names is extracted from the server's trust
349   // bundle, and the client may use this lint as a hint to decide which
350   // certificate it should send to the server.
351   //
352   // WARNING: This is an extremely dangerous option. If the server's trust
353   // bundle is sufficiently large, then setting this bit to true will result in
354   // the server being unable to generate a ServerHello, and hence the server
355   // will be unusable.
356   bool send_client_ca_list;
357 
tsi_ssl_server_handshaker_optionstsi_ssl_server_handshaker_options358   tsi_ssl_server_handshaker_options()
359       : pem_key_cert_pairs(nullptr),
360         num_key_cert_pairs(0),
361         pem_client_root_certs(nullptr),
362         client_certificate_request(TSI_DONT_REQUEST_CLIENT_CERTIFICATE),
363         cipher_suites(nullptr),
364         alpn_protocols(nullptr),
365         num_alpn_protocols(0),
366         session_ticket_key(nullptr),
367         session_ticket_key_size(0),
368         min_tls_version(tsi_tls_version::TSI_TLS1_2),
369         max_tls_version(tsi_tls_version::TSI_TLS1_3),
370         key_logger(nullptr),
371         crl_directory(nullptr),
372         send_client_ca_list(true) {}
373 };
374 
375 // Creates a server handshaker factory.
376 // - options is the options used to create a factory.
377 // - factory is the address of the factory pointer to be created.
378 
379 // - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case
380 //   where a parameter is invalid.
381 tsi_result tsi_create_ssl_server_handshaker_factory_with_options(
382     const tsi_ssl_server_handshaker_options* options,
383     tsi_ssl_server_handshaker_factory** factory);
384 
385 // Creates a server handshaker.
386 //- factory is the factory from which the handshaker will be created.
387 //- network_bio_buf_size and ssl_bio_buf_size represent BIO pair buffers used in
388 //  SSL. The buffer size being 0 translates to 17KB in boringSSL.
389 //- handshaker is the address of the handshaker pointer to be created.
390 
391 //- This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case
392 //  where a parameter is invalid.
393 tsi_result tsi_ssl_server_handshaker_factory_create_handshaker(
394     tsi_ssl_server_handshaker_factory* factory, size_t network_bio_buf_size,
395     size_t ssl_bio_buf_size, tsi_handshaker** handshaker);
396 
397 // Decrements reference count of the handshaker factory. Handshaker factory will
398 // be destroyed once no references exist.
399 void tsi_ssl_server_handshaker_factory_unref(
400     tsi_ssl_server_handshaker_factory* factory);
401 
402 // Util that checks that an ssl peer matches a specific name.
403 // Still TODO(jboeuf):
404 // - handle mixed case.
405 // - handle %encoded chars.
406 // - handle public suffix wildchar more strictly (e.g. *.co.uk)
407 int tsi_ssl_peer_matches_name(const tsi_peer* peer, absl::string_view name);
408 
409 // --- Testing support. ---
410 
411 // These functions and typedefs are not intended to be used outside of testing.
412 //
413 
414 // Base type of client and server handshaker factories.
415 typedef struct tsi_ssl_handshaker_factory tsi_ssl_handshaker_factory;
416 
417 // Function pointer to handshaker_factory destructor.
418 typedef void (*tsi_ssl_handshaker_factory_destructor)(
419     tsi_ssl_handshaker_factory* factory);
420 
421 // Virtual table for tsi_ssl_handshaker_factory.
422 struct tsi_ssl_handshaker_factory_vtable {
423   tsi_ssl_handshaker_factory_destructor destroy;
424 };
425 // Set destructor of handshaker_factory to new_destructor, returns previous
426 // destructor.
427 const tsi_ssl_handshaker_factory_vtable* tsi_ssl_handshaker_factory_swap_vtable(
428     tsi_ssl_handshaker_factory* factory,
429     tsi_ssl_handshaker_factory_vtable* new_vtable);
430 
431 // Exposed for testing only.
432 tsi_result tsi_ssl_extract_x509_subject_names_from_pem_cert(
433     const char* pem_cert, tsi_peer* peer);
434 
435 // Exposed for testing only.
436 tsi_result tsi_ssl_get_cert_chain_contents(STACK_OF(X509) * peer_chain,
437                                            tsi_peer_property* property);
438 
439 #endif  // GRPC_SRC_CORE_TSI_SSL_TRANSPORT_SECURITY_H
440