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