Files
Li, Xun 8a22317709 Linux 2.22 Open Source Gold Release
Upgraded to OpenSSL 3.0.10.
Added interoperable RA-TLS support which follows CCC design.
Enhanced Protect File System performance and added additional dependency
  `libsgx_pthread.a`.
Added the Constant Time instruction Decoder (CTD) into the default AEX-Notify
  mitigation handler in order to prevent the introduction of any additional
  subtle sidechannel leakages within the default handler.
Added Mistletoe 3 mitigations to the IPP Cryptography Library to the AES-ECB,
  AESGCM, and AES-CMAC algorithms. These have been incorporated transparently
  into the `sgx_tcrypto` library.
Resigned all Intel® SGX Architecture Enclaves.
Upgraded Intel SGX Quote Verification Enclave to integrate OpenSSL/SgxSSL 3.0.10.
Added Attestation Library support for Intel(R) TDX Migration TD.
Added Rust wrapper for low-level Quote Generation APIs.
Enabled `SE_TRACE` log in release binary.
Updated Rust QVL wrapper to use native Rust structure for quote verification
  collateral.
Added a limitation in the DCAP QVL to only allow the user to set the QvE load
  policy once.
Fixed bugs.

Signed-off-by: Li, Xun <xun.li@intel.com>
2023-10-24 11:05:23 +08:00

296 lines
8.3 KiB
C++

/**
*
* MIT License
*
* Copyright (c) Open Enclave SDK contributors.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE
*
*/
#include <errno.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#include <string.h>
#include "../../common/openssl_utility.h"
#include "tls_client_t.h"
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdlib.h>
int verify_callback(int preverify_ok, X509_STORE_CTX* ctx);
extern "C"
{
int launch_tls_client(char* server_name, char* server_port);
};
unsigned long inet_addr2(const char *str)
{
unsigned long lHost = 0;
char *pLong = (char *)&lHost;
char *p = (char *)str;
while (p)
{
*pLong++ = atoi(p);
p = strchr(p, '.');
if (p)
++p;
}
return lHost;
}
// This routine conducts a simple HTTP request/response communication with
// server
int communicate_with_server(SSL* ssl)
{
unsigned char buf[200];
int ret = 1;
int error = 0;
int len = 0;
int bytes_written = 0;
int bytes_read = 0;
// Write an GET request to the server
t_print(TLS_CLIENT "-----> Write to server:\n");
len = snprintf((char*)buf, sizeof(buf) - 1, CLIENT_PAYLOAD);
while ((bytes_written = SSL_write(ssl, buf, (size_t)len)) <= 0)
{
error = SSL_get_error(ssl, bytes_written);
if (error == SSL_ERROR_WANT_WRITE)
continue;
t_print(TLS_CLIENT "Failed! SSL_write returned %d\n", error);
if (bytes_written == 0) ret = -1;
else ret = bytes_written;
goto done;
}
t_print(TLS_CLIENT "%d bytes written\n", bytes_written);
// Read the HTTP response from server
t_print(TLS_CLIENT "<---- Read from server:\n");
do
{
len = sizeof(buf) - 1;
memset(buf, 0, sizeof(buf));
bytes_read = SSL_read(ssl, buf, (size_t)len);
if (bytes_read <= 0)
{
int error = SSL_get_error(ssl, bytes_read);
if (error == SSL_ERROR_WANT_READ)
continue;
t_print(TLS_CLIENT "Failed! SSL_read returned error=%d\n", error);
if (bytes_read == 0) ret = -1;
else ret = bytes_read;
break;
}
t_print(TLS_CLIENT " %d bytes read\n", bytes_read);
// check to to see if received payload is expected
// Note that if you just want to use client here but server from other
// applications, you need to ignore this check, SERVER_PAYLOAD_SIZE
// need to be adjusted.
if ((bytes_read != SERVER_PAYLOAD_SIZE) ||
(memcmp(SERVER_PAYLOAD, buf, bytes_read) != 0))
{
t_print(
TLS_CLIENT "ERROR: expected reading %lu bytes but only "
"received %d bytes\n",
SERVER_PAYLOAD_SIZE,
bytes_read);
ret = bytes_read;
break;
}
else
{
t_print(TLS_CLIENT
" received all the expected data from server\n\n");
ret = 0;
break;
}
} while (1);
done:
return ret;
}
// create a socket and connect to the server_name:server_port
int create_socket(char* server_name, char* server_port)
{
int sockfd = -1;
struct sockaddr_in dest_sock;
int res = -1;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd == -1)
{
t_print(TLS_CLIENT "Error: Cannot create socket %d.\n", errno);
goto done;
}
dest_sock.sin_family = AF_INET;
dest_sock.sin_port = htons(atoi(server_port));
dest_sock.sin_addr.s_addr = inet_addr2(server_name);
bzero(&(dest_sock.sin_zero), sizeof(dest_sock.sin_zero));
if (connect(
sockfd, (sockaddr*) &dest_sock,
sizeof(struct sockaddr)) == -1)
{
t_print(
TLS_CLIENT "failed to connect to %s:%s (errno=%d)\n",
server_port,
server_port,
errno);
ocall_close(&res, sockfd);
if (res != 0)
t_print(TLS_CLIENT "OCALL: error closing socket\n");
sockfd = -1;
goto done;
}
t_print(TLS_CLIENT "connected to %s:%s\n", server_name, server_port);
done:
return sockfd;
}
int launch_tls_client(char* server_name, char* server_port)
{
t_print(TLS_CLIENT " called launch tls client\n");
int ret = 0;
SSL_CTX* ssl_client_ctx = nullptr;
SSL* ssl_session = nullptr;
X509* cert = nullptr;
EVP_PKEY* pkey = nullptr;
SSL_CONF_CTX* ssl_confctx = SSL_CONF_CTX_new();
int client_socket = -1;
int error = 0;
t_print("\nStarting" TLS_CLIENT "\n\n\n");
if ((ssl_client_ctx = SSL_CTX_new(TLS_client_method())) == nullptr)
{
t_print(TLS_CLIENT "unable to create a new SSL context\n");
goto done;
}
if (initalize_ssl_context(ssl_confctx, ssl_client_ctx) != SGX_SUCCESS)
{
t_print(TLS_CLIENT "unable to create a initialize SSL context\n ");
goto done;
}
// specify the verify_callback for custom verification
SSL_CTX_set_verify(ssl_client_ctx, SSL_VERIFY_PEER, &verify_callback);
t_print(TLS_CLIENT "load cert and key\n");
if (load_tls_certificates_and_keys(ssl_client_ctx, cert, pkey) != 0)
{
t_print(TLS_CLIENT
" unable to load certificate and private key on the client\n");
goto done;
}
if ((ssl_session = SSL_new(ssl_client_ctx)) == nullptr)
{
t_print(TLS_CLIENT
"Unable to create a new SSL connection state object\n");
goto done;
}
t_print(TLS_CLIENT "new ssl connection getting created\n");
client_socket = create_socket(server_name, server_port);
if (client_socket == -1)
{
t_print(
TLS_CLIENT
"create a socket and initiate a TCP connect to server: %s:%s "
"(errno=%d)\n",
server_name,
server_port,
errno);
goto done;
}
// set up ssl socket and initiate TLS connection with TLS server
SSL_set_fd(ssl_session, client_socket);
if ((error = SSL_connect(ssl_session)) != 1)
{
t_print(
TLS_CLIENT "Error: Could not establish a TLS session ret2=%d "
"SSL_get_error()=%d\n",
error,
SSL_get_error(ssl_session, error));
goto done;
}
t_print(
TLS_CLIENT "successfully established TLS channel:%s\n",
SSL_get_version(ssl_session));
// start the client server communication
if ((error = communicate_with_server(ssl_session)) != 0)
{
t_print(TLS_CLIENT "Failed: communicate_with_server (ret=%d)\n", error);
goto done;
}
// Free the structures we don't need anymore
ret = 0;
done:
if (client_socket != -1)
{
ocall_close(&ret, client_socket);
if (ret != 0)
t_print(TLS_CLIENT "OCALL: error close socket\n");
}
if (ssl_session)
{
SSL_shutdown(ssl_session);
SSL_free(ssl_session);
}
if (cert)
X509_free(cert);
if (pkey)
EVP_PKEY_free(pkey);
if (ssl_client_ctx)
SSL_CTX_free(ssl_client_ctx);
if (ssl_confctx)
SSL_CONF_CTX_free(ssl_confctx);
t_print(TLS_CLIENT " %s\n", (ret == 0) ? "success" : "failed");
return (ret);
}