https://bugzilla.tianocore.org/show_bug.cgi?id=1373 Replace BSD 2-Clause License with BSD+Patent License. This change is based on the following emails: https://lists.01.org/pipermail/edk2-devel/2019-February/036260.html https://lists.01.org/pipermail/edk2-devel/2018-October/030385.html RFCs with detailed process for the license change: V3: https://lists.01.org/pipermail/edk2-devel/2019-March/038116.html V2: https://lists.01.org/pipermail/edk2-devel/2019-March/037669.html V1: https://lists.01.org/pipermail/edk2-devel/2019-March/037500.html Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Jian J Wang <jian.j.wang@intel.com>
		
			
				
	
	
		
			264 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			264 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @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, 0);
 | 
						|
 | 
						|
  //
 | 
						|
  // 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;
 | 
						|
}
 | 
						|
 |