diff options
Diffstat (limited to 'CryptoPkg/Library/TlsLib/TlsInit.c')
-rw-r--r-- | CryptoPkg/Library/TlsLib/TlsInit.c | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/CryptoPkg/Library/TlsLib/TlsInit.c b/CryptoPkg/Library/TlsLib/TlsInit.c new file mode 100644 index 0000000000..6b1fd93ea9 --- /dev/null +++ b/CryptoPkg/Library/TlsLib/TlsInit.c @@ -0,0 +1,291 @@ +/** @file + SSL/TLS Initialization Library Wrapper Implementation over OpenSSL. + +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> +(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR> +This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "InternalTlsLib.h" + +/** + Initializes the OpenSSL library. + + This function registers ciphers and digests used directly and indirectly + by SSL/TLS, and initializes the readable error messages. + This function must be called before any other action takes places. + +**/ +VOID +EFIAPI +TlsInitialize ( + VOID + ) +{ + // + // Performs initialization of crypto and ssl library, and loads required + // algorithms. + // + SSL_library_init (); + + // + // Loads error strings from both crypto and ssl library. + // + SSL_load_error_strings (); + + /// OpenSSL_add_all_algorithms(); + + // + // Initialize the pseudorandom number generator. + // + RandomSeed (NULL, 0); +} + +/** + Free an allocated SSL_CTX object. + + @param[in] TlsCtx Pointer to the SSL_CTX object to be released. + +**/ +VOID +EFIAPI +TlsCtxFree ( + IN VOID *TlsCtx + ) +{ + if (TlsCtx == NULL) { + return; + } + + if (TlsCtx != NULL) { + SSL_CTX_free ((SSL_CTX *) (TlsCtx)); + } +} + +/** + Creates a new SSL_CTX object as framework to establish TLS/SSL enabled + connections. + + @param[in] MajorVer Major Version of TLS/SSL Protocol. + @param[in] MinorVer Minor Version of TLS/SSL Protocol. + + @return Pointer to an allocated SSL_CTX object. + If the creation failed, TlsCtxNew() returns NULL. + +**/ +VOID * +EFIAPI +TlsCtxNew ( + IN UINT8 MajorVer, + IN UINT8 MinorVer + ) +{ + SSL_CTX *TlsCtx; + UINT16 ProtoVersion; + + ProtoVersion = (MajorVer << 8) | MinorVer; + + TlsCtx = SSL_CTX_new (SSLv23_client_method ()); + if (TlsCtx == NULL) { + return NULL; + } + + // + // Ensure SSLv3 is disabled + // + SSL_CTX_set_options (TlsCtx, SSL_OP_NO_SSLv3); + + // + // Treat as minimum accepted versions. Client can use higher + // TLS version if server supports it + // + switch (ProtoVersion) { + case TLS1_VERSION: + // + // TLS 1.0 + // + break; + case TLS1_1_VERSION: + // + // TLS 1.1 + // + SSL_CTX_set_options (TlsCtx, SSL_OP_NO_TLSv1); + break; + case TLS1_2_VERSION: + // + // TLS 1.2 + // + SSL_CTX_set_options (TlsCtx, SSL_OP_NO_TLSv1); + SSL_CTX_set_options (TlsCtx, SSL_OP_NO_TLSv1_1); + break; + default: + // + // Unsupported TLS/SSL Protocol Version. + // + break; + } + + return (VOID *) TlsCtx; +} + +/** + Free an allocated TLS object. + + This function removes the TLS object pointed to by Tls and frees up the + allocated memory. If Tls is NULL, nothing is done. + + @param[in] Tls Pointer to the TLS object to be freed. + +**/ +VOID +EFIAPI +TlsFree ( + IN VOID *Tls + ) +{ + TLS_CONNECTION *TlsConn; + + TlsConn = (TLS_CONNECTION *) Tls; + if (TlsConn == NULL) { + return; + } + + // + // Free the internal TLS and BIO objects. + // + if (TlsConn->Ssl != NULL) { + SSL_free (TlsConn->Ssl); + } + + if (TlsConn->InBio != NULL) { + BIO_free (TlsConn->InBio); + } + + if (TlsConn->OutBio != NULL) { + BIO_free (TlsConn->OutBio); + } + + OPENSSL_free (Tls); +} + +/** + Create a new TLS object for a connection. + + This function creates a new TLS object for a connection. The new object + inherits the setting of the underlying context TlsCtx: connection method, + options, verification setting. + + @param[in] TlsCtx Pointer to the SSL_CTX object. + + @return Pointer to an allocated SSL object. + If the creation failed, TlsNew() returns NULL. + +**/ +VOID * +EFIAPI +TlsNew ( + IN VOID *TlsCtx + ) +{ + TLS_CONNECTION *TlsConn; + SSL_CTX *SslCtx; + X509_STORE *X509Store; + + TlsConn = NULL; + + // + // Allocate one new TLS_CONNECTION object + // + TlsConn = (TLS_CONNECTION *) OPENSSL_malloc (sizeof (TLS_CONNECTION)); + if (TlsConn == NULL) { + return NULL; + } + + TlsConn->Ssl = NULL; + + // + // Create a new SSL Object + // + TlsConn->Ssl = SSL_new ((SSL_CTX *) TlsCtx); + if (TlsConn->Ssl == NULL) { + TlsFree ((VOID *) TlsConn); + return NULL; + } + + // + // Initialize the created SSL Object + // + SSL_set_info_callback (TlsConn->Ssl, NULL); + + TlsConn->InBio = NULL; + + // + // Set up Reading BIO for TLS connection + // + TlsConn->InBio = BIO_new (BIO_s_mem ()); + if (TlsConn->InBio == NULL) { + TlsFree ((VOID *) TlsConn); + return NULL; + } + + // + // Sets the behaviour of memory BIO when it is empty. It will set the + // read retry flag. + // + BIO_set_mem_eof_return (TlsConn->InBio, -1); + + TlsConn->OutBio = NULL; + + // + // Set up Writing BIO for TLS connection + // + TlsConn->OutBio = BIO_new (BIO_s_mem ()); + if (TlsConn->OutBio == NULL) { + TlsFree ((VOID *) TlsConn); + return NULL; + } + + // + // Sets the behaviour of memory BIO when it is empty. It will set the + // write retry flag. + // + BIO_set_mem_eof_return (TlsConn->OutBio, -1); + + ASSERT (TlsConn->Ssl != NULL && TlsConn->InBio != NULL && TlsConn->OutBio != NULL); + + // + // Connects the InBio and OutBio for the read and write operations. + // + SSL_set_bio (TlsConn->Ssl, TlsConn->InBio, TlsConn->OutBio); + + // + // Create new X509 store if needed + // + SslCtx = SSL_get_SSL_CTX (TlsConn->Ssl); + X509Store = SSL_CTX_get_cert_store (SslCtx); + if (X509Store == NULL) { + X509Store = X509_STORE_new (); + if (X509Store == NULL) { + TlsFree ((VOID *) TlsConn); + return NULL; + } + SSL_CTX_set1_verify_cert_store (SslCtx, X509Store); + X509_STORE_free (X509Store); + } + + // + // Set X509_STORE flags used in certificate validation + // + X509_STORE_set_flags ( + X509Store, + X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_NO_CHECK_TIME + ); + return (VOID *) TlsConn; +} |