Imported Upstream version 1.36.0
[platform/upstream/grpc.git] / src / core / tsi / ssl_transport_security.h
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_CORE_TSI_SSL_TRANSPORT_SECURITY_H
20 #define GRPC_CORE_TSI_SSL_TRANSPORT_SECURITY_H
21
22 #include <grpc/support/port_platform.h>
23
24 #include <grpc/grpc_security_constants.h>
25 #include "absl/strings/string_view.h"
26 #include "src/core/tsi/transport_security_interface.h"
27
28 extern "C" {
29 #include <openssl/x509.h>
30 }
31
32 /* Value for the TSI_CERTIFICATE_TYPE_PEER_PROPERTY property for X509 certs. */
33 #define TSI_X509_CERTIFICATE_TYPE "X509"
34
35 /* This property is of type TSI_PEER_PROPERTY_STRING.  */
36 #define TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY "x509_subject_common_name"
37 #define TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY \
38   "x509_subject_alternative_name"
39 #define TSI_SSL_SESSION_REUSED_PEER_PROPERTY "ssl_session_reused"
40
41 #define TSI_X509_PEM_CERT_PROPERTY "x509_pem_cert"
42
43 #define TSI_X509_PEM_CERT_CHAIN_PROPERTY "x509_pem_cert_chain"
44
45 #define TSI_SSL_ALPN_SELECTED_PROTOCOL "ssl_alpn_selected_protocol"
46
47 #define TSI_X509_URI_PEER_PROPERTY "x509_uri"
48
49 /* --- tsi_ssl_root_certs_store object ---
50
51    This object stores SSL root certificates. It can be shared by multiple SSL
52    context. */
53 typedef struct tsi_ssl_root_certs_store tsi_ssl_root_certs_store;
54
55 /* Given a NULL-terminated string containing the PEM encoding of the root
56    certificates, creates a tsi_ssl_root_certs_store object. */
57 tsi_ssl_root_certs_store* tsi_ssl_root_certs_store_create(
58     const char* pem_roots);
59
60 /* Destroys the tsi_ssl_root_certs_store object. */
61 void tsi_ssl_root_certs_store_destroy(tsi_ssl_root_certs_store* self);
62
63 /* --- tsi_ssl_session_cache object ---
64
65    Cache for SSL sessions for sessions resumption.  */
66
67 typedef struct tsi_ssl_session_cache tsi_ssl_session_cache;
68
69 /* Create LRU cache for SSL sessions with \a capacity.  */
70 tsi_ssl_session_cache* tsi_ssl_session_cache_create_lru(size_t capacity);
71
72 /* Increment reference counter of \a cache.  */
73 void tsi_ssl_session_cache_ref(tsi_ssl_session_cache* cache);
74
75 /* Decrement reference counter of \a cache.  */
76 void tsi_ssl_session_cache_unref(tsi_ssl_session_cache* cache);
77
78 /* --- tsi_ssl_client_handshaker_factory object ---
79
80    This object creates a client tsi_handshaker objects implemented in terms of
81    the TLS 1.2 specificiation.  */
82
83 typedef struct tsi_ssl_client_handshaker_factory
84     tsi_ssl_client_handshaker_factory;
85
86 /* Object that holds a private key / certificate chain pair in PEM format. */
87 struct tsi_ssl_pem_key_cert_pair {
88   /* private_key is the NULL-terminated string containing the PEM encoding of
89      the client's private key. */
90   const char* private_key;
91
92   /* cert_chain is the NULL-terminated string containing the PEM encoding of
93      the client's certificate chain. */
94   const char* cert_chain;
95 };
96 /* TO BE DEPRECATED.
97    Creates a client handshaker factory.
98    - pem_key_cert_pair is a pointer to the object containing client's private
99      key and certificate chain. This parameter can be NULL if the client does
100      not have such a key/cert pair.
101    - pem_roots_cert is the NULL-terminated string containing the PEM encoding of
102      the server root certificates.
103    - cipher_suites contains an optional list of the ciphers that the client
104      supports. The format of this string is described in:
105      https://www.openssl.org/docs/apps/ciphers.html.
106      This parameter can be set to NULL to use the default set of ciphers.
107      TODO(jboeuf): Revisit the format of this parameter.
108    - alpn_protocols is an array containing the NULL terminated protocol names
109      that the handshakers created with this factory support. This parameter can
110      be NULL.
111    - num_alpn_protocols is the number of alpn protocols and associated lengths
112      specified. If this parameter is 0, the other alpn parameters must be NULL.
113    - factory is the address of the factory pointer to be created.
114
115    - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case
116      where a parameter is invalid.  */
117 tsi_result tsi_create_ssl_client_handshaker_factory(
118     const tsi_ssl_pem_key_cert_pair* pem_key_cert_pair,
119     const char* pem_root_certs, const char* cipher_suites,
120     const char** alpn_protocols, uint16_t num_alpn_protocols,
121     tsi_ssl_client_handshaker_factory** factory);
122
123 struct tsi_ssl_client_handshaker_options {
124   /* pem_key_cert_pair is a pointer to the object containing client's private
125      key and certificate chain. This parameter can be NULL if the client does
126      not have such a key/cert pair. */
127   const tsi_ssl_pem_key_cert_pair* pem_key_cert_pair;
128   /* pem_roots_cert is the NULL-terminated string containing the PEM encoding of
129      the client root certificates. */
130   const char* pem_root_certs;
131   /* root_store is a pointer to the ssl_root_certs_store object. If root_store
132     is not nullptr and SSL implementation permits, root_store will be used as
133     root certificates. Otherwise, pem_roots_cert will be used to load server
134     root certificates. */
135   const tsi_ssl_root_certs_store* root_store;
136   /* cipher_suites contains an optional list of the ciphers that the client
137      supports. The format of this string is described in:
138      https://www.openssl.org/docs/apps/ciphers.html.
139      This parameter can be set to NULL to use the default set of ciphers.
140      TODO(jboeuf): Revisit the format of this parameter. */
141   const char* cipher_suites;
142   /* alpn_protocols is an array containing the NULL terminated protocol names
143      that the handshakers created with this factory support. This parameter can
144      be NULL. */
145   const char** alpn_protocols;
146   /* num_alpn_protocols is the number of alpn protocols and associated lengths
147      specified. If this parameter is 0, the other alpn parameters must be
148      NULL. */
149   size_t num_alpn_protocols;
150   /* ssl_session_cache is a cache for reusable client-side sessions. */
151   tsi_ssl_session_cache* session_cache;
152
153   /* skip server certificate verification. */
154   bool skip_server_certificate_verification;
155
156   /* The min and max TLS versions that will be negotiated by the handshaker. */
157   tsi_tls_version min_tls_version;
158   tsi_tls_version max_tls_version;
159
160   tsi_ssl_client_handshaker_options()
161       : pem_key_cert_pair(nullptr),
162         pem_root_certs(nullptr),
163         root_store(nullptr),
164         cipher_suites(nullptr),
165         alpn_protocols(nullptr),
166         num_alpn_protocols(0),
167         session_cache(nullptr),
168         skip_server_certificate_verification(false),
169         min_tls_version(tsi_tls_version::TSI_TLS1_2),
170         max_tls_version(tsi_tls_version::TSI_TLS1_3) {}
171 };
172
173 /* Creates a client handshaker factory.
174    - options is the options used to create a factory.
175    - factory is the address of the factory pointer to be created.
176
177    - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case
178      where a parameter is invalid. */
179 tsi_result tsi_create_ssl_client_handshaker_factory_with_options(
180     const tsi_ssl_client_handshaker_options* options,
181     tsi_ssl_client_handshaker_factory** factory);
182
183 /* Creates a client handshaker.
184   - factory is the factory from which the handshaker will be created.
185   - server_name_indication indicates the name of the server the client is
186     trying to connect to which will be relayed to the server using the SNI
187     extension.
188   - handshaker is the address of the handshaker pointer to be created.
189
190   - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case
191     where a parameter is invalid.  */
192 tsi_result tsi_ssl_client_handshaker_factory_create_handshaker(
193     tsi_ssl_client_handshaker_factory* factory,
194     const char* server_name_indication, tsi_handshaker** handshaker);
195
196 /* Decrements reference count of the handshaker factory. Handshaker factory will
197  * be destroyed once no references exist. */
198 void tsi_ssl_client_handshaker_factory_unref(
199     tsi_ssl_client_handshaker_factory* factory);
200
201 /* --- tsi_ssl_server_handshaker_factory object ---
202
203    This object creates a client tsi_handshaker objects implemented in terms of
204    the TLS 1.2 specificiation.  */
205
206 typedef struct tsi_ssl_server_handshaker_factory
207     tsi_ssl_server_handshaker_factory;
208
209 /* TO BE DEPRECATED.
210    Creates a server handshaker factory.
211    - pem_key_cert_pairs is an array private key / certificate chains of the
212      server.
213    - num_key_cert_pairs is the number of items in the pem_key_cert_pairs array.
214    - pem_root_certs is the NULL-terminated string containing the PEM encoding
215      of the client root certificates. This parameter may be NULL if the server
216      does not want the client to be authenticated with SSL.
217    - cipher_suites contains an optional list of the ciphers that the server
218      supports. The format of this string is described in:
219      https://www.openssl.org/docs/apps/ciphers.html.
220      This parameter can be set to NULL to use the default set of ciphers.
221      TODO(jboeuf): Revisit the format of this parameter.
222    - alpn_protocols is an array containing the NULL terminated protocol names
223      that the handshakers created with this factory support. This parameter can
224      be NULL.
225    - num_alpn_protocols is the number of alpn protocols and associated lengths
226      specified. If this parameter is 0, the other alpn parameters must be NULL.
227    - factory is the address of the factory pointer to be created.
228
229    - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case
230      where a parameter is invalid.  */
231 tsi_result tsi_create_ssl_server_handshaker_factory(
232     const tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs,
233     size_t num_key_cert_pairs, const char* pem_client_root_certs,
234     int force_client_auth, const char* cipher_suites,
235     const char** alpn_protocols, uint16_t num_alpn_protocols,
236     tsi_ssl_server_handshaker_factory** factory);
237
238 /* TO BE DEPRECATED.
239    Same as tsi_create_ssl_server_handshaker_factory method except uses
240    tsi_client_certificate_request_type to support more ways to handle client
241    certificate authentication.
242    - client_certificate_request, if set to non-zero will force the client to
243      authenticate with an SSL cert. Note that this option is ignored if
244      pem_client_root_certs is NULL or pem_client_roots_certs_size is 0 */
245 tsi_result tsi_create_ssl_server_handshaker_factory_ex(
246     const tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs,
247     size_t num_key_cert_pairs, const char* pem_client_root_certs,
248     tsi_client_certificate_request_type client_certificate_request,
249     const char* cipher_suites, const char** alpn_protocols,
250     uint16_t num_alpn_protocols, tsi_ssl_server_handshaker_factory** factory);
251
252 struct tsi_ssl_server_handshaker_options {
253   /* pem_key_cert_pairs is an array private key / certificate chains of the
254      server. */
255   const tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs;
256   /* num_key_cert_pairs is the number of items in the pem_key_cert_pairs
257      array. */
258   size_t num_key_cert_pairs;
259   /* pem_root_certs is the NULL-terminated string containing the PEM encoding
260      of the server root certificates. This parameter may be NULL if the server
261      does not want the client to be authenticated with SSL. */
262   const char* pem_client_root_certs;
263   /* client_certificate_request, if set to non-zero will force the client to
264      authenticate with an SSL cert. Note that this option is ignored if
265      pem_client_root_certs is NULL or pem_client_roots_certs_size is 0. */
266   tsi_client_certificate_request_type client_certificate_request;
267   /* cipher_suites contains an optional list of the ciphers that the server
268      supports. The format of this string is described in:
269      https://www.openssl.org/docs/apps/ciphers.html.
270      This parameter can be set to NULL to use the default set of ciphers.
271      TODO(jboeuf): Revisit the format of this parameter. */
272   const char* cipher_suites;
273   /* alpn_protocols is an array containing the NULL terminated protocol names
274      that the handshakers created with this factory support. This parameter can
275      be NULL. */
276   const char** alpn_protocols;
277   /* num_alpn_protocols is the number of alpn protocols and associated lengths
278      specified. If this parameter is 0, the other alpn parameters must be
279      NULL. */
280   uint16_t num_alpn_protocols;
281   /* session_ticket_key is optional key for encrypting session keys. If
282      parameter is not specified it must be NULL. */
283   const char* session_ticket_key;
284   /* session_ticket_key_size is a size of session ticket encryption key. */
285   size_t session_ticket_key_size;
286   /* The min and max TLS versions that will be negotiated by the handshaker. */
287   tsi_tls_version min_tls_version;
288   tsi_tls_version max_tls_version;
289
290   tsi_ssl_server_handshaker_options()
291       : pem_key_cert_pairs(nullptr),
292         num_key_cert_pairs(0),
293         pem_client_root_certs(nullptr),
294         client_certificate_request(TSI_DONT_REQUEST_CLIENT_CERTIFICATE),
295         cipher_suites(nullptr),
296         alpn_protocols(nullptr),
297         num_alpn_protocols(0),
298         session_ticket_key(nullptr),
299         session_ticket_key_size(0),
300         min_tls_version(tsi_tls_version::TSI_TLS1_2),
301         max_tls_version(tsi_tls_version::TSI_TLS1_3) {}
302 };
303
304 /* Creates a server handshaker factory.
305    - options is the options used to create a factory.
306    - factory is the address of the factory pointer to be created.
307
308    - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case
309      where a parameter is invalid. */
310 tsi_result tsi_create_ssl_server_handshaker_factory_with_options(
311     const tsi_ssl_server_handshaker_options* options,
312     tsi_ssl_server_handshaker_factory** factory);
313
314 /* Creates a server handshaker.
315   - factory is the factory from which the handshaker will be created.
316   - handshaker is the address of the handshaker pointer to be created.
317
318   - This method returns TSI_OK on success or TSI_INVALID_PARAMETER in the case
319     where a parameter is invalid.  */
320 tsi_result tsi_ssl_server_handshaker_factory_create_handshaker(
321     tsi_ssl_server_handshaker_factory* factory, tsi_handshaker** handshaker);
322
323 /* Decrements reference count of the handshaker factory. Handshaker factory will
324  * be destroyed once no references exist. */
325 void tsi_ssl_server_handshaker_factory_unref(
326     tsi_ssl_server_handshaker_factory* factory);
327
328 /* Util that checks that an ssl peer matches a specific name.
329    Still TODO(jboeuf):
330    - handle mixed case.
331    - handle %encoded chars.
332    - handle public suffix wildchar more strictly (e.g. *.co.uk) */
333 int tsi_ssl_peer_matches_name(const tsi_peer* peer, absl::string_view name);
334
335 /* --- Testing support. ---
336
337    These functions and typedefs are not intended to be used outside of testing.
338    */
339
340 /* Base type of client and server handshaker factories. */
341 typedef struct tsi_ssl_handshaker_factory tsi_ssl_handshaker_factory;
342
343 /* Function pointer to handshaker_factory destructor. */
344 typedef void (*tsi_ssl_handshaker_factory_destructor)(
345     tsi_ssl_handshaker_factory* factory);
346
347 /* Virtual table for tsi_ssl_handshaker_factory. */
348 struct tsi_ssl_handshaker_factory_vtable {
349   tsi_ssl_handshaker_factory_destructor destroy;
350 };
351 /* Set destructor of handshaker_factory to new_destructor, returns previous
352    destructor. */
353 const tsi_ssl_handshaker_factory_vtable* tsi_ssl_handshaker_factory_swap_vtable(
354     tsi_ssl_handshaker_factory* factory,
355     tsi_ssl_handshaker_factory_vtable* new_vtable);
356
357 /* Exposed for testing only. */
358 tsi_result tsi_ssl_extract_x509_subject_names_from_pem_cert(
359     const char* pem_cert, tsi_peer* peer);
360
361 /* Exposed for testing only. */
362 tsi_result tsi_ssl_get_cert_chain_contents(STACK_OF(X509) * peer_chain,
363                                            tsi_peer_property* property);
364
365 #endif /* GRPC_CORE_TSI_SSL_TRANSPORT_SECURITY_H */