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 tsi_ssl_client_handshaker_optionstsi_ssl_client_handshaker_options160 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 tsi_ssl_server_handshaker_optionstsi_ssl_server_handshaker_options290 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 */ 366