1 /* 2 * 3 * Copyright 2016 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 #include "test/core/handshake/server_ssl_common.h" 20 21 #include <arpa/inet.h> 22 #include <openssl/err.h> 23 #include <openssl/ssl.h> 24 #include <string.h> 25 #include <sys/socket.h> 26 #include <unistd.h> 27 28 #include <grpc/grpc.h> 29 #include <grpc/grpc_security.h> 30 #include <grpc/support/alloc.h> 31 #include <grpc/support/log.h> 32 #include <grpc/support/string_util.h> 33 #include <grpc/support/sync.h> 34 35 #include "src/core/lib/gprpp/thd.h" 36 #include "src/core/lib/iomgr/load_file.h" 37 #include "test/core/util/port.h" 38 #include "test/core/util/test_config.h" 39 40 #define SSL_CERT_PATH "src/core/tsi/test_creds/server1.pem" 41 #define SSL_KEY_PATH "src/core/tsi/test_creds/server1.key" 42 #define SSL_CA_PATH "src/core/tsi/test_creds/ca.pem" 43 44 // Handshake completed signal to server thread. 45 static gpr_event client_handshake_complete; 46 47 static int create_socket(int port) { 48 int s; 49 struct sockaddr_in addr; 50 51 addr.sin_family = AF_INET; 52 addr.sin_port = htons(static_cast<uint16_t>(port)); 53 addr.sin_addr.s_addr = htonl(INADDR_ANY); 54 55 s = socket(AF_INET, SOCK_STREAM, 0); 56 if (s < 0) { 57 perror("Unable to create socket"); 58 return -1; 59 } 60 61 if (connect(s, reinterpret_cast<struct sockaddr*>(&addr), sizeof(addr)) < 0) { 62 perror("Unable to connect"); 63 return -1; 64 } 65 66 return s; 67 } 68 69 // Simple gRPC server. This listens until client_handshake_complete occurs. 70 static void server_thread(void* arg) { 71 const int port = *static_cast<int*>(arg); 72 73 // Load key pair and establish server SSL credentials. 74 grpc_ssl_pem_key_cert_pair pem_key_cert_pair; 75 grpc_slice ca_slice, cert_slice, key_slice; 76 GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", 77 grpc_load_file(SSL_CA_PATH, 1, &ca_slice))); 78 GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", 79 grpc_load_file(SSL_CERT_PATH, 1, &cert_slice))); 80 GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", 81 grpc_load_file(SSL_KEY_PATH, 1, &key_slice))); 82 const char* ca_cert = 83 reinterpret_cast<const char*> GRPC_SLICE_START_PTR(ca_slice); 84 pem_key_cert_pair.private_key = 85 reinterpret_cast<const char*> GRPC_SLICE_START_PTR(key_slice); 86 pem_key_cert_pair.cert_chain = 87 reinterpret_cast<const char*> GRPC_SLICE_START_PTR(cert_slice); 88 grpc_server_credentials* ssl_creds = grpc_ssl_server_credentials_create( 89 ca_cert, &pem_key_cert_pair, 1, 0, nullptr); 90 91 // Start server listening on local port. 92 char* addr; 93 gpr_asprintf(&addr, "127.0.0.1:%d", port); 94 grpc_server* server = grpc_server_create(nullptr, nullptr); 95 GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, ssl_creds)); 96 free(addr); 97 98 grpc_completion_queue* cq = grpc_completion_queue_create_for_next(nullptr); 99 100 grpc_server_register_completion_queue(server, cq, nullptr); 101 grpc_server_start(server); 102 103 // Wait a bounded number of time until client_handshake_complete is set, 104 // sleeping between polls. 105 int retries = 10; 106 while (!gpr_event_get(&client_handshake_complete) && retries-- > 0) { 107 const gpr_timespec cq_deadline = grpc_timeout_seconds_to_deadline(1); 108 grpc_event ev = grpc_completion_queue_next(cq, cq_deadline, nullptr); 109 GPR_ASSERT(ev.type == GRPC_QUEUE_TIMEOUT); 110 } 111 112 gpr_log(GPR_INFO, "Shutting down server"); 113 grpc_server_shutdown_and_notify(server, cq, nullptr); 114 grpc_completion_queue_shutdown(cq); 115 116 const gpr_timespec cq_deadline = grpc_timeout_seconds_to_deadline(5); 117 grpc_event ev = grpc_completion_queue_next(cq, cq_deadline, nullptr); 118 GPR_ASSERT(ev.type == GRPC_OP_COMPLETE); 119 120 grpc_server_destroy(server); 121 grpc_completion_queue_destroy(cq); 122 grpc_server_credentials_release(ssl_creds); 123 grpc_slice_unref(cert_slice); 124 grpc_slice_unref(key_slice); 125 grpc_slice_unref(ca_slice); 126 } 127 128 // This test launches a gRPC server on a separate thread and then establishes a 129 // TLS handshake via a minimal TLS client. The TLS client has configurable (via 130 // alpn_list) ALPN settings and can probe at the supported ALPN preferences 131 // using this (via alpn_expected). 132 bool server_ssl_test(const char* alpn_list[], unsigned int alpn_list_len, 133 const char* alpn_expected) { 134 bool success = true; 135 136 grpc_init(); 137 int port = grpc_pick_unused_port_or_die(); 138 gpr_event_init(&client_handshake_complete); 139 140 // Launch the gRPC server thread. 141 bool ok; 142 grpc_core::Thread thd("grpc_ssl_test", server_thread, &port, &ok); 143 GPR_ASSERT(ok); 144 thd.Start(); 145 146 SSL_load_error_strings(); 147 OpenSSL_add_ssl_algorithms(); 148 149 const SSL_METHOD* method = TLSv1_2_client_method(); 150 SSL_CTX* ctx = SSL_CTX_new(method); 151 if (!ctx) { 152 perror("Unable to create SSL context"); 153 ERR_print_errors_fp(stderr); 154 abort(); 155 } 156 157 // Load key pair. 158 if (SSL_CTX_use_certificate_file(ctx, SSL_CERT_PATH, SSL_FILETYPE_PEM) < 0) { 159 ERR_print_errors_fp(stderr); 160 abort(); 161 } 162 if (SSL_CTX_use_PrivateKey_file(ctx, SSL_KEY_PATH, SSL_FILETYPE_PEM) < 0) { 163 ERR_print_errors_fp(stderr); 164 abort(); 165 } 166 167 // Set the cipher list to match the one expressed in 168 // src/core/tsi/ssl_transport_security.c. 169 const char* cipher_list = 170 "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-" 171 "SHA384:ECDHE-RSA-AES256-GCM-SHA384"; 172 if (!SSL_CTX_set_cipher_list(ctx, cipher_list)) { 173 ERR_print_errors_fp(stderr); 174 gpr_log(GPR_ERROR, "Couldn't set server cipher list."); 175 abort(); 176 } 177 178 // Configure ALPN list the client will send to the server. This must match the 179 // wire format, see documentation for SSL_CTX_set_alpn_protos. 180 unsigned int alpn_protos_len = alpn_list_len; 181 for (unsigned int i = 0; i < alpn_list_len; ++i) { 182 alpn_protos_len += static_cast<unsigned int>(strlen(alpn_list[i])); 183 } 184 unsigned char* alpn_protos = 185 static_cast<unsigned char*>(gpr_malloc(alpn_protos_len)); 186 unsigned char* p = alpn_protos; 187 for (unsigned int i = 0; i < alpn_list_len; ++i) { 188 const uint8_t len = static_cast<uint8_t>(strlen(alpn_list[i])); 189 *p++ = len; 190 memcpy(p, alpn_list[i], len); 191 p += len; 192 } 193 GPR_ASSERT(SSL_CTX_set_alpn_protos(ctx, alpn_protos, alpn_protos_len) == 0); 194 195 // Try and connect to server. We allow a bounded number of retries as we might 196 // be racing with the server setup on its separate thread. 197 int retries = 10; 198 int sock = -1; 199 while (sock == -1 && retries-- > 0) { 200 sock = create_socket(port); 201 if (sock < 0) { 202 sleep(1); 203 } 204 } 205 GPR_ASSERT(sock > 0); 206 gpr_log(GPR_INFO, "Connected to server on port %d", port); 207 208 // Establish a SSL* and connect at SSL layer. 209 SSL* ssl = SSL_new(ctx); 210 GPR_ASSERT(ssl); 211 SSL_set_fd(ssl, sock); 212 if (SSL_connect(ssl) <= 0) { 213 ERR_print_errors_fp(stderr); 214 gpr_log(GPR_ERROR, "Handshake failed."); 215 success = false; 216 } else { 217 gpr_log(GPR_INFO, "Handshake successful."); 218 // Validate ALPN preferred by server matches alpn_expected. 219 const unsigned char* alpn_selected; 220 unsigned int alpn_selected_len; 221 SSL_get0_alpn_selected(ssl, &alpn_selected, &alpn_selected_len); 222 if (strlen(alpn_expected) != alpn_selected_len || 223 strncmp(reinterpret_cast<const char*>(alpn_selected), alpn_expected, 224 alpn_selected_len) != 0) { 225 gpr_log(GPR_ERROR, "Unexpected ALPN protocol preference"); 226 success = false; 227 } 228 } 229 gpr_event_set(&client_handshake_complete, &client_handshake_complete); 230 231 SSL_free(ssl); 232 gpr_free(alpn_protos); 233 SSL_CTX_free(ctx); 234 EVP_cleanup(); 235 close(sock); 236 237 thd.Join(); 238 239 grpc_shutdown(); 240 241 return success; 242 } 243