| /** @file | |
| SSL/TLS Initialization Library Wrapper Implementation over OpenSSL. | |
| Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR> | |
| (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR> | |
| SPDX-License-Identifier: BSD-2-Clause-Patent | |
| **/ | |
| #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. | |
| @retval TRUE The OpenSSL library has been initialized. | |
| @retval FALSE Failed to initialize the OpenSSL library. | |
| **/ | |
| BOOLEAN | |
| EFIAPI | |
| TlsInitialize ( | |
| VOID | |
| ) | |
| { | |
| INTN Ret; | |
| // | |
| // Performs initialization of crypto and ssl library, and loads required | |
| // algorithms. | |
| // | |
| Ret = OPENSSL_init_ssl ( | |
| OPENSSL_INIT_LOAD_SSL_STRINGS | OPENSSL_INIT_LOAD_CRYPTO_STRINGS, | |
| NULL | |
| ); | |
| if (Ret != 1) { | |
| return FALSE; | |
| } | |
| // | |
| // Initialize the pseudorandom number generator. | |
| // | |
| return 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 by setting the minimal bound. | |
| // Client can use higher TLS version if server supports it | |
| // | |
| SSL_CTX_set_min_proto_version (TlsCtx, ProtoVersion); | |
| 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 related BIO objects. | |
| // | |
| if (TlsConn->Ssl != NULL) { | |
| SSL_free (TlsConn->Ssl); | |
| } | |
| 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; | |
| } | |
| // | |
| // This retains compatibility with previous version of OpenSSL. | |
| // | |
| SSL_set_security_level (TlsConn->Ssl, 3); | |
| // | |
| // 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 | |
| ); | |
| return (VOID *)TlsConn; | |
| } |