diff options
author | 2015-09-22 10:42:19 -0700 | |
---|---|---|
committer | 2015-09-22 10:42:19 -0700 | |
commit | 45724b35e411fef7c5da66a74c78428c11d56843 (patch) | |
tree | 9264034aca675c89444e02f72ef58e67d7043604 /src/core/tsi/ssl_transport_security.c | |
parent | 298751c1195523ef6228595043b583c3a6270e08 (diff) |
indent pass to get logical source lines on one physical line
Diffstat (limited to 'src/core/tsi/ssl_transport_security.c')
-rw-r--r-- | src/core/tsi/ssl_transport_security.c | 2176 |
1 files changed, 1153 insertions, 1023 deletions
diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c index 99ce7ecadf..a4e3503a96 100644 --- a/src/core/tsi/ssl_transport_security.c +++ b/src/core/tsi/ssl_transport_security.c @@ -43,7 +43,7 @@ #include "src/core/tsi/transport_security.h" #include <openssl/bio.h> -#include <openssl/crypto.h> /* For OPENSSL_free */ +#include <openssl/crypto.h> /* For OPENSSL_free */ #include <openssl/err.h> #include <openssl/ssl.h> #include <openssl/x509.h> @@ -67,47 +67,50 @@ /* --- Structure definitions. ---*/ -struct tsi_ssl_handshaker_factory { - tsi_result (*create_handshaker)(tsi_ssl_handshaker_factory* self, - const char* server_name_indication, - tsi_handshaker** handshaker); - void (*destroy)(tsi_ssl_handshaker_factory* self); +struct tsi_ssl_handshaker_factory +{ + tsi_result (*create_handshaker) (tsi_ssl_handshaker_factory * self, const char *server_name_indication, tsi_handshaker ** handshaker); + void (*destroy) (tsi_ssl_handshaker_factory * self); }; -typedef struct { +typedef struct +{ tsi_ssl_handshaker_factory base; - SSL_CTX* ssl_context; - unsigned char* alpn_protocol_list; + SSL_CTX *ssl_context; + unsigned char *alpn_protocol_list; size_t alpn_protocol_list_length; } tsi_ssl_client_handshaker_factory; -typedef struct { +typedef struct +{ tsi_ssl_handshaker_factory base; /* Several contexts to support SNI. The tsi_peer array contains the subject names of the server certificates associated with the contexts at the same index. */ - SSL_CTX** ssl_contexts; - tsi_peer* ssl_context_x509_subject_names; + SSL_CTX **ssl_contexts; + tsi_peer *ssl_context_x509_subject_names; size_t ssl_context_count; - unsigned char* alpn_protocol_list; + unsigned char *alpn_protocol_list; size_t alpn_protocol_list_length; } tsi_ssl_server_handshaker_factory; -typedef struct { +typedef struct +{ tsi_handshaker base; - SSL* ssl; - BIO* into_ssl; - BIO* from_ssl; + SSL *ssl; + BIO *into_ssl; + BIO *from_ssl; tsi_result result; } tsi_ssl_handshaker; -typedef struct { +typedef struct +{ tsi_frame_protector base; - SSL* ssl; - BIO* into_ssl; - BIO* from_ssl; - unsigned char* buffer; + SSL *ssl; + BIO *into_ssl; + BIO *from_ssl; + unsigned char *buffer; size_t buffer_size; size_t buffer_offset; } tsi_ssl_frame_protector; @@ -115,41 +118,54 @@ typedef struct { /* --- Library Initialization. ---*/ static gpr_once init_openssl_once = GPR_ONCE_INIT; -static gpr_mu* openssl_mutexes = NULL; - -static void openssl_locking_cb(int mode, int type, const char* file, int line) { - if (mode & CRYPTO_LOCK) { - gpr_mu_lock(&openssl_mutexes[type]); - } else { - gpr_mu_unlock(&openssl_mutexes[type]); - } +static gpr_mu *openssl_mutexes = NULL; + +static void +openssl_locking_cb (int mode, int type, const char *file, int line) +{ + if (mode & CRYPTO_LOCK) + { + gpr_mu_lock (&openssl_mutexes[type]); + } + else + { + gpr_mu_unlock (&openssl_mutexes[type]); + } } -static unsigned long openssl_thread_id_cb(void) { - return (unsigned long)gpr_thd_currentid(); +static unsigned long +openssl_thread_id_cb (void) +{ + return (unsigned long) gpr_thd_currentid (); } -static void init_openssl(void) { +static void +init_openssl (void) +{ int i; int num_locks; - SSL_library_init(); - SSL_load_error_strings(); - OpenSSL_add_all_algorithms(); - num_locks = CRYPTO_num_locks(); - GPR_ASSERT(num_locks > 0); - openssl_mutexes = malloc((size_t)num_locks * sizeof(gpr_mu)); - GPR_ASSERT(openssl_mutexes != NULL); - for (i = 0; i < CRYPTO_num_locks(); i++) { - gpr_mu_init(&openssl_mutexes[i]); - } - CRYPTO_set_locking_callback(openssl_locking_cb); - CRYPTO_set_id_callback(openssl_thread_id_cb); + SSL_library_init (); + SSL_load_error_strings (); + OpenSSL_add_all_algorithms (); + num_locks = CRYPTO_num_locks (); + GPR_ASSERT (num_locks > 0); + openssl_mutexes = malloc ((size_t) num_locks * sizeof (gpr_mu)); + GPR_ASSERT (openssl_mutexes != NULL); + for (i = 0; i < CRYPTO_num_locks (); i++) + { + gpr_mu_init (&openssl_mutexes[i]); + } + CRYPTO_set_locking_callback (openssl_locking_cb); + CRYPTO_set_id_callback (openssl_thread_id_cb); } /* --- Ssl utils. ---*/ -static const char* ssl_error_string(int error) { - switch (error) { +static const char * +ssl_error_string (int error) +{ + switch (error) + { case SSL_ERROR_NONE: return "SSL_ERROR_NONE"; case SSL_ERROR_ZERO_RETURN: @@ -170,791 +186,885 @@ static const char* ssl_error_string(int error) { return "SSL_ERROR_SSL"; default: return "Unknown error"; - } + } } /* TODO(jboeuf): Remove when we are past the debugging phase with this code. */ -static void ssl_log_where_info(const SSL* ssl, int where, int flag, - const char* msg) { - if ((where & flag) && tsi_tracing_enabled) { - gpr_log(GPR_INFO, "%20.20s - %30.30s - %5.10s", msg, - SSL_state_string_long(ssl), SSL_state_string(ssl)); - } +static void +ssl_log_where_info (const SSL * ssl, int where, int flag, const char *msg) +{ + if ((where & flag) && tsi_tracing_enabled) + { + gpr_log (GPR_INFO, "%20.20s - %30.30s - %5.10s", msg, SSL_state_string_long (ssl), SSL_state_string (ssl)); + } } /* Used for debugging. TODO(jboeuf): Remove when code is mature enough. */ -static void ssl_info_callback(const SSL* ssl, int where, int ret) { - if (ret == 0) { - gpr_log(GPR_ERROR, "ssl_info_callback: error occured.\n"); - return; - } +static void +ssl_info_callback (const SSL * ssl, int where, int ret) +{ + if (ret == 0) + { + gpr_log (GPR_ERROR, "ssl_info_callback: error occured.\n"); + return; + } - ssl_log_where_info(ssl, where, SSL_CB_LOOP, "LOOP"); - ssl_log_where_info(ssl, where, SSL_CB_HANDSHAKE_START, "HANDSHAKE START"); - ssl_log_where_info(ssl, where, SSL_CB_HANDSHAKE_DONE, "HANDSHAKE DONE"); + ssl_log_where_info (ssl, where, SSL_CB_LOOP, "LOOP"); + ssl_log_where_info (ssl, where, SSL_CB_HANDSHAKE_START, "HANDSHAKE START"); + ssl_log_where_info (ssl, where, SSL_CB_HANDSHAKE_DONE, "HANDSHAKE DONE"); } /* Returns 1 if name looks like an IP address, 0 otherwise. This is a very rough heuristic as it does not handle IPV6 or things like: 0300.0250.00.01, 0xC0.0Xa8.0x0.0x1, 000030052000001, 0xc0.052000001 */ -static int looks_like_ip_address(const char* name) { +static int +looks_like_ip_address (const char *name) +{ size_t i; size_t dot_count = 0; size_t num_size = 0; - for (i = 0; i < strlen(name); i++) { - if (name[i] >= '0' && name[i] <= '9') { - if (num_size > 3) return 0; - num_size++; - } else if (name[i] == '.') { - if (dot_count > 3 || num_size == 0) return 0; - dot_count++; - num_size = 0; - } else { - return 0; + for (i = 0; i < strlen (name); i++) + { + if (name[i] >= '0' && name[i] <= '9') + { + if (num_size > 3) + return 0; + num_size++; + } + else if (name[i] == '.') + { + if (dot_count > 3 || num_size == 0) + return 0; + dot_count++; + num_size = 0; + } + else + { + return 0; + } } - } - if (dot_count < 3 || num_size == 0) return 0; + if (dot_count < 3 || num_size == 0) + return 0; return 1; } /* Gets the subject CN from an X509 cert. */ -static tsi_result ssl_get_x509_common_name(X509* cert, unsigned char** utf8, - size_t* utf8_size) { +static tsi_result +ssl_get_x509_common_name (X509 * cert, unsigned char **utf8, size_t * utf8_size) +{ int common_name_index = -1; - X509_NAME_ENTRY* common_name_entry = NULL; - ASN1_STRING* common_name_asn1 = NULL; - X509_NAME* subject_name = X509_get_subject_name(cert); + X509_NAME_ENTRY *common_name_entry = NULL; + ASN1_STRING *common_name_asn1 = NULL; + X509_NAME *subject_name = X509_get_subject_name (cert); int utf8_returned_size = 0; - if (subject_name == NULL) { - gpr_log(GPR_ERROR, "Could not get subject name from certificate."); - return TSI_NOT_FOUND; - } - common_name_index = - X509_NAME_get_index_by_NID(subject_name, NID_commonName, -1); - if (common_name_index == -1) { - gpr_log(GPR_ERROR, - "Could not get common name of subject from certificate."); - return TSI_NOT_FOUND; - } - common_name_entry = X509_NAME_get_entry(subject_name, common_name_index); - if (common_name_entry == NULL) { - gpr_log(GPR_ERROR, "Could not get common name entry from certificate."); - return TSI_INTERNAL_ERROR; - } - common_name_asn1 = X509_NAME_ENTRY_get_data(common_name_entry); - if (common_name_asn1 == NULL) { - gpr_log(GPR_ERROR, - "Could not get common name entry asn1 from certificate."); - return TSI_INTERNAL_ERROR; - } - utf8_returned_size = ASN1_STRING_to_UTF8(utf8, common_name_asn1); - if (utf8_returned_size < 0) { - gpr_log(GPR_ERROR, "Could not extract utf8 from asn1 string."); - return TSI_OUT_OF_RESOURCES; - } - *utf8_size = (size_t)utf8_returned_size; + if (subject_name == NULL) + { + gpr_log (GPR_ERROR, "Could not get subject name from certificate."); + return TSI_NOT_FOUND; + } + common_name_index = X509_NAME_get_index_by_NID (subject_name, NID_commonName, -1); + if (common_name_index == -1) + { + gpr_log (GPR_ERROR, "Could not get common name of subject from certificate."); + return TSI_NOT_FOUND; + } + common_name_entry = X509_NAME_get_entry (subject_name, common_name_index); + if (common_name_entry == NULL) + { + gpr_log (GPR_ERROR, "Could not get common name entry from certificate."); + return TSI_INTERNAL_ERROR; + } + common_name_asn1 = X509_NAME_ENTRY_get_data (common_name_entry); + if (common_name_asn1 == NULL) + { + gpr_log (GPR_ERROR, "Could not get common name entry asn1 from certificate."); + return TSI_INTERNAL_ERROR; + } + utf8_returned_size = ASN1_STRING_to_UTF8 (utf8, common_name_asn1); + if (utf8_returned_size < 0) + { + gpr_log (GPR_ERROR, "Could not extract utf8 from asn1 string."); + return TSI_OUT_OF_RESOURCES; + } + *utf8_size = (size_t) utf8_returned_size; return TSI_OK; } /* Gets the subject CN of an X509 cert as a tsi_peer_property. */ -static tsi_result peer_property_from_x509_common_name( - X509* cert, tsi_peer_property* property) { - unsigned char* common_name; +static tsi_result +peer_property_from_x509_common_name (X509 * cert, tsi_peer_property * property) +{ + unsigned char *common_name; size_t common_name_size; - tsi_result result = - ssl_get_x509_common_name(cert, &common_name, &common_name_size); - if (result != TSI_OK) { - if (result == TSI_NOT_FOUND) { - common_name = NULL; - common_name_size = 0; - } else { - return result; + tsi_result result = ssl_get_x509_common_name (cert, &common_name, &common_name_size); + if (result != TSI_OK) + { + if (result == TSI_NOT_FOUND) + { + common_name = NULL; + common_name_size = 0; + } + else + { + return result; + } } - } - result = tsi_construct_string_peer_property( - TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, - common_name == NULL ? "" : (const char*)common_name, common_name_size, - property); - OPENSSL_free(common_name); + result = tsi_construct_string_peer_property (TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, common_name == NULL ? "" : (const char *) common_name, common_name_size, property); + OPENSSL_free (common_name); return result; } /* Gets the subject SANs from an X509 cert as a tsi_peer_property. */ -static tsi_result add_subject_alt_names_properties_to_peer( - tsi_peer* peer, GENERAL_NAMES* subject_alt_names, - size_t subject_alt_name_count) { +static tsi_result +add_subject_alt_names_properties_to_peer (tsi_peer * peer, GENERAL_NAMES * subject_alt_names, size_t subject_alt_name_count) +{ size_t i; tsi_result result = TSI_OK; /* Reset for DNS entries filtering. */ peer->property_count -= subject_alt_name_count; - for (i = 0; i < subject_alt_name_count; i++) { - GENERAL_NAME* subject_alt_name = - sk_GENERAL_NAME_value(subject_alt_names, (int)i); - /* Filter out the non-dns entries names. */ - if (subject_alt_name->type == GEN_DNS) { - unsigned char* dns_name = NULL; - int dns_name_size = - ASN1_STRING_to_UTF8(&dns_name, subject_alt_name->d.dNSName); - if (dns_name_size < 0) { - gpr_log(GPR_ERROR, "Could not get utf8 from asn1 string."); - result = TSI_INTERNAL_ERROR; - break; - } - result = tsi_construct_string_peer_property( - TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, - (const char*)dns_name, (size_t)dns_name_size, - &peer->properties[peer->property_count++]); - OPENSSL_free(dns_name); - if (result != TSI_OK) break; + for (i = 0; i < subject_alt_name_count; i++) + { + GENERAL_NAME *subject_alt_name = sk_GENERAL_NAME_value (subject_alt_names, (int) i); + /* Filter out the non-dns entries names. */ + if (subject_alt_name->type == GEN_DNS) + { + unsigned char *dns_name = NULL; + int dns_name_size = ASN1_STRING_to_UTF8 (&dns_name, subject_alt_name->d.dNSName); + if (dns_name_size < 0) + { + gpr_log (GPR_ERROR, "Could not get utf8 from asn1 string."); + result = TSI_INTERNAL_ERROR; + break; + } + result = tsi_construct_string_peer_property (TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, (const char *) dns_name, (size_t) dns_name_size, &peer->properties[peer->property_count++]); + OPENSSL_free (dns_name); + if (result != TSI_OK) + break; + } } - } return result; } /* Gets information about the peer's X509 cert as a tsi_peer object. */ -static tsi_result peer_from_x509(X509* cert, int include_certificate_type, - tsi_peer* peer) { +static tsi_result +peer_from_x509 (X509 * cert, int include_certificate_type, tsi_peer * peer) +{ /* TODO(jboeuf): Maybe add more properties. */ - GENERAL_NAMES* subject_alt_names = - X509_get_ext_d2i(cert, NID_subject_alt_name, 0, 0); - int subject_alt_name_count = - (subject_alt_names != NULL) ? sk_GENERAL_NAME_num(subject_alt_names) : 0; + GENERAL_NAMES *subject_alt_names = X509_get_ext_d2i (cert, NID_subject_alt_name, 0, 0); + int subject_alt_name_count = (subject_alt_names != NULL) ? sk_GENERAL_NAME_num (subject_alt_names) : 0; size_t property_count; tsi_result result; - GPR_ASSERT(subject_alt_name_count >= 0); - property_count = (include_certificate_type ? (size_t)1 : 0) + - 1 /* common name */ + (size_t)subject_alt_name_count; - result = tsi_construct_peer(property_count, peer); - if (result != TSI_OK) return result; - do { - if (include_certificate_type) { - result = tsi_construct_string_peer_property_from_cstring( - TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE, - &peer->properties[0]); - if (result != TSI_OK) break; - } - result = peer_property_from_x509_common_name( - cert, &peer->properties[include_certificate_type ? 1 : 0]); - if (result != TSI_OK) break; - - if (subject_alt_name_count != 0) { - result = add_subject_alt_names_properties_to_peer( - peer, subject_alt_names, (size_t)subject_alt_name_count); - if (result != TSI_OK) break; - } - } while (0); - - if (subject_alt_names != NULL) { - sk_GENERAL_NAME_pop_free(subject_alt_names, GENERAL_NAME_free); - } - if (result != TSI_OK) tsi_peer_destruct(peer); + GPR_ASSERT (subject_alt_name_count >= 0); + property_count = (include_certificate_type ? (size_t) 1 : 0) + 1 /* common name */ + (size_t) subject_alt_name_count; + result = tsi_construct_peer (property_count, peer); + if (result != TSI_OK) + return result; + do + { + if (include_certificate_type) + { + result = tsi_construct_string_peer_property_from_cstring (TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE, &peer->properties[0]); + if (result != TSI_OK) + break; + } + result = peer_property_from_x509_common_name (cert, &peer->properties[include_certificate_type ? 1 : 0]); + if (result != TSI_OK) + break; + + if (subject_alt_name_count != 0) + { + result = add_subject_alt_names_properties_to_peer (peer, subject_alt_names, (size_t) subject_alt_name_count); + if (result != TSI_OK) + break; + } + } + while (0); + + if (subject_alt_names != NULL) + { + sk_GENERAL_NAME_pop_free (subject_alt_names, GENERAL_NAME_free); + } + if (result != TSI_OK) + tsi_peer_destruct (peer); return result; } /* Logs the SSL error stack. */ -static void log_ssl_error_stack(void) { +static void +log_ssl_error_stack (void) +{ unsigned long err; - while ((err = ERR_get_error()) != 0) { - char details[256]; - ERR_error_string_n(err, details, sizeof(details)); - gpr_log(GPR_ERROR, "%s", details); - } + while ((err = ERR_get_error ()) != 0) + { + char details[256]; + ERR_error_string_n (err, details, sizeof (details)); + gpr_log (GPR_ERROR, "%s", details); + } } /* Performs an SSL_read and handle errors. */ -static tsi_result do_ssl_read(SSL* ssl, unsigned char* unprotected_bytes, - size_t* unprotected_bytes_size) { +static tsi_result +do_ssl_read (SSL * ssl, unsigned char *unprotected_bytes, size_t * unprotected_bytes_size) +{ int read_from_ssl; - GPR_ASSERT(*unprotected_bytes_size <= INT_MAX); - read_from_ssl = - SSL_read(ssl, unprotected_bytes, (int)*unprotected_bytes_size); - if (read_from_ssl == 0) { - gpr_log(GPR_ERROR, "SSL_read returned 0 unexpectedly."); - return TSI_INTERNAL_ERROR; - } - if (read_from_ssl < 0) { - read_from_ssl = SSL_get_error(ssl, read_from_ssl); - switch (read_from_ssl) { - case SSL_ERROR_WANT_READ: - /* We need more data to finish the frame. */ - *unprotected_bytes_size = 0; - return TSI_OK; - case SSL_ERROR_WANT_WRITE: - gpr_log( - GPR_ERROR, - "Peer tried to renegotiate SSL connection. This is unsupported."); - return TSI_UNIMPLEMENTED; - case SSL_ERROR_SSL: - gpr_log(GPR_ERROR, "Corruption detected."); - log_ssl_error_stack(); - return TSI_DATA_CORRUPTED; - default: - gpr_log(GPR_ERROR, "SSL_read failed with error %s.", - ssl_error_string(read_from_ssl)); - return TSI_PROTOCOL_FAILURE; + GPR_ASSERT (*unprotected_bytes_size <= INT_MAX); + read_from_ssl = SSL_read (ssl, unprotected_bytes, (int) *unprotected_bytes_size); + if (read_from_ssl == 0) + { + gpr_log (GPR_ERROR, "SSL_read returned 0 unexpectedly."); + return TSI_INTERNAL_ERROR; } - } - *unprotected_bytes_size = (size_t)read_from_ssl; + if (read_from_ssl < 0) + { + read_from_ssl = SSL_get_error (ssl, read_from_ssl); + switch (read_from_ssl) + { + case SSL_ERROR_WANT_READ: + /* We need more data to finish the frame. */ + *unprotected_bytes_size = 0; + return TSI_OK; + case SSL_ERROR_WANT_WRITE: + gpr_log (GPR_ERROR, "Peer tried to renegotiate SSL connection. This is unsupported."); + return TSI_UNIMPLEMENTED; + case SSL_ERROR_SSL: + gpr_log (GPR_ERROR, "Corruption detected."); + log_ssl_error_stack (); + return TSI_DATA_CORRUPTED; + default: + gpr_log (GPR_ERROR, "SSL_read failed with error %s.", ssl_error_string (read_from_ssl)); + return TSI_PROTOCOL_FAILURE; + } + } + *unprotected_bytes_size = (size_t) read_from_ssl; return TSI_OK; } /* Performs an SSL_write and handle errors. */ -static tsi_result do_ssl_write(SSL* ssl, unsigned char* unprotected_bytes, - size_t unprotected_bytes_size) { +static tsi_result +do_ssl_write (SSL * ssl, unsigned char *unprotected_bytes, size_t unprotected_bytes_size) +{ int ssl_write_result; - GPR_ASSERT(unprotected_bytes_size <= INT_MAX); - ssl_write_result = - SSL_write(ssl, unprotected_bytes, (int)unprotected_bytes_size); - if (ssl_write_result < 0) { - ssl_write_result = SSL_get_error(ssl, ssl_write_result); - if (ssl_write_result == SSL_ERROR_WANT_READ) { - gpr_log(GPR_ERROR, - "Peer tried to renegotiate SSL connection. This is unsupported."); - return TSI_UNIMPLEMENTED; - } else { - gpr_log(GPR_ERROR, "SSL_write failed with error %s.", - ssl_error_string(ssl_write_result)); - return TSI_INTERNAL_ERROR; + GPR_ASSERT (unprotected_bytes_size <= INT_MAX); + ssl_write_result = SSL_write (ssl, unprotected_bytes, (int) unprotected_bytes_size); + if (ssl_write_result < 0) + { + ssl_write_result = SSL_get_error (ssl, ssl_write_result); + if (ssl_write_result == SSL_ERROR_WANT_READ) + { + gpr_log (GPR_ERROR, "Peer tried to renegotiate SSL connection. This is unsupported."); + return TSI_UNIMPLEMENTED; + } + else + { + gpr_log (GPR_ERROR, "SSL_write failed with error %s.", ssl_error_string (ssl_write_result)); + return TSI_INTERNAL_ERROR; + } } - } return TSI_OK; } /* Loads an in-memory PEM certificate chain into the SSL context. */ -static tsi_result ssl_ctx_use_certificate_chain( - SSL_CTX* context, const unsigned char* pem_cert_chain, - size_t pem_cert_chain_size) { +static tsi_result +ssl_ctx_use_certificate_chain (SSL_CTX * context, const unsigned char *pem_cert_chain, size_t pem_cert_chain_size) +{ tsi_result result = TSI_OK; - X509* certificate = NULL; - BIO* pem; - GPR_ASSERT(pem_cert_chain_size <= INT_MAX); - pem = BIO_new_mem_buf((void*)pem_cert_chain, (int)pem_cert_chain_size); - if (pem == NULL) return TSI_OUT_OF_RESOURCES; - - do { - certificate = PEM_read_bio_X509_AUX(pem, NULL, NULL, ""); - if (certificate == NULL) { - result = TSI_INVALID_ARGUMENT; - break; - } - if (!SSL_CTX_use_certificate(context, certificate)) { - result = TSI_INVALID_ARGUMENT; - break; - } - while (1) { - X509* certificate_authority = PEM_read_bio_X509(pem, NULL, NULL, ""); - if (certificate_authority == NULL) { - ERR_clear_error(); - break; /* Done reading. */ - } - if (!SSL_CTX_add_extra_chain_cert(context, certificate_authority)) { - X509_free(certificate_authority); - result = TSI_INVALID_ARGUMENT; - break; - } - /* We don't need to free certificate_authority as its ownership has been - transfered to the context. That is not the case for certificate though. - */ + X509 *certificate = NULL; + BIO *pem; + GPR_ASSERT (pem_cert_chain_size <= INT_MAX); + pem = BIO_new_mem_buf ((void *) pem_cert_chain, (int) pem_cert_chain_size); + if (pem == NULL) + return TSI_OUT_OF_RESOURCES; + + do + { + certificate = PEM_read_bio_X509_AUX (pem, NULL, NULL, ""); + if (certificate == NULL) + { + result = TSI_INVALID_ARGUMENT; + break; + } + if (!SSL_CTX_use_certificate (context, certificate)) + { + result = TSI_INVALID_ARGUMENT; + break; + } + while (1) + { + X509 *certificate_authority = PEM_read_bio_X509 (pem, NULL, NULL, ""); + if (certificate_authority == NULL) + { + ERR_clear_error (); + break; /* Done reading. */ + } + if (!SSL_CTX_add_extra_chain_cert (context, certificate_authority)) + { + X509_free (certificate_authority); + result = TSI_INVALID_ARGUMENT; + break; + } + /* We don't need to free certificate_authority as its ownership has been + transfered to the context. That is not the case for certificate though. + */ + } } - } while (0); + while (0); - if (certificate != NULL) X509_free(certificate); - BIO_free(pem); + if (certificate != NULL) + X509_free (certificate); + BIO_free (pem); return result; } /* Loads an in-memory PEM private key into the SSL context. */ -static tsi_result ssl_ctx_use_private_key(SSL_CTX* context, - const unsigned char* pem_key, - size_t pem_key_size) { +static tsi_result +ssl_ctx_use_private_key (SSL_CTX * context, const unsigned char *pem_key, size_t pem_key_size) +{ tsi_result result = TSI_OK; - EVP_PKEY* private_key = NULL; - BIO* pem; - GPR_ASSERT(pem_key_size <= INT_MAX); - pem = BIO_new_mem_buf((void*)pem_key, (int)pem_key_size); - if (pem == NULL) return TSI_OUT_OF_RESOURCES; - do { - private_key = PEM_read_bio_PrivateKey(pem, NULL, NULL, ""); - if (private_key == NULL) { - result = TSI_INVALID_ARGUMENT; - break; - } - if (!SSL_CTX_use_PrivateKey(context, private_key)) { - result = TSI_INVALID_ARGUMENT; - break; + EVP_PKEY *private_key = NULL; + BIO *pem; + GPR_ASSERT (pem_key_size <= INT_MAX); + pem = BIO_new_mem_buf ((void *) pem_key, (int) pem_key_size); + if (pem == NULL) + return TSI_OUT_OF_RESOURCES; + do + { + private_key = PEM_read_bio_PrivateKey (pem, NULL, NULL, ""); + if (private_key == NULL) + { + result = TSI_INVALID_ARGUMENT; + break; + } + if (!SSL_CTX_use_PrivateKey (context, private_key)) + { + result = TSI_INVALID_ARGUMENT; + break; + } } - } while (0); - if (private_key != NULL) EVP_PKEY_free(private_key); - BIO_free(pem); + while (0); + if (private_key != NULL) + EVP_PKEY_free (private_key); + BIO_free (pem); return result; } /* Loads in-memory PEM verification certs into the SSL context and optionally returns the verification cert names (root_names can be NULL). */ -static tsi_result ssl_ctx_load_verification_certs( - SSL_CTX* context, const unsigned char* pem_roots, size_t pem_roots_size, - STACK_OF(X509_NAME) * *root_names) { +static tsi_result +ssl_ctx_load_verification_certs (SSL_CTX * context, const unsigned char *pem_roots, size_t pem_roots_size, STACK_OF (X509_NAME) * *root_names) +{ tsi_result result = TSI_OK; size_t num_roots = 0; - X509* root = NULL; - X509_NAME* root_name = NULL; - BIO* pem; - X509_STORE* root_store; - GPR_ASSERT(pem_roots_size <= INT_MAX); - pem = BIO_new_mem_buf((void*)pem_roots, (int)pem_roots_size); - root_store = SSL_CTX_get_cert_store(context); - if (root_store == NULL) return TSI_INVALID_ARGUMENT; - if (pem == NULL) return TSI_OUT_OF_RESOURCES; - if (root_names != NULL) { - *root_names = sk_X509_NAME_new_null(); - if (*root_names == NULL) return TSI_OUT_OF_RESOURCES; - } - - while (1) { - root = PEM_read_bio_X509_AUX(pem, NULL, NULL, ""); - if (root == NULL) { - ERR_clear_error(); - break; /* We're at the end of stream. */ - } - if (root_names != NULL) { - root_name = X509_get_subject_name(root); - if (root_name == NULL) { - gpr_log(GPR_ERROR, "Could not get name from root certificate."); - result = TSI_INVALID_ARGUMENT; - break; - } - root_name = X509_NAME_dup(root_name); - if (root_name == NULL) { - result = TSI_OUT_OF_RESOURCES; - break; - } - sk_X509_NAME_push(*root_names, root_name); - root_name = NULL; + X509 *root = NULL; + X509_NAME *root_name = NULL; + BIO *pem; + X509_STORE *root_store; + GPR_ASSERT (pem_roots_size <= INT_MAX); + pem = BIO_new_mem_buf ((void *) pem_roots, (int) pem_roots_size); + root_store = SSL_CTX_get_cert_store (context); + if (root_store == NULL) + return TSI_INVALID_ARGUMENT; + if (pem == NULL) + return TSI_OUT_OF_RESOURCES; + if (root_names != NULL) + { + *root_names = sk_X509_NAME_new_null (); + if (*root_names == NULL) + return TSI_OUT_OF_RESOURCES; } - if (!X509_STORE_add_cert(root_store, root)) { - gpr_log(GPR_ERROR, "Could not add root certificate to ssl context."); - result = TSI_INTERNAL_ERROR; - break; + + while (1) + { + root = PEM_read_bio_X509_AUX (pem, NULL, NULL, ""); + if (root == NULL) + { + ERR_clear_error (); + break; /* We're at the end of stream. */ + } + if (root_names != NULL) + { + root_name = X509_get_subject_name (root); + if (root_name == NULL) + { + gpr_log (GPR_ERROR, "Could not get name from root certificate."); + result = TSI_INVALID_ARGUMENT; + break; + } + root_name = X509_NAME_dup (root_name); + if (root_name == NULL) + { + result = TSI_OUT_OF_RESOURCES; + break; + } + sk_X509_NAME_push (*root_names, root_name); + root_name = NULL; + } + if (!X509_STORE_add_cert (root_store, root)) + { + gpr_log (GPR_ERROR, "Could not add root certificate to ssl context."); + result = TSI_INTERNAL_ERROR; + break; + } + X509_free (root); + num_roots++; } - X509_free(root); - num_roots++; - } - if (num_roots == 0) { - gpr_log(GPR_ERROR, "Could not load any root certificate."); - result = TSI_INVALID_ARGUMENT; - } + if (num_roots == 0) + { + gpr_log (GPR_ERROR, "Could not load any root certificate."); + result = TSI_INVALID_ARGUMENT; + } - if (result != TSI_OK) { - if (root != NULL) X509_free(root); - if (root_names != NULL) { - sk_X509_NAME_pop_free(*root_names, X509_NAME_free); - *root_names = NULL; - if (root_name != NULL) X509_NAME_free(root_name); + if (result != TSI_OK) + { + if (root != NULL) + X509_free (root); + if (root_names != NULL) + { + sk_X509_NAME_pop_free (*root_names, X509_NAME_free); + *root_names = NULL; + if (root_name != NULL) + X509_NAME_free (root_name); + } } - } - BIO_free(pem); + BIO_free (pem); return result; } /* Populates the SSL context with a private key and a cert chain, and sets the cipher list and the ephemeral ECDH key. */ -static tsi_result populate_ssl_context( - SSL_CTX* context, const unsigned char* pem_private_key, - size_t pem_private_key_size, const unsigned char* pem_certificate_chain, - size_t pem_certificate_chain_size, const char* cipher_list) { +static tsi_result +populate_ssl_context (SSL_CTX * context, const unsigned char *pem_private_key, size_t pem_private_key_size, const unsigned char *pem_certificate_chain, size_t pem_certificate_chain_size, const char *cipher_list) +{ tsi_result result = TSI_OK; - if (pem_certificate_chain != NULL) { - result = ssl_ctx_use_certificate_chain(context, pem_certificate_chain, - pem_certificate_chain_size); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Invalid cert chain file."); - return result; + if (pem_certificate_chain != NULL) + { + result = ssl_ctx_use_certificate_chain (context, pem_certificate_chain, pem_certificate_chain_size); + if (result != TSI_OK) + { + gpr_log (GPR_ERROR, "Invalid cert chain file."); + return result; + } } - } - if (pem_private_key != NULL) { - result = - ssl_ctx_use_private_key(context, pem_private_key, pem_private_key_size); - if (result != TSI_OK || !SSL_CTX_check_private_key(context)) { - gpr_log(GPR_ERROR, "Invalid private key."); - return result != TSI_OK ? result : TSI_INVALID_ARGUMENT; + if (pem_private_key != NULL) + { + result = ssl_ctx_use_private_key (context, pem_private_key, pem_private_key_size); + if (result != TSI_OK || !SSL_CTX_check_private_key (context)) + { + gpr_log (GPR_ERROR, "Invalid private key."); + return result != TSI_OK ? result : TSI_INVALID_ARGUMENT; + } } - } - if ((cipher_list != NULL) && !SSL_CTX_set_cipher_list(context, cipher_list)) { - gpr_log(GPR_ERROR, "Invalid cipher list: %s.", cipher_list); - return TSI_INVALID_ARGUMENT; - } - { - EC_KEY* ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); - if (!SSL_CTX_set_tmp_ecdh(context, ecdh)) { - gpr_log(GPR_ERROR, "Could not set ephemeral ECDH key."); - EC_KEY_free(ecdh); - return TSI_INTERNAL_ERROR; + if ((cipher_list != NULL) && !SSL_CTX_set_cipher_list (context, cipher_list)) + { + gpr_log (GPR_ERROR, "Invalid cipher list: %s.", cipher_list); + return TSI_INVALID_ARGUMENT; } - SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE); - EC_KEY_free(ecdh); + { + EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1); + if (!SSL_CTX_set_tmp_ecdh (context, ecdh)) + { + gpr_log (GPR_ERROR, "Could not set ephemeral ECDH key."); + EC_KEY_free (ecdh); + return TSI_INTERNAL_ERROR; + } + SSL_CTX_set_options (context, SSL_OP_SINGLE_ECDH_USE); + EC_KEY_free (ecdh); } return TSI_OK; } /* Extracts the CN and the SANs from an X509 cert as a peer object. */ -static tsi_result extract_x509_subject_names_from_pem_cert( - const unsigned char* pem_cert, size_t pem_cert_size, tsi_peer* peer) { +static tsi_result +extract_x509_subject_names_from_pem_cert (const unsigned char *pem_cert, size_t pem_cert_size, tsi_peer * peer) +{ tsi_result result = TSI_OK; - X509* cert = NULL; - BIO* pem; - GPR_ASSERT(pem_cert_size <= INT_MAX); - pem = BIO_new_mem_buf((void*)pem_cert, (int)pem_cert_size); - if (pem == NULL) return TSI_OUT_OF_RESOURCES; - - cert = PEM_read_bio_X509(pem, NULL, NULL, ""); - if (cert == NULL) { - gpr_log(GPR_ERROR, "Invalid certificate"); - result = TSI_INVALID_ARGUMENT; - } else { - result = peer_from_x509(cert, 0, peer); - } - if (cert != NULL) X509_free(cert); - BIO_free(pem); + X509 *cert = NULL; + BIO *pem; + GPR_ASSERT (pem_cert_size <= INT_MAX); + pem = BIO_new_mem_buf ((void *) pem_cert, (int) pem_cert_size); + if (pem == NULL) + return TSI_OUT_OF_RESOURCES; + + cert = PEM_read_bio_X509 (pem, NULL, NULL, ""); + if (cert == NULL) + { + gpr_log (GPR_ERROR, "Invalid certificate"); + result = TSI_INVALID_ARGUMENT; + } + else + { + result = peer_from_x509 (cert, 0, peer); + } + if (cert != NULL) + X509_free (cert); + BIO_free (pem); return result; } /* Builds the alpn protocol name list according to rfc 7301. */ -static tsi_result build_alpn_protocol_name_list( - const unsigned char** alpn_protocols, - const unsigned char* alpn_protocols_lengths, uint16_t num_alpn_protocols, - unsigned char** protocol_name_list, size_t* protocol_name_list_length) { +static tsi_result +build_alpn_protocol_name_list (const unsigned char **alpn_protocols, const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, unsigned char **protocol_name_list, size_t * protocol_name_list_length) +{ uint16_t i; - unsigned char* current; + unsigned char *current; *protocol_name_list = NULL; *protocol_name_list_length = 0; - if (num_alpn_protocols == 0) return TSI_INVALID_ARGUMENT; - for (i = 0; i < num_alpn_protocols; i++) { - if (alpn_protocols_lengths[i] == 0) { - gpr_log(GPR_ERROR, "Invalid 0-length protocol name."); - return TSI_INVALID_ARGUMENT; + if (num_alpn_protocols == 0) + return TSI_INVALID_ARGUMENT; + for (i = 0; i < num_alpn_protocols; i++) + { + if (alpn_protocols_lengths[i] == 0) + { + gpr_log (GPR_ERROR, "Invalid 0-length protocol name."); + return TSI_INVALID_ARGUMENT; + } + *protocol_name_list_length += (size_t) alpn_protocols_lengths[i] + 1; } - *protocol_name_list_length += (size_t)alpn_protocols_lengths[i] + 1; - } - *protocol_name_list = malloc(*protocol_name_list_length); - if (*protocol_name_list == NULL) return TSI_OUT_OF_RESOURCES; + *protocol_name_list = malloc (*protocol_name_list_length); + if (*protocol_name_list == NULL) + return TSI_OUT_OF_RESOURCES; current = *protocol_name_list; - for (i = 0; i < num_alpn_protocols; i++) { - *(current++) = alpn_protocols_lengths[i]; - memcpy(current, alpn_protocols[i], alpn_protocols_lengths[i]); - current += alpn_protocols_lengths[i]; - } + for (i = 0; i < num_alpn_protocols; i++) + { + *(current++) = alpn_protocols_lengths[i]; + memcpy (current, alpn_protocols[i], alpn_protocols_lengths[i]); + current += alpn_protocols_lengths[i]; + } /* Safety check. */ - if ((current < *protocol_name_list) || - ((gpr_uintptr)(current - *protocol_name_list) != - *protocol_name_list_length)) { - return TSI_INTERNAL_ERROR; - } + if ((current < *protocol_name_list) || ((gpr_uintptr) (current - *protocol_name_list) != *protocol_name_list_length)) + { + return TSI_INTERNAL_ERROR; + } return TSI_OK; } /* --- tsi_frame_protector methods implementation. ---*/ -static tsi_result ssl_protector_protect(tsi_frame_protector* self, - const unsigned char* unprotected_bytes, - size_t* unprotected_bytes_size, - unsigned char* protected_output_frames, - size_t* protected_output_frames_size) { - tsi_ssl_frame_protector* impl = (tsi_ssl_frame_protector*)self; +static tsi_result +ssl_protector_protect (tsi_frame_protector * self, const unsigned char *unprotected_bytes, size_t * unprotected_bytes_size, unsigned char *protected_output_frames, size_t * protected_output_frames_size) +{ + tsi_ssl_frame_protector *impl = (tsi_ssl_frame_protector *) self; int read_from_ssl; size_t available; tsi_result result = TSI_OK; /* First see if we have some pending data in the SSL BIO. */ - int pending_in_ssl = BIO_pending(impl->from_ssl); - if (pending_in_ssl > 0) { - *unprotected_bytes_size = 0; - GPR_ASSERT(*protected_output_frames_size <= INT_MAX); - read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames, - (int)*protected_output_frames_size); - if (read_from_ssl < 0) { - gpr_log(GPR_ERROR, - "Could not read from BIO even though some data is pending"); - return TSI_INTERNAL_ERROR; + int pending_in_ssl = BIO_pending (impl->from_ssl); + if (pending_in_ssl > 0) + { + *unprotected_bytes_size = 0; + GPR_ASSERT (*protected_output_frames_size <= INT_MAX); + read_from_ssl = BIO_read (impl->from_ssl, protected_output_frames, (int) *protected_output_frames_size); + if (read_from_ssl < 0) + { + gpr_log (GPR_ERROR, "Could not read from BIO even though some data is pending"); + return TSI_INTERNAL_ERROR; + } + *protected_output_frames_size = (size_t) read_from_ssl; + return TSI_OK; } - *protected_output_frames_size = (size_t)read_from_ssl; - return TSI_OK; - } /* Now see if we can send a complete frame. */ available = impl->buffer_size - impl->buffer_offset; - if (available > *unprotected_bytes_size) { - /* If we cannot, just copy the data in our internal buffer. */ - memcpy(impl->buffer + impl->buffer_offset, unprotected_bytes, - *unprotected_bytes_size); - impl->buffer_offset += *unprotected_bytes_size; - *protected_output_frames_size = 0; - return TSI_OK; - } + if (available > *unprotected_bytes_size) + { + /* If we cannot, just copy the data in our internal buffer. */ + memcpy (impl->buffer + impl->buffer_offset, unprotected_bytes, *unprotected_bytes_size); + impl->buffer_offset += *unprotected_bytes_size; + *protected_output_frames_size = 0; + return TSI_OK; + } /* If we can, prepare the buffer, send it to SSL_write and read. */ - memcpy(impl->buffer + impl->buffer_offset, unprotected_bytes, available); - result = do_ssl_write(impl->ssl, impl->buffer, impl->buffer_size); - if (result != TSI_OK) return result; - - GPR_ASSERT(*protected_output_frames_size <= INT_MAX); - read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames, - (int)*protected_output_frames_size); - if (read_from_ssl < 0) { - gpr_log(GPR_ERROR, "Could not read from BIO after SSL_write."); - return TSI_INTERNAL_ERROR; - } - *protected_output_frames_size = (size_t)read_from_ssl; + memcpy (impl->buffer + impl->buffer_offset, unprotected_bytes, available); + result = do_ssl_write (impl->ssl, impl->buffer, impl->buffer_size); + if (result != TSI_OK) + return result; + + GPR_ASSERT (*protected_output_frames_size <= INT_MAX); + read_from_ssl = BIO_read (impl->from_ssl, protected_output_frames, (int) *protected_output_frames_size); + if (read_from_ssl < 0) + { + gpr_log (GPR_ERROR, "Could not read from BIO after SSL_write."); + return TSI_INTERNAL_ERROR; + } + *protected_output_frames_size = (size_t) read_from_ssl; *unprotected_bytes_size = available; impl->buffer_offset = 0; return TSI_OK; } -static tsi_result ssl_protector_protect_flush( - tsi_frame_protector* self, unsigned char* protected_output_frames, - size_t* protected_output_frames_size, size_t* still_pending_size) { +static tsi_result +ssl_protector_protect_flush (tsi_frame_protector * self, unsigned char *protected_output_frames, size_t * protected_output_frames_size, size_t * still_pending_size) +{ tsi_result result = TSI_OK; - tsi_ssl_frame_protector* impl = (tsi_ssl_frame_protector*)self; + tsi_ssl_frame_protector *impl = (tsi_ssl_frame_protector *) self; int read_from_ssl = 0; int pending; - if (impl->buffer_offset != 0) { - result = do_ssl_write(impl->ssl, impl->buffer, impl->buffer_offset); - if (result != TSI_OK) return result; - impl->buffer_offset = 0; - } + if (impl->buffer_offset != 0) + { + result = do_ssl_write (impl->ssl, impl->buffer, impl->buffer_offset); + if (result != TSI_OK) + return result; + impl->buffer_offset = 0; + } - pending = BIO_pending(impl->from_ssl); - GPR_ASSERT(pending >= 0); - *still_pending_size = (size_t)pending; - if (*still_pending_size == 0) return TSI_OK; - - GPR_ASSERT(*protected_output_frames_size <= INT_MAX); - read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames, - (int)*protected_output_frames_size); - if (read_from_ssl <= 0) { - gpr_log(GPR_ERROR, "Could not read from BIO after SSL_write."); - return TSI_INTERNAL_ERROR; - } - *protected_output_frames_size = (size_t)read_from_ssl; - pending = BIO_pending(impl->from_ssl); - GPR_ASSERT(pending >= 0); - *still_pending_size = (size_t)pending; + pending = BIO_pending (impl->from_ssl); + GPR_ASSERT (pending >= 0); + *still_pending_size = (size_t) pending; + if (*still_pending_size == 0) + return TSI_OK; + + GPR_ASSERT (*protected_output_frames_size <= INT_MAX); + read_from_ssl = BIO_read (impl->from_ssl, protected_output_frames, (int) *protected_output_frames_size); + if (read_from_ssl <= 0) + { + gpr_log (GPR_ERROR, "Could not read from BIO after SSL_write."); + return TSI_INTERNAL_ERROR; + } + *protected_output_frames_size = (size_t) read_from_ssl; + pending = BIO_pending (impl->from_ssl); + GPR_ASSERT (pending >= 0); + *still_pending_size = (size_t) pending; return TSI_OK; } -static tsi_result ssl_protector_unprotect( - tsi_frame_protector* self, const unsigned char* protected_frames_bytes, - size_t* protected_frames_bytes_size, unsigned char* unprotected_bytes, - size_t* unprotected_bytes_size) { +static tsi_result +ssl_protector_unprotect (tsi_frame_protector * self, const unsigned char *protected_frames_bytes, size_t * protected_frames_bytes_size, unsigned char *unprotected_bytes, size_t * unprotected_bytes_size) +{ tsi_result result = TSI_OK; int written_into_ssl = 0; size_t output_bytes_size = *unprotected_bytes_size; size_t output_bytes_offset = 0; - tsi_ssl_frame_protector* impl = (tsi_ssl_frame_protector*)self; + tsi_ssl_frame_protector *impl = (tsi_ssl_frame_protector *) self; /* First, try to read remaining data from ssl. */ - result = do_ssl_read(impl->ssl, unprotected_bytes, unprotected_bytes_size); - if (result != TSI_OK) return result; - if (*unprotected_bytes_size == output_bytes_size) { - /* We have read everything we could and cannot process any more input. */ - *protected_frames_bytes_size = 0; - return TSI_OK; - } + result = do_ssl_read (impl->ssl, unprotected_bytes, unprotected_bytes_size); + if (result != TSI_OK) + return result; + if (*unprotected_bytes_size == output_bytes_size) + { + /* We have read everything we could and cannot process any more input. */ + *protected_frames_bytes_size = 0; + return TSI_OK; + } output_bytes_offset = *unprotected_bytes_size; unprotected_bytes += output_bytes_offset; *unprotected_bytes_size = output_bytes_size - output_bytes_offset; /* Then, try to write some data to ssl. */ - GPR_ASSERT(*protected_frames_bytes_size <= INT_MAX); - written_into_ssl = BIO_write(impl->into_ssl, protected_frames_bytes, - (int)*protected_frames_bytes_size); - if (written_into_ssl < 0) { - gpr_log(GPR_ERROR, "Sending protected frame to ssl failed with %d", - written_into_ssl); - return TSI_INTERNAL_ERROR; - } - *protected_frames_bytes_size = (size_t)written_into_ssl; + GPR_ASSERT (*protected_frames_bytes_size <= INT_MAX); + written_into_ssl = BIO_write (impl->into_ssl, protected_frames_bytes, (int) *protected_frames_bytes_size); + if (written_into_ssl < 0) + { + gpr_log (GPR_ERROR, "Sending protected frame to ssl failed with %d", written_into_ssl); + return TSI_INTERNAL_ERROR; + } + *protected_frames_bytes_size = (size_t) written_into_ssl; /* Now try to read some data again. */ - result = do_ssl_read(impl->ssl, unprotected_bytes, unprotected_bytes_size); - if (result == TSI_OK) { - /* Don't forget to output the total number of bytes read. */ - *unprotected_bytes_size += output_bytes_offset; - } + result = do_ssl_read (impl->ssl, unprotected_bytes, unprotected_bytes_size); + if (result == TSI_OK) + { + /* Don't forget to output the total number of bytes read. */ + *unprotected_bytes_size += output_bytes_offset; + } return result; } -static void ssl_protector_destroy(tsi_frame_protector* self) { - tsi_ssl_frame_protector* impl = (tsi_ssl_frame_protector*)self; - if (impl->buffer != NULL) free(impl->buffer); - if (impl->ssl != NULL) SSL_free(impl->ssl); - free(self); +static void +ssl_protector_destroy (tsi_frame_protector * self) +{ + tsi_ssl_frame_protector *impl = (tsi_ssl_frame_protector *) self; + if (impl->buffer != NULL) + free (impl->buffer); + if (impl->ssl != NULL) + SSL_free (impl->ssl); + free (self); } static const tsi_frame_protector_vtable frame_protector_vtable = { - ssl_protector_protect, ssl_protector_protect_flush, ssl_protector_unprotect, - ssl_protector_destroy, + ssl_protector_protect, ssl_protector_protect_flush, ssl_protector_unprotect, + ssl_protector_destroy, }; /* --- tsi_handshaker methods implementation. ---*/ -static tsi_result ssl_handshaker_get_bytes_to_send_to_peer(tsi_handshaker* self, - unsigned char* bytes, - size_t* bytes_size) { - tsi_ssl_handshaker* impl = (tsi_ssl_handshaker*)self; +static tsi_result +ssl_handshaker_get_bytes_to_send_to_peer (tsi_handshaker * self, unsigned char *bytes, size_t * bytes_size) +{ + tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *) self; int bytes_read_from_ssl = 0; - if (bytes == NULL || bytes_size == NULL || *bytes_size == 0 || - *bytes_size > INT_MAX) { - return TSI_INVALID_ARGUMENT; - } - GPR_ASSERT(*bytes_size <= INT_MAX); - bytes_read_from_ssl = BIO_read(impl->from_ssl, bytes, (int)*bytes_size); - if (bytes_read_from_ssl < 0) { - *bytes_size = 0; - if (!BIO_should_retry(impl->from_ssl)) { - impl->result = TSI_INTERNAL_ERROR; - return impl->result; - } else { - return TSI_OK; + if (bytes == NULL || bytes_size == NULL || *bytes_size == 0 || *bytes_size > INT_MAX) + { + return TSI_INVALID_ARGUMENT; } - } - *bytes_size = (size_t)bytes_read_from_ssl; - return BIO_pending(impl->from_ssl) == 0 ? TSI_OK : TSI_INCOMPLETE_DATA; + GPR_ASSERT (*bytes_size <= INT_MAX); + bytes_read_from_ssl = BIO_read (impl->from_ssl, bytes, (int) *bytes_size); + if (bytes_read_from_ssl < 0) + { + *bytes_size = 0; + if (!BIO_should_retry (impl->from_ssl)) + { + impl->result = TSI_INTERNAL_ERROR; + return impl->result; + } + else + { + return TSI_OK; + } + } + *bytes_size = (size_t) bytes_read_from_ssl; + return BIO_pending (impl->from_ssl) == 0 ? TSI_OK : TSI_INCOMPLETE_DATA; } -static tsi_result ssl_handshaker_get_result(tsi_handshaker* self) { - tsi_ssl_handshaker* impl = (tsi_ssl_handshaker*)self; - if ((impl->result == TSI_HANDSHAKE_IN_PROGRESS) && - SSL_is_init_finished(impl->ssl)) { - impl->result = TSI_OK; - } +static tsi_result +ssl_handshaker_get_result (tsi_handshaker * self) +{ + tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *) self; + if ((impl->result == TSI_HANDSHAKE_IN_PROGRESS) && SSL_is_init_finished (impl->ssl)) + { + impl->result = TSI_OK; + } return impl->result; } -static tsi_result ssl_handshaker_process_bytes_from_peer( - tsi_handshaker* self, const unsigned char* bytes, size_t* bytes_size) { - tsi_ssl_handshaker* impl = (tsi_ssl_handshaker*)self; +static tsi_result +ssl_handshaker_process_bytes_from_peer (tsi_handshaker * self, const unsigned char *bytes, size_t * bytes_size) +{ + tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *) self; int bytes_written_into_ssl_size = 0; - if (bytes == NULL || bytes_size == 0 || *bytes_size > INT_MAX) { - return TSI_INVALID_ARGUMENT; - } - GPR_ASSERT(*bytes_size <= INT_MAX); - bytes_written_into_ssl_size = - BIO_write(impl->into_ssl, bytes, (int)*bytes_size); - if (bytes_written_into_ssl_size < 0) { - gpr_log(GPR_ERROR, "Could not write to memory BIO."); - impl->result = TSI_INTERNAL_ERROR; - return impl->result; - } - *bytes_size = (size_t)bytes_written_into_ssl_size; - - if (!tsi_handshaker_is_in_progress(self)) { - impl->result = TSI_OK; - return impl->result; - } else { - /* Get ready to get some bytes from SSL. */ - int ssl_result = SSL_do_handshake(impl->ssl); - ssl_result = SSL_get_error(impl->ssl, ssl_result); - switch (ssl_result) { - case SSL_ERROR_WANT_READ: - if (BIO_pending(impl->from_ssl) == 0) { - /* We need more data. */ - return TSI_INCOMPLETE_DATA; - } else { - return TSI_OK; - } - case SSL_ERROR_NONE: - return TSI_OK; - default: { - char err_str[256]; - ERR_error_string_n(ERR_get_error(), err_str, sizeof(err_str)); - gpr_log(GPR_ERROR, "Handshake failed with fatal error %s: %s.", - ssl_error_string(ssl_result), err_str); - impl->result = TSI_PROTOCOL_FAILURE; - return impl->result; - } + if (bytes == NULL || bytes_size == 0 || *bytes_size > INT_MAX) + { + return TSI_INVALID_ARGUMENT; + } + GPR_ASSERT (*bytes_size <= INT_MAX); + bytes_written_into_ssl_size = BIO_write (impl->into_ssl, bytes, (int) *bytes_size); + if (bytes_written_into_ssl_size < 0) + { + gpr_log (GPR_ERROR, "Could not write to memory BIO."); + impl->result = TSI_INTERNAL_ERROR; + return impl->result; + } + *bytes_size = (size_t) bytes_written_into_ssl_size; + + if (!tsi_handshaker_is_in_progress (self)) + { + impl->result = TSI_OK; + return impl->result; + } + else + { + /* Get ready to get some bytes from SSL. */ + int ssl_result = SSL_do_handshake (impl->ssl); + ssl_result = SSL_get_error (impl->ssl, ssl_result); + switch (ssl_result) + { + case SSL_ERROR_WANT_READ: + if (BIO_pending (impl->from_ssl) == 0) + { + /* We need more data. */ + return TSI_INCOMPLETE_DATA; + } + else + { + return TSI_OK; + } + case SSL_ERROR_NONE: + return TSI_OK; + default: + { + char err_str[256]; + ERR_error_string_n (ERR_get_error (), err_str, sizeof (err_str)); + gpr_log (GPR_ERROR, "Handshake failed with fatal error %s: %s.", ssl_error_string (ssl_result), err_str); + impl->result = TSI_PROTOCOL_FAILURE; + return impl->result; + } + } } - } } -static tsi_result ssl_handshaker_extract_peer(tsi_handshaker* self, - tsi_peer* peer) { +static tsi_result +ssl_handshaker_extract_peer (tsi_handshaker * self, tsi_peer * peer) +{ tsi_result result = TSI_OK; - const unsigned char* alpn_selected = NULL; + const unsigned char *alpn_selected = NULL; unsigned int alpn_selected_len; - tsi_ssl_handshaker* impl = (tsi_ssl_handshaker*)self; - X509* peer_cert = SSL_get_peer_certificate(impl->ssl); - if (peer_cert != NULL) { - result = peer_from_x509(peer_cert, 1, peer); - X509_free(peer_cert); - if (result != TSI_OK) return result; - } + tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *) self; + X509 *peer_cert = SSL_get_peer_certificate (impl->ssl); + if (peer_cert != NULL) + { + result = peer_from_x509 (peer_cert, 1, peer); + X509_free (peer_cert); + if (result != TSI_OK) + return result; + } #if TSI_OPENSSL_ALPN_SUPPORT - SSL_get0_alpn_selected(impl->ssl, &alpn_selected, &alpn_selected_len); + SSL_get0_alpn_selected (impl->ssl, &alpn_selected, &alpn_selected_len); #endif /* TSI_OPENSSL_ALPN_SUPPORT */ - if (alpn_selected == NULL) { - /* Try npn. */ - SSL_get0_next_proto_negotiated(impl->ssl, &alpn_selected, - &alpn_selected_len); - } - if (alpn_selected != NULL) { - size_t i; - tsi_peer_property* new_properties = - calloc(1, sizeof(tsi_peer_property) * (peer->property_count + 1)); - if (new_properties == NULL) return TSI_OUT_OF_RESOURCES; - for (i = 0; i < peer->property_count; i++) { - new_properties[i] = peer->properties[i]; - } - result = tsi_construct_string_peer_property( - TSI_SSL_ALPN_SELECTED_PROTOCOL, (const char*)alpn_selected, - alpn_selected_len, &new_properties[peer->property_count]); - if (result != TSI_OK) { - free(new_properties); - return result; + if (alpn_selected == NULL) + { + /* Try npn. */ + SSL_get0_next_proto_negotiated (impl->ssl, &alpn_selected, &alpn_selected_len); + } + if (alpn_selected != NULL) + { + size_t i; + tsi_peer_property *new_properties = calloc (1, sizeof (tsi_peer_property) * (peer->property_count + 1)); + if (new_properties == NULL) + return TSI_OUT_OF_RESOURCES; + for (i = 0; i < peer->property_count; i++) + { + new_properties[i] = peer->properties[i]; + } + result = tsi_construct_string_peer_property (TSI_SSL_ALPN_SELECTED_PROTOCOL, (const char *) alpn_selected, alpn_selected_len, &new_properties[peer->property_count]); + if (result != TSI_OK) + { + free (new_properties); + return result; + } + if (peer->properties != NULL) + free (peer->properties); + peer->property_count++; + peer->properties = new_properties; } - if (peer->properties != NULL) free(peer->properties); - peer->property_count++; - peer->properties = new_properties; - } return result; } -static tsi_result ssl_handshaker_create_frame_protector( - tsi_handshaker* self, size_t* max_output_protected_frame_size, - tsi_frame_protector** protector) { - size_t actual_max_output_protected_frame_size = - TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND; - tsi_ssl_handshaker* impl = (tsi_ssl_handshaker*)self; - tsi_ssl_frame_protector* protector_impl = - calloc(1, sizeof(tsi_ssl_frame_protector)); - if (protector_impl == NULL) { - return TSI_OUT_OF_RESOURCES; - } +static tsi_result +ssl_handshaker_create_frame_protector (tsi_handshaker * self, size_t * max_output_protected_frame_size, tsi_frame_protector ** protector) +{ + size_t actual_max_output_protected_frame_size = TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND; + tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *) self; + tsi_ssl_frame_protector *protector_impl = calloc (1, sizeof (tsi_ssl_frame_protector)); + if (protector_impl == NULL) + { + return TSI_OUT_OF_RESOURCES; + } - if (max_output_protected_frame_size != NULL) { - if (*max_output_protected_frame_size > - TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND) { - *max_output_protected_frame_size = - TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND; - } else if (*max_output_protected_frame_size < - TSI_SSL_MAX_PROTECTED_FRAME_SIZE_LOWER_BOUND) { - *max_output_protected_frame_size = - TSI_SSL_MAX_PROTECTED_FRAME_SIZE_LOWER_BOUND; - } - actual_max_output_protected_frame_size = *max_output_protected_frame_size; - } - protector_impl->buffer_size = - actual_max_output_protected_frame_size - TSI_SSL_MAX_PROTECTION_OVERHEAD; - protector_impl->buffer = malloc(protector_impl->buffer_size); - if (protector_impl->buffer == NULL) { - gpr_log(GPR_ERROR, - "Could not allocated buffer for tsi_ssl_frame_protector."); - free(protector_impl); - return TSI_INTERNAL_ERROR; - } + if (max_output_protected_frame_size != NULL) + { + if (*max_output_protected_frame_size > TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND) + { + *max_output_protected_frame_size = TSI_SSL_MAX_PROTECTED_FRAME_SIZE_UPPER_BOUND; + } + else if (*max_output_protected_frame_size < TSI_SSL_MAX_PROTECTED_FRAME_SIZE_LOWER_BOUND) + { + *max_output_protected_frame_size = TSI_SSL_MAX_PROTECTED_FRAME_SIZE_LOWER_BOUND; + } + actual_max_output_protected_frame_size = *max_output_protected_frame_size; + } + protector_impl->buffer_size = actual_max_output_protected_frame_size - TSI_SSL_MAX_PROTECTION_OVERHEAD; + protector_impl->buffer = malloc (protector_impl->buffer_size); + if (protector_impl->buffer == NULL) + { + gpr_log (GPR_ERROR, "Could not allocated buffer for tsi_ssl_frame_protector."); + free (protector_impl); + return TSI_INTERNAL_ERROR; + } /* Transfer ownership of ssl to the frame protector. It is OK as the caller * cannot call anything else but destroy on the handshaker after this call. */ @@ -968,91 +1078,106 @@ static tsi_result ssl_handshaker_create_frame_protector( return TSI_OK; } -static void ssl_handshaker_destroy(tsi_handshaker* self) { - tsi_ssl_handshaker* impl = (tsi_ssl_handshaker*)self; - SSL_free(impl->ssl); /* The BIO objects are owned by ssl */ - free(impl); +static void +ssl_handshaker_destroy (tsi_handshaker * self) +{ + tsi_ssl_handshaker *impl = (tsi_ssl_handshaker *) self; + SSL_free (impl->ssl); /* The BIO objects are owned by ssl */ + free (impl); } static const tsi_handshaker_vtable handshaker_vtable = { - ssl_handshaker_get_bytes_to_send_to_peer, - ssl_handshaker_process_bytes_from_peer, - ssl_handshaker_get_result, - ssl_handshaker_extract_peer, - ssl_handshaker_create_frame_protector, - ssl_handshaker_destroy, + ssl_handshaker_get_bytes_to_send_to_peer, + ssl_handshaker_process_bytes_from_peer, + ssl_handshaker_get_result, + ssl_handshaker_extract_peer, + ssl_handshaker_create_frame_protector, + ssl_handshaker_destroy, }; /* --- tsi_ssl_handshaker_factory common methods. --- */ -tsi_result tsi_ssl_handshaker_factory_create_handshaker( - tsi_ssl_handshaker_factory* self, const char* server_name_indication, - tsi_handshaker** handshaker) { - if (self == NULL || handshaker == NULL) return TSI_INVALID_ARGUMENT; - return self->create_handshaker(self, server_name_indication, handshaker); +tsi_result +tsi_ssl_handshaker_factory_create_handshaker (tsi_ssl_handshaker_factory * self, const char *server_name_indication, tsi_handshaker ** handshaker) +{ + if (self == NULL || handshaker == NULL) + return TSI_INVALID_ARGUMENT; + return self->create_handshaker (self, server_name_indication, handshaker); } -void tsi_ssl_handshaker_factory_destroy(tsi_ssl_handshaker_factory* self) { - if (self == NULL) return; - self->destroy(self); +void +tsi_ssl_handshaker_factory_destroy (tsi_ssl_handshaker_factory * self) +{ + if (self == NULL) + return; + self->destroy (self); } -static tsi_result create_tsi_ssl_handshaker(SSL_CTX* ctx, int is_client, - const char* server_name_indication, - tsi_handshaker** handshaker) { - SSL* ssl = SSL_new(ctx); - BIO* into_ssl = NULL; - BIO* from_ssl = NULL; - tsi_ssl_handshaker* impl = NULL; +static tsi_result +create_tsi_ssl_handshaker (SSL_CTX * ctx, int is_client, const char *server_name_indication, tsi_handshaker ** handshaker) +{ + SSL *ssl = SSL_new (ctx); + BIO *into_ssl = NULL; + BIO *from_ssl = NULL; + tsi_ssl_handshaker *impl = NULL; *handshaker = NULL; - if (ctx == NULL) { - gpr_log(GPR_ERROR, "SSL Context is null. Should never happen."); - return TSI_INTERNAL_ERROR; - } - if (ssl == NULL) { - return TSI_OUT_OF_RESOURCES; - } - SSL_set_info_callback(ssl, ssl_info_callback); - - into_ssl = BIO_new(BIO_s_mem()); - from_ssl = BIO_new(BIO_s_mem()); - if (into_ssl == NULL || from_ssl == NULL) { - gpr_log(GPR_ERROR, "BIO_new failed."); - SSL_free(ssl); - if (into_ssl != NULL) BIO_free(into_ssl); - if (from_ssl != NULL) BIO_free(into_ssl); - return TSI_OUT_OF_RESOURCES; - } - SSL_set_bio(ssl, into_ssl, from_ssl); - if (is_client) { - int ssl_result; - SSL_set_connect_state(ssl); - if (server_name_indication != NULL) { - if (!SSL_set_tlsext_host_name(ssl, server_name_indication)) { - gpr_log(GPR_ERROR, "Invalid server name indication %s.", - server_name_indication); - SSL_free(ssl); - return TSI_INTERNAL_ERROR; - } - } - ssl_result = SSL_do_handshake(ssl); - ssl_result = SSL_get_error(ssl, ssl_result); - if (ssl_result != SSL_ERROR_WANT_READ) { - gpr_log(GPR_ERROR, - "Unexpected error received from first SSL_do_handshake call: %s", - ssl_error_string(ssl_result)); - SSL_free(ssl); + if (ctx == NULL) + { + gpr_log (GPR_ERROR, "SSL Context is null. Should never happen."); return TSI_INTERNAL_ERROR; } - } else { - SSL_set_accept_state(ssl); - } + if (ssl == NULL) + { + return TSI_OUT_OF_RESOURCES; + } + SSL_set_info_callback (ssl, ssl_info_callback); + + into_ssl = BIO_new (BIO_s_mem ()); + from_ssl = BIO_new (BIO_s_mem ()); + if (into_ssl == NULL || from_ssl == NULL) + { + gpr_log (GPR_ERROR, "BIO_new failed."); + SSL_free (ssl); + if (into_ssl != NULL) + BIO_free (into_ssl); + if (from_ssl != NULL) + BIO_free (into_ssl); + return TSI_OUT_OF_RESOURCES; + } + SSL_set_bio (ssl, into_ssl, from_ssl); + if (is_client) + { + int ssl_result; + SSL_set_connect_state (ssl); + if (server_name_indication != NULL) + { + if (!SSL_set_tlsext_host_name (ssl, server_name_indication)) + { + gpr_log (GPR_ERROR, "Invalid server name indication %s.", server_name_indication); + SSL_free (ssl); + return TSI_INTERNAL_ERROR; + } + } + ssl_result = SSL_do_handshake (ssl); + ssl_result = SSL_get_error (ssl, ssl_result); + if (ssl_result != SSL_ERROR_WANT_READ) + { + gpr_log (GPR_ERROR, "Unexpected error received from first SSL_do_handshake call: %s", ssl_error_string (ssl_result)); + SSL_free (ssl); + return TSI_INTERNAL_ERROR; + } + } + else + { + SSL_set_accept_state (ssl); + } - impl = calloc(1, sizeof(tsi_ssl_handshaker)); - if (impl == NULL) { - SSL_free(ssl); - return TSI_OUT_OF_RESOURCES; - } + impl = calloc (1, sizeof (tsi_ssl_handshaker)); + if (impl == NULL) + { + SSL_free (ssl); + return TSI_OUT_OF_RESOURCES; + } impl->ssl = ssl; impl->into_ssl = into_ssl; impl->from_ssl = from_ssl; @@ -1062,407 +1187,412 @@ static tsi_result create_tsi_ssl_handshaker(SSL_CTX* ctx, int is_client, return TSI_OK; } -static int select_protocol_list(const unsigned char** out, - unsigned char* outlen, - const unsigned char* client_list, - size_t client_list_len, - const unsigned char* server_list, - size_t server_list_len) { - const unsigned char* client_current = client_list; - while ((unsigned int)(client_current - client_list) < client_list_len) { - unsigned char client_current_len = *(client_current++); - const unsigned char* server_current = server_list; - while ((server_current >= server_list) && - (gpr_uintptr)(server_current - server_list) < server_list_len) { - unsigned char server_current_len = *(server_current++); - if ((client_current_len == server_current_len) && - !memcmp(client_current, server_current, server_current_len)) { - *out = server_current; - *outlen = server_current_len; - return SSL_TLSEXT_ERR_OK; - } - server_current += server_current_len; +static int +select_protocol_list (const unsigned char **out, unsigned char *outlen, const unsigned char *client_list, size_t client_list_len, const unsigned char *server_list, size_t server_list_len) +{ + const unsigned char *client_current = client_list; + while ((unsigned int) (client_current - client_list) < client_list_len) + { + unsigned char client_current_len = *(client_current++); + const unsigned char *server_current = server_list; + while ((server_current >= server_list) && (gpr_uintptr) (server_current - server_list) < server_list_len) + { + unsigned char server_current_len = *(server_current++); + if ((client_current_len == server_current_len) && !memcmp (client_current, server_current, server_current_len)) + { + *out = server_current; + *outlen = server_current_len; + return SSL_TLSEXT_ERR_OK; + } + server_current += server_current_len; + } + client_current += client_current_len; } - client_current += client_current_len; - } return SSL_TLSEXT_ERR_NOACK; } /* --- tsi_ssl__client_handshaker_factory methods implementation. --- */ -static tsi_result ssl_client_handshaker_factory_create_handshaker( - tsi_ssl_handshaker_factory* self, const char* server_name_indication, - tsi_handshaker** handshaker) { - tsi_ssl_client_handshaker_factory* impl = - (tsi_ssl_client_handshaker_factory*)self; - return create_tsi_ssl_handshaker(impl->ssl_context, 1, server_name_indication, - handshaker); +static tsi_result +ssl_client_handshaker_factory_create_handshaker (tsi_ssl_handshaker_factory * self, const char *server_name_indication, tsi_handshaker ** handshaker) +{ + tsi_ssl_client_handshaker_factory *impl = (tsi_ssl_client_handshaker_factory *) self; + return create_tsi_ssl_handshaker (impl->ssl_context, 1, server_name_indication, handshaker); } -static void ssl_client_handshaker_factory_destroy( - tsi_ssl_handshaker_factory* self) { - tsi_ssl_client_handshaker_factory* impl = - (tsi_ssl_client_handshaker_factory*)self; - if (impl->ssl_context != NULL) SSL_CTX_free(impl->ssl_context); - if (impl->alpn_protocol_list != NULL) free(impl->alpn_protocol_list); - free(impl); +static void +ssl_client_handshaker_factory_destroy (tsi_ssl_handshaker_factory * self) +{ + tsi_ssl_client_handshaker_factory *impl = (tsi_ssl_client_handshaker_factory *) self; + if (impl->ssl_context != NULL) + SSL_CTX_free (impl->ssl_context); + if (impl->alpn_protocol_list != NULL) + free (impl->alpn_protocol_list); + free (impl); } -static int client_handshaker_factory_npn_callback(SSL* ssl, unsigned char** out, - unsigned char* outlen, - const unsigned char* in, - unsigned int inlen, - void* arg) { - tsi_ssl_client_handshaker_factory* factory = - (tsi_ssl_client_handshaker_factory*)arg; - return select_protocol_list((const unsigned char**)out, outlen, - factory->alpn_protocol_list, - factory->alpn_protocol_list_length, in, inlen); +static int +client_handshaker_factory_npn_callback (SSL * ssl, unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg) +{ + tsi_ssl_client_handshaker_factory *factory = (tsi_ssl_client_handshaker_factory *) arg; + return select_protocol_list ((const unsigned char **) out, outlen, factory->alpn_protocol_list, factory->alpn_protocol_list_length, in, inlen); } /* --- tsi_ssl_server_handshaker_factory methods implementation. --- */ -static tsi_result ssl_server_handshaker_factory_create_handshaker( - tsi_ssl_handshaker_factory* self, const char* server_name_indication, - tsi_handshaker** handshaker) { - tsi_ssl_server_handshaker_factory* impl = - (tsi_ssl_server_handshaker_factory*)self; - if (impl->ssl_context_count == 0 || server_name_indication != NULL) { - return TSI_INVALID_ARGUMENT; - } +static tsi_result +ssl_server_handshaker_factory_create_handshaker (tsi_ssl_handshaker_factory * self, const char *server_name_indication, tsi_handshaker ** handshaker) +{ + tsi_ssl_server_handshaker_factory *impl = (tsi_ssl_server_handshaker_factory *) self; + if (impl->ssl_context_count == 0 || server_name_indication != NULL) + { + return TSI_INVALID_ARGUMENT; + } /* Create the handshaker with the first context. We will switch if needed because of SNI in ssl_server_handshaker_factory_servername_callback. */ - return create_tsi_ssl_handshaker(impl->ssl_contexts[0], 0, NULL, handshaker); + return create_tsi_ssl_handshaker (impl->ssl_contexts[0], 0, NULL, handshaker); } -static void ssl_server_handshaker_factory_destroy( - tsi_ssl_handshaker_factory* self) { - tsi_ssl_server_handshaker_factory* impl = - (tsi_ssl_server_handshaker_factory*)self; +static void +ssl_server_handshaker_factory_destroy (tsi_ssl_handshaker_factory * self) +{ + tsi_ssl_server_handshaker_factory *impl = (tsi_ssl_server_handshaker_factory *) self; size_t i; - for (i = 0; i < impl->ssl_context_count; i++) { - if (impl->ssl_contexts[i] != NULL) { - SSL_CTX_free(impl->ssl_contexts[i]); - tsi_peer_destruct(&impl->ssl_context_x509_subject_names[i]); + for (i = 0; i < impl->ssl_context_count; i++) + { + if (impl->ssl_contexts[i] != NULL) + { + SSL_CTX_free (impl->ssl_contexts[i]); + tsi_peer_destruct (&impl->ssl_context_x509_subject_names[i]); + } } - } - if (impl->ssl_contexts != NULL) free(impl->ssl_contexts); - if (impl->ssl_context_x509_subject_names != NULL) { - free(impl->ssl_context_x509_subject_names); - } - if (impl->alpn_protocol_list != NULL) free(impl->alpn_protocol_list); - free(impl); + if (impl->ssl_contexts != NULL) + free (impl->ssl_contexts); + if (impl->ssl_context_x509_subject_names != NULL) + { + free (impl->ssl_context_x509_subject_names); + } + if (impl->alpn_protocol_list != NULL) + free (impl->alpn_protocol_list); + free (impl); } -static int does_entry_match_name(const char* entry, size_t entry_length, - const char* name) { - const char* dot; - const char* name_subdomain = NULL; - size_t name_length = strlen(name); +static int +does_entry_match_name (const char *entry, size_t entry_length, const char *name) +{ + const char *dot; + const char *name_subdomain = NULL; + size_t name_length = strlen (name); size_t name_subdomain_length; - if (entry_length == 0) return 0; + if (entry_length == 0) + return 0; /* Take care of '.' terminations. */ - if (name[name_length - 1] == '.') { - name_length--; - } - if (entry[entry_length - 1] == '.') { - entry_length--; - if (entry_length == 0) return 0; - } + if (name[name_length - 1] == '.') + { + name_length--; + } + if (entry[entry_length - 1] == '.') + { + entry_length--; + if (entry_length == 0) + return 0; + } - if ((name_length == entry_length) && - strncmp(name, entry, entry_length) == 0) { - return 1; /* Perfect match. */ - } - if (entry[0] != '*') return 0; + if ((name_length == entry_length) && strncmp (name, entry, entry_length) == 0) + { + return 1; /* Perfect match. */ + } + if (entry[0] != '*') + return 0; /* Wildchar subdomain matching. */ - if (entry_length < 3 || entry[1] != '.') { /* At least *.x */ - gpr_log(GPR_ERROR, "Invalid wildchar entry."); + if (entry_length < 3 || entry[1] != '.') + { /* At least *.x */ + gpr_log (GPR_ERROR, "Invalid wildchar entry."); + return 0; + } + name_subdomain = strchr (name, '.'); + if (name_subdomain == NULL) return 0; - } - name_subdomain = strchr(name, '.'); - if (name_subdomain == NULL) return 0; - name_subdomain_length = strlen(name_subdomain); - if (name_subdomain_length < 2) return 0; - name_subdomain++; /* Starts after the dot. */ + name_subdomain_length = strlen (name_subdomain); + if (name_subdomain_length < 2) + return 0; + name_subdomain++; /* Starts after the dot. */ name_subdomain_length--; - entry += 2; /* Remove *. */ + entry += 2; /* Remove *. */ entry_length -= 2; - dot = strchr(name_subdomain, '.'); - if ((dot == NULL) || (dot == &name_subdomain[name_subdomain_length - 1])) { - gpr_log(GPR_ERROR, "Invalid toplevel subdomain: %s", name_subdomain); - return 0; - } - if (name_subdomain[name_subdomain_length - 1] == '.') { - name_subdomain_length--; - } - return ((entry_length > 0) && (name_subdomain_length == entry_length) && - strncmp(entry, name_subdomain, entry_length) == 0); + dot = strchr (name_subdomain, '.'); + if ((dot == NULL) || (dot == &name_subdomain[name_subdomain_length - 1])) + { + gpr_log (GPR_ERROR, "Invalid toplevel subdomain: %s", name_subdomain); + return 0; + } + if (name_subdomain[name_subdomain_length - 1] == '.') + { + name_subdomain_length--; + } + return ((entry_length > 0) && (name_subdomain_length == entry_length) && strncmp (entry, name_subdomain, entry_length) == 0); } -static int ssl_server_handshaker_factory_servername_callback(SSL* ssl, int* ap, - void* arg) { - tsi_ssl_server_handshaker_factory* impl = - (tsi_ssl_server_handshaker_factory*)arg; +static int +ssl_server_handshaker_factory_servername_callback (SSL * ssl, int *ap, void *arg) +{ + tsi_ssl_server_handshaker_factory *impl = (tsi_ssl_server_handshaker_factory *) arg; size_t i = 0; - const char* servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); - if (servername == NULL || strlen(servername) == 0) { - return SSL_TLSEXT_ERR_NOACK; - } + const char *servername = SSL_get_servername (ssl, TLSEXT_NAMETYPE_host_name); + if (servername == NULL || strlen (servername) == 0) + { + return SSL_TLSEXT_ERR_NOACK; + } - for (i = 0; i < impl->ssl_context_count; i++) { - if (tsi_ssl_peer_matches_name(&impl->ssl_context_x509_subject_names[i], - servername)) { - SSL_set_SSL_CTX(ssl, impl->ssl_contexts[i]); - return SSL_TLSEXT_ERR_OK; + for (i = 0; i < impl->ssl_context_count; i++) + { + if (tsi_ssl_peer_matches_name (&impl->ssl_context_x509_subject_names[i], servername)) + { + SSL_set_SSL_CTX (ssl, impl->ssl_contexts[i]); + return SSL_TLSEXT_ERR_OK; + } } - } - gpr_log(GPR_ERROR, "No match found for server name: %s.", servername); + gpr_log (GPR_ERROR, "No match found for server name: %s.", servername); return SSL_TLSEXT_ERR_ALERT_WARNING; } #if TSI_OPENSSL_ALPN_SUPPORT -static int server_handshaker_factory_alpn_callback( - SSL* ssl, const unsigned char** out, unsigned char* outlen, - const unsigned char* in, unsigned int inlen, void* arg) { - tsi_ssl_server_handshaker_factory* factory = - (tsi_ssl_server_handshaker_factory*)arg; - return select_protocol_list(out, outlen, in, inlen, - factory->alpn_protocol_list, - factory->alpn_protocol_list_length); +static int +server_handshaker_factory_alpn_callback (SSL * ssl, const unsigned char **out, unsigned char *outlen, const unsigned char *in, unsigned int inlen, void *arg) +{ + tsi_ssl_server_handshaker_factory *factory = (tsi_ssl_server_handshaker_factory *) arg; + return select_protocol_list (out, outlen, in, inlen, factory->alpn_protocol_list, factory->alpn_protocol_list_length); } #endif /* TSI_OPENSSL_ALPN_SUPPORT */ -static int server_handshaker_factory_npn_advertised_callback( - SSL* ssl, const unsigned char** out, unsigned int* outlen, void* arg) { - tsi_ssl_server_handshaker_factory* factory = - (tsi_ssl_server_handshaker_factory*)arg; +static int +server_handshaker_factory_npn_advertised_callback (SSL * ssl, const unsigned char **out, unsigned int *outlen, void *arg) +{ + tsi_ssl_server_handshaker_factory *factory = (tsi_ssl_server_handshaker_factory *) arg; *out = factory->alpn_protocol_list; - GPR_ASSERT(factory->alpn_protocol_list_length <= UINT_MAX); - *outlen = (unsigned int)factory->alpn_protocol_list_length; + GPR_ASSERT (factory->alpn_protocol_list_length <= UINT_MAX); + *outlen = (unsigned int) factory->alpn_protocol_list_length; return SSL_TLSEXT_ERR_OK; } /* --- tsi_ssl_handshaker_factory constructors. --- */ -tsi_result tsi_create_ssl_client_handshaker_factory( - const unsigned char* pem_private_key, size_t pem_private_key_size, - const unsigned char* pem_cert_chain, size_t pem_cert_chain_size, - const unsigned char* pem_root_certs, size_t pem_root_certs_size, - const char* cipher_list, const unsigned char** alpn_protocols, - const unsigned char* alpn_protocols_lengths, uint16_t num_alpn_protocols, - tsi_ssl_handshaker_factory** factory) { - SSL_CTX* ssl_context = NULL; - tsi_ssl_client_handshaker_factory* impl = NULL; +tsi_result +tsi_create_ssl_client_handshaker_factory (const unsigned char *pem_private_key, size_t pem_private_key_size, const unsigned char *pem_cert_chain, size_t pem_cert_chain_size, const unsigned char *pem_root_certs, size_t pem_root_certs_size, const char *cipher_list, const unsigned char **alpn_protocols, const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, tsi_ssl_handshaker_factory ** factory) +{ + SSL_CTX *ssl_context = NULL; + tsi_ssl_client_handshaker_factory *impl = NULL; tsi_result result = TSI_OK; - gpr_once_init(&init_openssl_once, init_openssl); + gpr_once_init (&init_openssl_once, init_openssl); - if (factory == NULL) return TSI_INVALID_ARGUMENT; + if (factory == NULL) + return TSI_INVALID_ARGUMENT; *factory = NULL; - if (pem_root_certs == NULL) return TSI_INVALID_ARGUMENT; - - ssl_context = SSL_CTX_new(TLSv1_2_method()); - if (ssl_context == NULL) { - gpr_log(GPR_ERROR, "Could not create ssl context."); + if (pem_root_certs == NULL) return TSI_INVALID_ARGUMENT; - } - impl = calloc(1, sizeof(tsi_ssl_client_handshaker_factory)); - if (impl == NULL) { - SSL_CTX_free(ssl_context); - return TSI_OUT_OF_RESOURCES; - } + ssl_context = SSL_CTX_new (TLSv1_2_method ()); + if (ssl_context == NULL) + { + gpr_log (GPR_ERROR, "Could not create ssl context."); + return TSI_INVALID_ARGUMENT; + } + + impl = calloc (1, sizeof (tsi_ssl_client_handshaker_factory)); + if (impl == NULL) + { + SSL_CTX_free (ssl_context); + return TSI_OUT_OF_RESOURCES; + } impl->ssl_context = ssl_context; - do { - result = - populate_ssl_context(ssl_context, pem_private_key, pem_private_key_size, - pem_cert_chain, pem_cert_chain_size, cipher_list); - if (result != TSI_OK) break; - result = ssl_ctx_load_verification_certs(ssl_context, pem_root_certs, - pem_root_certs_size, NULL); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Cannot load server root certificates."); - break; - } - - if (num_alpn_protocols != 0) { - result = build_alpn_protocol_name_list( - alpn_protocols, alpn_protocols_lengths, num_alpn_protocols, - &impl->alpn_protocol_list, &impl->alpn_protocol_list_length); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Building alpn list failed with error %s.", - tsi_result_to_string(result)); - break; - } + do + { + result = populate_ssl_context (ssl_context, pem_private_key, pem_private_key_size, pem_cert_chain, pem_cert_chain_size, cipher_list); + if (result != TSI_OK) + break; + result = ssl_ctx_load_verification_certs (ssl_context, pem_root_certs, pem_root_certs_size, NULL); + if (result != TSI_OK) + { + gpr_log (GPR_ERROR, "Cannot load server root certificates."); + break; + } + + if (num_alpn_protocols != 0) + { + result = build_alpn_protocol_name_list (alpn_protocols, alpn_protocols_lengths, num_alpn_protocols, &impl->alpn_protocol_list, &impl->alpn_protocol_list_length); + if (result != TSI_OK) + { + gpr_log (GPR_ERROR, "Building alpn list failed with error %s.", tsi_result_to_string (result)); + break; + } #if TSI_OPENSSL_ALPN_SUPPORT - GPR_ASSERT(impl->alpn_protocol_list_length < UINT_MAX); - if (SSL_CTX_set_alpn_protos( - ssl_context, impl->alpn_protocol_list, - (unsigned int)impl->alpn_protocol_list_length)) { - gpr_log(GPR_ERROR, "Could not set alpn protocol list to context."); - result = TSI_INVALID_ARGUMENT; - break; - } + GPR_ASSERT (impl->alpn_protocol_list_length < UINT_MAX); + if (SSL_CTX_set_alpn_protos (ssl_context, impl->alpn_protocol_list, (unsigned int) impl->alpn_protocol_list_length)) + { + gpr_log (GPR_ERROR, "Could not set alpn protocol list to context."); + result = TSI_INVALID_ARGUMENT; + break; + } #endif /* TSI_OPENSSL_ALPN_SUPPORT */ - SSL_CTX_set_next_proto_select_cb( - ssl_context, client_handshaker_factory_npn_callback, impl); + SSL_CTX_set_next_proto_select_cb (ssl_context, client_handshaker_factory_npn_callback, impl); + } } - } while (0); - if (result != TSI_OK) { - ssl_client_handshaker_factory_destroy(&impl->base); - return result; - } - SSL_CTX_set_verify(ssl_context, SSL_VERIFY_PEER, NULL); + while (0); + if (result != TSI_OK) + { + ssl_client_handshaker_factory_destroy (&impl->base); + return result; + } + SSL_CTX_set_verify (ssl_context, SSL_VERIFY_PEER, NULL); /* TODO(jboeuf): Add revocation verification. */ - impl->base.create_handshaker = - ssl_client_handshaker_factory_create_handshaker; + impl->base.create_handshaker = ssl_client_handshaker_factory_create_handshaker; impl->base.destroy = ssl_client_handshaker_factory_destroy; *factory = &impl->base; return TSI_OK; } -tsi_result tsi_create_ssl_server_handshaker_factory( - const unsigned char** pem_private_keys, - const size_t* pem_private_keys_sizes, const unsigned char** pem_cert_chains, - const size_t* pem_cert_chains_sizes, size_t key_cert_pair_count, - const unsigned char* pem_client_root_certs, - size_t pem_client_root_certs_size, int force_client_auth, - const char* cipher_list, const unsigned char** alpn_protocols, - const unsigned char* alpn_protocols_lengths, uint16_t num_alpn_protocols, - tsi_ssl_handshaker_factory** factory) { - tsi_ssl_server_handshaker_factory* impl = NULL; +tsi_result +tsi_create_ssl_server_handshaker_factory (const unsigned char **pem_private_keys, const size_t * pem_private_keys_sizes, const unsigned char **pem_cert_chains, const size_t * pem_cert_chains_sizes, size_t key_cert_pair_count, const unsigned char *pem_client_root_certs, size_t pem_client_root_certs_size, int force_client_auth, const char *cipher_list, const unsigned char **alpn_protocols, const unsigned char *alpn_protocols_lengths, uint16_t num_alpn_protocols, tsi_ssl_handshaker_factory ** factory) +{ + tsi_ssl_server_handshaker_factory *impl = NULL; tsi_result result = TSI_OK; size_t i = 0; - gpr_once_init(&init_openssl_once, init_openssl); + gpr_once_init (&init_openssl_once, init_openssl); - if (factory == NULL) return TSI_INVALID_ARGUMENT; - *factory = NULL; - if (key_cert_pair_count == 0 || pem_private_keys == NULL || - pem_cert_chains == NULL) { + if (factory == NULL) return TSI_INVALID_ARGUMENT; - } + *factory = NULL; + if (key_cert_pair_count == 0 || pem_private_keys == NULL || pem_cert_chains == NULL) + { + return TSI_INVALID_ARGUMENT; + } - impl = calloc(1, sizeof(tsi_ssl_server_handshaker_factory)); - if (impl == NULL) return TSI_OUT_OF_RESOURCES; - impl->base.create_handshaker = - ssl_server_handshaker_factory_create_handshaker; - impl->base.destroy = ssl_server_handshaker_factory_destroy; - impl->ssl_contexts = calloc(key_cert_pair_count, sizeof(SSL_CTX*)); - impl->ssl_context_x509_subject_names = - calloc(key_cert_pair_count, sizeof(tsi_peer)); - if (impl->ssl_contexts == NULL || - impl->ssl_context_x509_subject_names == NULL) { - tsi_ssl_handshaker_factory_destroy(&impl->base); + impl = calloc (1, sizeof (tsi_ssl_server_handshaker_factory)); + if (impl == NULL) return TSI_OUT_OF_RESOURCES; - } + impl->base.create_handshaker = ssl_server_handshaker_factory_create_handshaker; + impl->base.destroy = ssl_server_handshaker_factory_destroy; + impl->ssl_contexts = calloc (key_cert_pair_count, sizeof (SSL_CTX *)); + impl->ssl_context_x509_subject_names = calloc (key_cert_pair_count, sizeof (tsi_peer)); + if (impl->ssl_contexts == NULL || impl->ssl_context_x509_subject_names == NULL) + { + tsi_ssl_handshaker_factory_destroy (&impl->base); + return TSI_OUT_OF_RESOURCES; + } impl->ssl_context_count = key_cert_pair_count; - if (num_alpn_protocols > 0) { - result = build_alpn_protocol_name_list( - alpn_protocols, alpn_protocols_lengths, num_alpn_protocols, - &impl->alpn_protocol_list, &impl->alpn_protocol_list_length); - if (result != TSI_OK) { - tsi_ssl_handshaker_factory_destroy(&impl->base); - return result; + if (num_alpn_protocols > 0) + { + result = build_alpn_protocol_name_list (alpn_protocols, alpn_protocols_lengths, num_alpn_protocols, &impl->alpn_protocol_list, &impl->alpn_protocol_list_length); + if (result != TSI_OK) + { + tsi_ssl_handshaker_factory_destroy (&impl->base); + return result; + } } - } - - for (i = 0; i < key_cert_pair_count; i++) { - do { - impl->ssl_contexts[i] = SSL_CTX_new(TLSv1_2_method()); - if (impl->ssl_contexts[i] == NULL) { - gpr_log(GPR_ERROR, "Could not create ssl context."); - result = TSI_OUT_OF_RESOURCES; - break; - } - result = populate_ssl_context( - impl->ssl_contexts[i], pem_private_keys[i], pem_private_keys_sizes[i], - pem_cert_chains[i], pem_cert_chains_sizes[i], cipher_list); - if (result != TSI_OK) break; - - if (pem_client_root_certs != NULL) { - int flags = SSL_VERIFY_PEER; - STACK_OF(X509_NAME)* root_names = NULL; - result = ssl_ctx_load_verification_certs( - impl->ssl_contexts[i], pem_client_root_certs, - pem_client_root_certs_size, &root_names); - if (result != TSI_OK) { - gpr_log(GPR_ERROR, "Invalid verification certs."); - break; - } - SSL_CTX_set_client_CA_list(impl->ssl_contexts[i], root_names); - if (force_client_auth) flags |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; - SSL_CTX_set_verify(impl->ssl_contexts[i], flags, NULL); - /* TODO(jboeuf): Add revocation verification. */ - } - - result = extract_x509_subject_names_from_pem_cert( - pem_cert_chains[i], pem_cert_chains_sizes[i], - &impl->ssl_context_x509_subject_names[i]); - if (result != TSI_OK) break; - SSL_CTX_set_tlsext_servername_callback( - impl->ssl_contexts[i], - ssl_server_handshaker_factory_servername_callback); - SSL_CTX_set_tlsext_servername_arg(impl->ssl_contexts[i], impl); + for (i = 0; i < key_cert_pair_count; i++) + { + do + { + impl->ssl_contexts[i] = SSL_CTX_new (TLSv1_2_method ()); + if (impl->ssl_contexts[i] == NULL) + { + gpr_log (GPR_ERROR, "Could not create ssl context."); + result = TSI_OUT_OF_RESOURCES; + break; + } + result = populate_ssl_context (impl->ssl_contexts[i], pem_private_keys[i], pem_private_keys_sizes[i], pem_cert_chains[i], pem_cert_chains_sizes[i], cipher_list); + if (result != TSI_OK) + break; + + if (pem_client_root_certs != NULL) + { + int flags = SSL_VERIFY_PEER; + STACK_OF (X509_NAME) * root_names = NULL; + result = ssl_ctx_load_verification_certs (impl->ssl_contexts[i], pem_client_root_certs, pem_client_root_certs_size, &root_names); + if (result != TSI_OK) + { + gpr_log (GPR_ERROR, "Invalid verification certs."); + break; + } + SSL_CTX_set_client_CA_list (impl->ssl_contexts[i], root_names); + if (force_client_auth) + flags |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT; + SSL_CTX_set_verify (impl->ssl_contexts[i], flags, NULL); + /* TODO(jboeuf): Add revocation verification. */ + } + + result = extract_x509_subject_names_from_pem_cert (pem_cert_chains[i], pem_cert_chains_sizes[i], &impl->ssl_context_x509_subject_names[i]); + if (result != TSI_OK) + break; + + SSL_CTX_set_tlsext_servername_callback (impl->ssl_contexts[i], ssl_server_handshaker_factory_servername_callback); + SSL_CTX_set_tlsext_servername_arg (impl->ssl_contexts[i], impl); #if TSI_OPENSSL_ALPN_SUPPORT - SSL_CTX_set_alpn_select_cb(impl->ssl_contexts[i], - server_handshaker_factory_alpn_callback, impl); + SSL_CTX_set_alpn_select_cb (impl->ssl_contexts[i], server_handshaker_factory_alpn_callback, impl); #endif /* TSI_OPENSSL_ALPN_SUPPORT */ - SSL_CTX_set_next_protos_advertised_cb( - impl->ssl_contexts[i], - server_handshaker_factory_npn_advertised_callback, impl); - } while (0); - - if (result != TSI_OK) { - tsi_ssl_handshaker_factory_destroy(&impl->base); - return result; + SSL_CTX_set_next_protos_advertised_cb (impl->ssl_contexts[i], server_handshaker_factory_npn_advertised_callback, impl); + } + while (0); + + if (result != TSI_OK) + { + tsi_ssl_handshaker_factory_destroy (&impl->base); + return result; + } } - } *factory = &impl->base; return TSI_OK; } /* --- tsi_ssl utils. --- */ -int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name) { +int +tsi_ssl_peer_matches_name (const tsi_peer * peer, const char *name) +{ size_t i = 0; size_t san_count = 0; - const tsi_peer_property* cn_property = NULL; + const tsi_peer_property *cn_property = NULL; /* For now reject what looks like an IP address. */ - if (looks_like_ip_address(name)) return 0; + if (looks_like_ip_address (name)) + return 0; /* Check the SAN first. */ - for (i = 0; i < peer->property_count; i++) { - const tsi_peer_property* property = &peer->properties[i]; - if (property->name == NULL) continue; - if (strcmp(property->name, - TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) { - san_count++; - if (does_entry_match_name(property->value.data, property->value.length, - name)) { - return 1; - } - } else if (strcmp(property->name, - TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY) == 0) { - cn_property = property; + for (i = 0; i < peer->property_count; i++) + { + const tsi_peer_property *property = &peer->properties[i]; + if (property->name == NULL) + continue; + if (strcmp (property->name, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) == 0) + { + san_count++; + if (does_entry_match_name (property->value.data, property->value.length, name)) + { + return 1; + } + } + else if (strcmp (property->name, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY) == 0) + { + cn_property = property; + } } - } /* If there's no SAN, try the CN. */ - if (san_count == 0 && cn_property != NULL) { - if (does_entry_match_name(cn_property->value.data, - cn_property->value.length, name)) { - return 1; + if (san_count == 0 && cn_property != NULL) + { + if (does_entry_match_name (cn_property->value.data, cn_property->value.length, name)) + { + return 1; + } } - } - return 0; /* Not found. */ + return 0; /* Not found. */ } |