From: Hao Wu Date: Thu, 6 Apr 2017 02:10:39 +0000 (+0800) Subject: NetworkPkg: Convert files to CRLF line ending X-Git-Tag: edk2-stable201903~4219 X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=commitdiff_plain;h=7618784b85c5df91fae4c0d7a910bfb07b248caf;hp=973f8862f2b44a16b028f5afabbc8a0042029a29 NetworkPkg: Convert files to CRLF line ending Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Hao Wu Reviewed-by: Siyuan Fu Reviewed-by: Jiaxin Wu --- diff --git a/NetworkPkg/HttpDxe/HttpsSupport.c b/NetworkPkg/HttpDxe/HttpsSupport.c index f0077dd4b8..e4d9a37bee 100644 --- a/NetworkPkg/HttpDxe/HttpsSupport.c +++ b/NetworkPkg/HttpDxe/HttpsSupport.c @@ -1,1719 +1,1720 @@ -/** @file - Miscellaneous routines specific to Https for HttpDxe driver. - -Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
-(C) Copyright 2016 Hewlett Packard Enterprise Development LP
-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 "HttpDriver.h" - -/** - Returns the first occurrence of a Null-terminated ASCII sub-string in a Null-terminated - ASCII string and ignore case during the search process. - - This function scans the contents of the ASCII string specified by String - and returns the first occurrence of SearchString and ignore case during the search process. - If SearchString is not found in String, then NULL is returned. If the length of SearchString - is zero, then String is returned. - - If String is NULL, then ASSERT(). - If SearchString is NULL, then ASSERT(). - - @param[in] String A pointer to a Null-terminated ASCII string. - @param[in] SearchString A pointer to a Null-terminated ASCII string to search for. - - @retval NULL If the SearchString does not appear in String. - @retval others If there is a match return the first occurrence of SearchingString. - If the length of SearchString is zero,return String. - -**/ -CHAR8 * -AsciiStrCaseStr ( - IN CONST CHAR8 *String, - IN CONST CHAR8 *SearchString - ) -{ - CONST CHAR8 *FirstMatch; - CONST CHAR8 *SearchStringTmp; - - CHAR8 Src; - CHAR8 Dst; - - // - // ASSERT both strings are less long than PcdMaximumAsciiStringLength - // - ASSERT (AsciiStrSize (String) != 0); - ASSERT (AsciiStrSize (SearchString) != 0); - - if (*SearchString == '\0') { - return (CHAR8 *) String; - } - - while (*String != '\0') { - SearchStringTmp = SearchString; - FirstMatch = String; - - while ((*SearchStringTmp != '\0') - && (*String != '\0')) { - Src = *String; - Dst = *SearchStringTmp; - - if ((Src >= 'A') && (Src <= 'Z')) { - Src -= ('A' - 'a'); - } - - if ((Dst >= 'A') && (Dst <= 'Z')) { - Dst -= ('A' - 'a'); - } - - if (Src != Dst) { - break; - } - - String++; - SearchStringTmp++; - } - - if (*SearchStringTmp == '\0') { - return (CHAR8 *) FirstMatch; - } - - String = FirstMatch + 1; - } - - return NULL; -} - -/** - The callback function to free the net buffer list. - - @param[in] Arg The opaque parameter. - -**/ -VOID -EFIAPI -FreeNbufList ( - IN VOID *Arg - ) -{ - ASSERT (Arg != NULL); - - NetbufFreeList ((LIST_ENTRY *) Arg); - FreePool (Arg); -} - -/** - Check whether the Url is from Https. - - @param[in] Url The pointer to a HTTP or HTTPS URL string. - - @retval TRUE The Url is from HTTPS. - @retval FALSE The Url is from HTTP. - -**/ -BOOLEAN -IsHttpsUrl ( - IN CHAR8 *Url - ) -{ - CHAR8 *Tmp; - - Tmp = NULL; - - Tmp = AsciiStrCaseStr (Url, HTTPS_FLAG); - if (Tmp != NULL && Tmp == Url) { - return TRUE; - } - - return FALSE; -} - -/** - Creates a Tls child handle, open EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL. - - @param[in] ImageHandle The firmware allocated handle for the UEFI image. - @param[out] TlsProto Pointer to the EFI_TLS_PROTOCOL instance. - @param[out] TlsConfiguration Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance. - - @return The child handle with opened EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL. - -**/ -EFI_HANDLE -EFIAPI -TlsCreateChild ( - IN EFI_HANDLE ImageHandle, - OUT EFI_TLS_PROTOCOL **TlsProto, - OUT EFI_TLS_CONFIGURATION_PROTOCOL **TlsConfiguration - ) -{ - EFI_STATUS Status; - EFI_SERVICE_BINDING_PROTOCOL *TlsSb; - EFI_HANDLE TlsChildHandle; - - TlsSb = NULL; - TlsChildHandle = 0; - - // - // Locate TlsServiceBinding protocol. - // - gBS->LocateProtocol ( - &gEfiTlsServiceBindingProtocolGuid, - NULL, - (VOID **) &TlsSb - ); - if (TlsSb == NULL) { - return NULL; - } - - Status = TlsSb->CreateChild (TlsSb, &TlsChildHandle); - if (EFI_ERROR (Status)) { - return NULL; - } - - Status = gBS->OpenProtocol ( - TlsChildHandle, - &gEfiTlsProtocolGuid, - (VOID **) TlsProto, - ImageHandle, - TlsChildHandle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - TlsSb->DestroyChild (TlsSb, TlsChildHandle); - return NULL; - } - - Status = gBS->OpenProtocol ( - TlsChildHandle, - &gEfiTlsConfigurationProtocolGuid, - (VOID **) TlsConfiguration, - ImageHandle, - TlsChildHandle, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - TlsSb->DestroyChild (TlsSb, TlsChildHandle); - return NULL; - } - - return TlsChildHandle; -} - -/** - Create event for the TLS receive and transmit tokens which are used to receive and - transmit TLS related messages. - - @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure. - - @retval EFI_SUCCESS The events are created successfully. - @retval others Other error as indicated. - -**/ -EFI_STATUS -EFIAPI -TlsCreateTxRxEvent ( - IN OUT HTTP_PROTOCOL *HttpInstance - ) -{ - EFI_STATUS Status; - - if (!HttpInstance->LocalAddressIsIPv6) { - // - // For Tcp4TlsTxToken. - // - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - HttpCommonNotify, - &HttpInstance->TlsIsTxDone, - &HttpInstance->Tcp4TlsTxToken.CompletionToken.Event - ); - if (EFI_ERROR (Status)) { - goto ERROR; - } - - HttpInstance->Tcp4TlsTxData.Push = TRUE; - HttpInstance->Tcp4TlsTxData.Urgent = FALSE; - HttpInstance->Tcp4TlsTxData.DataLength = 0; - HttpInstance->Tcp4TlsTxData.FragmentCount = 1; - HttpInstance->Tcp4TlsTxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp4TlsTxData.DataLength; - HttpInstance->Tcp4TlsTxData.FragmentTable[0].FragmentBuffer = NULL; - HttpInstance->Tcp4TlsTxToken.Packet.TxData = &HttpInstance->Tcp4TlsTxData; - HttpInstance->Tcp4TlsTxToken.CompletionToken.Status = EFI_NOT_READY; - - // - // For Tcp4TlsRxToken. - // - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - HttpCommonNotify, - &HttpInstance->TlsIsRxDone, - &HttpInstance->Tcp4TlsRxToken.CompletionToken.Event - ); - if (EFI_ERROR (Status)) { - goto ERROR; - } - - HttpInstance->Tcp4TlsRxData.DataLength = 0; - HttpInstance->Tcp4TlsRxData.FragmentCount = 1; - HttpInstance->Tcp4TlsRxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp4TlsRxData.DataLength ; - HttpInstance->Tcp4TlsRxData.FragmentTable[0].FragmentBuffer = NULL; - HttpInstance->Tcp4TlsRxToken.Packet.RxData = &HttpInstance->Tcp4TlsRxData; - HttpInstance->Tcp4TlsRxToken.CompletionToken.Status = EFI_NOT_READY; - } else { - // - // For Tcp6TlsTxToken. - // - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - HttpCommonNotify, - &HttpInstance->TlsIsTxDone, - &HttpInstance->Tcp6TlsTxToken.CompletionToken.Event - ); - if (EFI_ERROR (Status)) { - goto ERROR; - } - - HttpInstance->Tcp6TlsTxData.Push = TRUE; - HttpInstance->Tcp6TlsTxData.Urgent = FALSE; - HttpInstance->Tcp6TlsTxData.DataLength = 0; - HttpInstance->Tcp6TlsTxData.FragmentCount = 1; - HttpInstance->Tcp6TlsTxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp6TlsTxData.DataLength; - HttpInstance->Tcp6TlsTxData.FragmentTable[0].FragmentBuffer = NULL; - HttpInstance->Tcp6TlsTxToken.Packet.TxData = &HttpInstance->Tcp6TlsTxData; - HttpInstance->Tcp6TlsTxToken.CompletionToken.Status = EFI_NOT_READY; - - // - // For Tcp6TlsRxToken. - // - Status = gBS->CreateEvent ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - HttpCommonNotify, - &HttpInstance->TlsIsRxDone, - &HttpInstance->Tcp6TlsRxToken.CompletionToken.Event - ); - if (EFI_ERROR (Status)) { - goto ERROR; - } - - HttpInstance->Tcp6TlsRxData.DataLength = 0; - HttpInstance->Tcp6TlsRxData.FragmentCount = 1; - HttpInstance->Tcp6TlsRxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp6TlsRxData.DataLength ; - HttpInstance->Tcp6TlsRxData.FragmentTable[0].FragmentBuffer = NULL; - HttpInstance->Tcp6TlsRxToken.Packet.RxData = &HttpInstance->Tcp6TlsRxData; - HttpInstance->Tcp6TlsRxToken.CompletionToken.Status = EFI_NOT_READY; - } - - return Status; - -ERROR: - // - // Error handling - // - TlsCloseTxRxEvent (HttpInstance); - - return Status; -} - -/** - Close events in the TlsTxToken and TlsRxToken. - - @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure. - -**/ -VOID -EFIAPI -TlsCloseTxRxEvent ( - IN HTTP_PROTOCOL *HttpInstance - ) -{ - ASSERT (HttpInstance != NULL); - if (!HttpInstance->LocalAddressIsIPv6) { - if (NULL != HttpInstance->Tcp4TlsTxToken.CompletionToken.Event) { - gBS->CloseEvent(HttpInstance->Tcp4TlsTxToken.CompletionToken.Event); - HttpInstance->Tcp4TlsTxToken.CompletionToken.Event = NULL; - } - - if (NULL != HttpInstance->Tcp4TlsRxToken.CompletionToken.Event) { - gBS->CloseEvent (HttpInstance->Tcp4TlsRxToken.CompletionToken.Event); - HttpInstance->Tcp4TlsRxToken.CompletionToken.Event = NULL; - } - } else { - if (NULL != HttpInstance->Tcp6TlsTxToken.CompletionToken.Event) { - gBS->CloseEvent(HttpInstance->Tcp6TlsTxToken.CompletionToken.Event); - HttpInstance->Tcp6TlsTxToken.CompletionToken.Event = NULL; - } - - if (NULL != HttpInstance->Tcp6TlsRxToken.CompletionToken.Event) { - gBS->CloseEvent (HttpInstance->Tcp6TlsRxToken.CompletionToken.Event); - HttpInstance->Tcp6TlsRxToken.CompletionToken.Event = NULL; - } - } -} - -/** - Read the TlsCaCertificate variable and configure it. - - @param[in, out] HttpInstance The HTTP instance private data. - - @retval EFI_SUCCESS TlsCaCertificate is configured. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_NOT_FOUND Fail to get 'TlsCaCertificate' variable. - @retval Others Other error as indicated. - -**/ -EFI_STATUS -TlsConfigCertificate ( - IN OUT HTTP_PROTOCOL *HttpInstance - ) -{ - EFI_STATUS Status; - UINT8 *CACert; - UINTN CACertSize; - UINT32 Index; - EFI_SIGNATURE_LIST *CertList; - EFI_SIGNATURE_DATA *Cert; - UINTN CertCount; - UINT32 ItemDataSize; - - CACert = NULL; - CACertSize = 0; - - // - // Try to read the TlsCaCertificate variable. - // - Status = gRT->GetVariable ( - EFI_TLS_CA_CERTIFICATE_VARIABLE, - &gEfiTlsCaCertificateGuid, - NULL, - &CACertSize, - NULL - ); - - if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) { - return Status; - } - - // - // Allocate buffer and read the config variable. - // - CACert = AllocatePool (CACertSize); - if (CACert == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - Status = gRT->GetVariable ( - EFI_TLS_CA_CERTIFICATE_VARIABLE, - &gEfiTlsCaCertificateGuid, - NULL, - &CACertSize, - CACert - ); - if (EFI_ERROR (Status)) { - // - // GetVariable still error or the variable is corrupted. - // Fall back to the default value. - // - FreePool (CACert); - - return EFI_NOT_FOUND; - } - - ASSERT (CACert != NULL); - - // - // Enumerate all data and erasing the target item. - // - ItemDataSize = (UINT32) CACertSize; - CertList = (EFI_SIGNATURE_LIST *) CACert; - while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) { - Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize); - CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize; - for (Index = 0; Index < CertCount; Index++) { - // - // EfiTlsConfigDataTypeCACertificate - // - Status = HttpInstance->TlsConfiguration->SetData ( - HttpInstance->TlsConfiguration, - EfiTlsConfigDataTypeCACertificate, - Cert->SignatureData, - CertList->SignatureSize - sizeof (Cert->SignatureOwner) - ); - if (EFI_ERROR (Status)) { - FreePool (CACert); - return Status; - } - - Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize); - } - - ItemDataSize -= CertList->SignatureListSize; - CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize); - } - - FreePool (CACert); - return Status; -} - -/** - Configure TLS session data. - - @param[in, out] HttpInstance The HTTP instance private data. - - @retval EFI_SUCCESS TLS session data is configured. - @retval Others Other error as indicated. - -**/ -EFI_STATUS -EFIAPI -TlsConfigureSession ( - IN OUT HTTP_PROTOCOL *HttpInstance - ) -{ - EFI_STATUS Status; - - // - // TlsConfigData initialization - // - HttpInstance->TlsConfigData.ConnectionEnd = EfiTlsClient; - HttpInstance->TlsConfigData.VerifyMethod = EFI_TLS_VERIFY_PEER; - HttpInstance->TlsConfigData.SessionState = EfiTlsSessionNotStarted; - - // - // EfiTlsConnectionEnd, - // EfiTlsVerifyMethod - // EfiTlsSessionState - // - Status = HttpInstance->Tls->SetSessionData ( - HttpInstance->Tls, - EfiTlsConnectionEnd, - &(HttpInstance->TlsConfigData.ConnectionEnd), - sizeof (EFI_TLS_CONNECTION_END) - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = HttpInstance->Tls->SetSessionData ( - HttpInstance->Tls, - EfiTlsVerifyMethod, - &HttpInstance->TlsConfigData.VerifyMethod, - sizeof (EFI_TLS_VERIFY) - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = HttpInstance->Tls->SetSessionData ( - HttpInstance->Tls, - EfiTlsSessionState, - &(HttpInstance->TlsConfigData.SessionState), - sizeof (EFI_TLS_SESSION_STATE) - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Tls Config Certificate - // - Status = TlsConfigCertificate (HttpInstance); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "TLS Certificate Config Error!\n")); - return Status; - } - - // - // TlsCreateTxRxEvent - // - Status = TlsCreateTxRxEvent (HttpInstance); - if (EFI_ERROR (Status)) { - goto ERROR; - } - - return Status; - -ERROR: - TlsCloseTxRxEvent (HttpInstance); - - return Status; -} - -/** - Transmit the Packet by processing the associated HTTPS token. - - @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure. - @param[in] Packet The packet to transmit. - - @retval EFI_SUCCESS The packet is transmitted. - @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. - @retval Others Other errors as indicated. - -**/ -EFI_STATUS -EFIAPI -TlsCommonTransmit ( - IN OUT HTTP_PROTOCOL *HttpInstance, - IN NET_BUF *Packet - ) -{ - EFI_STATUS Status; - VOID *Data; - UINTN Size; - - if ((HttpInstance == NULL) || (Packet == NULL)) { - return EFI_INVALID_PARAMETER; - } - - if (!HttpInstance->LocalAddressIsIPv6) { - Size = sizeof (EFI_TCP4_TRANSMIT_DATA) + - (Packet->BlockOpNum - 1) * sizeof (EFI_TCP4_FRAGMENT_DATA); - } else { - Size = sizeof (EFI_TCP6_TRANSMIT_DATA) + - (Packet->BlockOpNum - 1) * sizeof (EFI_TCP6_FRAGMENT_DATA); - } - - Data = AllocatePool (Size); - if (Data == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - if (!HttpInstance->LocalAddressIsIPv6) { - ((EFI_TCP4_TRANSMIT_DATA *) Data)->Push = TRUE; - ((EFI_TCP4_TRANSMIT_DATA *) Data)->Urgent = FALSE; - ((EFI_TCP4_TRANSMIT_DATA *) Data)->DataLength = Packet->TotalSize; - - // - // Build the fragment table. - // - ((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentCount = Packet->BlockOpNum; - - NetbufBuildExt ( - Packet, - (NET_FRAGMENT *) &((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentTable[0], - &((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentCount - ); - - HttpInstance->Tcp4TlsTxToken.Packet.TxData = (EFI_TCP4_TRANSMIT_DATA *) Data; - - Status = EFI_DEVICE_ERROR; - - // - // Transmit the packet. - // - Status = HttpInstance->Tcp4->Transmit (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsTxToken); - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - - while (!HttpInstance->TlsIsTxDone) { - HttpInstance->Tcp4->Poll (HttpInstance->Tcp4); - } - - HttpInstance->TlsIsTxDone = FALSE; - Status = HttpInstance->Tcp4TlsTxToken.CompletionToken.Status; - } else { - ((EFI_TCP6_TRANSMIT_DATA *) Data)->Push = TRUE; - ((EFI_TCP6_TRANSMIT_DATA *) Data)->Urgent = FALSE; - ((EFI_TCP6_TRANSMIT_DATA *) Data)->DataLength = Packet->TotalSize; - - // - // Build the fragment table. - // - ((EFI_TCP6_TRANSMIT_DATA *) Data)->FragmentCount = Packet->BlockOpNum; - - NetbufBuildExt ( - Packet, - (NET_FRAGMENT *) &((EFI_TCP6_TRANSMIT_DATA *) Data)->FragmentTable[0], - &((EFI_TCP6_TRANSMIT_DATA *) Data)->FragmentCount - ); - - HttpInstance->Tcp6TlsTxToken.Packet.TxData = (EFI_TCP6_TRANSMIT_DATA *) Data; - - Status = EFI_DEVICE_ERROR; - - // - // Transmit the packet. - // - Status = HttpInstance->Tcp6->Transmit (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsTxToken); - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - - while (!HttpInstance->TlsIsTxDone) { - HttpInstance->Tcp6->Poll (HttpInstance->Tcp6); - } - - HttpInstance->TlsIsTxDone = FALSE; - Status = HttpInstance->Tcp6TlsTxToken.CompletionToken.Status; - } - -ON_EXIT: - FreePool (Data); - - return Status; -} - -/** - Receive the Packet by processing the associated HTTPS token. - - @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure. - @param[in] Packet The packet to transmit. - @param[in] Timeout The time to wait for connection done. - - @retval EFI_SUCCESS The Packet is received. - @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_TIMEOUT The operation is time out. - @retval Others Other error as indicated. - -**/ -EFI_STATUS -EFIAPI -TlsCommonReceive ( - IN OUT HTTP_PROTOCOL *HttpInstance, - IN NET_BUF *Packet, - IN EFI_EVENT Timeout - ) -{ - EFI_TCP4_RECEIVE_DATA *Tcp4RxData; - EFI_TCP6_RECEIVE_DATA *Tcp6RxData; - EFI_STATUS Status; - NET_FRAGMENT *Fragment; - UINT32 FragmentCount; - UINT32 CurrentFragment; - - Tcp4RxData = NULL; - Tcp6RxData = NULL; - - if ((HttpInstance == NULL) || (Packet == NULL)) { - return EFI_INVALID_PARAMETER; - } - - FragmentCount = Packet->BlockOpNum; - Fragment = AllocatePool (FragmentCount * sizeof (NET_FRAGMENT)); - if (Fragment == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - // - // Build the fragment table. - // - NetbufBuildExt (Packet, Fragment, &FragmentCount); - - if (!HttpInstance->LocalAddressIsIPv6) { - Tcp4RxData = HttpInstance->Tcp4TlsRxToken.Packet.RxData; - if (Tcp4RxData == NULL) { - return EFI_INVALID_PARAMETER; - } - Tcp4RxData->FragmentCount = 1; - } else { - Tcp6RxData = HttpInstance->Tcp6TlsRxToken.Packet.RxData; - if (Tcp6RxData == NULL) { - return EFI_INVALID_PARAMETER; - } - Tcp6RxData->FragmentCount = 1; - } - - CurrentFragment = 0; - Status = EFI_SUCCESS; - - while (CurrentFragment < FragmentCount) { - if (!HttpInstance->LocalAddressIsIPv6) { - Tcp4RxData->DataLength = Fragment[CurrentFragment].Len; - Tcp4RxData->FragmentTable[0].FragmentLength = Fragment[CurrentFragment].Len; - Tcp4RxData->FragmentTable[0].FragmentBuffer = Fragment[CurrentFragment].Bulk; - Status = HttpInstance->Tcp4->Receive (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsRxToken); - } else { - Tcp6RxData->DataLength = Fragment[CurrentFragment].Len; - Tcp6RxData->FragmentTable[0].FragmentLength = Fragment[CurrentFragment].Len; - Tcp6RxData->FragmentTable[0].FragmentBuffer = Fragment[CurrentFragment].Bulk; - Status = HttpInstance->Tcp6->Receive (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsRxToken); - } - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - - while (!HttpInstance->TlsIsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) { - // - // Poll until some data is received or an error occurs. - // - if (!HttpInstance->LocalAddressIsIPv6) { - HttpInstance->Tcp4->Poll (HttpInstance->Tcp4); - } else { - HttpInstance->Tcp6->Poll (HttpInstance->Tcp6); - } - } - - if (!HttpInstance->TlsIsRxDone) { - // - // Timeout occurs, cancel the receive request. - // - if (!HttpInstance->LocalAddressIsIPv6) { - HttpInstance->Tcp4->Cancel (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsRxToken.CompletionToken); - } else { - HttpInstance->Tcp6->Cancel (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsRxToken.CompletionToken); - } - - Status = EFI_TIMEOUT; - goto ON_EXIT; - } else { - HttpInstance->TlsIsRxDone = FALSE; - } - - if (!HttpInstance->LocalAddressIsIPv6) { - Status = HttpInstance->Tcp4TlsRxToken.CompletionToken.Status; - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - - Fragment[CurrentFragment].Len -= Tcp4RxData->FragmentTable[0].FragmentLength; - if (Fragment[CurrentFragment].Len == 0) { - CurrentFragment++; - } else { - Fragment[CurrentFragment].Bulk += Tcp4RxData->FragmentTable[0].FragmentLength; - } - } else { - Status = HttpInstance->Tcp6TlsRxToken.CompletionToken.Status; - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - - Fragment[CurrentFragment].Len -= Tcp6RxData->FragmentTable[0].FragmentLength; - if (Fragment[CurrentFragment].Len == 0) { - CurrentFragment++; - } else { - Fragment[CurrentFragment].Bulk += Tcp6RxData->FragmentTable[0].FragmentLength; - } - } - } - -ON_EXIT: - - if (Fragment != NULL) { - FreePool (Fragment); - } - - return Status; -} - -/** - Receive one TLS PDU. An TLS PDU contains an TLS record header and it's - corresponding record data. These two parts will be put into two blocks of buffers in the - net buffer. - - @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure. - @param[out] Pdu The received TLS PDU. - @param[in] Timeout The time to wait for connection done. - - @retval EFI_SUCCESS An TLS PDU is received. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_PROTOCOL_ERROR An unexpected TLS packet was received. - @retval Others Other errors as indicated. - -**/ -EFI_STATUS -EFIAPI -TlsReceiveOnePdu ( - IN OUT HTTP_PROTOCOL *HttpInstance, - OUT NET_BUF **Pdu, - IN EFI_EVENT Timeout - ) -{ - EFI_STATUS Status; - - LIST_ENTRY *NbufList; - - UINT32 Len; - - NET_BUF *PduHdr; - UINT8 *Header; - TLS_RECORD_HEADER RecordHeader; - - NET_BUF *DataSeg; - - NbufList = NULL; - PduHdr = NULL; - Header = NULL; - DataSeg = NULL; - - NbufList = AllocatePool (sizeof (LIST_ENTRY)); - if (NbufList == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - InitializeListHead (NbufList); - - // - // Allocate buffer to receive one TLS header. - // - Len = sizeof (TLS_RECORD_HEADER); - PduHdr = NetbufAlloc (Len); - if (PduHdr == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - Header = NetbufAllocSpace (PduHdr, Len, NET_BUF_TAIL); - if (Header == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - // - // First step, receive one TLS header. - // - Status = TlsCommonReceive (HttpInstance, PduHdr, Timeout); - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - - RecordHeader = *(TLS_RECORD_HEADER *) Header; - if ((RecordHeader.ContentType == TlsContentTypeHandshake || - RecordHeader.ContentType == TlsContentTypeAlert || - RecordHeader.ContentType == TlsContentTypeChangeCipherSpec || - RecordHeader.ContentType == TlsContentTypeApplicationData) && - (RecordHeader.Version.Major == 0x03) && /// Major versions are same. - (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR || - RecordHeader.Version.Minor ==TLS11_PROTOCOL_VERSION_MINOR || - RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR) - ) { - InsertTailList (NbufList, &PduHdr->List); - } else { - Status = EFI_PROTOCOL_ERROR; - goto ON_EXIT; - } - - Len = SwapBytes16(RecordHeader.Length); - if (Len == 0) { - // - // No TLS payload. - // - goto FORM_PDU; - } - - // - // Allocate buffer to receive one TLS payload. - // - DataSeg = NetbufAlloc (Len); - if (DataSeg == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - NetbufAllocSpace (DataSeg, Len, NET_BUF_TAIL); - - // - // Second step, receive one TLS payload. - // - Status = TlsCommonReceive (HttpInstance, DataSeg, Timeout); - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - - InsertTailList (NbufList, &DataSeg->List); - -FORM_PDU: - // - // Form the PDU from a list of PDU. - // - *Pdu = NetbufFromBufList (NbufList, 0, 0, FreeNbufList, NbufList); - if (*Pdu == NULL) { - Status = EFI_OUT_OF_RESOURCES; - } - -ON_EXIT: - - if (EFI_ERROR (Status)) { - // - // Free the Nbufs in this NbufList and the NbufList itself. - // - FreeNbufList (NbufList); - } - - return Status; -} - -/** - Connect one TLS session by finishing the TLS handshake process. - - @param[in] HttpInstance The HTTP instance private data. - @param[in] Timeout The time to wait for connection done. - - @retval EFI_SUCCESS The TLS session is established. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_ABORTED TLS session state is incorrect. - @retval Others Other error as indicated. - -**/ -EFI_STATUS -EFIAPI -TlsConnectSession ( - IN HTTP_PROTOCOL *HttpInstance, - IN EFI_EVENT Timeout - ) -{ - EFI_STATUS Status; - UINT8 *BufferOut; - UINTN BufferOutSize; - NET_BUF *PacketOut; - UINT8 *DataOut; - NET_BUF *Pdu; - UINT8 *BufferIn; - UINTN BufferInSize; - UINT8 *GetSessionDataBuffer; - UINTN GetSessionDataBufferSize; - - BufferOut = NULL; - PacketOut = NULL; - DataOut = NULL; - Pdu = NULL; - BufferIn = NULL; - - // - // Initialize TLS state. - // - HttpInstance->TlsSessionState = EfiTlsSessionNotStarted; - Status = HttpInstance->Tls->SetSessionData ( - HttpInstance->Tls, - EfiTlsSessionState, - &(HttpInstance->TlsSessionState), - sizeof (EFI_TLS_SESSION_STATE) - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Create ClientHello - // - BufferOutSize = DEF_BUF_LEN; - BufferOut = AllocateZeroPool (BufferOutSize); - if (BufferOut == NULL) { - Status = EFI_OUT_OF_RESOURCES; - return Status; - } - - Status = HttpInstance->Tls->BuildResponsePacket ( - HttpInstance->Tls, - NULL, - 0, - BufferOut, - &BufferOutSize - ); - if (Status == EFI_BUFFER_TOO_SMALL) { - FreePool (BufferOut); - BufferOut = AllocateZeroPool (BufferOutSize); - if (BufferOut == NULL) { - Status = EFI_OUT_OF_RESOURCES; - return Status; - } - - Status = HttpInstance->Tls->BuildResponsePacket ( - HttpInstance->Tls, - NULL, - 0, - BufferOut, - &BufferOutSize - ); - } - if (EFI_ERROR (Status)) { - FreePool (BufferOut); - return Status; - } - - // - // Transmit ClientHello - // - PacketOut = NetbufAlloc ((UINT32) BufferOutSize); - DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL); - if (DataOut == NULL) { - FreePool (BufferOut); - return EFI_OUT_OF_RESOURCES; - } - - CopyMem (DataOut, BufferOut, BufferOutSize); - Status = TlsCommonTransmit (HttpInstance, PacketOut); - - FreePool (BufferOut); - NetbufFree (PacketOut); - - if (EFI_ERROR (Status)) { - return Status; - } - - while(HttpInstance->TlsSessionState != EfiTlsSessionDataTransferring && \ - ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) { - // - // Receive one TLS record. - // - Status = TlsReceiveOnePdu (HttpInstance, &Pdu, Timeout); - if (EFI_ERROR (Status)) { - return Status; - } - - BufferInSize = Pdu->TotalSize; - BufferIn = AllocateZeroPool (BufferInSize); - if (BufferIn == NULL) { - NetbufFree (Pdu); - Status = EFI_OUT_OF_RESOURCES; - return Status; - } - - NetbufCopy (Pdu, 0, (UINT32)BufferInSize, BufferIn); - - NetbufFree (Pdu); - - // - // Handle Receive data. - // - BufferOutSize = DEF_BUF_LEN; - BufferOut = AllocateZeroPool (BufferOutSize); - if (BufferOut == NULL) { - Status = EFI_OUT_OF_RESOURCES; - return Status; - } - - Status = HttpInstance->Tls->BuildResponsePacket ( - HttpInstance->Tls, - BufferIn, - BufferInSize, - BufferOut, - &BufferOutSize - ); - if (Status == EFI_BUFFER_TOO_SMALL) { - FreePool (BufferOut); - BufferOut = AllocateZeroPool (BufferOutSize); - if (BufferOut == NULL) { - FreePool (BufferIn); - Status = EFI_OUT_OF_RESOURCES; - return Status; - } - - Status = HttpInstance->Tls->BuildResponsePacket ( - HttpInstance->Tls, - BufferIn, - BufferInSize, - BufferOut, - &BufferOutSize - ); - } - - FreePool (BufferIn); - - if (EFI_ERROR (Status)) { - FreePool (BufferOut); - return Status; - } - - if (BufferOutSize != 0) { - // - // Transmit the response packet. - // - PacketOut = NetbufAlloc ((UINT32) BufferOutSize); - DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL); - if (DataOut == NULL) { - FreePool (BufferOut); - return EFI_OUT_OF_RESOURCES; - } - - CopyMem (DataOut, BufferOut, BufferOutSize); - - Status = TlsCommonTransmit (HttpInstance, PacketOut); - - NetbufFree (PacketOut); - - if (EFI_ERROR (Status)) { - FreePool (BufferOut); - return Status; - } - } - - FreePool (BufferOut); - - // - // Get the session state, then decide whether need to continue handle received packet. - // - GetSessionDataBufferSize = DEF_BUF_LEN; - GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize); - if (GetSessionDataBuffer == NULL) { - Status = EFI_OUT_OF_RESOURCES; - return Status; - } - - Status = HttpInstance->Tls->GetSessionData ( - HttpInstance->Tls, - EfiTlsSessionState, - GetSessionDataBuffer, - &GetSessionDataBufferSize - ); - if (Status == EFI_BUFFER_TOO_SMALL) { - FreePool (GetSessionDataBuffer); - GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize); - if (GetSessionDataBuffer == NULL) { - Status = EFI_OUT_OF_RESOURCES; - return Status; - } - - Status = HttpInstance->Tls->GetSessionData ( - HttpInstance->Tls, - EfiTlsSessionState, - GetSessionDataBuffer, - &GetSessionDataBufferSize - ); - } - if (EFI_ERROR (Status)) { - FreePool(GetSessionDataBuffer); - return Status; - } - - ASSERT(GetSessionDataBufferSize == sizeof (EFI_TLS_SESSION_STATE)); - HttpInstance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) GetSessionDataBuffer; - - FreePool (GetSessionDataBuffer); - - if(HttpInstance->TlsSessionState == EfiTlsSessionError) { - return EFI_ABORTED; - } - } - - if (HttpInstance->TlsSessionState != EfiTlsSessionDataTransferring) { - Status = EFI_ABORTED; - } - - return Status; -} - -/** - Close the TLS session and send out the close notification message. - - @param[in] HttpInstance The HTTP instance private data. - - @retval EFI_SUCCESS The TLS session is closed. - @retval EFI_INVALID_PARAMETER HttpInstance is NULL. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval Others Other error as indicated. - -**/ -EFI_STATUS -EFIAPI -TlsCloseSession ( - IN HTTP_PROTOCOL *HttpInstance - ) -{ - EFI_STATUS Status; - - UINT8 *BufferOut; - UINTN BufferOutSize; - - NET_BUF *PacketOut; - UINT8 *DataOut; - - Status = EFI_SUCCESS; - BufferOut = NULL; - PacketOut = NULL; - DataOut = NULL; - - if (HttpInstance == NULL) { - return EFI_INVALID_PARAMETER; - } - - HttpInstance->TlsSessionState = EfiTlsSessionClosing; - - Status = HttpInstance->Tls->SetSessionData ( - HttpInstance->Tls, - EfiTlsSessionState, - &(HttpInstance->TlsSessionState), - sizeof (EFI_TLS_SESSION_STATE) - ); - if (EFI_ERROR (Status)) { - return Status; - } - - BufferOutSize = DEF_BUF_LEN; - BufferOut = AllocateZeroPool (BufferOutSize); - if (BufferOut == NULL) { - Status = EFI_OUT_OF_RESOURCES; - return Status; - } - - Status = HttpInstance->Tls->BuildResponsePacket ( - HttpInstance->Tls, - NULL, - 0, - BufferOut, - &BufferOutSize - ); - if (Status == EFI_BUFFER_TOO_SMALL) { - FreePool (BufferOut); - BufferOut = AllocateZeroPool (BufferOutSize); - if (BufferOut == NULL) { - Status = EFI_OUT_OF_RESOURCES; - return Status; - } - - Status = HttpInstance->Tls->BuildResponsePacket ( - HttpInstance->Tls, - NULL, - 0, - BufferOut, - &BufferOutSize - ); - } - - if (EFI_ERROR (Status)) { - FreePool (BufferOut); - return Status; - } - - PacketOut = NetbufAlloc ((UINT32) BufferOutSize); - DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL); - if (DataOut == NULL) { - FreePool (BufferOut); - return EFI_OUT_OF_RESOURCES; - } - - CopyMem (DataOut, BufferOut, BufferOutSize); - - Status = TlsCommonTransmit (HttpInstance, PacketOut); - - FreePool (BufferOut); - NetbufFree (PacketOut); - - return Status; -} - -/** - Process one message according to the CryptMode. - - @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure. - @param[in] Message Pointer to the message buffer needed to processed. - @param[in] MessageSize Pointer to the message buffer size. - @param[in] ProcessMode Process mode. - @param[in, out] Fragment Only one Fragment returned after the Message is - processed successfully. - - @retval EFI_SUCCESS Message is processed successfully. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval Others Other errors as indicated. - -**/ -EFI_STATUS -EFIAPI -TlsProcessMessage ( - IN HTTP_PROTOCOL *HttpInstance, - IN UINT8 *Message, - IN UINTN MessageSize, - IN EFI_TLS_CRYPT_MODE ProcessMode, - IN OUT NET_FRAGMENT *Fragment - ) -{ - EFI_STATUS Status; - UINT8 *Buffer; - UINT32 BufferSize; - UINT32 BytesCopied; - EFI_TLS_FRAGMENT_DATA *FragmentTable; - UINT32 FragmentCount; - EFI_TLS_FRAGMENT_DATA *OriginalFragmentTable; - UINTN Index; - - Status = EFI_SUCCESS; - Buffer = NULL; - BufferSize = 0; - BytesCopied = 0; - FragmentTable = NULL; - OriginalFragmentTable = NULL; - - // - // Rebuild fragment table from BufferIn. - // - FragmentCount = 1; - FragmentTable = AllocateZeroPool (FragmentCount * sizeof (EFI_TLS_FRAGMENT_DATA)); - if (FragmentTable == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - FragmentTable->FragmentLength = (UINT32) MessageSize; - FragmentTable->FragmentBuffer = Message; - - // - // Record the original FragmentTable. - // - OriginalFragmentTable = FragmentTable; - - // - // Process the Message. - // - Status = HttpInstance->Tls->ProcessPacket ( - HttpInstance->Tls, - &FragmentTable, - &FragmentCount, - ProcessMode - ); - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - - // - // Calculate the size according to FragmentTable. - // - for (Index = 0; Index < FragmentCount; Index++) { - BufferSize += FragmentTable[Index].FragmentLength; - } - - // - // Allocate buffer for processed data. - // - Buffer = AllocateZeroPool (BufferSize); - if (Buffer == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - // - // Copy the new FragmentTable buffer into Buffer. - // - for (Index = 0; Index < FragmentCount; Index++) { - CopyMem ( - (Buffer + BytesCopied), - FragmentTable[Index].FragmentBuffer, - FragmentTable[Index].FragmentLength - ); - BytesCopied += FragmentTable[Index].FragmentLength; - - // - // Free the FragmentBuffer since it has been copied. - // - FreePool (FragmentTable[Index].FragmentBuffer); - } - - Fragment->Len = BufferSize; - Fragment->Bulk = Buffer; - -ON_EXIT: - - if (OriginalFragmentTable != NULL) { - FreePool (OriginalFragmentTable); - OriginalFragmentTable = NULL; - } - - // - // Caller has the responsibility to free the FragmentTable. - // - if (FragmentTable != NULL) { - FreePool (FragmentTable); - FragmentTable = NULL; - } - - return Status; -} - -/** - Receive one fragment decrypted from one TLS record. - - @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure. - @param[in, out] Fragment The received Fragment. - @param[in] Timeout The time to wait for connection done. - - @retval EFI_SUCCESS One fragment is received. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_ABORTED Something wrong decryption the message. - @retval Others Other errors as indicated. - -**/ -EFI_STATUS -EFIAPI -HttpsReceive ( - IN HTTP_PROTOCOL *HttpInstance, - IN OUT NET_FRAGMENT *Fragment, - IN EFI_EVENT Timeout - ) -{ - EFI_STATUS Status; - NET_BUF *Pdu; - TLS_RECORD_HEADER RecordHeader; - UINT8 *BufferIn; - UINTN BufferInSize; - NET_FRAGMENT TempFragment; - UINT8 *BufferOut; - UINTN BufferOutSize; - NET_BUF *PacketOut; - UINT8 *DataOut; - UINT8 *GetSessionDataBuffer; - UINTN GetSessionDataBufferSize; - - Status = EFI_SUCCESS; - Pdu = NULL; - BufferIn = NULL; - BufferInSize = 0; - BufferOut = NULL; - BufferOutSize = 0; - PacketOut = NULL; - DataOut = NULL; - GetSessionDataBuffer = NULL; - GetSessionDataBufferSize = 0; - - // - // Receive only one TLS record - // - Status = TlsReceiveOnePdu (HttpInstance, &Pdu, Timeout); - if (EFI_ERROR (Status)) { - return Status; - } - - BufferInSize = Pdu->TotalSize; - BufferIn = AllocateZeroPool (BufferInSize); - if (BufferIn == NULL) { - Status = EFI_OUT_OF_RESOURCES; - NetbufFree (Pdu); - return Status; - } - - NetbufCopy (Pdu, 0, (UINT32) BufferInSize, BufferIn); - - NetbufFree (Pdu); - - // - // Handle Receive data. - // - RecordHeader = *(TLS_RECORD_HEADER *) BufferIn; - - if ((RecordHeader.ContentType == TlsContentTypeApplicationData) && - (RecordHeader.Version.Major == 0x03) && - (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR || - RecordHeader.Version.Minor == TLS11_PROTOCOL_VERSION_MINOR || - RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR) - ) { - // - // Decrypt Packet. - // - Status = TlsProcessMessage ( - HttpInstance, - BufferIn, - BufferInSize, - EfiTlsDecrypt, - &TempFragment - ); - - FreePool (BufferIn); - - if (EFI_ERROR (Status)) { - if (Status == EFI_ABORTED) { - // - // Something wrong decryption the message. - // BuildResponsePacket() will be called to generate Error Alert message and send it out. - // - BufferOutSize = DEF_BUF_LEN; - BufferOut = AllocateZeroPool (BufferOutSize); - if (BufferOut == NULL) { - Status = EFI_OUT_OF_RESOURCES; - return Status; - } - - Status = HttpInstance->Tls->BuildResponsePacket ( - HttpInstance->Tls, - NULL, - 0, - BufferOut, - &BufferOutSize - ); - if (Status == EFI_BUFFER_TOO_SMALL) { - FreePool (BufferOut); - BufferOut = AllocateZeroPool (BufferOutSize); - if (BufferOut == NULL) { - Status = EFI_OUT_OF_RESOURCES; - return Status; - } - - Status = HttpInstance->Tls->BuildResponsePacket ( - HttpInstance->Tls, - NULL, - 0, - BufferOut, - &BufferOutSize - ); - } - if (EFI_ERROR (Status)) { - FreePool(BufferOut); - return Status; - } - - if (BufferOutSize != 0) { - PacketOut = NetbufAlloc ((UINT32)BufferOutSize); - DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL); - if (DataOut == NULL) { - FreePool (BufferOut); - return EFI_OUT_OF_RESOURCES; - } - - CopyMem (DataOut, BufferOut, BufferOutSize); - - Status = TlsCommonTransmit (HttpInstance, PacketOut); - - NetbufFree (PacketOut); - } - - FreePool(BufferOut); - - if (EFI_ERROR (Status)) { - return Status; - } - - return EFI_ABORTED; - } - - return Status; - } - - // - // Parsing buffer. - // - ASSERT (((TLS_RECORD_HEADER *) (TempFragment.Bulk))->ContentType == TlsContentTypeApplicationData); - - BufferInSize = ((TLS_RECORD_HEADER *) (TempFragment.Bulk))->Length; - BufferIn = AllocateZeroPool (BufferInSize); - if (BufferIn == NULL) { - Status = EFI_OUT_OF_RESOURCES; - return Status; - } - - CopyMem (BufferIn, TempFragment.Bulk + sizeof (TLS_RECORD_HEADER), BufferInSize); - - // - // Free the buffer in TempFragment. - // - FreePool (TempFragment.Bulk); - - } else if ((RecordHeader.ContentType == TlsContentTypeAlert) && - (RecordHeader.Version.Major == 0x03) && - (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR || - RecordHeader.Version.Minor == TLS11_PROTOCOL_VERSION_MINOR || - RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR) - ) { - BufferOutSize = DEF_BUF_LEN; - BufferOut = AllocateZeroPool (BufferOutSize); - if (BufferOut == NULL) { - FreePool (BufferIn); - Status = EFI_OUT_OF_RESOURCES; - return Status; - } - - Status = HttpInstance->Tls->BuildResponsePacket ( - HttpInstance->Tls, - BufferIn, - BufferInSize, - BufferOut, - &BufferOutSize - ); - if (Status == EFI_BUFFER_TOO_SMALL) { - FreePool (BufferOut); - BufferOut = AllocateZeroPool (BufferOutSize); - if (BufferOut == NULL) { - FreePool (BufferIn); - Status = EFI_OUT_OF_RESOURCES; - return Status; - } - - Status = HttpInstance->Tls->BuildResponsePacket ( - HttpInstance->Tls, - BufferIn, - BufferInSize, - BufferOut, - &BufferOutSize - ); - } - - FreePool (BufferIn); - - if (EFI_ERROR (Status)) { - FreePool (BufferOut); - return Status; - } - - if (BufferOutSize != 0) { - PacketOut = NetbufAlloc ((UINT32) BufferOutSize); - DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL); - if (DataOut == NULL) { - FreePool (BufferOut); - return EFI_OUT_OF_RESOURCES; - } - - CopyMem (DataOut, BufferOut, BufferOutSize); - - Status = TlsCommonTransmit (HttpInstance, PacketOut); - - NetbufFree (PacketOut); - } - - FreePool (BufferOut); - - // - // Get the session state. - // - GetSessionDataBufferSize = DEF_BUF_LEN; - GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize); - if (GetSessionDataBuffer == NULL) { - Status = EFI_OUT_OF_RESOURCES; - return Status; - } - - Status = HttpInstance->Tls->GetSessionData ( - HttpInstance->Tls, - EfiTlsSessionState, - GetSessionDataBuffer, - &GetSessionDataBufferSize - ); - if (Status == EFI_BUFFER_TOO_SMALL) { - FreePool (GetSessionDataBuffer); - GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize); - if (GetSessionDataBuffer == NULL) { - Status = EFI_OUT_OF_RESOURCES; - return Status; - } - - Status = HttpInstance->Tls->GetSessionData ( - HttpInstance->Tls, - EfiTlsSessionState, - GetSessionDataBuffer, - &GetSessionDataBufferSize - ); - } - if (EFI_ERROR (Status)) { - FreePool (GetSessionDataBuffer); - return Status; - } - - ASSERT(GetSessionDataBufferSize == sizeof (EFI_TLS_SESSION_STATE)); - HttpInstance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) GetSessionDataBuffer; - - FreePool (GetSessionDataBuffer); - - if(HttpInstance->TlsSessionState == EfiTlsSessionError) { - DEBUG ((EFI_D_ERROR, "TLS Session State Error!\n")); - return EFI_ABORTED; - } - - BufferIn = NULL; - BufferInSize = 0; - } - - Fragment->Bulk = BufferIn; - Fragment->Len = (UINT32) BufferInSize; - - return Status; -} +/** @file + Miscellaneous routines specific to Https for HttpDxe driver. + +Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP
+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 "HttpDriver.h" + +/** + Returns the first occurrence of a Null-terminated ASCII sub-string in a Null-terminated + ASCII string and ignore case during the search process. + + This function scans the contents of the ASCII string specified by String + and returns the first occurrence of SearchString and ignore case during the search process. + If SearchString is not found in String, then NULL is returned. If the length of SearchString + is zero, then String is returned. + + If String is NULL, then ASSERT(). + If SearchString is NULL, then ASSERT(). + + @param[in] String A pointer to a Null-terminated ASCII string. + @param[in] SearchString A pointer to a Null-terminated ASCII string to search for. + + @retval NULL If the SearchString does not appear in String. + @retval others If there is a match return the first occurrence of SearchingString. + If the length of SearchString is zero,return String. + +**/ +CHAR8 * +AsciiStrCaseStr ( + IN CONST CHAR8 *String, + IN CONST CHAR8 *SearchString + ) +{ + CONST CHAR8 *FirstMatch; + CONST CHAR8 *SearchStringTmp; + + CHAR8 Src; + CHAR8 Dst; + + // + // ASSERT both strings are less long than PcdMaximumAsciiStringLength + // + ASSERT (AsciiStrSize (String) != 0); + ASSERT (AsciiStrSize (SearchString) != 0); + + if (*SearchString == '\0') { + return (CHAR8 *) String; + } + + while (*String != '\0') { + SearchStringTmp = SearchString; + FirstMatch = String; + + while ((*SearchStringTmp != '\0') + && (*String != '\0')) { + Src = *String; + Dst = *SearchStringTmp; + + if ((Src >= 'A') && (Src <= 'Z')) { + Src -= ('A' - 'a'); + } + + if ((Dst >= 'A') && (Dst <= 'Z')) { + Dst -= ('A' - 'a'); + } + + if (Src != Dst) { + break; + } + + String++; + SearchStringTmp++; + } + + if (*SearchStringTmp == '\0') { + return (CHAR8 *) FirstMatch; + } + + String = FirstMatch + 1; + } + + return NULL; +} + +/** + The callback function to free the net buffer list. + + @param[in] Arg The opaque parameter. + +**/ +VOID +EFIAPI +FreeNbufList ( + IN VOID *Arg + ) +{ + ASSERT (Arg != NULL); + + NetbufFreeList ((LIST_ENTRY *) Arg); + FreePool (Arg); +} + +/** + Check whether the Url is from Https. + + @param[in] Url The pointer to a HTTP or HTTPS URL string. + + @retval TRUE The Url is from HTTPS. + @retval FALSE The Url is from HTTP. + +**/ +BOOLEAN +IsHttpsUrl ( + IN CHAR8 *Url + ) +{ + CHAR8 *Tmp; + + Tmp = NULL; + + Tmp = AsciiStrCaseStr (Url, HTTPS_FLAG); + if (Tmp != NULL && Tmp == Url) { + return TRUE; + } + + return FALSE; +} + +/** + Creates a Tls child handle, open EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL. + + @param[in] ImageHandle The firmware allocated handle for the UEFI image. + @param[out] TlsProto Pointer to the EFI_TLS_PROTOCOL instance. + @param[out] TlsConfiguration Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance. + + @return The child handle with opened EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL. + +**/ +EFI_HANDLE +EFIAPI +TlsCreateChild ( + IN EFI_HANDLE ImageHandle, + OUT EFI_TLS_PROTOCOL **TlsProto, + OUT EFI_TLS_CONFIGURATION_PROTOCOL **TlsConfiguration + ) +{ + EFI_STATUS Status; + EFI_SERVICE_BINDING_PROTOCOL *TlsSb; + EFI_HANDLE TlsChildHandle; + + TlsSb = NULL; + TlsChildHandle = 0; + + // + // Locate TlsServiceBinding protocol. + // + gBS->LocateProtocol ( + &gEfiTlsServiceBindingProtocolGuid, + NULL, + (VOID **) &TlsSb + ); + if (TlsSb == NULL) { + return NULL; + } + + Status = TlsSb->CreateChild (TlsSb, &TlsChildHandle); + if (EFI_ERROR (Status)) { + return NULL; + } + + Status = gBS->OpenProtocol ( + TlsChildHandle, + &gEfiTlsProtocolGuid, + (VOID **) TlsProto, + ImageHandle, + TlsChildHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + TlsSb->DestroyChild (TlsSb, TlsChildHandle); + return NULL; + } + + Status = gBS->OpenProtocol ( + TlsChildHandle, + &gEfiTlsConfigurationProtocolGuid, + (VOID **) TlsConfiguration, + ImageHandle, + TlsChildHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + TlsSb->DestroyChild (TlsSb, TlsChildHandle); + return NULL; + } + + return TlsChildHandle; +} + +/** + Create event for the TLS receive and transmit tokens which are used to receive and + transmit TLS related messages. + + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure. + + @retval EFI_SUCCESS The events are created successfully. + @retval others Other error as indicated. + +**/ +EFI_STATUS +EFIAPI +TlsCreateTxRxEvent ( + IN OUT HTTP_PROTOCOL *HttpInstance + ) +{ + EFI_STATUS Status; + + if (!HttpInstance->LocalAddressIsIPv6) { + // + // For Tcp4TlsTxToken. + // + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + HttpCommonNotify, + &HttpInstance->TlsIsTxDone, + &HttpInstance->Tcp4TlsTxToken.CompletionToken.Event + ); + if (EFI_ERROR (Status)) { + goto ERROR; + } + + HttpInstance->Tcp4TlsTxData.Push = TRUE; + HttpInstance->Tcp4TlsTxData.Urgent = FALSE; + HttpInstance->Tcp4TlsTxData.DataLength = 0; + HttpInstance->Tcp4TlsTxData.FragmentCount = 1; + HttpInstance->Tcp4TlsTxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp4TlsTxData.DataLength; + HttpInstance->Tcp4TlsTxData.FragmentTable[0].FragmentBuffer = NULL; + HttpInstance->Tcp4TlsTxToken.Packet.TxData = &HttpInstance->Tcp4TlsTxData; + HttpInstance->Tcp4TlsTxToken.CompletionToken.Status = EFI_NOT_READY; + + // + // For Tcp4TlsRxToken. + // + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + HttpCommonNotify, + &HttpInstance->TlsIsRxDone, + &HttpInstance->Tcp4TlsRxToken.CompletionToken.Event + ); + if (EFI_ERROR (Status)) { + goto ERROR; + } + + HttpInstance->Tcp4TlsRxData.DataLength = 0; + HttpInstance->Tcp4TlsRxData.FragmentCount = 1; + HttpInstance->Tcp4TlsRxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp4TlsRxData.DataLength ; + HttpInstance->Tcp4TlsRxData.FragmentTable[0].FragmentBuffer = NULL; + HttpInstance->Tcp4TlsRxToken.Packet.RxData = &HttpInstance->Tcp4TlsRxData; + HttpInstance->Tcp4TlsRxToken.CompletionToken.Status = EFI_NOT_READY; + } else { + // + // For Tcp6TlsTxToken. + // + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + HttpCommonNotify, + &HttpInstance->TlsIsTxDone, + &HttpInstance->Tcp6TlsTxToken.CompletionToken.Event + ); + if (EFI_ERROR (Status)) { + goto ERROR; + } + + HttpInstance->Tcp6TlsTxData.Push = TRUE; + HttpInstance->Tcp6TlsTxData.Urgent = FALSE; + HttpInstance->Tcp6TlsTxData.DataLength = 0; + HttpInstance->Tcp6TlsTxData.FragmentCount = 1; + HttpInstance->Tcp6TlsTxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp6TlsTxData.DataLength; + HttpInstance->Tcp6TlsTxData.FragmentTable[0].FragmentBuffer = NULL; + HttpInstance->Tcp6TlsTxToken.Packet.TxData = &HttpInstance->Tcp6TlsTxData; + HttpInstance->Tcp6TlsTxToken.CompletionToken.Status = EFI_NOT_READY; + + // + // For Tcp6TlsRxToken. + // + Status = gBS->CreateEvent ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + HttpCommonNotify, + &HttpInstance->TlsIsRxDone, + &HttpInstance->Tcp6TlsRxToken.CompletionToken.Event + ); + if (EFI_ERROR (Status)) { + goto ERROR; + } + + HttpInstance->Tcp6TlsRxData.DataLength = 0; + HttpInstance->Tcp6TlsRxData.FragmentCount = 1; + HttpInstance->Tcp6TlsRxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp6TlsRxData.DataLength ; + HttpInstance->Tcp6TlsRxData.FragmentTable[0].FragmentBuffer = NULL; + HttpInstance->Tcp6TlsRxToken.Packet.RxData = &HttpInstance->Tcp6TlsRxData; + HttpInstance->Tcp6TlsRxToken.CompletionToken.Status = EFI_NOT_READY; + } + + return Status; + +ERROR: + // + // Error handling + // + TlsCloseTxRxEvent (HttpInstance); + + return Status; +} + +/** + Close events in the TlsTxToken and TlsRxToken. + + @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure. + +**/ +VOID +EFIAPI +TlsCloseTxRxEvent ( + IN HTTP_PROTOCOL *HttpInstance + ) +{ + ASSERT (HttpInstance != NULL); + if (!HttpInstance->LocalAddressIsIPv6) { + if (NULL != HttpInstance->Tcp4TlsTxToken.CompletionToken.Event) { + gBS->CloseEvent(HttpInstance->Tcp4TlsTxToken.CompletionToken.Event); + HttpInstance->Tcp4TlsTxToken.CompletionToken.Event = NULL; + } + + if (NULL != HttpInstance->Tcp4TlsRxToken.CompletionToken.Event) { + gBS->CloseEvent (HttpInstance->Tcp4TlsRxToken.CompletionToken.Event); + HttpInstance->Tcp4TlsRxToken.CompletionToken.Event = NULL; + } + } else { + if (NULL != HttpInstance->Tcp6TlsTxToken.CompletionToken.Event) { + gBS->CloseEvent(HttpInstance->Tcp6TlsTxToken.CompletionToken.Event); + HttpInstance->Tcp6TlsTxToken.CompletionToken.Event = NULL; + } + + if (NULL != HttpInstance->Tcp6TlsRxToken.CompletionToken.Event) { + gBS->CloseEvent (HttpInstance->Tcp6TlsRxToken.CompletionToken.Event); + HttpInstance->Tcp6TlsRxToken.CompletionToken.Event = NULL; + } + } +} + +/** + Read the TlsCaCertificate variable and configure it. + + @param[in, out] HttpInstance The HTTP instance private data. + + @retval EFI_SUCCESS TlsCaCertificate is configured. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. + @retval EFI_NOT_FOUND Fail to get 'TlsCaCertificate' variable. + @retval Others Other error as indicated. + +**/ +EFI_STATUS +TlsConfigCertificate ( + IN OUT HTTP_PROTOCOL *HttpInstance + ) +{ + EFI_STATUS Status; + UINT8 *CACert; + UINTN CACertSize; + UINT32 Index; + EFI_SIGNATURE_LIST *CertList; + EFI_SIGNATURE_DATA *Cert; + UINTN CertCount; + UINT32 ItemDataSize; + + CACert = NULL; + CACertSize = 0; + + // + // Try to read the TlsCaCertificate variable. + // + Status = gRT->GetVariable ( + EFI_TLS_CA_CERTIFICATE_VARIABLE, + &gEfiTlsCaCertificateGuid, + NULL, + &CACertSize, + NULL + ); + + if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) { + return Status; + } + + // + // Allocate buffer and read the config variable. + // + CACert = AllocatePool (CACertSize); + if (CACert == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Status = gRT->GetVariable ( + EFI_TLS_CA_CERTIFICATE_VARIABLE, + &gEfiTlsCaCertificateGuid, + NULL, + &CACertSize, + CACert + ); + if (EFI_ERROR (Status)) { + // + // GetVariable still error or the variable is corrupted. + // Fall back to the default value. + // + FreePool (CACert); + + return EFI_NOT_FOUND; + } + + ASSERT (CACert != NULL); + + // + // Enumerate all data and erasing the target item. + // + ItemDataSize = (UINT32) CACertSize; + CertList = (EFI_SIGNATURE_LIST *) CACert; + while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) { + Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize); + CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize; + for (Index = 0; Index < CertCount; Index++) { + // + // EfiTlsConfigDataTypeCACertificate + // + Status = HttpInstance->TlsConfiguration->SetData ( + HttpInstance->TlsConfiguration, + EfiTlsConfigDataTypeCACertificate, + Cert->SignatureData, + CertList->SignatureSize - sizeof (Cert->SignatureOwner) + ); + if (EFI_ERROR (Status)) { + FreePool (CACert); + return Status; + } + + Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize); + } + + ItemDataSize -= CertList->SignatureListSize; + CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize); + } + + FreePool (CACert); + return Status; +} + +/** + Configure TLS session data. + + @param[in, out] HttpInstance The HTTP instance private data. + + @retval EFI_SUCCESS TLS session data is configured. + @retval Others Other error as indicated. + +**/ +EFI_STATUS +EFIAPI +TlsConfigureSession ( + IN OUT HTTP_PROTOCOL *HttpInstance + ) +{ + EFI_STATUS Status; + + // + // TlsConfigData initialization + // + HttpInstance->TlsConfigData.ConnectionEnd = EfiTlsClient; + HttpInstance->TlsConfigData.VerifyMethod = EFI_TLS_VERIFY_PEER; + HttpInstance->TlsConfigData.SessionState = EfiTlsSessionNotStarted; + + // + // EfiTlsConnectionEnd, + // EfiTlsVerifyMethod + // EfiTlsSessionState + // + Status = HttpInstance->Tls->SetSessionData ( + HttpInstance->Tls, + EfiTlsConnectionEnd, + &(HttpInstance->TlsConfigData.ConnectionEnd), + sizeof (EFI_TLS_CONNECTION_END) + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = HttpInstance->Tls->SetSessionData ( + HttpInstance->Tls, + EfiTlsVerifyMethod, + &HttpInstance->TlsConfigData.VerifyMethod, + sizeof (EFI_TLS_VERIFY) + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = HttpInstance->Tls->SetSessionData ( + HttpInstance->Tls, + EfiTlsSessionState, + &(HttpInstance->TlsConfigData.SessionState), + sizeof (EFI_TLS_SESSION_STATE) + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Tls Config Certificate + // + Status = TlsConfigCertificate (HttpInstance); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "TLS Certificate Config Error!\n")); + return Status; + } + + // + // TlsCreateTxRxEvent + // + Status = TlsCreateTxRxEvent (HttpInstance); + if (EFI_ERROR (Status)) { + goto ERROR; + } + + return Status; + +ERROR: + TlsCloseTxRxEvent (HttpInstance); + + return Status; +} + +/** + Transmit the Packet by processing the associated HTTPS token. + + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure. + @param[in] Packet The packet to transmit. + + @retval EFI_SUCCESS The packet is transmitted. + @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +EFIAPI +TlsCommonTransmit ( + IN OUT HTTP_PROTOCOL *HttpInstance, + IN NET_BUF *Packet + ) +{ + EFI_STATUS Status; + VOID *Data; + UINTN Size; + + if ((HttpInstance == NULL) || (Packet == NULL)) { + return EFI_INVALID_PARAMETER; + } + + if (!HttpInstance->LocalAddressIsIPv6) { + Size = sizeof (EFI_TCP4_TRANSMIT_DATA) + + (Packet->BlockOpNum - 1) * sizeof (EFI_TCP4_FRAGMENT_DATA); + } else { + Size = sizeof (EFI_TCP6_TRANSMIT_DATA) + + (Packet->BlockOpNum - 1) * sizeof (EFI_TCP6_FRAGMENT_DATA); + } + + Data = AllocatePool (Size); + if (Data == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + if (!HttpInstance->LocalAddressIsIPv6) { + ((EFI_TCP4_TRANSMIT_DATA *) Data)->Push = TRUE; + ((EFI_TCP4_TRANSMIT_DATA *) Data)->Urgent = FALSE; + ((EFI_TCP4_TRANSMIT_DATA *) Data)->DataLength = Packet->TotalSize; + + // + // Build the fragment table. + // + ((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentCount = Packet->BlockOpNum; + + NetbufBuildExt ( + Packet, + (NET_FRAGMENT *) &((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentTable[0], + &((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentCount + ); + + HttpInstance->Tcp4TlsTxToken.Packet.TxData = (EFI_TCP4_TRANSMIT_DATA *) Data; + + Status = EFI_DEVICE_ERROR; + + // + // Transmit the packet. + // + Status = HttpInstance->Tcp4->Transmit (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsTxToken); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + while (!HttpInstance->TlsIsTxDone) { + HttpInstance->Tcp4->Poll (HttpInstance->Tcp4); + } + + HttpInstance->TlsIsTxDone = FALSE; + Status = HttpInstance->Tcp4TlsTxToken.CompletionToken.Status; + } else { + ((EFI_TCP6_TRANSMIT_DATA *) Data)->Push = TRUE; + ((EFI_TCP6_TRANSMIT_DATA *) Data)->Urgent = FALSE; + ((EFI_TCP6_TRANSMIT_DATA *) Data)->DataLength = Packet->TotalSize; + + // + // Build the fragment table. + // + ((EFI_TCP6_TRANSMIT_DATA *) Data)->FragmentCount = Packet->BlockOpNum; + + NetbufBuildExt ( + Packet, + (NET_FRAGMENT *) &((EFI_TCP6_TRANSMIT_DATA *) Data)->FragmentTable[0], + &((EFI_TCP6_TRANSMIT_DATA *) Data)->FragmentCount + ); + + HttpInstance->Tcp6TlsTxToken.Packet.TxData = (EFI_TCP6_TRANSMIT_DATA *) Data; + + Status = EFI_DEVICE_ERROR; + + // + // Transmit the packet. + // + Status = HttpInstance->Tcp6->Transmit (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsTxToken); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + while (!HttpInstance->TlsIsTxDone) { + HttpInstance->Tcp6->Poll (HttpInstance->Tcp6); + } + + HttpInstance->TlsIsTxDone = FALSE; + Status = HttpInstance->Tcp6TlsTxToken.CompletionToken.Status; + } + +ON_EXIT: + FreePool (Data); + + return Status; +} + +/** + Receive the Packet by processing the associated HTTPS token. + + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure. + @param[in] Packet The packet to transmit. + @param[in] Timeout The time to wait for connection done. + + @retval EFI_SUCCESS The Packet is received. + @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. + @retval EFI_TIMEOUT The operation is time out. + @retval Others Other error as indicated. + +**/ +EFI_STATUS +EFIAPI +TlsCommonReceive ( + IN OUT HTTP_PROTOCOL *HttpInstance, + IN NET_BUF *Packet, + IN EFI_EVENT Timeout + ) +{ + EFI_TCP4_RECEIVE_DATA *Tcp4RxData; + EFI_TCP6_RECEIVE_DATA *Tcp6RxData; + EFI_STATUS Status; + NET_FRAGMENT *Fragment; + UINT32 FragmentCount; + UINT32 CurrentFragment; + + Tcp4RxData = NULL; + Tcp6RxData = NULL; + + if ((HttpInstance == NULL) || (Packet == NULL)) { + return EFI_INVALID_PARAMETER; + } + + FragmentCount = Packet->BlockOpNum; + Fragment = AllocatePool (FragmentCount * sizeof (NET_FRAGMENT)); + if (Fragment == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + // + // Build the fragment table. + // + NetbufBuildExt (Packet, Fragment, &FragmentCount); + + if (!HttpInstance->LocalAddressIsIPv6) { + Tcp4RxData = HttpInstance->Tcp4TlsRxToken.Packet.RxData; + if (Tcp4RxData == NULL) { + return EFI_INVALID_PARAMETER; + } + Tcp4RxData->FragmentCount = 1; + } else { + Tcp6RxData = HttpInstance->Tcp6TlsRxToken.Packet.RxData; + if (Tcp6RxData == NULL) { + return EFI_INVALID_PARAMETER; + } + Tcp6RxData->FragmentCount = 1; + } + + CurrentFragment = 0; + Status = EFI_SUCCESS; + + while (CurrentFragment < FragmentCount) { + if (!HttpInstance->LocalAddressIsIPv6) { + Tcp4RxData->DataLength = Fragment[CurrentFragment].Len; + Tcp4RxData->FragmentTable[0].FragmentLength = Fragment[CurrentFragment].Len; + Tcp4RxData->FragmentTable[0].FragmentBuffer = Fragment[CurrentFragment].Bulk; + Status = HttpInstance->Tcp4->Receive (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsRxToken); + } else { + Tcp6RxData->DataLength = Fragment[CurrentFragment].Len; + Tcp6RxData->FragmentTable[0].FragmentLength = Fragment[CurrentFragment].Len; + Tcp6RxData->FragmentTable[0].FragmentBuffer = Fragment[CurrentFragment].Bulk; + Status = HttpInstance->Tcp6->Receive (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsRxToken); + } + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + while (!HttpInstance->TlsIsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) { + // + // Poll until some data is received or an error occurs. + // + if (!HttpInstance->LocalAddressIsIPv6) { + HttpInstance->Tcp4->Poll (HttpInstance->Tcp4); + } else { + HttpInstance->Tcp6->Poll (HttpInstance->Tcp6); + } + } + + if (!HttpInstance->TlsIsRxDone) { + // + // Timeout occurs, cancel the receive request. + // + if (!HttpInstance->LocalAddressIsIPv6) { + HttpInstance->Tcp4->Cancel (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsRxToken.CompletionToken); + } else { + HttpInstance->Tcp6->Cancel (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsRxToken.CompletionToken); + } + + Status = EFI_TIMEOUT; + goto ON_EXIT; + } else { + HttpInstance->TlsIsRxDone = FALSE; + } + + if (!HttpInstance->LocalAddressIsIPv6) { + Status = HttpInstance->Tcp4TlsRxToken.CompletionToken.Status; + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + Fragment[CurrentFragment].Len -= Tcp4RxData->FragmentTable[0].FragmentLength; + if (Fragment[CurrentFragment].Len == 0) { + CurrentFragment++; + } else { + Fragment[CurrentFragment].Bulk += Tcp4RxData->FragmentTable[0].FragmentLength; + } + } else { + Status = HttpInstance->Tcp6TlsRxToken.CompletionToken.Status; + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + Fragment[CurrentFragment].Len -= Tcp6RxData->FragmentTable[0].FragmentLength; + if (Fragment[CurrentFragment].Len == 0) { + CurrentFragment++; + } else { + Fragment[CurrentFragment].Bulk += Tcp6RxData->FragmentTable[0].FragmentLength; + } + } + } + +ON_EXIT: + + if (Fragment != NULL) { + FreePool (Fragment); + } + + return Status; +} + +/** + Receive one TLS PDU. An TLS PDU contains an TLS record header and it's + corresponding record data. These two parts will be put into two blocks of buffers in the + net buffer. + + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure. + @param[out] Pdu The received TLS PDU. + @param[in] Timeout The time to wait for connection done. + + @retval EFI_SUCCESS An TLS PDU is received. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. + @retval EFI_PROTOCOL_ERROR An unexpected TLS packet was received. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +EFIAPI +TlsReceiveOnePdu ( + IN OUT HTTP_PROTOCOL *HttpInstance, + OUT NET_BUF **Pdu, + IN EFI_EVENT Timeout + ) +{ + EFI_STATUS Status; + + LIST_ENTRY *NbufList; + + UINT32 Len; + + NET_BUF *PduHdr; + UINT8 *Header; + TLS_RECORD_HEADER RecordHeader; + + NET_BUF *DataSeg; + + NbufList = NULL; + PduHdr = NULL; + Header = NULL; + DataSeg = NULL; + + NbufList = AllocatePool (sizeof (LIST_ENTRY)); + if (NbufList == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + InitializeListHead (NbufList); + + // + // Allocate buffer to receive one TLS header. + // + Len = sizeof (TLS_RECORD_HEADER); + PduHdr = NetbufAlloc (Len); + if (PduHdr == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + Header = NetbufAllocSpace (PduHdr, Len, NET_BUF_TAIL); + if (Header == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + // + // First step, receive one TLS header. + // + Status = TlsCommonReceive (HttpInstance, PduHdr, Timeout); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + RecordHeader = *(TLS_RECORD_HEADER *) Header; + if ((RecordHeader.ContentType == TlsContentTypeHandshake || + RecordHeader.ContentType == TlsContentTypeAlert || + RecordHeader.ContentType == TlsContentTypeChangeCipherSpec || + RecordHeader.ContentType == TlsContentTypeApplicationData) && + (RecordHeader.Version.Major == 0x03) && /// Major versions are same. + (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR || + RecordHeader.Version.Minor ==TLS11_PROTOCOL_VERSION_MINOR || + RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR) + ) { + InsertTailList (NbufList, &PduHdr->List); + } else { + Status = EFI_PROTOCOL_ERROR; + goto ON_EXIT; + } + + Len = SwapBytes16(RecordHeader.Length); + if (Len == 0) { + // + // No TLS payload. + // + goto FORM_PDU; + } + + // + // Allocate buffer to receive one TLS payload. + // + DataSeg = NetbufAlloc (Len); + if (DataSeg == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + NetbufAllocSpace (DataSeg, Len, NET_BUF_TAIL); + + // + // Second step, receive one TLS payload. + // + Status = TlsCommonReceive (HttpInstance, DataSeg, Timeout); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + InsertTailList (NbufList, &DataSeg->List); + +FORM_PDU: + // + // Form the PDU from a list of PDU. + // + *Pdu = NetbufFromBufList (NbufList, 0, 0, FreeNbufList, NbufList); + if (*Pdu == NULL) { + Status = EFI_OUT_OF_RESOURCES; + } + +ON_EXIT: + + if (EFI_ERROR (Status)) { + // + // Free the Nbufs in this NbufList and the NbufList itself. + // + FreeNbufList (NbufList); + } + + return Status; +} + +/** + Connect one TLS session by finishing the TLS handshake process. + + @param[in] HttpInstance The HTTP instance private data. + @param[in] Timeout The time to wait for connection done. + + @retval EFI_SUCCESS The TLS session is established. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. + @retval EFI_ABORTED TLS session state is incorrect. + @retval Others Other error as indicated. + +**/ +EFI_STATUS +EFIAPI +TlsConnectSession ( + IN HTTP_PROTOCOL *HttpInstance, + IN EFI_EVENT Timeout + ) +{ + EFI_STATUS Status; + UINT8 *BufferOut; + UINTN BufferOutSize; + NET_BUF *PacketOut; + UINT8 *DataOut; + NET_BUF *Pdu; + UINT8 *BufferIn; + UINTN BufferInSize; + UINT8 *GetSessionDataBuffer; + UINTN GetSessionDataBufferSize; + + BufferOut = NULL; + PacketOut = NULL; + DataOut = NULL; + Pdu = NULL; + BufferIn = NULL; + + // + // Initialize TLS state. + // + HttpInstance->TlsSessionState = EfiTlsSessionNotStarted; + Status = HttpInstance->Tls->SetSessionData ( + HttpInstance->Tls, + EfiTlsSessionState, + &(HttpInstance->TlsSessionState), + sizeof (EFI_TLS_SESSION_STATE) + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Create ClientHello + // + BufferOutSize = DEF_BUF_LEN; + BufferOut = AllocateZeroPool (BufferOutSize); + if (BufferOut == NULL) { + Status = EFI_OUT_OF_RESOURCES; + return Status; + } + + Status = HttpInstance->Tls->BuildResponsePacket ( + HttpInstance->Tls, + NULL, + 0, + BufferOut, + &BufferOutSize + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + FreePool (BufferOut); + BufferOut = AllocateZeroPool (BufferOutSize); + if (BufferOut == NULL) { + Status = EFI_OUT_OF_RESOURCES; + return Status; + } + + Status = HttpInstance->Tls->BuildResponsePacket ( + HttpInstance->Tls, + NULL, + 0, + BufferOut, + &BufferOutSize + ); + } + if (EFI_ERROR (Status)) { + FreePool (BufferOut); + return Status; + } + + // + // Transmit ClientHello + // + PacketOut = NetbufAlloc ((UINT32) BufferOutSize); + DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL); + if (DataOut == NULL) { + FreePool (BufferOut); + return EFI_OUT_OF_RESOURCES; + } + + CopyMem (DataOut, BufferOut, BufferOutSize); + Status = TlsCommonTransmit (HttpInstance, PacketOut); + + FreePool (BufferOut); + NetbufFree (PacketOut); + + if (EFI_ERROR (Status)) { + return Status; + } + + while(HttpInstance->TlsSessionState != EfiTlsSessionDataTransferring && \ + ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) { + // + // Receive one TLS record. + // + Status = TlsReceiveOnePdu (HttpInstance, &Pdu, Timeout); + if (EFI_ERROR (Status)) { + return Status; + } + + BufferInSize = Pdu->TotalSize; + BufferIn = AllocateZeroPool (BufferInSize); + if (BufferIn == NULL) { + NetbufFree (Pdu); + Status = EFI_OUT_OF_RESOURCES; + return Status; + } + + NetbufCopy (Pdu, 0, (UINT32)BufferInSize, BufferIn); + + NetbufFree (Pdu); + + // + // Handle Receive data. + // + BufferOutSize = DEF_BUF_LEN; + BufferOut = AllocateZeroPool (BufferOutSize); + if (BufferOut == NULL) { + Status = EFI_OUT_OF_RESOURCES; + return Status; + } + + Status = HttpInstance->Tls->BuildResponsePacket ( + HttpInstance->Tls, + BufferIn, + BufferInSize, + BufferOut, + &BufferOutSize + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + FreePool (BufferOut); + BufferOut = AllocateZeroPool (BufferOutSize); + if (BufferOut == NULL) { + FreePool (BufferIn); + Status = EFI_OUT_OF_RESOURCES; + return Status; + } + + Status = HttpInstance->Tls->BuildResponsePacket ( + HttpInstance->Tls, + BufferIn, + BufferInSize, + BufferOut, + &BufferOutSize + ); + } + + FreePool (BufferIn); + + if (EFI_ERROR (Status)) { + FreePool (BufferOut); + return Status; + } + + if (BufferOutSize != 0) { + // + // Transmit the response packet. + // + PacketOut = NetbufAlloc ((UINT32) BufferOutSize); + DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL); + if (DataOut == NULL) { + FreePool (BufferOut); + return EFI_OUT_OF_RESOURCES; + } + + CopyMem (DataOut, BufferOut, BufferOutSize); + + Status = TlsCommonTransmit (HttpInstance, PacketOut); + + NetbufFree (PacketOut); + + if (EFI_ERROR (Status)) { + FreePool (BufferOut); + return Status; + } + } + + FreePool (BufferOut); + + // + // Get the session state, then decide whether need to continue handle received packet. + // + GetSessionDataBufferSize = DEF_BUF_LEN; + GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize); + if (GetSessionDataBuffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + return Status; + } + + Status = HttpInstance->Tls->GetSessionData ( + HttpInstance->Tls, + EfiTlsSessionState, + GetSessionDataBuffer, + &GetSessionDataBufferSize + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + FreePool (GetSessionDataBuffer); + GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize); + if (GetSessionDataBuffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + return Status; + } + + Status = HttpInstance->Tls->GetSessionData ( + HttpInstance->Tls, + EfiTlsSessionState, + GetSessionDataBuffer, + &GetSessionDataBufferSize + ); + } + if (EFI_ERROR (Status)) { + FreePool(GetSessionDataBuffer); + return Status; + } + + ASSERT(GetSessionDataBufferSize == sizeof (EFI_TLS_SESSION_STATE)); + HttpInstance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) GetSessionDataBuffer; + + FreePool (GetSessionDataBuffer); + + if(HttpInstance->TlsSessionState == EfiTlsSessionError) { + return EFI_ABORTED; + } + } + + if (HttpInstance->TlsSessionState != EfiTlsSessionDataTransferring) { + Status = EFI_ABORTED; + } + + return Status; +} + +/** + Close the TLS session and send out the close notification message. + + @param[in] HttpInstance The HTTP instance private data. + + @retval EFI_SUCCESS The TLS session is closed. + @retval EFI_INVALID_PARAMETER HttpInstance is NULL. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. + @retval Others Other error as indicated. + +**/ +EFI_STATUS +EFIAPI +TlsCloseSession ( + IN HTTP_PROTOCOL *HttpInstance + ) +{ + EFI_STATUS Status; + + UINT8 *BufferOut; + UINTN BufferOutSize; + + NET_BUF *PacketOut; + UINT8 *DataOut; + + Status = EFI_SUCCESS; + BufferOut = NULL; + PacketOut = NULL; + DataOut = NULL; + + if (HttpInstance == NULL) { + return EFI_INVALID_PARAMETER; + } + + HttpInstance->TlsSessionState = EfiTlsSessionClosing; + + Status = HttpInstance->Tls->SetSessionData ( + HttpInstance->Tls, + EfiTlsSessionState, + &(HttpInstance->TlsSessionState), + sizeof (EFI_TLS_SESSION_STATE) + ); + if (EFI_ERROR (Status)) { + return Status; + } + + BufferOutSize = DEF_BUF_LEN; + BufferOut = AllocateZeroPool (BufferOutSize); + if (BufferOut == NULL) { + Status = EFI_OUT_OF_RESOURCES; + return Status; + } + + Status = HttpInstance->Tls->BuildResponsePacket ( + HttpInstance->Tls, + NULL, + 0, + BufferOut, + &BufferOutSize + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + FreePool (BufferOut); + BufferOut = AllocateZeroPool (BufferOutSize); + if (BufferOut == NULL) { + Status = EFI_OUT_OF_RESOURCES; + return Status; + } + + Status = HttpInstance->Tls->BuildResponsePacket ( + HttpInstance->Tls, + NULL, + 0, + BufferOut, + &BufferOutSize + ); + } + + if (EFI_ERROR (Status)) { + FreePool (BufferOut); + return Status; + } + + PacketOut = NetbufAlloc ((UINT32) BufferOutSize); + DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL); + if (DataOut == NULL) { + FreePool (BufferOut); + return EFI_OUT_OF_RESOURCES; + } + + CopyMem (DataOut, BufferOut, BufferOutSize); + + Status = TlsCommonTransmit (HttpInstance, PacketOut); + + FreePool (BufferOut); + NetbufFree (PacketOut); + + return Status; +} + +/** + Process one message according to the CryptMode. + + @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure. + @param[in] Message Pointer to the message buffer needed to processed. + @param[in] MessageSize Pointer to the message buffer size. + @param[in] ProcessMode Process mode. + @param[in, out] Fragment Only one Fragment returned after the Message is + processed successfully. + + @retval EFI_SUCCESS Message is processed successfully. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +EFIAPI +TlsProcessMessage ( + IN HTTP_PROTOCOL *HttpInstance, + IN UINT8 *Message, + IN UINTN MessageSize, + IN EFI_TLS_CRYPT_MODE ProcessMode, + IN OUT NET_FRAGMENT *Fragment + ) +{ + EFI_STATUS Status; + UINT8 *Buffer; + UINT32 BufferSize; + UINT32 BytesCopied; + EFI_TLS_FRAGMENT_DATA *FragmentTable; + UINT32 FragmentCount; + EFI_TLS_FRAGMENT_DATA *OriginalFragmentTable; + UINTN Index; + + Status = EFI_SUCCESS; + Buffer = NULL; + BufferSize = 0; + BytesCopied = 0; + FragmentTable = NULL; + OriginalFragmentTable = NULL; + + // + // Rebuild fragment table from BufferIn. + // + FragmentCount = 1; + FragmentTable = AllocateZeroPool (FragmentCount * sizeof (EFI_TLS_FRAGMENT_DATA)); + if (FragmentTable == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + FragmentTable->FragmentLength = (UINT32) MessageSize; + FragmentTable->FragmentBuffer = Message; + + // + // Record the original FragmentTable. + // + OriginalFragmentTable = FragmentTable; + + // + // Process the Message. + // + Status = HttpInstance->Tls->ProcessPacket ( + HttpInstance->Tls, + &FragmentTable, + &FragmentCount, + ProcessMode + ); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + // + // Calculate the size according to FragmentTable. + // + for (Index = 0; Index < FragmentCount; Index++) { + BufferSize += FragmentTable[Index].FragmentLength; + } + + // + // Allocate buffer for processed data. + // + Buffer = AllocateZeroPool (BufferSize); + if (Buffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + // + // Copy the new FragmentTable buffer into Buffer. + // + for (Index = 0; Index < FragmentCount; Index++) { + CopyMem ( + (Buffer + BytesCopied), + FragmentTable[Index].FragmentBuffer, + FragmentTable[Index].FragmentLength + ); + BytesCopied += FragmentTable[Index].FragmentLength; + + // + // Free the FragmentBuffer since it has been copied. + // + FreePool (FragmentTable[Index].FragmentBuffer); + } + + Fragment->Len = BufferSize; + Fragment->Bulk = Buffer; + +ON_EXIT: + + if (OriginalFragmentTable != NULL) { + FreePool (OriginalFragmentTable); + OriginalFragmentTable = NULL; + } + + // + // Caller has the responsibility to free the FragmentTable. + // + if (FragmentTable != NULL) { + FreePool (FragmentTable); + FragmentTable = NULL; + } + + return Status; +} + +/** + Receive one fragment decrypted from one TLS record. + + @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure. + @param[in, out] Fragment The received Fragment. + @param[in] Timeout The time to wait for connection done. + + @retval EFI_SUCCESS One fragment is received. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. + @retval EFI_ABORTED Something wrong decryption the message. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +EFIAPI +HttpsReceive ( + IN HTTP_PROTOCOL *HttpInstance, + IN OUT NET_FRAGMENT *Fragment, + IN EFI_EVENT Timeout + ) +{ + EFI_STATUS Status; + NET_BUF *Pdu; + TLS_RECORD_HEADER RecordHeader; + UINT8 *BufferIn; + UINTN BufferInSize; + NET_FRAGMENT TempFragment; + UINT8 *BufferOut; + UINTN BufferOutSize; + NET_BUF *PacketOut; + UINT8 *DataOut; + UINT8 *GetSessionDataBuffer; + UINTN GetSessionDataBufferSize; + + Status = EFI_SUCCESS; + Pdu = NULL; + BufferIn = NULL; + BufferInSize = 0; + BufferOut = NULL; + BufferOutSize = 0; + PacketOut = NULL; + DataOut = NULL; + GetSessionDataBuffer = NULL; + GetSessionDataBufferSize = 0; + + // + // Receive only one TLS record + // + Status = TlsReceiveOnePdu (HttpInstance, &Pdu, Timeout); + if (EFI_ERROR (Status)) { + return Status; + } + + BufferInSize = Pdu->TotalSize; + BufferIn = AllocateZeroPool (BufferInSize); + if (BufferIn == NULL) { + Status = EFI_OUT_OF_RESOURCES; + NetbufFree (Pdu); + return Status; + } + + NetbufCopy (Pdu, 0, (UINT32) BufferInSize, BufferIn); + + NetbufFree (Pdu); + + // + // Handle Receive data. + // + RecordHeader = *(TLS_RECORD_HEADER *) BufferIn; + + if ((RecordHeader.ContentType == TlsContentTypeApplicationData) && + (RecordHeader.Version.Major == 0x03) && + (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR || + RecordHeader.Version.Minor == TLS11_PROTOCOL_VERSION_MINOR || + RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR) + ) { + // + // Decrypt Packet. + // + Status = TlsProcessMessage ( + HttpInstance, + BufferIn, + BufferInSize, + EfiTlsDecrypt, + &TempFragment + ); + + FreePool (BufferIn); + + if (EFI_ERROR (Status)) { + if (Status == EFI_ABORTED) { + // + // Something wrong decryption the message. + // BuildResponsePacket() will be called to generate Error Alert message and send it out. + // + BufferOutSize = DEF_BUF_LEN; + BufferOut = AllocateZeroPool (BufferOutSize); + if (BufferOut == NULL) { + Status = EFI_OUT_OF_RESOURCES; + return Status; + } + + Status = HttpInstance->Tls->BuildResponsePacket ( + HttpInstance->Tls, + NULL, + 0, + BufferOut, + &BufferOutSize + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + FreePool (BufferOut); + BufferOut = AllocateZeroPool (BufferOutSize); + if (BufferOut == NULL) { + Status = EFI_OUT_OF_RESOURCES; + return Status; + } + + Status = HttpInstance->Tls->BuildResponsePacket ( + HttpInstance->Tls, + NULL, + 0, + BufferOut, + &BufferOutSize + ); + } + if (EFI_ERROR (Status)) { + FreePool(BufferOut); + return Status; + } + + if (BufferOutSize != 0) { + PacketOut = NetbufAlloc ((UINT32)BufferOutSize); + DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL); + if (DataOut == NULL) { + FreePool (BufferOut); + return EFI_OUT_OF_RESOURCES; + } + + CopyMem (DataOut, BufferOut, BufferOutSize); + + Status = TlsCommonTransmit (HttpInstance, PacketOut); + + NetbufFree (PacketOut); + } + + FreePool(BufferOut); + + if (EFI_ERROR (Status)) { + return Status; + } + + return EFI_ABORTED; + } + + return Status; + } + + // + // Parsing buffer. + // + ASSERT (((TLS_RECORD_HEADER *) (TempFragment.Bulk))->ContentType == TlsContentTypeApplicationData); + + BufferInSize = ((TLS_RECORD_HEADER *) (TempFragment.Bulk))->Length; + BufferIn = AllocateZeroPool (BufferInSize); + if (BufferIn == NULL) { + Status = EFI_OUT_OF_RESOURCES; + return Status; + } + + CopyMem (BufferIn, TempFragment.Bulk + sizeof (TLS_RECORD_HEADER), BufferInSize); + + // + // Free the buffer in TempFragment. + // + FreePool (TempFragment.Bulk); + + } else if ((RecordHeader.ContentType == TlsContentTypeAlert) && + (RecordHeader.Version.Major == 0x03) && + (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR || + RecordHeader.Version.Minor == TLS11_PROTOCOL_VERSION_MINOR || + RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR) + ) { + BufferOutSize = DEF_BUF_LEN; + BufferOut = AllocateZeroPool (BufferOutSize); + if (BufferOut == NULL) { + FreePool (BufferIn); + Status = EFI_OUT_OF_RESOURCES; + return Status; + } + + Status = HttpInstance->Tls->BuildResponsePacket ( + HttpInstance->Tls, + BufferIn, + BufferInSize, + BufferOut, + &BufferOutSize + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + FreePool (BufferOut); + BufferOut = AllocateZeroPool (BufferOutSize); + if (BufferOut == NULL) { + FreePool (BufferIn); + Status = EFI_OUT_OF_RESOURCES; + return Status; + } + + Status = HttpInstance->Tls->BuildResponsePacket ( + HttpInstance->Tls, + BufferIn, + BufferInSize, + BufferOut, + &BufferOutSize + ); + } + + FreePool (BufferIn); + + if (EFI_ERROR (Status)) { + FreePool (BufferOut); + return Status; + } + + if (BufferOutSize != 0) { + PacketOut = NetbufAlloc ((UINT32) BufferOutSize); + DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL); + if (DataOut == NULL) { + FreePool (BufferOut); + return EFI_OUT_OF_RESOURCES; + } + + CopyMem (DataOut, BufferOut, BufferOutSize); + + Status = TlsCommonTransmit (HttpInstance, PacketOut); + + NetbufFree (PacketOut); + } + + FreePool (BufferOut); + + // + // Get the session state. + // + GetSessionDataBufferSize = DEF_BUF_LEN; + GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize); + if (GetSessionDataBuffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + return Status; + } + + Status = HttpInstance->Tls->GetSessionData ( + HttpInstance->Tls, + EfiTlsSessionState, + GetSessionDataBuffer, + &GetSessionDataBufferSize + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + FreePool (GetSessionDataBuffer); + GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize); + if (GetSessionDataBuffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + return Status; + } + + Status = HttpInstance->Tls->GetSessionData ( + HttpInstance->Tls, + EfiTlsSessionState, + GetSessionDataBuffer, + &GetSessionDataBufferSize + ); + } + if (EFI_ERROR (Status)) { + FreePool (GetSessionDataBuffer); + return Status; + } + + ASSERT(GetSessionDataBufferSize == sizeof (EFI_TLS_SESSION_STATE)); + HttpInstance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) GetSessionDataBuffer; + + FreePool (GetSessionDataBuffer); + + if(HttpInstance->TlsSessionState == EfiTlsSessionError) { + DEBUG ((EFI_D_ERROR, "TLS Session State Error!\n")); + return EFI_ABORTED; + } + + BufferIn = NULL; + BufferInSize = 0; + } + + Fragment->Bulk = BufferIn; + Fragment->Len = (UINT32) BufferInSize; + + return Status; +} + diff --git a/NetworkPkg/HttpDxe/HttpsSupport.h b/NetworkPkg/HttpDxe/HttpsSupport.h index fcb3aa05c1..68a6073ceb 100644 --- a/NetworkPkg/HttpDxe/HttpsSupport.h +++ b/NetworkPkg/HttpDxe/HttpsSupport.h @@ -1,260 +1,261 @@ -/** @file - The header files of miscellaneous routines specific to Https for HttpDxe driver. - -Copyright (c) 2016, Intel Corporation. All rights reserved.
-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. - -**/ - -#ifndef __EFI_HTTPS_SUPPORT_H__ -#define __EFI_HTTPS_SUPPORT_H__ - -#define HTTPS_DEFAULT_PORT 443 - -#define HTTPS_FLAG "https://" - -/** - Check whether the Url is from Https. - - @param[in] Url The pointer to a HTTP or HTTPS URL string. - - @retval TRUE The Url is from HTTPS. - @retval FALSE The Url is from HTTP. - -**/ -BOOLEAN -IsHttpsUrl ( - IN CHAR8 *Url - ); - -/** - Creates a Tls child handle, open EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL. - - @param[in] ImageHandle The firmware allocated handle for the UEFI image. - @param[out] TlsProto Pointer to the EFI_TLS_PROTOCOL instance. - @param[out] TlsConfiguration Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance. - - @return The child handle with opened EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL. - -**/ -EFI_HANDLE -EFIAPI -TlsCreateChild ( - IN EFI_HANDLE ImageHandle, - OUT EFI_TLS_PROTOCOL **TlsProto, - OUT EFI_TLS_CONFIGURATION_PROTOCOL **TlsConfiguration - ); - -/** - Create event for the TLS receive and transmit tokens which are used to receive and - transmit TLS related messages. - - @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure. - - @retval EFI_SUCCESS The events are created successfully. - @retval others Other error as indicated. - -**/ -EFI_STATUS -EFIAPI -TlsCreateTxRxEvent ( - IN OUT HTTP_PROTOCOL *HttpInstance - ); - -/** - Close events in the TlsTxToken and TlsRxToken. - - @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure. - -**/ -VOID -EFIAPI -TlsCloseTxRxEvent ( - IN HTTP_PROTOCOL *HttpInstance - ); - -/** - Read the TlsCaCertificate variable and configure it. - - @param[in, out] HttpInstance The HTTP instance private data. - - @retval EFI_SUCCESS TlsCaCertificate is configured. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_NOT_FOUND Fail to get "TlsCaCertificate" variable. - @retval Others Other error as indicated. - -**/ -EFI_STATUS -TlsConfigCertificate ( - IN OUT HTTP_PROTOCOL *HttpInstance - ); - -/** - Configure TLS session data. - - @param[in, out] HttpInstance The HTTP instance private data. - - @retval EFI_SUCCESS TLS session data is configured. - @retval Others Other error as indicated. - -**/ -EFI_STATUS -EFIAPI -TlsConfigureSession ( - IN OUT HTTP_PROTOCOL *HttpInstance - ); - -/** - Transmit the Packet by processing the associated HTTPS token. - - @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure. - @param[in] Packet The packet to transmit. - - @retval EFI_SUCCESS The packet is transmitted. - @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. - @retval Others Other errors as indicated. - -**/ -EFI_STATUS -EFIAPI -TlsCommonTransmit ( - IN OUT HTTP_PROTOCOL *HttpInstance, - IN NET_BUF *Packet - ); - -/** - Receive the Packet by processing the associated HTTPS token. - - @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure. - @param[in] Packet The packet to transmit. - @param[in] Timeout The time to wait for connection done. - - @retval EFI_SUCCESS The Packet is received. - @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_TIMEOUT The operation is time out. - @retval Others Other error as indicated. - -**/ -EFI_STATUS -EFIAPI -TlsCommonReceive ( - IN OUT HTTP_PROTOCOL *HttpInstance, - IN NET_BUF *Packet, - IN EFI_EVENT Timeout - ); - -/** - Receive one TLS PDU. An TLS PDU contains an TLS record header and it's - corresponding record data. These two parts will be put into two blocks of buffers in the - net buffer. - - @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure. - @param[out] Pdu The received TLS PDU. - @param[in] Timeout The time to wait for connection done. - - @retval EFI_SUCCESS An TLS PDU is received. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_PROTOCOL_ERROR An unexpected TLS packet was received. - @retval Others Other errors as indicated. - -**/ -EFI_STATUS -EFIAPI -TlsReceiveOnePdu ( - IN OUT HTTP_PROTOCOL *HttpInstance, - OUT NET_BUF **Pdu, - IN EFI_EVENT Timeout - ); - -/** - Connect one TLS session by finishing the TLS handshake process. - - @param[in] HttpInstance The HTTP instance private data. - @param[in] Timeout The time to wait for connection done. - - @retval EFI_SUCCESS The TLS session is established. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_ABORTED TLS session state is incorrect. - @retval Others Other error as indicated. - -**/ -EFI_STATUS -EFIAPI -TlsConnectSession ( - IN HTTP_PROTOCOL *HttpInstance, - IN EFI_EVENT Timeout - ); - -/** - Close the TLS session and send out the close notification message. - - @param[in] HttpInstance The HTTP instance private data. - - @retval EFI_SUCCESS The TLS session is closed. - @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval Others Other error as indicated. - -**/ -EFI_STATUS -EFIAPI -TlsCloseSession ( - IN HTTP_PROTOCOL *HttpInstance - ); - -/** - Process one message according to the CryptMode. - - @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure. - @param[in] Message Pointer to the message buffer needed to processed. - @param[in] MessageSize Pointer to the message buffer size. - @param[in] ProcessMode Process mode. - @param[in, out] Fragment Only one Fragment returned after the Message is - processed successfully. - - @retval EFI_SUCCESS Message is processed successfully. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval Others Other errors as indicated. - -**/ -EFI_STATUS -EFIAPI -TlsProcessMessage ( - IN HTTP_PROTOCOL *HttpInstance, - IN UINT8 *Message, - IN UINTN MessageSize, - IN EFI_TLS_CRYPT_MODE ProcessMode, - IN OUT NET_FRAGMENT *Fragment - ); - -/** - Receive one fragment decrypted from one TLS record. - - @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure. - @param[in, out] Fragment The received Fragment. - @param[in] Timeout The time to wait for connection done. - - @retval EFI_SUCCESS One fragment is received. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_ABORTED Something wrong decryption the message. - @retval Others Other errors as indicated. - -**/ -EFI_STATUS -EFIAPI -HttpsReceive ( - IN HTTP_PROTOCOL *HttpInstance, - IN OUT NET_FRAGMENT *Fragment, - IN EFI_EVENT Timeout - ); - -#endif +/** @file + The header files of miscellaneous routines specific to Https for HttpDxe driver. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+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. + +**/ + +#ifndef __EFI_HTTPS_SUPPORT_H__ +#define __EFI_HTTPS_SUPPORT_H__ + +#define HTTPS_DEFAULT_PORT 443 + +#define HTTPS_FLAG "https://" + +/** + Check whether the Url is from Https. + + @param[in] Url The pointer to a HTTP or HTTPS URL string. + + @retval TRUE The Url is from HTTPS. + @retval FALSE The Url is from HTTP. + +**/ +BOOLEAN +IsHttpsUrl ( + IN CHAR8 *Url + ); + +/** + Creates a Tls child handle, open EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL. + + @param[in] ImageHandle The firmware allocated handle for the UEFI image. + @param[out] TlsProto Pointer to the EFI_TLS_PROTOCOL instance. + @param[out] TlsConfiguration Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance. + + @return The child handle with opened EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL. + +**/ +EFI_HANDLE +EFIAPI +TlsCreateChild ( + IN EFI_HANDLE ImageHandle, + OUT EFI_TLS_PROTOCOL **TlsProto, + OUT EFI_TLS_CONFIGURATION_PROTOCOL **TlsConfiguration + ); + +/** + Create event for the TLS receive and transmit tokens which are used to receive and + transmit TLS related messages. + + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure. + + @retval EFI_SUCCESS The events are created successfully. + @retval others Other error as indicated. + +**/ +EFI_STATUS +EFIAPI +TlsCreateTxRxEvent ( + IN OUT HTTP_PROTOCOL *HttpInstance + ); + +/** + Close events in the TlsTxToken and TlsRxToken. + + @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure. + +**/ +VOID +EFIAPI +TlsCloseTxRxEvent ( + IN HTTP_PROTOCOL *HttpInstance + ); + +/** + Read the TlsCaCertificate variable and configure it. + + @param[in, out] HttpInstance The HTTP instance private data. + + @retval EFI_SUCCESS TlsCaCertificate is configured. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. + @retval EFI_NOT_FOUND Fail to get "TlsCaCertificate" variable. + @retval Others Other error as indicated. + +**/ +EFI_STATUS +TlsConfigCertificate ( + IN OUT HTTP_PROTOCOL *HttpInstance + ); + +/** + Configure TLS session data. + + @param[in, out] HttpInstance The HTTP instance private data. + + @retval EFI_SUCCESS TLS session data is configured. + @retval Others Other error as indicated. + +**/ +EFI_STATUS +EFIAPI +TlsConfigureSession ( + IN OUT HTTP_PROTOCOL *HttpInstance + ); + +/** + Transmit the Packet by processing the associated HTTPS token. + + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure. + @param[in] Packet The packet to transmit. + + @retval EFI_SUCCESS The packet is transmitted. + @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. + @retval EFI_DEVICE_ERROR An unexpected system or network error occurred. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +EFIAPI +TlsCommonTransmit ( + IN OUT HTTP_PROTOCOL *HttpInstance, + IN NET_BUF *Packet + ); + +/** + Receive the Packet by processing the associated HTTPS token. + + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure. + @param[in] Packet The packet to transmit. + @param[in] Timeout The time to wait for connection done. + + @retval EFI_SUCCESS The Packet is received. + @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. + @retval EFI_TIMEOUT The operation is time out. + @retval Others Other error as indicated. + +**/ +EFI_STATUS +EFIAPI +TlsCommonReceive ( + IN OUT HTTP_PROTOCOL *HttpInstance, + IN NET_BUF *Packet, + IN EFI_EVENT Timeout + ); + +/** + Receive one TLS PDU. An TLS PDU contains an TLS record header and it's + corresponding record data. These two parts will be put into two blocks of buffers in the + net buffer. + + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure. + @param[out] Pdu The received TLS PDU. + @param[in] Timeout The time to wait for connection done. + + @retval EFI_SUCCESS An TLS PDU is received. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. + @retval EFI_PROTOCOL_ERROR An unexpected TLS packet was received. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +EFIAPI +TlsReceiveOnePdu ( + IN OUT HTTP_PROTOCOL *HttpInstance, + OUT NET_BUF **Pdu, + IN EFI_EVENT Timeout + ); + +/** + Connect one TLS session by finishing the TLS handshake process. + + @param[in] HttpInstance The HTTP instance private data. + @param[in] Timeout The time to wait for connection done. + + @retval EFI_SUCCESS The TLS session is established. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. + @retval EFI_ABORTED TLS session state is incorrect. + @retval Others Other error as indicated. + +**/ +EFI_STATUS +EFIAPI +TlsConnectSession ( + IN HTTP_PROTOCOL *HttpInstance, + IN EFI_EVENT Timeout + ); + +/** + Close the TLS session and send out the close notification message. + + @param[in] HttpInstance The HTTP instance private data. + + @retval EFI_SUCCESS The TLS session is closed. + @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. + @retval Others Other error as indicated. + +**/ +EFI_STATUS +EFIAPI +TlsCloseSession ( + IN HTTP_PROTOCOL *HttpInstance + ); + +/** + Process one message according to the CryptMode. + + @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure. + @param[in] Message Pointer to the message buffer needed to processed. + @param[in] MessageSize Pointer to the message buffer size. + @param[in] ProcessMode Process mode. + @param[in, out] Fragment Only one Fragment returned after the Message is + processed successfully. + + @retval EFI_SUCCESS Message is processed successfully. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +EFIAPI +TlsProcessMessage ( + IN HTTP_PROTOCOL *HttpInstance, + IN UINT8 *Message, + IN UINTN MessageSize, + IN EFI_TLS_CRYPT_MODE ProcessMode, + IN OUT NET_FRAGMENT *Fragment + ); + +/** + Receive one fragment decrypted from one TLS record. + + @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure. + @param[in, out] Fragment The received Fragment. + @param[in] Timeout The time to wait for connection done. + + @retval EFI_SUCCESS One fragment is received. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. + @retval EFI_ABORTED Something wrong decryption the message. + @retval Others Other errors as indicated. + +**/ +EFI_STATUS +EFIAPI +HttpsReceive ( + IN HTTP_PROTOCOL *HttpInstance, + IN OUT NET_FRAGMENT *Fragment, + IN EFI_EVENT Timeout + ); + +#endif + diff --git a/NetworkPkg/Include/Guid/TlsAuthConfigHii.h b/NetworkPkg/Include/Guid/TlsAuthConfigHii.h index 9d21426f9f..5e5637c4c6 100644 --- a/NetworkPkg/Include/Guid/TlsAuthConfigHii.h +++ b/NetworkPkg/Include/Guid/TlsAuthConfigHii.h @@ -1,25 +1,26 @@ -/** @file - GUIDs used as HII FormSet and HII Package list GUID in TlsAuthConfigDxe driver. - -Copyright (c) 2016, Intel Corporation. All rights reserved.
-This program and the accompanying materials are licensed and made available under -the terms and conditions of the BSD License that 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. - -**/ - -#ifndef __TLS_AUTH_CONFIG_HII_GUID_H__ -#define __TLS_AUTH_CONFIG_HII_GUID_H__ - -#define TLS_AUTH_CONFIG_GUID \ - { \ - 0xb0eae4f8, 0x9a04, 0x4c6d, { 0xa7, 0x48, 0x79, 0x3d, 0xaa, 0xf, 0x65, 0xdf } \ - } - -extern EFI_GUID gTlsAuthConfigGuid; - -#endif +/** @file + GUIDs used as HII FormSet and HII Package list GUID in TlsAuthConfigDxe driver. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+This program and the accompanying materials are licensed and made available under +the terms and conditions of the BSD License that 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. + +**/ + +#ifndef __TLS_AUTH_CONFIG_HII_GUID_H__ +#define __TLS_AUTH_CONFIG_HII_GUID_H__ + +#define TLS_AUTH_CONFIG_GUID \ + { \ + 0xb0eae4f8, 0x9a04, 0x4c6d, { 0xa7, 0x48, 0x79, 0x3d, 0xaa, 0xf, 0x65, 0xdf } \ + } + +extern EFI_GUID gTlsAuthConfigGuid; + +#endif + diff --git a/NetworkPkg/Include/Guid/TlsAuthentication.h b/NetworkPkg/Include/Guid/TlsAuthentication.h index 2e800dce12..e8497be68b 100644 --- a/NetworkPkg/Include/Guid/TlsAuthentication.h +++ b/NetworkPkg/Include/Guid/TlsAuthentication.h @@ -1,29 +1,30 @@ -/** @file - This file defines TlsCaCertificate variable. - -Copyright (c) 2016, Intel Corporation. All rights reserved.
-This program and the accompanying materials are licensed and made available under -the terms and conditions of the BSD License that 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. - -**/ - -#ifndef __TLS_AUTHENTICATION_H__ -#define __TLS_AUTHENTICATION_H__ - -// Private variable for CA Certificate configuration -// -#define EFI_TLS_CA_CERTIFICATE_GUID \ - { \ - 0xfd2340D0, 0x3dab, 0x4349, { 0xa6, 0xc7, 0x3b, 0x4f, 0x12, 0xb4, 0x8e, 0xae } \ - } - -#define EFI_TLS_CA_CERTIFICATE_VARIABLE L"TlsCaCertificate" - -extern EFI_GUID gEfiTlsCaCertificateGuid; - -#endif +/** @file + This file defines TlsCaCertificate variable. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+This program and the accompanying materials are licensed and made available under +the terms and conditions of the BSD License that 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. + +**/ + +#ifndef __TLS_AUTHENTICATION_H__ +#define __TLS_AUTHENTICATION_H__ + +// Private variable for CA Certificate configuration +// +#define EFI_TLS_CA_CERTIFICATE_GUID \ + { \ + 0xfd2340D0, 0x3dab, 0x4349, { 0xa6, 0xc7, 0x3b, 0x4f, 0x12, 0xb4, 0x8e, 0xae } \ + } + +#define EFI_TLS_CA_CERTIFICATE_VARIABLE L"TlsCaCertificate" + +extern EFI_GUID gEfiTlsCaCertificateGuid; + +#endif + diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c index 647bc2f01b..351656ff0c 100644 --- a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c @@ -1,135 +1,135 @@ -/** @file - The DriverEntryPoint for TlsAuthConfigDxe driver. - - Copyright (c) 2016, Intel Corporation. All rights reserved.
- - 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 "TlsAuthConfigImpl.h" - -/** - Unloads an image. - - @param ImageHandle Handle that identifies the image to be unloaded. - - @retval EFI_SUCCESS The image has been unloaded. - @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle. - -**/ -EFI_STATUS -EFIAPI -TlsAuthConfigDxeUnload ( - IN EFI_HANDLE ImageHandle - ) -{ - EFI_STATUS Status; - TLS_AUTH_CONFIG_PRIVATE_DATA *PrivateData; - - Status = gBS->HandleProtocol ( - ImageHandle, - &gEfiCallerIdGuid, - (VOID **) &PrivateData - ); - if (EFI_ERROR (Status)) { - return Status; - } - - ASSERT (PrivateData->Signature == TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE); - - gBS->UninstallMultipleProtocolInterfaces ( - &ImageHandle, - &gEfiCallerIdGuid, - PrivateData, - NULL - ); - - TlsAuthConfigFormUnload (PrivateData); - - return EFI_SUCCESS; -} - -/** - This is the declaration of an EFI image entry point. This entry point is - the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including - both device drivers and bus drivers. - - @param ImageHandle The firmware allocated handle for the UEFI image. - @param SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The operation completed successfully. - @retval Others An unexpected error occurred. -**/ -EFI_STATUS -EFIAPI -TlsAuthConfigDxeDriverEntryPoint ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - TLS_AUTH_CONFIG_PRIVATE_DATA *PrivateData; - - PrivateData = NULL; - - // - // If already started, return. - // - Status = gBS->OpenProtocol ( - ImageHandle, - &gEfiCallerIdGuid, - NULL, - ImageHandle, - ImageHandle, - EFI_OPEN_PROTOCOL_TEST_PROTOCOL - ); - if (!EFI_ERROR (Status)) { - return EFI_ALREADY_STARTED; - } - - // - // Initialize the private data structure. - // - PrivateData = AllocateZeroPool (sizeof (TLS_AUTH_CONFIG_PRIVATE_DATA)); - if (PrivateData == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Initialize the HII configuration form. - // - Status = TlsAuthConfigFormInit (PrivateData); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - // - // Install private GUID. - // - Status = gBS->InstallMultipleProtocolInterfaces ( - &ImageHandle, - &gEfiCallerIdGuid, - PrivateData, - NULL - ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - return EFI_SUCCESS; - -ON_ERROR: - TlsAuthConfigFormUnload (PrivateData); - FreePool (PrivateData); - - return Status; -} - +/** @file + The DriverEntryPoint for TlsAuthConfigDxe driver. + + Copyright (c) 2016, Intel Corporation. All rights reserved.
+ + 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 "TlsAuthConfigImpl.h" + +/** + Unloads an image. + + @param ImageHandle Handle that identifies the image to be unloaded. + + @retval EFI_SUCCESS The image has been unloaded. + @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle. + +**/ +EFI_STATUS +EFIAPI +TlsAuthConfigDxeUnload ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + TLS_AUTH_CONFIG_PRIVATE_DATA *PrivateData; + + Status = gBS->HandleProtocol ( + ImageHandle, + &gEfiCallerIdGuid, + (VOID **) &PrivateData + ); + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (PrivateData->Signature == TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE); + + gBS->UninstallMultipleProtocolInterfaces ( + &ImageHandle, + &gEfiCallerIdGuid, + PrivateData, + NULL + ); + + TlsAuthConfigFormUnload (PrivateData); + + return EFI_SUCCESS; +} + +/** + This is the declaration of an EFI image entry point. This entry point is + the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including + both device drivers and bus drivers. + + @param ImageHandle The firmware allocated handle for the UEFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The operation completed successfully. + @retval Others An unexpected error occurred. +**/ +EFI_STATUS +EFIAPI +TlsAuthConfigDxeDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + TLS_AUTH_CONFIG_PRIVATE_DATA *PrivateData; + + PrivateData = NULL; + + // + // If already started, return. + // + Status = gBS->OpenProtocol ( + ImageHandle, + &gEfiCallerIdGuid, + NULL, + ImageHandle, + ImageHandle, + EFI_OPEN_PROTOCOL_TEST_PROTOCOL + ); + if (!EFI_ERROR (Status)) { + return EFI_ALREADY_STARTED; + } + + // + // Initialize the private data structure. + // + PrivateData = AllocateZeroPool (sizeof (TLS_AUTH_CONFIG_PRIVATE_DATA)); + if (PrivateData == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Initialize the HII configuration form. + // + Status = TlsAuthConfigFormInit (PrivateData); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + + // + // Install private GUID. + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &ImageHandle, + &gEfiCallerIdGuid, + PrivateData, + NULL + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + + return EFI_SUCCESS; + +ON_ERROR: + TlsAuthConfigFormUnload (PrivateData); + FreePool (PrivateData); + + return Status; +} + diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf index 19f095e89d..2a893689bb 100644 --- a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf @@ -1,73 +1,74 @@ -## @file -# Provides the capability to configure Tls Authentication in a setup browser -# By this module, user may change the content of TlsCaCertificate. -# -# Copyright (c) 2016, Intel Corporation. All rights reserved.
-# 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. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = TlsAuthConfigDxe - MODULE_UNI_FILE = TlsAuthConfigDxe.uni - FILE_GUID = 7ca1024f-eb17-11e5-9dba-28d2447c4829 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = TlsAuthConfigDxeDriverEntryPoint - UNLOAD_IMAGE = TlsAuthConfigDxeUnload - -# -# VALID_ARCHITECTURES = IA32 X64 -# - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - NetworkPkg/NetworkPkg.dec - -[Sources] - TlsAuthConfigImpl.c - TlsAuthConfigImpl.h - TlsAuthConfigNvData.h - TlsAuthConfigDxe.c - TlsAuthConfigDxeStrings.uni - TlsAuthConfigVfr.vfr - -[LibraryClasses] - BaseLib - BaseMemoryLib - MemoryAllocationLib - UefiLib - UefiBootServicesTableLib - UefiRuntimeServicesTableLib - UefiDriverEntryPoint - DebugLib - HiiLib - DevicePathLib - UefiHiiServicesLib - FileExplorerLib - PrintLib - -[Protocols] - gEfiDevicePathProtocolGuid ## PRODUCES - gEfiHiiConfigAccessProtocolGuid ## PRODUCES - gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES - -[Guids] - gTlsAuthConfigGuid ## PRODUCES ## GUID - gEfiCertX509Guid ## CONSUMES ## GUID # Indicate the cert type - gEfiIfrTianoGuid ## CONSUMES ## HII - gEfiTlsCaCertificateGuid ## PRODUCES ## GUID - -[Depex] - gEfiHiiConfigRoutingProtocolGuid AND - gEfiHiiDatabaseProtocolGuid - -[UserExtensions.TianoCore."ExtraFiles"] - TlsAuthConfigDxeExtra.uni +## @file +# Provides the capability to configure Tls Authentication in a setup browser +# By this module, user may change the content of TlsCaCertificate. +# +# Copyright (c) 2016, Intel Corporation. All rights reserved.
+# 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. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = TlsAuthConfigDxe + MODULE_UNI_FILE = TlsAuthConfigDxe.uni + FILE_GUID = 7ca1024f-eb17-11e5-9dba-28d2447c4829 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = TlsAuthConfigDxeDriverEntryPoint + UNLOAD_IMAGE = TlsAuthConfigDxeUnload + +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + NetworkPkg/NetworkPkg.dec + +[Sources] + TlsAuthConfigImpl.c + TlsAuthConfigImpl.h + TlsAuthConfigNvData.h + TlsAuthConfigDxe.c + TlsAuthConfigDxeStrings.uni + TlsAuthConfigVfr.vfr + +[LibraryClasses] + BaseLib + BaseMemoryLib + MemoryAllocationLib + UefiLib + UefiBootServicesTableLib + UefiRuntimeServicesTableLib + UefiDriverEntryPoint + DebugLib + HiiLib + DevicePathLib + UefiHiiServicesLib + FileExplorerLib + PrintLib + +[Protocols] + gEfiDevicePathProtocolGuid ## PRODUCES + gEfiHiiConfigAccessProtocolGuid ## PRODUCES + gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES + +[Guids] + gTlsAuthConfigGuid ## PRODUCES ## GUID + gEfiCertX509Guid ## CONSUMES ## GUID # Indicate the cert type + gEfiIfrTianoGuid ## CONSUMES ## HII + gEfiTlsCaCertificateGuid ## PRODUCES ## GUID + +[Depex] + gEfiHiiConfigRoutingProtocolGuid AND + gEfiHiiDatabaseProtocolGuid + +[UserExtensions.TianoCore."ExtraFiles"] + TlsAuthConfigDxeExtra.uni + diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni index f99a14f575..dcd308fda0 100644 --- a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni @@ -1,21 +1,21 @@ -// /** @file -// Provides the capability to configure Tls Authentication in a setup browser -// -// By this module, user may change the content of TlsCaCertificate. -// -// Copyright (c) 2016, Intel Corporation. All rights reserved.
-// -// 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. -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "Provides the capability to configure Tls Authentication in a setup browser" - -#string STR_MODULE_DESCRIPTION #language en-US "By this module, user may change the content of TlsCaCertificate." - +// /** @file +// Provides the capability to configure Tls Authentication in a setup browser +// +// By this module, user may change the content of TlsCaCertificate. +// +// Copyright (c) 2016, Intel Corporation. All rights reserved.
+// +// 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. +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Provides the capability to configure Tls Authentication in a setup browser" + +#string STR_MODULE_DESCRIPTION #language en-US "By this module, user may change the content of TlsCaCertificate." + diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni index ee4c49f15b..d284537303 100644 --- a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni @@ -1,19 +1,19 @@ -// /** @file -// TlsAuthConfigDxe Localized Strings and Content -// -// Copyright (c) 2016, Intel Corporation. All rights reserved.
-// -// 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. -// -// **/ - -#string STR_PROPERTIES_MODULE_NAME -#language en-US -"TLS Auth Config DXE" - - +// /** @file +// TlsAuthConfigDxe Localized Strings and Content +// +// Copyright (c) 2016, Intel Corporation. All rights reserved.
+// +// 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. +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"TLS Auth Config DXE" + + diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni index a8f7e434c3..6ffa52df62 100644 --- a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni @@ -1,39 +1,39 @@ -/** @file - String definitions for Tls Authentication Configuration form. - -Copyright (c) 2016, Intel Corporation. All rights reserved.
-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. - -**/ - -#langdef en-US "English" - -#string STR_TLS_AUTH_CONFIG_TITLE #language en-US "Tls Auth Configuration" -#string STR_TLS_AUTH_CONFIG_HELP #language en-US "Press to select Tls Auth Configuration." - -#string STR_TLS_AUTH_CONFIG_SERVER_CA #language en-US "Server CA Configuration" -#string STR_TLS_AUTH_CONFIG_SERVER_CA_HELP #language en-US "Press to configure Server CA." -#string STR_TLS_AUTH_CONFIG_CLIENT_CERT #language en-US "Client Cert Configuration" -#string STR_TLS_AUTH_CONFIG_CLIENT_CERT_HELP #language en-US "Client cert configuration is unsupported currently." - -#string STR_TLS_AUTH_CONFIG_ENROLL_CERT #language en-US "Enroll Cert" -#string STR_TLS_AUTH_CONFIG_ENROLL_CERT_HELP #language en-US "Press to enroll cert." -#string STR_TLS_AUTH_CONFIG_DELETE_CERT #language en-US "Delete Cert" -#string STR_TLS_AUTH_CONFIG_DELETE_CERT_HELP #language en-US "Press to delete cert." - -#string STR_TLS_AUTH_CONFIG_ADD_CERT_FILE #language en-US "Enroll Cert Using File" - -#string STR_TLS_AUTH_CONFIG_CERT_GUID #language en-US "Cert GUID" -#string STR_TLS_AUTH_CONFIG_CERT_GUID_HELP #language en-US "Input digit character in 11111111-2222-3333-4444-1234567890ab format." -#string STR_TLS_AUTH_CONFIG_SAVE_AND_EXIT #language en-US "Commit Changes and Exit" -#string STR_TLS_AUTH_CONFIG_NO_SAVE_AND_EXIT #language en-US "Discard Changes and Exit" - -#string STR_CERT_TYPE_PCKS_GUID #language en-US "GUID for CERT" - -#string STR_NULL #language en-US "" \ No newline at end of file +/** @file + String definitions for Tls Authentication Configuration form. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+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. + +**/ + +#langdef en-US "English" + +#string STR_TLS_AUTH_CONFIG_TITLE #language en-US "Tls Auth Configuration" +#string STR_TLS_AUTH_CONFIG_HELP #language en-US "Press to select Tls Auth Configuration." + +#string STR_TLS_AUTH_CONFIG_SERVER_CA #language en-US "Server CA Configuration" +#string STR_TLS_AUTH_CONFIG_SERVER_CA_HELP #language en-US "Press to configure Server CA." +#string STR_TLS_AUTH_CONFIG_CLIENT_CERT #language en-US "Client Cert Configuration" +#string STR_TLS_AUTH_CONFIG_CLIENT_CERT_HELP #language en-US "Client cert configuration is unsupported currently." + +#string STR_TLS_AUTH_CONFIG_ENROLL_CERT #language en-US "Enroll Cert" +#string STR_TLS_AUTH_CONFIG_ENROLL_CERT_HELP #language en-US "Press to enroll cert." +#string STR_TLS_AUTH_CONFIG_DELETE_CERT #language en-US "Delete Cert" +#string STR_TLS_AUTH_CONFIG_DELETE_CERT_HELP #language en-US "Press to delete cert." + +#string STR_TLS_AUTH_CONFIG_ADD_CERT_FILE #language en-US "Enroll Cert Using File" + +#string STR_TLS_AUTH_CONFIG_CERT_GUID #language en-US "Cert GUID" +#string STR_TLS_AUTH_CONFIG_CERT_GUID_HELP #language en-US "Input digit character in 11111111-2222-3333-4444-1234567890ab format." +#string STR_TLS_AUTH_CONFIG_SAVE_AND_EXIT #language en-US "Commit Changes and Exit" +#string STR_TLS_AUTH_CONFIG_NO_SAVE_AND_EXIT #language en-US "Discard Changes and Exit" + +#string STR_CERT_TYPE_PCKS_GUID #language en-US "GUID for CERT" + +#string STR_NULL #language en-US "" diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c index 5b4756f16b..81f7e7d0f4 100644 --- a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c @@ -1,1688 +1,1689 @@ -/** @file - The Miscellaneous Routines for TlsAuthConfigDxe driver. - -Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- -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 "TlsAuthConfigImpl.h" - -VOID *mStartOpCodeHandle = NULL; -VOID *mEndOpCodeHandle = NULL; -EFI_IFR_GUID_LABEL *mStartLabel = NULL; -EFI_IFR_GUID_LABEL *mEndLabel = NULL; - - -CHAR16 mTlsAuthConfigStorageName[] = L"TLS_AUTH_CONFIG_IFR_NVDATA"; - -TLS_AUTH_CONFIG_PRIVATE_DATA *mTlsAuthPrivateData = NULL; - -HII_VENDOR_DEVICE_PATH mTlsAuthConfigHiiVendorDevicePath = { - { - { - HARDWARE_DEVICE_PATH, - HW_VENDOR_DP, - { - (UINT8) (sizeof (VENDOR_DEVICE_PATH)), - (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) - } - }, - TLS_AUTH_CONFIG_GUID - }, - { - END_DEVICE_PATH_TYPE, - END_ENTIRE_DEVICE_PATH_SUBTYPE, - { - (UINT8) (END_DEVICE_PATH_LENGTH), - (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8) - } - } -}; - -// -// Possible DER-encoded certificate file suffixes, end with NULL pointer. -// -CHAR16* mDerPemEncodedSuffix[] = { - L".cer", - L".der", - L".crt", - L".pem", - NULL -}; - -/** - This code checks if the FileSuffix is one of the possible DER/PEM-encoded certificate suffix. - - @param[in] FileSuffix The suffix of the input certificate file - - @retval TRUE It's a DER/PEM-encoded certificate. - @retval FALSE It's NOT a DER/PEM-encoded certificate. - -**/ -BOOLEAN -IsDerPemEncodeCertificate ( - IN CONST CHAR16 *FileSuffix -) -{ - UINTN Index; - for (Index = 0; mDerPemEncodedSuffix[Index] != NULL; Index++) { - if (StrCmp (FileSuffix, mDerPemEncodedSuffix[Index]) == 0) { - return TRUE; - } - } - return FALSE; -} - -/** - Worker function that prints an EFI_GUID into specified Buffer. - - @param[in] Guid Pointer to GUID to print. - @param[in] Buffer Buffer to print Guid into. - @param[in] BufferSize Size of Buffer. - - @retval Number of characters printed. - -**/ -UINTN -GuidToString ( - IN EFI_GUID *Guid, - IN CHAR16 *Buffer, - IN UINTN BufferSize - ) -{ - return UnicodeSPrint ( - Buffer, - BufferSize, - L"%g", - Guid - ); -} - -/** - List all cert in specified database by GUID in the page - for user to select and delete as needed. - - @param[in] PrivateData Module's private data. - @param[in] VariableName The variable name of the vendor's signature database. - @param[in] VendorGuid A unique identifier for the vendor. - @param[in] LabelNumber Label number to insert opcodes. - @param[in] FormId Form ID of current page. - @param[in] QuestionIdBase Base question id of the signature list. - - @retval EFI_SUCCESS Success to update the signature list page - @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources. - -**/ -EFI_STATUS -UpdateDeletePage ( - IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private, - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - IN UINT16 LabelNumber, - IN EFI_FORM_ID FormId, - IN EFI_QUESTION_ID QuestionIdBase - ) -{ - EFI_STATUS Status; - UINT32 Index; - UINTN CertCount; - UINTN GuidIndex; - VOID *StartOpCodeHandle; - VOID *EndOpCodeHandle; - EFI_IFR_GUID_LABEL *StartLabel; - EFI_IFR_GUID_LABEL *EndLabel; - UINTN DataSize; - UINT8 *Data; - EFI_SIGNATURE_LIST *CertList; - EFI_SIGNATURE_DATA *Cert; - UINT32 ItemDataSize; - CHAR16 *GuidStr; - EFI_STRING_ID GuidID; - EFI_STRING_ID Help; - - Data = NULL; - CertList = NULL; - Cert = NULL; - GuidStr = NULL; - StartOpCodeHandle = NULL; - EndOpCodeHandle = NULL; - - // - // Initialize the container for dynamic opcodes. - // - StartOpCodeHandle = HiiAllocateOpCodeHandle (); - if (StartOpCodeHandle == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - EndOpCodeHandle = HiiAllocateOpCodeHandle (); - if (EndOpCodeHandle == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - // - // Create Hii Extend Label OpCode. - // - StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( - StartOpCodeHandle, - &gEfiIfrTianoGuid, - NULL, - sizeof (EFI_IFR_GUID_LABEL) - ); - StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; - StartLabel->Number = LabelNumber; - - EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( - EndOpCodeHandle, - &gEfiIfrTianoGuid, - NULL, - sizeof (EFI_IFR_GUID_LABEL) - ); - EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; - EndLabel->Number = LABEL_END; - - // - // Read Variable. - // - DataSize = 0; - Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, Data); - if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) { - goto ON_EXIT; - } - - Data = (UINT8 *) AllocateZeroPool (DataSize); - if (Data == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, Data); - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - - GuidStr = AllocateZeroPool (100); - if (GuidStr == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - // - // Enumerate all data. - // - ItemDataSize = (UINT32) DataSize; - CertList = (EFI_SIGNATURE_LIST *) Data; - GuidIndex = 0; - - while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) { - - if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) { - Help = STRING_TOKEN (STR_CERT_TYPE_PCKS_GUID); - } else { - // - // The signature type is not supported in current implementation. - // - ItemDataSize -= CertList->SignatureListSize; - CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize); - continue; - } - - CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize; - for (Index = 0; Index < CertCount; Index++) { - Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList - + sizeof (EFI_SIGNATURE_LIST) - + CertList->SignatureHeaderSize - + Index * CertList->SignatureSize); - // - // Display GUID and help - // - GuidToString (&Cert->SignatureOwner, GuidStr, 100); - GuidID = HiiSetString (Private->RegisteredHandle, 0, GuidStr, NULL); - HiiCreateCheckBoxOpCode ( - StartOpCodeHandle, - (EFI_QUESTION_ID) (QuestionIdBase + GuidIndex++), - 0, - 0, - GuidID, - Help, - EFI_IFR_FLAG_CALLBACK, - 0, - NULL - ); - } - - ItemDataSize -= CertList->SignatureListSize; - CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize); - } - -ON_EXIT: - HiiUpdateForm ( - Private->RegisteredHandle, - &gTlsAuthConfigGuid, - FormId, - StartOpCodeHandle, - EndOpCodeHandle - ); - - if (StartOpCodeHandle != NULL) { - HiiFreeOpCodeHandle (StartOpCodeHandle); - } - - if (EndOpCodeHandle != NULL) { - HiiFreeOpCodeHandle (EndOpCodeHandle); - } - - if (Data != NULL) { - FreePool (Data); - } - - if (GuidStr != NULL) { - FreePool (GuidStr); - } - - return EFI_SUCCESS; -} - -/** - Delete one entry from cert database. - - @param[in] PrivateData Module's private data. - @param[in] VariableName The variable name of the database. - @param[in] VendorGuid A unique identifier for the vendor. - @param[in] LabelNumber Label number to insert opcodes. - @param[in] FormId Form ID of current page. - @param[in] QuestionIdBase Base question id of the cert list. - @param[in] DeleteIndex Cert index to delete. - - @retval EFI_SUCCESS Delete siganture successfully. - @retval EFI_NOT_FOUND Can't find the signature item, - @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources. -**/ -EFI_STATUS -DeleteCert ( - IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private, - IN CHAR16 *VariableName, - IN EFI_GUID *VendorGuid, - IN UINT16 LabelNumber, - IN EFI_FORM_ID FormId, - IN EFI_QUESTION_ID QuestionIdBase, - IN UINTN DeleteIndex - ) -{ - EFI_STATUS Status; - UINTN DataSize; - UINT8 *Data; - UINT8 *OldData; - UINT32 Attr; - UINT32 Index; - EFI_SIGNATURE_LIST *CertList; - EFI_SIGNATURE_LIST *NewCertList; - EFI_SIGNATURE_DATA *Cert; - UINTN CertCount; - UINT32 Offset; - BOOLEAN IsItemFound; - UINT32 ItemDataSize; - UINTN GuidIndex; - - Data = NULL; - OldData = NULL; - CertList = NULL; - Cert = NULL; - Attr = 0; - - // - // Get original signature list data. - // - DataSize = 0; - Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, NULL); - if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) { - goto ON_EXIT; - } - - OldData = (UINT8 *) AllocateZeroPool (DataSize); - if (OldData == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - Status = gRT->GetVariable (VariableName, VendorGuid, &Attr, &DataSize, OldData); - if (EFI_ERROR(Status)) { - goto ON_EXIT; - } - - // - // Allocate space for new variable. - // - Data = (UINT8*) AllocateZeroPool (DataSize); - if (Data == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - // - // Enumerate all data and erasing the target item. - // - IsItemFound = FALSE; - ItemDataSize = (UINT32) DataSize; - CertList = (EFI_SIGNATURE_LIST *) OldData; - Offset = 0; - GuidIndex = 0; - while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) { - if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) { - // - // Copy EFI_SIGNATURE_LIST header then calculate the signature count in this list. - // - CopyMem (Data + Offset, CertList, (sizeof(EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize)); - NewCertList = (EFI_SIGNATURE_LIST*) (Data + Offset); - Offset += (sizeof(EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize); - Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize); - CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize; - for (Index = 0; Index < CertCount; Index++) { - if (GuidIndex == DeleteIndex) { - // - // Find it! Skip it! - // - NewCertList->SignatureListSize -= CertList->SignatureSize; - IsItemFound = TRUE; - } else { - // - // This item doesn't match. Copy it to the Data buffer. - // - CopyMem (Data + Offset, (UINT8*)(Cert), CertList->SignatureSize); - Offset += CertList->SignatureSize; - } - GuidIndex++; - Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize); - } - } else { - // - // This List doesn't match. Just copy it to the Data buffer. - // - CopyMem (Data + Offset, (UINT8*)(CertList), CertList->SignatureListSize); - Offset += CertList->SignatureListSize; - } - - ItemDataSize -= CertList->SignatureListSize; - CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize); - } - - if (!IsItemFound) { - // - // Doesn't find the signature Item! - // - Status = EFI_NOT_FOUND; - goto ON_EXIT; - } - - // - // Delete the EFI_SIGNATURE_LIST header if there is no signature in the list. - // - ItemDataSize = Offset; - CertList = (EFI_SIGNATURE_LIST *) Data; - Offset = 0; - ZeroMem (OldData, ItemDataSize); - while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) { - CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize; - DEBUG ((DEBUG_INFO, " CertCount = %x\n", CertCount)); - if (CertCount != 0) { - CopyMem (OldData + Offset, (UINT8*)(CertList), CertList->SignatureListSize); - Offset += CertList->SignatureListSize; - } - ItemDataSize -= CertList->SignatureListSize; - CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize); - } - - DataSize = Offset; - - Status = gRT->SetVariable( - VariableName, - VendorGuid, - Attr, - DataSize, - OldData - ); - if (EFI_ERROR (Status)) { - DEBUG ((DEBUG_ERROR, "Failed to set variable, Status = %r\n", Status)); - goto ON_EXIT; - } - -ON_EXIT: - if (Data != NULL) { - FreePool(Data); - } - - if (OldData != NULL) { - FreePool(OldData); - } - - return UpdateDeletePage ( - Private, - VariableName, - VendorGuid, - LabelNumber, - FormId, - QuestionIdBase - ); -} - - -/** - Close an open file handle. - - @param[in] FileHandle The file handle to close. - -**/ -VOID -CloseFile ( - IN EFI_FILE_HANDLE FileHandle - ) -{ - if (FileHandle != NULL) { - FileHandle->Close (FileHandle); - } -} - -/** - Read file content into BufferPtr, the size of the allocate buffer - is *FileSize plus AddtionAllocateSize. - - @param[in] FileHandle The file to be read. - @param[in, out] BufferPtr Pointers to the pointer of allocated buffer. - @param[out] FileSize Size of input file - @param[in] AddtionAllocateSize Addtion size the buffer need to be allocated. - In case the buffer need to contain others besides the file content. - - @retval EFI_SUCCESS The file was read into the buffer. - @retval EFI_INVALID_PARAMETER A parameter was invalid. - @retval EFI_OUT_OF_RESOURCES A memory allocation failed. - @retval others Unexpected error. - -**/ -EFI_STATUS -ReadFileContent ( - IN EFI_FILE_HANDLE FileHandle, - IN OUT VOID **BufferPtr, - OUT UINTN *FileSize, - IN UINTN AddtionAllocateSize - ) - -{ - UINTN BufferSize; - UINT64 SourceFileSize; - VOID *Buffer; - EFI_STATUS Status; - - if ((FileHandle == NULL) || (FileSize == NULL)) { - return EFI_INVALID_PARAMETER; - } - - Buffer = NULL; - - // - // Get the file size - // - Status = FileHandle->SetPosition (FileHandle, (UINT64) -1); - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - - Status = FileHandle->GetPosition (FileHandle, &SourceFileSize); - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - - Status = FileHandle->SetPosition (FileHandle, 0); - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - - BufferSize = (UINTN) SourceFileSize + AddtionAllocateSize; - Buffer = AllocateZeroPool(BufferSize); - if (Buffer == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - BufferSize = (UINTN) SourceFileSize; - *FileSize = BufferSize; - - Status = FileHandle->Read (FileHandle, &BufferSize, Buffer); - if (EFI_ERROR (Status) || BufferSize != *FileSize) { - FreePool (Buffer); - Buffer = NULL; - Status = EFI_BAD_BUFFER_SIZE; - goto ON_EXIT; - } - -ON_EXIT: - - *BufferPtr = Buffer; - return Status; -} - -/** - This function will open a file or directory referenced by DevicePath. - - This function opens a file with the open mode according to the file path. The - Attributes is valid only for EFI_FILE_MODE_CREATE. - - @param[in, out] FilePath On input, the device path to the file. - On output, the remaining device path. - @param[out] FileHandle Pointer to the file handle. - @param[in] OpenMode The mode to open the file with. - @param[in] Attributes The file's file attributes. - - @retval EFI_SUCCESS The information was set. - @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. - @retval EFI_UNSUPPORTED Could not open the file path. - @retval EFI_NOT_FOUND The specified file could not be found on the - device or the file system could not be found on - the device. - @retval EFI_NO_MEDIA The device has no medium. - @retval EFI_MEDIA_CHANGED The device has a different medium in it or the - medium is no longer supported. - @retval EFI_DEVICE_ERROR The device reported an error. - @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. - @retval EFI_WRITE_PROTECTED The file or medium is write protected. - @retval EFI_ACCESS_DENIED The file was opened read only. - @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the - file. - @retval EFI_VOLUME_FULL The volume is full. -**/ -EFI_STATUS -EFIAPI -OpenFileByDevicePath ( - IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath, - OUT EFI_FILE_HANDLE *FileHandle, - IN UINT64 OpenMode, - IN UINT64 Attributes - ) -{ - EFI_STATUS Status; - EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *EfiSimpleFileSystemProtocol; - EFI_FILE_PROTOCOL *Handle1; - EFI_FILE_PROTOCOL *Handle2; - EFI_HANDLE DeviceHandle; - - if ((FilePath == NULL || FileHandle == NULL)) { - return EFI_INVALID_PARAMETER; - } - - Status = gBS->LocateDevicePath ( - &gEfiSimpleFileSystemProtocolGuid, - FilePath, - &DeviceHandle - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = gBS->OpenProtocol( - DeviceHandle, - &gEfiSimpleFileSystemProtocolGuid, - (VOID**)&EfiSimpleFileSystemProtocol, - gImageHandle, - NULL, - EFI_OPEN_PROTOCOL_GET_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return Status; - } - - Status = EfiSimpleFileSystemProtocol->OpenVolume(EfiSimpleFileSystemProtocol, &Handle1); - if (EFI_ERROR (Status)) { - FileHandle = NULL; - return Status; - } - - // - // go down directories one node at a time. - // - while (!IsDevicePathEnd (*FilePath)) { - // - // For file system access each node should be a file path component - // - if (DevicePathType (*FilePath) != MEDIA_DEVICE_PATH || - DevicePathSubType (*FilePath) != MEDIA_FILEPATH_DP - ) { - FileHandle = NULL; - return (EFI_INVALID_PARAMETER); - } - // - // Open this file path node - // - Handle2 = Handle1; - Handle1 = NULL; - - // - // Try to test opening an existing file - // - Status = Handle2->Open ( - Handle2, - &Handle1, - ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName, - OpenMode &~EFI_FILE_MODE_CREATE, - 0 - ); - - // - // see if the error was that it needs to be created - // - if ((EFI_ERROR (Status)) && (OpenMode != (OpenMode &~EFI_FILE_MODE_CREATE))) { - Status = Handle2->Open ( - Handle2, - &Handle1, - ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName, - OpenMode, - Attributes - ); - } - // - // Close the last node - // - Handle2->Close (Handle2); - - if (EFI_ERROR(Status)) { - return (Status); - } - - // - // Get the next node - // - *FilePath = NextDevicePathNode (*FilePath); - } - - // - // This is a weak spot since if the undefined SHELL_FILE_HANDLE format changes this must change also! - // - *FileHandle = (VOID*)Handle1; - return EFI_SUCCESS; -} - -/** - This function converts an input device structure to a Unicode string. - - @param[in] DevPath A pointer to the device path structure. - - @return A new allocated Unicode string that represents the device path. - -**/ -CHAR16 * -EFIAPI -DevicePathToStr ( - IN EFI_DEVICE_PATH_PROTOCOL *DevPath - ) -{ - return ConvertDevicePathToText ( - DevPath, - FALSE, - TRUE - ); -} - - -/** - Extract filename from device path. The returned buffer is allocated using AllocateCopyPool. - The caller is responsible for freeing the allocated buffer using FreePool(). If return NULL - means not enough memory resource. - - @param DevicePath Device path. - - @retval NULL Not enough memory resourece for AllocateCopyPool. - @retval Other A new allocated string that represents the file name. - -**/ -CHAR16 * -ExtractFileNameFromDevicePath ( - IN EFI_DEVICE_PATH_PROTOCOL *DevicePath - ) -{ - CHAR16 *String; - CHAR16 *MatchString; - CHAR16 *LastMatch; - CHAR16 *FileName; - UINTN Length; - - ASSERT(DevicePath != NULL); - - String = DevicePathToStr(DevicePath); - MatchString = String; - LastMatch = String; - FileName = NULL; - - while(MatchString != NULL){ - LastMatch = MatchString + 1; - MatchString = StrStr(LastMatch,L"\\"); - } - - Length = StrLen(LastMatch); - FileName = AllocateCopyPool ((Length + 1) * sizeof(CHAR16), LastMatch); - if (FileName != NULL) { - *(FileName + Length) = 0; - } - - FreePool(String); - - return FileName; -} - -/** - Enroll a new X509 certificate into Variable. - - @param[in] PrivateData The module's private data. - @param[in] VariableName Variable name of CA database. - - @retval EFI_SUCCESS New X509 is enrolled successfully. - @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources. - -**/ -EFI_STATUS -EnrollX509toVariable ( - IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private, - IN CHAR16 *VariableName - ) -{ - EFI_STATUS Status; - UINTN X509DataSize; - VOID *X509Data; - EFI_SIGNATURE_LIST *CACert; - EFI_SIGNATURE_DATA *CACertData; - VOID *Data; - UINTN DataSize; - UINTN SigDataSize; - UINT32 Attr; - - X509DataSize = 0; - SigDataSize = 0; - DataSize = 0; - X509Data = NULL; - CACert = NULL; - CACertData = NULL; - Data = NULL; - - Status = ReadFileContent ( - Private->FileContext->FHandle, - &X509Data, - &X509DataSize, - 0 - ); - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - ASSERT (X509Data != NULL); - - SigDataSize = sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_SIGNATURE_DATA) - 1 + X509DataSize; - - Data = AllocateZeroPool (SigDataSize); - if (Data == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - // - // Fill Certificate Database parameters. - // - CACert = (EFI_SIGNATURE_LIST*) Data; - CACert->SignatureListSize = (UINT32) SigDataSize; - CACert->SignatureHeaderSize = 0; - CACert->SignatureSize = (UINT32) (sizeof(EFI_SIGNATURE_DATA) - 1 + X509DataSize); - CopyGuid (&CACert->SignatureType, &gEfiCertX509Guid); - - CACertData = (EFI_SIGNATURE_DATA*) ((UINT8* ) CACert + sizeof (EFI_SIGNATURE_LIST)); - CopyGuid (&CACertData->SignatureOwner, Private->CertGuid); - CopyMem ((UINT8* ) (CACertData->SignatureData), X509Data, X509DataSize); - - // - // Check if signature database entry has been already existed. - // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the - // new signature data to original variable - // - Attr = TLS_AUTH_CONFIG_VAR_BASE_ATTR; - - Status = gRT->GetVariable( - VariableName, - &gEfiTlsCaCertificateGuid, - NULL, - &DataSize, - NULL - ); - if (Status == EFI_BUFFER_TOO_SMALL) { - Attr |= EFI_VARIABLE_APPEND_WRITE; - } else if (Status != EFI_NOT_FOUND) { - goto ON_EXIT; - } - - Status = gRT->SetVariable( - VariableName, - &gEfiTlsCaCertificateGuid, - Attr, - SigDataSize, - Data - ); - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - -ON_EXIT: - - CloseFile (Private->FileContext->FHandle); - if (Private->FileContext->FileName != NULL) { - FreePool(Private->FileContext->FileName); - Private->FileContext->FileName = NULL; - } - - Private->FileContext->FHandle = NULL; - - if (Private->CertGuid != NULL) { - FreePool (Private->CertGuid); - Private->CertGuid = NULL; - } - - if (Data != NULL) { - FreePool (Data); - } - - if (X509Data != NULL) { - FreePool (X509Data); - } - - return Status; -} - -/** - Enroll Cert into TlsCaCertificate. The GUID will be Private->CertGuid. - - @param[in] PrivateData The module's private data. - @param[in] VariableName Variable name of signature database. - - @retval EFI_SUCCESS New Cert enrolled successfully. - @retval EFI_INVALID_PARAMETER The parameter is invalid. - @retval EFI_UNSUPPORTED The Cert file is unsupported type. - @retval others Fail to enroll Cert data. - -**/ -EFI_STATUS -EnrollCertDatabase ( - IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private, - IN CHAR16 *VariableName - ) -{ - UINT16* FilePostFix; - UINTN NameLength; - - if ((Private->FileContext->FileName == NULL) || (Private->FileContext->FHandle == NULL) || (Private->CertGuid == NULL)) { - return EFI_INVALID_PARAMETER; - } - - // - // Parse the file's postfix. - // - NameLength = StrLen (Private->FileContext->FileName); - if (NameLength <= 4) { - return EFI_INVALID_PARAMETER; - } - FilePostFix = Private->FileContext->FileName + NameLength - 4; - - if (IsDerPemEncodeCertificate (FilePostFix)) { - // - // Supports DER-encoded X509 certificate. - // - return EnrollX509toVariable (Private, VariableName); - } - - return EFI_UNSUPPORTED; -} - -/** - Refresh the global UpdateData structure. - -**/ -VOID -RefreshUpdateData ( - VOID - ) -{ - // - // Free current updated date - // - if (mStartOpCodeHandle != NULL) { - HiiFreeOpCodeHandle (mStartOpCodeHandle); - } - - // - // Create new OpCode Handle - // - mStartOpCodeHandle = HiiAllocateOpCodeHandle (); - - // - // Create Hii Extend Label OpCode as the start opcode - // - mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( - mStartOpCodeHandle, - &gEfiIfrTianoGuid, - NULL, - sizeof (EFI_IFR_GUID_LABEL) - ); - mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; -} - -/** - Clean up the dynamic opcode at label and form specified by both LabelId. - - @param[in] LabelId It is both the Form ID and Label ID for opcode deletion. - @param[in] PrivateData Module private data. - -**/ -VOID -CleanUpPage ( - IN UINT16 LabelId, - IN TLS_AUTH_CONFIG_PRIVATE_DATA *PrivateData - ) -{ - RefreshUpdateData (); - - // - // Remove all op-codes from dynamic page - // - mStartLabel->Number = LabelId; - HiiUpdateForm ( - PrivateData->RegisteredHandle, - &gTlsAuthConfigGuid, - LabelId, - mStartOpCodeHandle, // Label LabelId - mEndOpCodeHandle // LABEL_END - ); -} - -/** - Update the form base on the selected file. - - @param FilePath Point to the file path. - @param FormId The form need to display. - - @retval TRUE Exit caller function. - @retval FALSE Not exit caller function. - -**/ -BOOLEAN -UpdatePage( - IN EFI_DEVICE_PATH_PROTOCOL *FilePath, - IN EFI_FORM_ID FormId - ) -{ - CHAR16 *FileName; - EFI_STRING_ID StringToken; - - FileName = NULL; - - if (FilePath != NULL) { - FileName = ExtractFileNameFromDevicePath(FilePath); - } - if (FileName == NULL) { - // - // FileName = NULL has two case: - // 1. FilePath == NULL, not select file. - // 2. FilePath != NULL, but ExtractFileNameFromDevicePath return NULL not enough memory resource. - // In these two case, no need to update the form, and exit the caller function. - // - return TRUE; - } - StringToken = HiiSetString (mTlsAuthPrivateData->RegisteredHandle, 0, FileName, NULL); - - mTlsAuthPrivateData->FileContext->FileName = FileName; - - OpenFileByDevicePath ( - &FilePath, - &mTlsAuthPrivateData->FileContext->FHandle, - EFI_FILE_MODE_READ, - 0 - ); - // - // Create Subtitle op-code for the display string of the option. - // - RefreshUpdateData (); - mStartLabel->Number = FormId; - - HiiCreateSubTitleOpCode ( - mStartOpCodeHandle, - StringToken, - 0, - 0, - 0 - ); - - HiiUpdateForm ( - mTlsAuthPrivateData->RegisteredHandle, - &gTlsAuthConfigGuid, - FormId, - mStartOpCodeHandle, /// Label FormId - mEndOpCodeHandle /// LABEL_END - ); - - return TRUE; -} - -/** - Update the form base on the input file path info. - - @param FilePath Point to the file path. - - @retval TRUE Exit caller function. - @retval FALSE Not exit caller function. -**/ -BOOLEAN -EFIAPI -UpdateCAFromFile ( - IN EFI_DEVICE_PATH_PROTOCOL *FilePath - ) -{ - return UpdatePage(FilePath, TLS_AUTH_CONFIG_FORMID4_FORM); -} - -/** - Unload the configuration form, this includes: delete all the configuration - entries, uninstall the form callback protocol, and free the resources used. - - @param[in] Private Pointer to the driver private data. - - @retval EFI_SUCCESS The configuration form is unloaded. - @retval Others Failed to unload the form. - -**/ -EFI_STATUS -TlsAuthConfigFormUnload ( - IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private - ) -{ - if (Private->DriverHandle != NULL) { - // - // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL - // - gBS->UninstallMultipleProtocolInterfaces ( - Private->DriverHandle, - &gEfiDevicePathProtocolGuid, - &mTlsAuthConfigHiiVendorDevicePath, - &gEfiHiiConfigAccessProtocolGuid, - &Private->ConfigAccess, - NULL - ); - Private->DriverHandle = NULL; - } - - if (Private->RegisteredHandle != NULL) { - // - // Remove HII package list - // - HiiRemovePackages (Private->RegisteredHandle); - Private->RegisteredHandle = NULL; - } - - if (Private->CertGuid != NULL) { - FreePool (Private->CertGuid); - } - - if (Private->FileContext != NULL) { - FreePool (Private->FileContext); - } - - FreePool (Private); - - if (mStartOpCodeHandle != NULL) { - HiiFreeOpCodeHandle (mStartOpCodeHandle); - } - - if (mEndOpCodeHandle != NULL) { - HiiFreeOpCodeHandle (mEndOpCodeHandle); - } - - return EFI_SUCCESS; -} - - -/** - Initialize the configuration form. - - @param[in] Private Pointer to the driver private data. - - @retval EFI_SUCCESS The configuration form is initialized. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. - -**/ -EFI_STATUS -TlsAuthConfigFormInit ( - IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private - ) -{ - EFI_STATUS Status; - - Private->Signature = TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE; - - Private->ConfigAccess.ExtractConfig = TlsAuthConfigAccessExtractConfig; - Private->ConfigAccess.RouteConfig = TlsAuthConfigAccessRouteConfig; - Private->ConfigAccess.Callback = TlsAuthConfigAccessCallback; - - // - // Install Device Path Protocol and Config Access protocol to driver handle. - // - Status = gBS->InstallMultipleProtocolInterfaces ( - &Private->DriverHandle, - &gEfiDevicePathProtocolGuid, - &mTlsAuthConfigHiiVendorDevicePath, - &gEfiHiiConfigAccessProtocolGuid, - &Private->ConfigAccess, - NULL - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Publish our HII data. - // - Private->RegisteredHandle = HiiAddPackages ( - &gTlsAuthConfigGuid, - Private->DriverHandle, - TlsAuthConfigDxeStrings, - TlsAuthConfigVfrBin, - NULL - ); - if (Private->RegisteredHandle == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - Private->FileContext = AllocateZeroPool (sizeof (TLS_AUTH_CONFIG_FILE_CONTEXT)); - if (Private->FileContext == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - // - // Init OpCode Handle and Allocate space for creation of Buffer - // - mStartOpCodeHandle = HiiAllocateOpCodeHandle (); - if (mStartOpCodeHandle == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - mEndOpCodeHandle = HiiAllocateOpCodeHandle (); - if (mEndOpCodeHandle == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto Error; - } - - // - // Create Hii Extend Label OpCode as the start opcode - // - mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( - mStartOpCodeHandle, - &gEfiIfrTianoGuid, - NULL, - sizeof (EFI_IFR_GUID_LABEL) - ); - mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; - - // - // Create Hii Extend Label OpCode as the end opcode - // - mEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( - mEndOpCodeHandle, - &gEfiIfrTianoGuid, - NULL, - sizeof (EFI_IFR_GUID_LABEL) - ); - mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; - mEndLabel->Number = LABEL_END; - - return EFI_SUCCESS; - -Error: - TlsAuthConfigFormUnload (Private); - return Status; -} - -/** - - This function allows the caller to request the current - configuration for one or more named elements. The resulting - string is in format. Any and all alternative - configuration strings shall also be appended to the end of the - current configuration string. If they are, they must appear - after the current configuration. They must contain the same - routing (GUID, NAME, PATH) as the current configuration string. - They must have an additional description indicating the type of - alternative configuration the string represents, - "ALTCFG=". That (when - converted from Hex UNICODE to binary) is a reference to a - string in the associated string pack. - - @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. - - @param Request A null-terminated Unicode string in - format. Note that this - includes the routing information as well as - the configurable name / value pairs. It is - invalid for this string to be in - format. - If a NULL is passed in for the Request field, - all of the settings being abstracted by this function - will be returned in the Results field. In addition, - if a ConfigHdr is passed in with no request elements, - all of the settings being abstracted for that particular - ConfigHdr reference will be returned in the Results Field. - - @param Progress On return, points to a character in the - Request string. Points to the string's null - terminator if request was successful. Points - to the most recent "&" before the first - failing name / value pair (or the beginning - of the string if the failure is in the first - name / value pair) if the request was not - successful. - - @param Results A null-terminated Unicode string in - format which has all values - filled in for the names in the Request string. - String to be allocated by the called function. - - @retval EFI_SUCCESS The Results string is filled with the - values corresponding to all requested - names. - - @retval EFI_OUT_OF_RESOURCES Not enough memory to store the - parts of the results that must be - stored awaiting possible future - protocols. - - @retval EFI_NOT_FOUND Routing data doesn't match any - known driver. Progress set to the - first character in the routing header. - Note: There is no requirement that the - driver validate the routing data. It - must skip the in order to - process the names. - - @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set - to most recent "&" before the - error or the beginning of the - string. - - @retval EFI_INVALID_PARAMETER Unknown name. Progress points - to the & before the name in - question. - -**/ -EFI_STATUS -EFIAPI -TlsAuthConfigAccessExtractConfig ( - IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, - IN CONST EFI_STRING Request, - OUT EFI_STRING *Progress, - OUT EFI_STRING *Results - ) -{ - EFI_STATUS Status; - UINTN BufferSize; - UINTN Size; - EFI_STRING ConfigRequest; - EFI_STRING ConfigRequestHdr; - TLS_AUTH_CONFIG_PRIVATE_DATA *Private; - BOOLEAN AllocatedRequest; - - if (Progress == NULL || Results == NULL) { - return EFI_INVALID_PARAMETER; - } - - AllocatedRequest = FALSE; - ConfigRequestHdr = NULL; - ConfigRequest = NULL; - Size = 0; - - Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This); - - BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA); - ZeroMem (&Private->TlsAuthConfigNvData, BufferSize); - - *Progress = Request; - - if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gTlsAuthConfigGuid, mTlsAuthConfigStorageName)) { - return EFI_NOT_FOUND; - } - - ConfigRequest = Request; - if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) { - // - // Request is set to NULL or OFFSET is NULL, construct full request string. - // - // Allocate and fill a buffer large enough to hold the template - // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator - // - ConfigRequestHdr = HiiConstructConfigHdr (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, Private->DriverHandle); - Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16); - ConfigRequest = AllocateZeroPool (Size); - ASSERT (ConfigRequest != NULL); - AllocatedRequest = TRUE; - UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize); - FreePool (ConfigRequestHdr); - ConfigRequestHdr = NULL; - } - - Status = gHiiConfigRouting->BlockToConfig ( - gHiiConfigRouting, - ConfigRequest, - (UINT8 *) &Private->TlsAuthConfigNvData, - BufferSize, - Results, - Progress - ); - - // - // Free the allocated config request string. - // - if (AllocatedRequest) { - FreePool (ConfigRequest); - } - - // - // Set Progress string to the original request string. - // - if (Request == NULL) { - *Progress = NULL; - } else if (StrStr (Request, L"OFFSET") == NULL) { - *Progress = Request + StrLen (Request); - } - - return Status; -} - -/** - - This function applies changes in a driver's configuration. - Input is a Configuration, which has the routing data for this - driver followed by name / value configuration pairs. The driver - must apply those pairs to its configurable storage. If the - driver's configuration is stored in a linear block of data - and the driver's name / value pairs are in - format, it may use the ConfigToBlock helper function (above) to - simplify the job. - - @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. - - @param Configuration A null-terminated Unicode string in - format. - - @param Progress A pointer to a string filled in with the - offset of the most recent '&' before the - first failing name / value pair (or the - beginn ing of the string if the failure - is in the first name / value pair) or - the terminating NULL if all was - successful. - - @retval EFI_SUCCESS The results have been distributed or are - awaiting distribution. - - @retval EFI_OUT_OF_RESOURCES Not enough memory to store the - parts of the results that must be - stored awaiting possible future - protocols. - - @retval EFI_INVALID_PARAMETERS Passing in a NULL for the - Results parameter would result - in this type of error. - - @retval EFI_NOT_FOUND Target for the specified routing data - was not found - -**/ -EFI_STATUS -EFIAPI -TlsAuthConfigAccessRouteConfig ( - IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, - IN CONST EFI_STRING Configuration, - OUT EFI_STRING *Progress - ) -{ - EFI_STATUS Status; - UINTN BufferSize; - TLS_AUTH_CONFIG_PRIVATE_DATA *Private; - - if (Progress == NULL) { - return EFI_INVALID_PARAMETER; - } - *Progress = Configuration; - - if (Configuration == NULL) { - return EFI_INVALID_PARAMETER; - } - - // - // Check routing data in . - // Note: there is no name for Name/Value storage, only GUID will be checked - // - if (!HiiIsConfigHdrMatch (Configuration, &gTlsAuthConfigGuid, mTlsAuthConfigStorageName)) { - return EFI_NOT_FOUND; - } - - Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This); - - BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA); - ZeroMem (&Private->TlsAuthConfigNvData, BufferSize); - - Status = gHiiConfigRouting->ConfigToBlock ( - gHiiConfigRouting, - Configuration, - (UINT8 *) &Private->TlsAuthConfigNvData, - &BufferSize, - Progress - ); - if (EFI_ERROR (Status)) { - return Status; - } - - return Status; -} - -/** - - This function is called to provide results data to the driver. - This data consists of a unique key that is used to identify - which data is either being passed back or being asked for. - - @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. - @param Action Specifies the type of action taken by the browser. - @param QuestionId A unique value which is sent to the original - exporting driver so that it can identify the type - of data to expect. The format of the data tends to - vary based on the opcode that generated the callback. - @param Type The type of value for the question. - @param Value A pointer to the data being sent to the original - exporting driver. - @param ActionRequest On return, points to the action requested by the - callback function. - - @retval EFI_SUCCESS The callback successfully handled the action. - @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the - variable and its data. - @retval EFI_DEVICE_ERROR The variable could not be saved. - @retval EFI_UNSUPPORTED The specified Action is not supported by the - callback. -**/ -EFI_STATUS -EFIAPI -TlsAuthConfigAccessCallback ( - IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, - IN EFI_BROWSER_ACTION Action, - IN EFI_QUESTION_ID QuestionId, - IN UINT8 Type, - IN OUT EFI_IFR_TYPE_VALUE *Value, - OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest - ) -{ - EFI_INPUT_KEY Key; - EFI_STATUS Status; - RETURN_STATUS RStatus; - TLS_AUTH_CONFIG_PRIVATE_DATA *Private; - UINTN BufferSize; - TLS_AUTH_CONFIG_IFR_NVDATA *IfrNvData; - UINT16 LabelId; - EFI_DEVICE_PATH_PROTOCOL *File; - - Status = EFI_SUCCESS; - File = NULL; - - if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) { - return EFI_INVALID_PARAMETER; - } - - Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This); - - mTlsAuthPrivateData = Private; - - // - // Retrieve uncommitted data from Browser - // - BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA); - IfrNvData = AllocateZeroPool (BufferSize); - if (IfrNvData == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - HiiGetBrowserData (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, BufferSize, (UINT8 *) IfrNvData); - - if ((Action != EFI_BROWSER_ACTION_CHANGED) && - (Action != EFI_BROWSER_ACTION_CHANGING)) { - Status = EFI_UNSUPPORTED; - goto EXIT; - } - - if (Action == EFI_BROWSER_ACTION_CHANGING) { - switch (QuestionId) { - case KEY_TLS_AUTH_CONFIG_CLIENT_CERT: - case KEY_TLS_AUTH_CONFIG_SERVER_CA: - // - // Clear Cert GUID. - // - ZeroMem (IfrNvData->CertGuid, sizeof (IfrNvData->CertGuid)); - if (Private->CertGuid == NULL) { - Private->CertGuid = (EFI_GUID *) AllocateZeroPool (sizeof (EFI_GUID)); - if (Private->CertGuid == NULL) { - return EFI_OUT_OF_RESOURCES; - } - } - if (QuestionId == KEY_TLS_AUTH_CONFIG_CLIENT_CERT) { - LabelId = TLS_AUTH_CONFIG_FORMID3_FORM; - } else { - LabelId = TLS_AUTH_CONFIG_FORMID4_FORM; - } - - // - // Refresh selected file. - // - CleanUpPage (LabelId, Private); - break; - case KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE: - ChooseFile( NULL, NULL, UpdateCAFromFile, &File); - break; - - case KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT: - Status = EnrollCertDatabase (Private, EFI_TLS_CA_CERTIFICATE_VARIABLE); - if (EFI_ERROR (Status)) { - CreatePopUp ( - EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, - &Key, - L"ERROR: Enroll Cert Failure!", - NULL - ); - } - break; - - case KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT: - if (Private->FileContext->FHandle != NULL) { - CloseFile (Private->FileContext->FHandle); - Private->FileContext->FHandle = NULL; - if (Private->FileContext->FileName!= NULL){ - FreePool(Private->FileContext->FileName); - Private->FileContext->FileName = NULL; - } - } - - if (Private->CertGuid!= NULL) { - FreePool (Private->CertGuid); - Private->CertGuid = NULL; - } - break; - - case KEY_TLS_AUTH_CONFIG_DELETE_CERT: - UpdateDeletePage ( - Private, - EFI_TLS_CA_CERTIFICATE_VARIABLE, - &gEfiTlsCaCertificateGuid, - LABEL_CA_DELETE, - TLS_AUTH_CONFIG_FORMID5_FORM, - OPTION_DEL_CA_ESTION_ID - ); - break; - - default: - if ((QuestionId >= OPTION_DEL_CA_ESTION_ID) && - (QuestionId < (OPTION_DEL_CA_ESTION_ID + OPTION_CONFIG_RANGE))) { - DeleteCert ( - Private, - EFI_TLS_CA_CERTIFICATE_VARIABLE, - &gEfiTlsCaCertificateGuid, - LABEL_CA_DELETE, - TLS_AUTH_CONFIG_FORMID5_FORM, - OPTION_DEL_CA_ESTION_ID, - QuestionId - OPTION_DEL_CA_ESTION_ID - ); - } - break; - } - } else if (Action == EFI_BROWSER_ACTION_CHANGED) { - switch (QuestionId) { - case KEY_TLS_AUTH_CONFIG_CERT_GUID: - ASSERT (Private->CertGuid != NULL); - RStatus = StrToGuid ( - IfrNvData->CertGuid, - Private->CertGuid - ); - if (RETURN_ERROR (RStatus) || (IfrNvData->CertGuid[GUID_STRING_LENGTH] != L'\0')) { - Status = EFI_INVALID_PARAMETER; - break; - } - - *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; - break; - default: - break; - } - } - -EXIT: - - if (!EFI_ERROR (Status)) { - BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA); - HiiSetBrowserData (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, BufferSize, (UINT8*) IfrNvData, NULL); - } - - FreePool (IfrNvData); - - if (File != NULL){ - FreePool(File); - File = NULL; - } - - return EFI_SUCCESS; - -} +/** @file + The Miscellaneous Routines for TlsAuthConfigDxe driver. + +Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
+ +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 "TlsAuthConfigImpl.h" + +VOID *mStartOpCodeHandle = NULL; +VOID *mEndOpCodeHandle = NULL; +EFI_IFR_GUID_LABEL *mStartLabel = NULL; +EFI_IFR_GUID_LABEL *mEndLabel = NULL; + + +CHAR16 mTlsAuthConfigStorageName[] = L"TLS_AUTH_CONFIG_IFR_NVDATA"; + +TLS_AUTH_CONFIG_PRIVATE_DATA *mTlsAuthPrivateData = NULL; + +HII_VENDOR_DEVICE_PATH mTlsAuthConfigHiiVendorDevicePath = { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8) (sizeof (VENDOR_DEVICE_PATH)), + (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) + } + }, + TLS_AUTH_CONFIG_GUID + }, + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { + (UINT8) (END_DEVICE_PATH_LENGTH), + (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8) + } + } +}; + +// +// Possible DER-encoded certificate file suffixes, end with NULL pointer. +// +CHAR16* mDerPemEncodedSuffix[] = { + L".cer", + L".der", + L".crt", + L".pem", + NULL +}; + +/** + This code checks if the FileSuffix is one of the possible DER/PEM-encoded certificate suffix. + + @param[in] FileSuffix The suffix of the input certificate file + + @retval TRUE It's a DER/PEM-encoded certificate. + @retval FALSE It's NOT a DER/PEM-encoded certificate. + +**/ +BOOLEAN +IsDerPemEncodeCertificate ( + IN CONST CHAR16 *FileSuffix +) +{ + UINTN Index; + for (Index = 0; mDerPemEncodedSuffix[Index] != NULL; Index++) { + if (StrCmp (FileSuffix, mDerPemEncodedSuffix[Index]) == 0) { + return TRUE; + } + } + return FALSE; +} + +/** + Worker function that prints an EFI_GUID into specified Buffer. + + @param[in] Guid Pointer to GUID to print. + @param[in] Buffer Buffer to print Guid into. + @param[in] BufferSize Size of Buffer. + + @retval Number of characters printed. + +**/ +UINTN +GuidToString ( + IN EFI_GUID *Guid, + IN CHAR16 *Buffer, + IN UINTN BufferSize + ) +{ + return UnicodeSPrint ( + Buffer, + BufferSize, + L"%g", + Guid + ); +} + +/** + List all cert in specified database by GUID in the page + for user to select and delete as needed. + + @param[in] PrivateData Module's private data. + @param[in] VariableName The variable name of the vendor's signature database. + @param[in] VendorGuid A unique identifier for the vendor. + @param[in] LabelNumber Label number to insert opcodes. + @param[in] FormId Form ID of current page. + @param[in] QuestionIdBase Base question id of the signature list. + + @retval EFI_SUCCESS Success to update the signature list page + @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources. + +**/ +EFI_STATUS +UpdateDeletePage ( + IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private, + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT16 LabelNumber, + IN EFI_FORM_ID FormId, + IN EFI_QUESTION_ID QuestionIdBase + ) +{ + EFI_STATUS Status; + UINT32 Index; + UINTN CertCount; + UINTN GuidIndex; + VOID *StartOpCodeHandle; + VOID *EndOpCodeHandle; + EFI_IFR_GUID_LABEL *StartLabel; + EFI_IFR_GUID_LABEL *EndLabel; + UINTN DataSize; + UINT8 *Data; + EFI_SIGNATURE_LIST *CertList; + EFI_SIGNATURE_DATA *Cert; + UINT32 ItemDataSize; + CHAR16 *GuidStr; + EFI_STRING_ID GuidID; + EFI_STRING_ID Help; + + Data = NULL; + CertList = NULL; + Cert = NULL; + GuidStr = NULL; + StartOpCodeHandle = NULL; + EndOpCodeHandle = NULL; + + // + // Initialize the container for dynamic opcodes. + // + StartOpCodeHandle = HiiAllocateOpCodeHandle (); + if (StartOpCodeHandle == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + EndOpCodeHandle = HiiAllocateOpCodeHandle (); + if (EndOpCodeHandle == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + // + // Create Hii Extend Label OpCode. + // + StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( + StartOpCodeHandle, + &gEfiIfrTianoGuid, + NULL, + sizeof (EFI_IFR_GUID_LABEL) + ); + StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + StartLabel->Number = LabelNumber; + + EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( + EndOpCodeHandle, + &gEfiIfrTianoGuid, + NULL, + sizeof (EFI_IFR_GUID_LABEL) + ); + EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + EndLabel->Number = LABEL_END; + + // + // Read Variable. + // + DataSize = 0; + Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, Data); + if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) { + goto ON_EXIT; + } + + Data = (UINT8 *) AllocateZeroPool (DataSize); + if (Data == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, Data); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + GuidStr = AllocateZeroPool (100); + if (GuidStr == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + // + // Enumerate all data. + // + ItemDataSize = (UINT32) DataSize; + CertList = (EFI_SIGNATURE_LIST *) Data; + GuidIndex = 0; + + while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) { + + if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) { + Help = STRING_TOKEN (STR_CERT_TYPE_PCKS_GUID); + } else { + // + // The signature type is not supported in current implementation. + // + ItemDataSize -= CertList->SignatureListSize; + CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize); + continue; + } + + CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize; + for (Index = 0; Index < CertCount; Index++) { + Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + + sizeof (EFI_SIGNATURE_LIST) + + CertList->SignatureHeaderSize + + Index * CertList->SignatureSize); + // + // Display GUID and help + // + GuidToString (&Cert->SignatureOwner, GuidStr, 100); + GuidID = HiiSetString (Private->RegisteredHandle, 0, GuidStr, NULL); + HiiCreateCheckBoxOpCode ( + StartOpCodeHandle, + (EFI_QUESTION_ID) (QuestionIdBase + GuidIndex++), + 0, + 0, + GuidID, + Help, + EFI_IFR_FLAG_CALLBACK, + 0, + NULL + ); + } + + ItemDataSize -= CertList->SignatureListSize; + CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize); + } + +ON_EXIT: + HiiUpdateForm ( + Private->RegisteredHandle, + &gTlsAuthConfigGuid, + FormId, + StartOpCodeHandle, + EndOpCodeHandle + ); + + if (StartOpCodeHandle != NULL) { + HiiFreeOpCodeHandle (StartOpCodeHandle); + } + + if (EndOpCodeHandle != NULL) { + HiiFreeOpCodeHandle (EndOpCodeHandle); + } + + if (Data != NULL) { + FreePool (Data); + } + + if (GuidStr != NULL) { + FreePool (GuidStr); + } + + return EFI_SUCCESS; +} + +/** + Delete one entry from cert database. + + @param[in] PrivateData Module's private data. + @param[in] VariableName The variable name of the database. + @param[in] VendorGuid A unique identifier for the vendor. + @param[in] LabelNumber Label number to insert opcodes. + @param[in] FormId Form ID of current page. + @param[in] QuestionIdBase Base question id of the cert list. + @param[in] DeleteIndex Cert index to delete. + + @retval EFI_SUCCESS Delete siganture successfully. + @retval EFI_NOT_FOUND Can't find the signature item, + @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources. +**/ +EFI_STATUS +DeleteCert ( + IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private, + IN CHAR16 *VariableName, + IN EFI_GUID *VendorGuid, + IN UINT16 LabelNumber, + IN EFI_FORM_ID FormId, + IN EFI_QUESTION_ID QuestionIdBase, + IN UINTN DeleteIndex + ) +{ + EFI_STATUS Status; + UINTN DataSize; + UINT8 *Data; + UINT8 *OldData; + UINT32 Attr; + UINT32 Index; + EFI_SIGNATURE_LIST *CertList; + EFI_SIGNATURE_LIST *NewCertList; + EFI_SIGNATURE_DATA *Cert; + UINTN CertCount; + UINT32 Offset; + BOOLEAN IsItemFound; + UINT32 ItemDataSize; + UINTN GuidIndex; + + Data = NULL; + OldData = NULL; + CertList = NULL; + Cert = NULL; + Attr = 0; + + // + // Get original signature list data. + // + DataSize = 0; + Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, NULL); + if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) { + goto ON_EXIT; + } + + OldData = (UINT8 *) AllocateZeroPool (DataSize); + if (OldData == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + Status = gRT->GetVariable (VariableName, VendorGuid, &Attr, &DataSize, OldData); + if (EFI_ERROR(Status)) { + goto ON_EXIT; + } + + // + // Allocate space for new variable. + // + Data = (UINT8*) AllocateZeroPool (DataSize); + if (Data == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + // + // Enumerate all data and erasing the target item. + // + IsItemFound = FALSE; + ItemDataSize = (UINT32) DataSize; + CertList = (EFI_SIGNATURE_LIST *) OldData; + Offset = 0; + GuidIndex = 0; + while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) { + if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) { + // + // Copy EFI_SIGNATURE_LIST header then calculate the signature count in this list. + // + CopyMem (Data + Offset, CertList, (sizeof(EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize)); + NewCertList = (EFI_SIGNATURE_LIST*) (Data + Offset); + Offset += (sizeof(EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize); + Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize); + CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize; + for (Index = 0; Index < CertCount; Index++) { + if (GuidIndex == DeleteIndex) { + // + // Find it! Skip it! + // + NewCertList->SignatureListSize -= CertList->SignatureSize; + IsItemFound = TRUE; + } else { + // + // This item doesn't match. Copy it to the Data buffer. + // + CopyMem (Data + Offset, (UINT8*)(Cert), CertList->SignatureSize); + Offset += CertList->SignatureSize; + } + GuidIndex++; + Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize); + } + } else { + // + // This List doesn't match. Just copy it to the Data buffer. + // + CopyMem (Data + Offset, (UINT8*)(CertList), CertList->SignatureListSize); + Offset += CertList->SignatureListSize; + } + + ItemDataSize -= CertList->SignatureListSize; + CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize); + } + + if (!IsItemFound) { + // + // Doesn't find the signature Item! + // + Status = EFI_NOT_FOUND; + goto ON_EXIT; + } + + // + // Delete the EFI_SIGNATURE_LIST header if there is no signature in the list. + // + ItemDataSize = Offset; + CertList = (EFI_SIGNATURE_LIST *) Data; + Offset = 0; + ZeroMem (OldData, ItemDataSize); + while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) { + CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize; + DEBUG ((DEBUG_INFO, " CertCount = %x\n", CertCount)); + if (CertCount != 0) { + CopyMem (OldData + Offset, (UINT8*)(CertList), CertList->SignatureListSize); + Offset += CertList->SignatureListSize; + } + ItemDataSize -= CertList->SignatureListSize; + CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize); + } + + DataSize = Offset; + + Status = gRT->SetVariable( + VariableName, + VendorGuid, + Attr, + DataSize, + OldData + ); + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "Failed to set variable, Status = %r\n", Status)); + goto ON_EXIT; + } + +ON_EXIT: + if (Data != NULL) { + FreePool(Data); + } + + if (OldData != NULL) { + FreePool(OldData); + } + + return UpdateDeletePage ( + Private, + VariableName, + VendorGuid, + LabelNumber, + FormId, + QuestionIdBase + ); +} + + +/** + Close an open file handle. + + @param[in] FileHandle The file handle to close. + +**/ +VOID +CloseFile ( + IN EFI_FILE_HANDLE FileHandle + ) +{ + if (FileHandle != NULL) { + FileHandle->Close (FileHandle); + } +} + +/** + Read file content into BufferPtr, the size of the allocate buffer + is *FileSize plus AddtionAllocateSize. + + @param[in] FileHandle The file to be read. + @param[in, out] BufferPtr Pointers to the pointer of allocated buffer. + @param[out] FileSize Size of input file + @param[in] AddtionAllocateSize Addtion size the buffer need to be allocated. + In case the buffer need to contain others besides the file content. + + @retval EFI_SUCCESS The file was read into the buffer. + @retval EFI_INVALID_PARAMETER A parameter was invalid. + @retval EFI_OUT_OF_RESOURCES A memory allocation failed. + @retval others Unexpected error. + +**/ +EFI_STATUS +ReadFileContent ( + IN EFI_FILE_HANDLE FileHandle, + IN OUT VOID **BufferPtr, + OUT UINTN *FileSize, + IN UINTN AddtionAllocateSize + ) + +{ + UINTN BufferSize; + UINT64 SourceFileSize; + VOID *Buffer; + EFI_STATUS Status; + + if ((FileHandle == NULL) || (FileSize == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Buffer = NULL; + + // + // Get the file size + // + Status = FileHandle->SetPosition (FileHandle, (UINT64) -1); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + Status = FileHandle->GetPosition (FileHandle, &SourceFileSize); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + Status = FileHandle->SetPosition (FileHandle, 0); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + BufferSize = (UINTN) SourceFileSize + AddtionAllocateSize; + Buffer = AllocateZeroPool(BufferSize); + if (Buffer == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + BufferSize = (UINTN) SourceFileSize; + *FileSize = BufferSize; + + Status = FileHandle->Read (FileHandle, &BufferSize, Buffer); + if (EFI_ERROR (Status) || BufferSize != *FileSize) { + FreePool (Buffer); + Buffer = NULL; + Status = EFI_BAD_BUFFER_SIZE; + goto ON_EXIT; + } + +ON_EXIT: + + *BufferPtr = Buffer; + return Status; +} + +/** + This function will open a file or directory referenced by DevicePath. + + This function opens a file with the open mode according to the file path. The + Attributes is valid only for EFI_FILE_MODE_CREATE. + + @param[in, out] FilePath On input, the device path to the file. + On output, the remaining device path. + @param[out] FileHandle Pointer to the file handle. + @param[in] OpenMode The mode to open the file with. + @param[in] Attributes The file's file attributes. + + @retval EFI_SUCCESS The information was set. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + @retval EFI_UNSUPPORTED Could not open the file path. + @retval EFI_NOT_FOUND The specified file could not be found on the + device or the file system could not be found on + the device. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_MEDIA_CHANGED The device has a different medium in it or the + medium is no longer supported. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED The file or medium is write protected. + @retval EFI_ACCESS_DENIED The file was opened read only. + @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the + file. + @retval EFI_VOLUME_FULL The volume is full. +**/ +EFI_STATUS +EFIAPI +OpenFileByDevicePath ( + IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath, + OUT EFI_FILE_HANDLE *FileHandle, + IN UINT64 OpenMode, + IN UINT64 Attributes + ) +{ + EFI_STATUS Status; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *EfiSimpleFileSystemProtocol; + EFI_FILE_PROTOCOL *Handle1; + EFI_FILE_PROTOCOL *Handle2; + EFI_HANDLE DeviceHandle; + + if ((FilePath == NULL || FileHandle == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Status = gBS->LocateDevicePath ( + &gEfiSimpleFileSystemProtocolGuid, + FilePath, + &DeviceHandle + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = gBS->OpenProtocol( + DeviceHandle, + &gEfiSimpleFileSystemProtocolGuid, + (VOID**)&EfiSimpleFileSystemProtocol, + gImageHandle, + NULL, + EFI_OPEN_PROTOCOL_GET_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + Status = EfiSimpleFileSystemProtocol->OpenVolume(EfiSimpleFileSystemProtocol, &Handle1); + if (EFI_ERROR (Status)) { + FileHandle = NULL; + return Status; + } + + // + // go down directories one node at a time. + // + while (!IsDevicePathEnd (*FilePath)) { + // + // For file system access each node should be a file path component + // + if (DevicePathType (*FilePath) != MEDIA_DEVICE_PATH || + DevicePathSubType (*FilePath) != MEDIA_FILEPATH_DP + ) { + FileHandle = NULL; + return (EFI_INVALID_PARAMETER); + } + // + // Open this file path node + // + Handle2 = Handle1; + Handle1 = NULL; + + // + // Try to test opening an existing file + // + Status = Handle2->Open ( + Handle2, + &Handle1, + ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName, + OpenMode &~EFI_FILE_MODE_CREATE, + 0 + ); + + // + // see if the error was that it needs to be created + // + if ((EFI_ERROR (Status)) && (OpenMode != (OpenMode &~EFI_FILE_MODE_CREATE))) { + Status = Handle2->Open ( + Handle2, + &Handle1, + ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName, + OpenMode, + Attributes + ); + } + // + // Close the last node + // + Handle2->Close (Handle2); + + if (EFI_ERROR(Status)) { + return (Status); + } + + // + // Get the next node + // + *FilePath = NextDevicePathNode (*FilePath); + } + + // + // This is a weak spot since if the undefined SHELL_FILE_HANDLE format changes this must change also! + // + *FileHandle = (VOID*)Handle1; + return EFI_SUCCESS; +} + +/** + This function converts an input device structure to a Unicode string. + + @param[in] DevPath A pointer to the device path structure. + + @return A new allocated Unicode string that represents the device path. + +**/ +CHAR16 * +EFIAPI +DevicePathToStr ( + IN EFI_DEVICE_PATH_PROTOCOL *DevPath + ) +{ + return ConvertDevicePathToText ( + DevPath, + FALSE, + TRUE + ); +} + + +/** + Extract filename from device path. The returned buffer is allocated using AllocateCopyPool. + The caller is responsible for freeing the allocated buffer using FreePool(). If return NULL + means not enough memory resource. + + @param DevicePath Device path. + + @retval NULL Not enough memory resourece for AllocateCopyPool. + @retval Other A new allocated string that represents the file name. + +**/ +CHAR16 * +ExtractFileNameFromDevicePath ( + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath + ) +{ + CHAR16 *String; + CHAR16 *MatchString; + CHAR16 *LastMatch; + CHAR16 *FileName; + UINTN Length; + + ASSERT(DevicePath != NULL); + + String = DevicePathToStr(DevicePath); + MatchString = String; + LastMatch = String; + FileName = NULL; + + while(MatchString != NULL){ + LastMatch = MatchString + 1; + MatchString = StrStr(LastMatch,L"\\"); + } + + Length = StrLen(LastMatch); + FileName = AllocateCopyPool ((Length + 1) * sizeof(CHAR16), LastMatch); + if (FileName != NULL) { + *(FileName + Length) = 0; + } + + FreePool(String); + + return FileName; +} + +/** + Enroll a new X509 certificate into Variable. + + @param[in] PrivateData The module's private data. + @param[in] VariableName Variable name of CA database. + + @retval EFI_SUCCESS New X509 is enrolled successfully. + @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources. + +**/ +EFI_STATUS +EnrollX509toVariable ( + IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private, + IN CHAR16 *VariableName + ) +{ + EFI_STATUS Status; + UINTN X509DataSize; + VOID *X509Data; + EFI_SIGNATURE_LIST *CACert; + EFI_SIGNATURE_DATA *CACertData; + VOID *Data; + UINTN DataSize; + UINTN SigDataSize; + UINT32 Attr; + + X509DataSize = 0; + SigDataSize = 0; + DataSize = 0; + X509Data = NULL; + CACert = NULL; + CACertData = NULL; + Data = NULL; + + Status = ReadFileContent ( + Private->FileContext->FHandle, + &X509Data, + &X509DataSize, + 0 + ); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + ASSERT (X509Data != NULL); + + SigDataSize = sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_SIGNATURE_DATA) - 1 + X509DataSize; + + Data = AllocateZeroPool (SigDataSize); + if (Data == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + // + // Fill Certificate Database parameters. + // + CACert = (EFI_SIGNATURE_LIST*) Data; + CACert->SignatureListSize = (UINT32) SigDataSize; + CACert->SignatureHeaderSize = 0; + CACert->SignatureSize = (UINT32) (sizeof(EFI_SIGNATURE_DATA) - 1 + X509DataSize); + CopyGuid (&CACert->SignatureType, &gEfiCertX509Guid); + + CACertData = (EFI_SIGNATURE_DATA*) ((UINT8* ) CACert + sizeof (EFI_SIGNATURE_LIST)); + CopyGuid (&CACertData->SignatureOwner, Private->CertGuid); + CopyMem ((UINT8* ) (CACertData->SignatureData), X509Data, X509DataSize); + + // + // Check if signature database entry has been already existed. + // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the + // new signature data to original variable + // + Attr = TLS_AUTH_CONFIG_VAR_BASE_ATTR; + + Status = gRT->GetVariable( + VariableName, + &gEfiTlsCaCertificateGuid, + NULL, + &DataSize, + NULL + ); + if (Status == EFI_BUFFER_TOO_SMALL) { + Attr |= EFI_VARIABLE_APPEND_WRITE; + } else if (Status != EFI_NOT_FOUND) { + goto ON_EXIT; + } + + Status = gRT->SetVariable( + VariableName, + &gEfiTlsCaCertificateGuid, + Attr, + SigDataSize, + Data + ); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + +ON_EXIT: + + CloseFile (Private->FileContext->FHandle); + if (Private->FileContext->FileName != NULL) { + FreePool(Private->FileContext->FileName); + Private->FileContext->FileName = NULL; + } + + Private->FileContext->FHandle = NULL; + + if (Private->CertGuid != NULL) { + FreePool (Private->CertGuid); + Private->CertGuid = NULL; + } + + if (Data != NULL) { + FreePool (Data); + } + + if (X509Data != NULL) { + FreePool (X509Data); + } + + return Status; +} + +/** + Enroll Cert into TlsCaCertificate. The GUID will be Private->CertGuid. + + @param[in] PrivateData The module's private data. + @param[in] VariableName Variable name of signature database. + + @retval EFI_SUCCESS New Cert enrolled successfully. + @retval EFI_INVALID_PARAMETER The parameter is invalid. + @retval EFI_UNSUPPORTED The Cert file is unsupported type. + @retval others Fail to enroll Cert data. + +**/ +EFI_STATUS +EnrollCertDatabase ( + IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private, + IN CHAR16 *VariableName + ) +{ + UINT16* FilePostFix; + UINTN NameLength; + + if ((Private->FileContext->FileName == NULL) || (Private->FileContext->FHandle == NULL) || (Private->CertGuid == NULL)) { + return EFI_INVALID_PARAMETER; + } + + // + // Parse the file's postfix. + // + NameLength = StrLen (Private->FileContext->FileName); + if (NameLength <= 4) { + return EFI_INVALID_PARAMETER; + } + FilePostFix = Private->FileContext->FileName + NameLength - 4; + + if (IsDerPemEncodeCertificate (FilePostFix)) { + // + // Supports DER-encoded X509 certificate. + // + return EnrollX509toVariable (Private, VariableName); + } + + return EFI_UNSUPPORTED; +} + +/** + Refresh the global UpdateData structure. + +**/ +VOID +RefreshUpdateData ( + VOID + ) +{ + // + // Free current updated date + // + if (mStartOpCodeHandle != NULL) { + HiiFreeOpCodeHandle (mStartOpCodeHandle); + } + + // + // Create new OpCode Handle + // + mStartOpCodeHandle = HiiAllocateOpCodeHandle (); + + // + // Create Hii Extend Label OpCode as the start opcode + // + mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( + mStartOpCodeHandle, + &gEfiIfrTianoGuid, + NULL, + sizeof (EFI_IFR_GUID_LABEL) + ); + mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; +} + +/** + Clean up the dynamic opcode at label and form specified by both LabelId. + + @param[in] LabelId It is both the Form ID and Label ID for opcode deletion. + @param[in] PrivateData Module private data. + +**/ +VOID +CleanUpPage ( + IN UINT16 LabelId, + IN TLS_AUTH_CONFIG_PRIVATE_DATA *PrivateData + ) +{ + RefreshUpdateData (); + + // + // Remove all op-codes from dynamic page + // + mStartLabel->Number = LabelId; + HiiUpdateForm ( + PrivateData->RegisteredHandle, + &gTlsAuthConfigGuid, + LabelId, + mStartOpCodeHandle, // Label LabelId + mEndOpCodeHandle // LABEL_END + ); +} + +/** + Update the form base on the selected file. + + @param FilePath Point to the file path. + @param FormId The form need to display. + + @retval TRUE Exit caller function. + @retval FALSE Not exit caller function. + +**/ +BOOLEAN +UpdatePage( + IN EFI_DEVICE_PATH_PROTOCOL *FilePath, + IN EFI_FORM_ID FormId + ) +{ + CHAR16 *FileName; + EFI_STRING_ID StringToken; + + FileName = NULL; + + if (FilePath != NULL) { + FileName = ExtractFileNameFromDevicePath(FilePath); + } + if (FileName == NULL) { + // + // FileName = NULL has two case: + // 1. FilePath == NULL, not select file. + // 2. FilePath != NULL, but ExtractFileNameFromDevicePath return NULL not enough memory resource. + // In these two case, no need to update the form, and exit the caller function. + // + return TRUE; + } + StringToken = HiiSetString (mTlsAuthPrivateData->RegisteredHandle, 0, FileName, NULL); + + mTlsAuthPrivateData->FileContext->FileName = FileName; + + OpenFileByDevicePath ( + &FilePath, + &mTlsAuthPrivateData->FileContext->FHandle, + EFI_FILE_MODE_READ, + 0 + ); + // + // Create Subtitle op-code for the display string of the option. + // + RefreshUpdateData (); + mStartLabel->Number = FormId; + + HiiCreateSubTitleOpCode ( + mStartOpCodeHandle, + StringToken, + 0, + 0, + 0 + ); + + HiiUpdateForm ( + mTlsAuthPrivateData->RegisteredHandle, + &gTlsAuthConfigGuid, + FormId, + mStartOpCodeHandle, /// Label FormId + mEndOpCodeHandle /// LABEL_END + ); + + return TRUE; +} + +/** + Update the form base on the input file path info. + + @param FilePath Point to the file path. + + @retval TRUE Exit caller function. + @retval FALSE Not exit caller function. +**/ +BOOLEAN +EFIAPI +UpdateCAFromFile ( + IN EFI_DEVICE_PATH_PROTOCOL *FilePath + ) +{ + return UpdatePage(FilePath, TLS_AUTH_CONFIG_FORMID4_FORM); +} + +/** + Unload the configuration form, this includes: delete all the configuration + entries, uninstall the form callback protocol, and free the resources used. + + @param[in] Private Pointer to the driver private data. + + @retval EFI_SUCCESS The configuration form is unloaded. + @retval Others Failed to unload the form. + +**/ +EFI_STATUS +TlsAuthConfigFormUnload ( + IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private + ) +{ + if (Private->DriverHandle != NULL) { + // + // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL + // + gBS->UninstallMultipleProtocolInterfaces ( + Private->DriverHandle, + &gEfiDevicePathProtocolGuid, + &mTlsAuthConfigHiiVendorDevicePath, + &gEfiHiiConfigAccessProtocolGuid, + &Private->ConfigAccess, + NULL + ); + Private->DriverHandle = NULL; + } + + if (Private->RegisteredHandle != NULL) { + // + // Remove HII package list + // + HiiRemovePackages (Private->RegisteredHandle); + Private->RegisteredHandle = NULL; + } + + if (Private->CertGuid != NULL) { + FreePool (Private->CertGuid); + } + + if (Private->FileContext != NULL) { + FreePool (Private->FileContext); + } + + FreePool (Private); + + if (mStartOpCodeHandle != NULL) { + HiiFreeOpCodeHandle (mStartOpCodeHandle); + } + + if (mEndOpCodeHandle != NULL) { + HiiFreeOpCodeHandle (mEndOpCodeHandle); + } + + return EFI_SUCCESS; +} + + +/** + Initialize the configuration form. + + @param[in] Private Pointer to the driver private data. + + @retval EFI_SUCCESS The configuration form is initialized. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + +**/ +EFI_STATUS +TlsAuthConfigFormInit ( + IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private + ) +{ + EFI_STATUS Status; + + Private->Signature = TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE; + + Private->ConfigAccess.ExtractConfig = TlsAuthConfigAccessExtractConfig; + Private->ConfigAccess.RouteConfig = TlsAuthConfigAccessRouteConfig; + Private->ConfigAccess.Callback = TlsAuthConfigAccessCallback; + + // + // Install Device Path Protocol and Config Access protocol to driver handle. + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &Private->DriverHandle, + &gEfiDevicePathProtocolGuid, + &mTlsAuthConfigHiiVendorDevicePath, + &gEfiHiiConfigAccessProtocolGuid, + &Private->ConfigAccess, + NULL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Publish our HII data. + // + Private->RegisteredHandle = HiiAddPackages ( + &gTlsAuthConfigGuid, + Private->DriverHandle, + TlsAuthConfigDxeStrings, + TlsAuthConfigVfrBin, + NULL + ); + if (Private->RegisteredHandle == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Error; + } + + Private->FileContext = AllocateZeroPool (sizeof (TLS_AUTH_CONFIG_FILE_CONTEXT)); + if (Private->FileContext == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Error; + } + + // + // Init OpCode Handle and Allocate space for creation of Buffer + // + mStartOpCodeHandle = HiiAllocateOpCodeHandle (); + if (mStartOpCodeHandle == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Error; + } + + mEndOpCodeHandle = HiiAllocateOpCodeHandle (); + if (mEndOpCodeHandle == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Error; + } + + // + // Create Hii Extend Label OpCode as the start opcode + // + mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( + mStartOpCodeHandle, + &gEfiIfrTianoGuid, + NULL, + sizeof (EFI_IFR_GUID_LABEL) + ); + mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + + // + // Create Hii Extend Label OpCode as the end opcode + // + mEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode ( + mEndOpCodeHandle, + &gEfiIfrTianoGuid, + NULL, + sizeof (EFI_IFR_GUID_LABEL) + ); + mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; + mEndLabel->Number = LABEL_END; + + return EFI_SUCCESS; + +Error: + TlsAuthConfigFormUnload (Private); + return Status; +} + +/** + + This function allows the caller to request the current + configuration for one or more named elements. The resulting + string is in format. Any and all alternative + configuration strings shall also be appended to the end of the + current configuration string. If they are, they must appear + after the current configuration. They must contain the same + routing (GUID, NAME, PATH) as the current configuration string. + They must have an additional description indicating the type of + alternative configuration the string represents, + "ALTCFG=". That (when + converted from Hex UNICODE to binary) is a reference to a + string in the associated string pack. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + + @param Request A null-terminated Unicode string in + format. Note that this + includes the routing information as well as + the configurable name / value pairs. It is + invalid for this string to be in + format. + If a NULL is passed in for the Request field, + all of the settings being abstracted by this function + will be returned in the Results field. In addition, + if a ConfigHdr is passed in with no request elements, + all of the settings being abstracted for that particular + ConfigHdr reference will be returned in the Results Field. + + @param Progress On return, points to a character in the + Request string. Points to the string's null + terminator if request was successful. Points + to the most recent "&" before the first + failing name / value pair (or the beginning + of the string if the failure is in the first + name / value pair) if the request was not + successful. + + @param Results A null-terminated Unicode string in + format which has all values + filled in for the names in the Request string. + String to be allocated by the called function. + + @retval EFI_SUCCESS The Results string is filled with the + values corresponding to all requested + names. + + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the + parts of the results that must be + stored awaiting possible future + protocols. + + @retval EFI_NOT_FOUND Routing data doesn't match any + known driver. Progress set to the + first character in the routing header. + Note: There is no requirement that the + driver validate the routing data. It + must skip the in order to + process the names. + + @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set + to most recent "&" before the + error or the beginning of the + string. + + @retval EFI_INVALID_PARAMETER Unknown name. Progress points + to the & before the name in + question. + +**/ +EFI_STATUS +EFIAPI +TlsAuthConfigAccessExtractConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Request, + OUT EFI_STRING *Progress, + OUT EFI_STRING *Results + ) +{ + EFI_STATUS Status; + UINTN BufferSize; + UINTN Size; + EFI_STRING ConfigRequest; + EFI_STRING ConfigRequestHdr; + TLS_AUTH_CONFIG_PRIVATE_DATA *Private; + BOOLEAN AllocatedRequest; + + if (Progress == NULL || Results == NULL) { + return EFI_INVALID_PARAMETER; + } + + AllocatedRequest = FALSE; + ConfigRequestHdr = NULL; + ConfigRequest = NULL; + Size = 0; + + Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This); + + BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA); + ZeroMem (&Private->TlsAuthConfigNvData, BufferSize); + + *Progress = Request; + + if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gTlsAuthConfigGuid, mTlsAuthConfigStorageName)) { + return EFI_NOT_FOUND; + } + + ConfigRequest = Request; + if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) { + // + // Request is set to NULL or OFFSET is NULL, construct full request string. + // + // Allocate and fill a buffer large enough to hold the template + // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator + // + ConfigRequestHdr = HiiConstructConfigHdr (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, Private->DriverHandle); + Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16); + ConfigRequest = AllocateZeroPool (Size); + ASSERT (ConfigRequest != NULL); + AllocatedRequest = TRUE; + UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize); + FreePool (ConfigRequestHdr); + ConfigRequestHdr = NULL; + } + + Status = gHiiConfigRouting->BlockToConfig ( + gHiiConfigRouting, + ConfigRequest, + (UINT8 *) &Private->TlsAuthConfigNvData, + BufferSize, + Results, + Progress + ); + + // + // Free the allocated config request string. + // + if (AllocatedRequest) { + FreePool (ConfigRequest); + } + + // + // Set Progress string to the original request string. + // + if (Request == NULL) { + *Progress = NULL; + } else if (StrStr (Request, L"OFFSET") == NULL) { + *Progress = Request + StrLen (Request); + } + + return Status; +} + +/** + + This function applies changes in a driver's configuration. + Input is a Configuration, which has the routing data for this + driver followed by name / value configuration pairs. The driver + must apply those pairs to its configurable storage. If the + driver's configuration is stored in a linear block of data + and the driver's name / value pairs are in + format, it may use the ConfigToBlock helper function (above) to + simplify the job. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + + @param Configuration A null-terminated Unicode string in + format. + + @param Progress A pointer to a string filled in with the + offset of the most recent '&' before the + first failing name / value pair (or the + beginn ing of the string if the failure + is in the first name / value pair) or + the terminating NULL if all was + successful. + + @retval EFI_SUCCESS The results have been distributed or are + awaiting distribution. + + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the + parts of the results that must be + stored awaiting possible future + protocols. + + @retval EFI_INVALID_PARAMETERS Passing in a NULL for the + Results parameter would result + in this type of error. + + @retval EFI_NOT_FOUND Target for the specified routing data + was not found + +**/ +EFI_STATUS +EFIAPI +TlsAuthConfigAccessRouteConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Configuration, + OUT EFI_STRING *Progress + ) +{ + EFI_STATUS Status; + UINTN BufferSize; + TLS_AUTH_CONFIG_PRIVATE_DATA *Private; + + if (Progress == NULL) { + return EFI_INVALID_PARAMETER; + } + *Progress = Configuration; + + if (Configuration == NULL) { + return EFI_INVALID_PARAMETER; + } + + // + // Check routing data in . + // Note: there is no name for Name/Value storage, only GUID will be checked + // + if (!HiiIsConfigHdrMatch (Configuration, &gTlsAuthConfigGuid, mTlsAuthConfigStorageName)) { + return EFI_NOT_FOUND; + } + + Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This); + + BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA); + ZeroMem (&Private->TlsAuthConfigNvData, BufferSize); + + Status = gHiiConfigRouting->ConfigToBlock ( + gHiiConfigRouting, + Configuration, + (UINT8 *) &Private->TlsAuthConfigNvData, + &BufferSize, + Progress + ); + if (EFI_ERROR (Status)) { + return Status; + } + + return Status; +} + +/** + + This function is called to provide results data to the driver. + This data consists of a unique key that is used to identify + which data is either being passed back or being asked for. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param Action Specifies the type of action taken by the browser. + @param QuestionId A unique value which is sent to the original + exporting driver so that it can identify the type + of data to expect. The format of the data tends to + vary based on the opcode that generated the callback. + @param Type The type of value for the question. + @param Value A pointer to the data being sent to the original + exporting driver. + @param ActionRequest On return, points to the action requested by the + callback function. + + @retval EFI_SUCCESS The callback successfully handled the action. + @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the + variable and its data. + @retval EFI_DEVICE_ERROR The variable could not be saved. + @retval EFI_UNSUPPORTED The specified Action is not supported by the + callback. +**/ +EFI_STATUS +EFIAPI +TlsAuthConfigAccessCallback ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN EFI_BROWSER_ACTION Action, + IN EFI_QUESTION_ID QuestionId, + IN UINT8 Type, + IN OUT EFI_IFR_TYPE_VALUE *Value, + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest + ) +{ + EFI_INPUT_KEY Key; + EFI_STATUS Status; + RETURN_STATUS RStatus; + TLS_AUTH_CONFIG_PRIVATE_DATA *Private; + UINTN BufferSize; + TLS_AUTH_CONFIG_IFR_NVDATA *IfrNvData; + UINT16 LabelId; + EFI_DEVICE_PATH_PROTOCOL *File; + + Status = EFI_SUCCESS; + File = NULL; + + if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) { + return EFI_INVALID_PARAMETER; + } + + Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This); + + mTlsAuthPrivateData = Private; + + // + // Retrieve uncommitted data from Browser + // + BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA); + IfrNvData = AllocateZeroPool (BufferSize); + if (IfrNvData == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + HiiGetBrowserData (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, BufferSize, (UINT8 *) IfrNvData); + + if ((Action != EFI_BROWSER_ACTION_CHANGED) && + (Action != EFI_BROWSER_ACTION_CHANGING)) { + Status = EFI_UNSUPPORTED; + goto EXIT; + } + + if (Action == EFI_BROWSER_ACTION_CHANGING) { + switch (QuestionId) { + case KEY_TLS_AUTH_CONFIG_CLIENT_CERT: + case KEY_TLS_AUTH_CONFIG_SERVER_CA: + // + // Clear Cert GUID. + // + ZeroMem (IfrNvData->CertGuid, sizeof (IfrNvData->CertGuid)); + if (Private->CertGuid == NULL) { + Private->CertGuid = (EFI_GUID *) AllocateZeroPool (sizeof (EFI_GUID)); + if (Private->CertGuid == NULL) { + return EFI_OUT_OF_RESOURCES; + } + } + if (QuestionId == KEY_TLS_AUTH_CONFIG_CLIENT_CERT) { + LabelId = TLS_AUTH_CONFIG_FORMID3_FORM; + } else { + LabelId = TLS_AUTH_CONFIG_FORMID4_FORM; + } + + // + // Refresh selected file. + // + CleanUpPage (LabelId, Private); + break; + case KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE: + ChooseFile( NULL, NULL, UpdateCAFromFile, &File); + break; + + case KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT: + Status = EnrollCertDatabase (Private, EFI_TLS_CA_CERTIFICATE_VARIABLE); + if (EFI_ERROR (Status)) { + CreatePopUp ( + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, + &Key, + L"ERROR: Enroll Cert Failure!", + NULL + ); + } + break; + + case KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT: + if (Private->FileContext->FHandle != NULL) { + CloseFile (Private->FileContext->FHandle); + Private->FileContext->FHandle = NULL; + if (Private->FileContext->FileName!= NULL){ + FreePool(Private->FileContext->FileName); + Private->FileContext->FileName = NULL; + } + } + + if (Private->CertGuid!= NULL) { + FreePool (Private->CertGuid); + Private->CertGuid = NULL; + } + break; + + case KEY_TLS_AUTH_CONFIG_DELETE_CERT: + UpdateDeletePage ( + Private, + EFI_TLS_CA_CERTIFICATE_VARIABLE, + &gEfiTlsCaCertificateGuid, + LABEL_CA_DELETE, + TLS_AUTH_CONFIG_FORMID5_FORM, + OPTION_DEL_CA_ESTION_ID + ); + break; + + default: + if ((QuestionId >= OPTION_DEL_CA_ESTION_ID) && + (QuestionId < (OPTION_DEL_CA_ESTION_ID + OPTION_CONFIG_RANGE))) { + DeleteCert ( + Private, + EFI_TLS_CA_CERTIFICATE_VARIABLE, + &gEfiTlsCaCertificateGuid, + LABEL_CA_DELETE, + TLS_AUTH_CONFIG_FORMID5_FORM, + OPTION_DEL_CA_ESTION_ID, + QuestionId - OPTION_DEL_CA_ESTION_ID + ); + } + break; + } + } else if (Action == EFI_BROWSER_ACTION_CHANGED) { + switch (QuestionId) { + case KEY_TLS_AUTH_CONFIG_CERT_GUID: + ASSERT (Private->CertGuid != NULL); + RStatus = StrToGuid ( + IfrNvData->CertGuid, + Private->CertGuid + ); + if (RETURN_ERROR (RStatus) || (IfrNvData->CertGuid[GUID_STRING_LENGTH] != L'\0')) { + Status = EFI_INVALID_PARAMETER; + break; + } + + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY; + break; + default: + break; + } + } + +EXIT: + + if (!EFI_ERROR (Status)) { + BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA); + HiiSetBrowserData (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, BufferSize, (UINT8*) IfrNvData, NULL); + } + + FreePool (IfrNvData); + + if (File != NULL){ + FreePool(File); + File = NULL; + } + + return EFI_SUCCESS; + +} + diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h index 398f7b6eea..f50d60d269 100644 --- a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h @@ -1,282 +1,282 @@ -/** @file - Header file of Miscellaneous Routines for TlsAuthConfigDxe driver. - -Copyright (c) 2016, Intel Corporation. All rights reserved.
- -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. - -**/ - -#ifndef __TLS_AUTH_CONFIG_IMPL_H__ -#define __TLS_AUTH_CONFIG_IMPL_H__ - -#include - -#include -#include - -// -// Libraries -// -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - - -// -// Include files with function prototypes -// -#include "TlsAuthConfigNvData.h" - -extern UINT8 TlsAuthConfigDxeStrings[]; -extern UINT8 TlsAuthConfigVfrBin[]; - -#define TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('T', 'A', 'C', 'D') -#define TLS_AUTH_CONFIG_PRIVATE_FROM_THIS(a) CR (a, TLS_AUTH_CONFIG_PRIVATE_DATA, ConfigAccess, TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE) - -#define TLS_AUTH_CONFIG_VAR_BASE_ATTR (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS) - -typedef struct _TLS_AUTH_CONFIG_PRIVATE_DATA TLS_AUTH_CONFIG_PRIVATE_DATA; -typedef struct _TLS_AUTH_CONFIG_FILE_CONTEXT TLS_AUTH_CONFIG_FILE_CONTEXT; - -/// -/// HII specific Vendor Device Path definition. -/// -typedef struct { - VENDOR_DEVICE_PATH VendorDevicePath; - EFI_DEVICE_PATH_PROTOCOL End; -} HII_VENDOR_DEVICE_PATH; - -struct _TLS_AUTH_CONFIG_FILE_CONTEXT { - EFI_FILE_HANDLE FHandle; - UINT16 *FileName; -}; - -struct _TLS_AUTH_CONFIG_PRIVATE_DATA { - UINTN Signature; - - EFI_HANDLE DriverHandle; - EFI_HII_HANDLE RegisteredHandle; - EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess; - TLS_AUTH_CONFIG_IFR_NVDATA TlsAuthConfigNvData; - - TLS_AUTH_CONFIG_FILE_CONTEXT *FileContext; - - EFI_GUID *CertGuid; -}; - -/** - Unload the configuration form, this includes: delete all the configuration - entries, uninstall the form callback protocol, and free the resources used. - The form will only be unload completely when both IP4 and IP6 stack are stopped. - - @param[in] Private Pointer to the driver private data. - - @retval EFI_SUCCESS The configuration form is unloaded. - @retval Others Failed to unload the form. - -**/ -EFI_STATUS -TlsAuthConfigFormUnload ( - IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private - ); - -/** - Initialize the configuration form. - - @param[in] Private Pointer to the driver private data. - - @retval EFI_SUCCESS The configuration form is initialized. - @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. - -**/ -EFI_STATUS -TlsAuthConfigFormInit ( - IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private - ); - -/** - - This function allows the caller to request the current - configuration for one or more named elements. The resulting - string is in format. Any and all alternative - configuration strings shall also be appended to the end of the - current configuration string. If they are, they must appear - after the current configuration. They must contain the same - routing (GUID, NAME, PATH) as the current configuration string. - They must have an additional description indicating the type of - alternative configuration the string represents, - "ALTCFG=". That (when - converted from Hex UNICODE to binary) is a reference to a - string in the associated string pack. - - @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. - - @param Request A null-terminated Unicode string in - format. Note that this - includes the routing information as well as - the configurable name / value pairs. It is - invalid for this string to be in - format. - If a NULL is passed in for the Request field, - all of the settings being abstracted by this function - will be returned in the Results field. In addition, - if a ConfigHdr is passed in with no request elements, - all of the settings being abstracted for that particular - ConfigHdr reference will be returned in the Results Field. - - @param Progress On return, points to a character in the - Request string. Points to the string's null - terminator if request was successful. Points - to the most recent "&" before the first - failing name / value pair (or the beginning - of the string if the failure is in the first - name / value pair) if the request was not - successful. - - @param Results A null-terminated Unicode string in - format which has all values - filled in for the names in the Request string. - String to be allocated by the called function. - - @retval EFI_SUCCESS The Results string is filled with the - values corresponding to all requested - names. - - @retval EFI_OUT_OF_RESOURCES Not enough memory to store the - parts of the results that must be - stored awaiting possible future - protocols. - - @retval EFI_NOT_FOUND Routing data doesn't match any - known driver. Progress set to the - first character in the routing header. - Note: There is no requirement that the - driver validate the routing data. It - must skip the in order to - process the names. - - @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set - to most recent "&" before the - error or the beginning of the - string. - - @retval EFI_INVALID_PARAMETER Unknown name. Progress points - to the & before the name in - question. - -**/ -EFI_STATUS -EFIAPI -TlsAuthConfigAccessExtractConfig ( - IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, - IN CONST EFI_STRING Request, - OUT EFI_STRING *Progress, - OUT EFI_STRING *Results - ); - -/** - - This function applies changes in a driver's configuration. - Input is a Configuration, which has the routing data for this - driver followed by name / value configuration pairs. The driver - must apply those pairs to its configurable storage. If the - driver's configuration is stored in a linear block of data - and the driver's name / value pairs are in - format, it may use the ConfigToBlock helper function (above) to - simplify the job. - - @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. - - @param Configuration A null-terminated Unicode string in - format. - - @param Progress A pointer to a string filled in with the - offset of the most recent '&' before the - first failing name / value pair (or the - beginn ing of the string if the failure - is in the first name / value pair) or - the terminating NULL if all was - successful. - - @retval EFI_SUCCESS The results have been distributed or are - awaiting distribution. - - @retval EFI_OUT_OF_RESOURCES Not enough memory to store the - parts of the results that must be - stored awaiting possible future - protocols. - - @retval EFI_INVALID_PARAMETERS Passing in a NULL for the - Results parameter would result - in this type of error. - - @retval EFI_NOT_FOUND Target for the specified routing data - was not found - -**/ -EFI_STATUS -EFIAPI -TlsAuthConfigAccessRouteConfig ( - IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, - IN CONST EFI_STRING Configuration, - OUT EFI_STRING *Progress - ); - -/** - - This function is called to provide results data to the driver. - This data consists of a unique key that is used to identify - which data is either being passed back or being asked for. - - @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. - @param Action Specifies the type of action taken by the browser. - @param QuestionId A unique value which is sent to the original - exporting driver so that it can identify the type - of data to expect. The format of the data tends to - vary based on the opcode that generated the callback. - @param Type The type of value for the question. - @param Value A pointer to the data being sent to the original - exporting driver. - @param ActionRequest On return, points to the action requested by the - callback function. - - @retval EFI_SUCCESS The callback successfully handled the action. - @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the - variable and its data. - @retval EFI_DEVICE_ERROR The variable could not be saved. - @retval EFI_UNSUPPORTED The specified Action is not supported by the - callback. -**/ -EFI_STATUS -EFIAPI -TlsAuthConfigAccessCallback ( - IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, - IN EFI_BROWSER_ACTION Action, - IN EFI_QUESTION_ID QuestionId, - IN UINT8 Type, - IN OUT EFI_IFR_TYPE_VALUE *Value, - OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest - ); - -#endif - +/** @file + Header file of Miscellaneous Routines for TlsAuthConfigDxe driver. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+ +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. + +**/ + +#ifndef __TLS_AUTH_CONFIG_IMPL_H__ +#define __TLS_AUTH_CONFIG_IMPL_H__ + +#include + +#include +#include + +// +// Libraries +// +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +// +// Include files with function prototypes +// +#include "TlsAuthConfigNvData.h" + +extern UINT8 TlsAuthConfigDxeStrings[]; +extern UINT8 TlsAuthConfigVfrBin[]; + +#define TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('T', 'A', 'C', 'D') +#define TLS_AUTH_CONFIG_PRIVATE_FROM_THIS(a) CR (a, TLS_AUTH_CONFIG_PRIVATE_DATA, ConfigAccess, TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE) + +#define TLS_AUTH_CONFIG_VAR_BASE_ATTR (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS) + +typedef struct _TLS_AUTH_CONFIG_PRIVATE_DATA TLS_AUTH_CONFIG_PRIVATE_DATA; +typedef struct _TLS_AUTH_CONFIG_FILE_CONTEXT TLS_AUTH_CONFIG_FILE_CONTEXT; + +/// +/// HII specific Vendor Device Path definition. +/// +typedef struct { + VENDOR_DEVICE_PATH VendorDevicePath; + EFI_DEVICE_PATH_PROTOCOL End; +} HII_VENDOR_DEVICE_PATH; + +struct _TLS_AUTH_CONFIG_FILE_CONTEXT { + EFI_FILE_HANDLE FHandle; + UINT16 *FileName; +}; + +struct _TLS_AUTH_CONFIG_PRIVATE_DATA { + UINTN Signature; + + EFI_HANDLE DriverHandle; + EFI_HII_HANDLE RegisteredHandle; + EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess; + TLS_AUTH_CONFIG_IFR_NVDATA TlsAuthConfigNvData; + + TLS_AUTH_CONFIG_FILE_CONTEXT *FileContext; + + EFI_GUID *CertGuid; +}; + +/** + Unload the configuration form, this includes: delete all the configuration + entries, uninstall the form callback protocol, and free the resources used. + The form will only be unload completely when both IP4 and IP6 stack are stopped. + + @param[in] Private Pointer to the driver private data. + + @retval EFI_SUCCESS The configuration form is unloaded. + @retval Others Failed to unload the form. + +**/ +EFI_STATUS +TlsAuthConfigFormUnload ( + IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private + ); + +/** + Initialize the configuration form. + + @param[in] Private Pointer to the driver private data. + + @retval EFI_SUCCESS The configuration form is initialized. + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory. + +**/ +EFI_STATUS +TlsAuthConfigFormInit ( + IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private + ); + +/** + + This function allows the caller to request the current + configuration for one or more named elements. The resulting + string is in format. Any and all alternative + configuration strings shall also be appended to the end of the + current configuration string. If they are, they must appear + after the current configuration. They must contain the same + routing (GUID, NAME, PATH) as the current configuration string. + They must have an additional description indicating the type of + alternative configuration the string represents, + "ALTCFG=". That (when + converted from Hex UNICODE to binary) is a reference to a + string in the associated string pack. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + + @param Request A null-terminated Unicode string in + format. Note that this + includes the routing information as well as + the configurable name / value pairs. It is + invalid for this string to be in + format. + If a NULL is passed in for the Request field, + all of the settings being abstracted by this function + will be returned in the Results field. In addition, + if a ConfigHdr is passed in with no request elements, + all of the settings being abstracted for that particular + ConfigHdr reference will be returned in the Results Field. + + @param Progress On return, points to a character in the + Request string. Points to the string's null + terminator if request was successful. Points + to the most recent "&" before the first + failing name / value pair (or the beginning + of the string if the failure is in the first + name / value pair) if the request was not + successful. + + @param Results A null-terminated Unicode string in + format which has all values + filled in for the names in the Request string. + String to be allocated by the called function. + + @retval EFI_SUCCESS The Results string is filled with the + values corresponding to all requested + names. + + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the + parts of the results that must be + stored awaiting possible future + protocols. + + @retval EFI_NOT_FOUND Routing data doesn't match any + known driver. Progress set to the + first character in the routing header. + Note: There is no requirement that the + driver validate the routing data. It + must skip the in order to + process the names. + + @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set + to most recent "&" before the + error or the beginning of the + string. + + @retval EFI_INVALID_PARAMETER Unknown name. Progress points + to the & before the name in + question. + +**/ +EFI_STATUS +EFIAPI +TlsAuthConfigAccessExtractConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Request, + OUT EFI_STRING *Progress, + OUT EFI_STRING *Results + ); + +/** + + This function applies changes in a driver's configuration. + Input is a Configuration, which has the routing data for this + driver followed by name / value configuration pairs. The driver + must apply those pairs to its configurable storage. If the + driver's configuration is stored in a linear block of data + and the driver's name / value pairs are in + format, it may use the ConfigToBlock helper function (above) to + simplify the job. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + + @param Configuration A null-terminated Unicode string in + format. + + @param Progress A pointer to a string filled in with the + offset of the most recent '&' before the + first failing name / value pair (or the + beginn ing of the string if the failure + is in the first name / value pair) or + the terminating NULL if all was + successful. + + @retval EFI_SUCCESS The results have been distributed or are + awaiting distribution. + + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the + parts of the results that must be + stored awaiting possible future + protocols. + + @retval EFI_INVALID_PARAMETERS Passing in a NULL for the + Results parameter would result + in this type of error. + + @retval EFI_NOT_FOUND Target for the specified routing data + was not found + +**/ +EFI_STATUS +EFIAPI +TlsAuthConfigAccessRouteConfig ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN CONST EFI_STRING Configuration, + OUT EFI_STRING *Progress + ); + +/** + + This function is called to provide results data to the driver. + This data consists of a unique key that is used to identify + which data is either being passed back or being asked for. + + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. + @param Action Specifies the type of action taken by the browser. + @param QuestionId A unique value which is sent to the original + exporting driver so that it can identify the type + of data to expect. The format of the data tends to + vary based on the opcode that generated the callback. + @param Type The type of value for the question. + @param Value A pointer to the data being sent to the original + exporting driver. + @param ActionRequest On return, points to the action requested by the + callback function. + + @retval EFI_SUCCESS The callback successfully handled the action. + @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the + variable and its data. + @retval EFI_DEVICE_ERROR The variable could not be saved. + @retval EFI_UNSUPPORTED The specified Action is not supported by the + callback. +**/ +EFI_STATUS +EFIAPI +TlsAuthConfigAccessCallback ( + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, + IN EFI_BROWSER_ACTION Action, + IN EFI_QUESTION_ID QuestionId, + IN UINT8 Type, + IN OUT EFI_IFR_TYPE_VALUE *Value, + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest + ); + +#endif + diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h index f453201cb7..80baa3836f 100644 --- a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h @@ -1,49 +1,50 @@ -/** @file - Header file for NV data structure definition. - -Copyright (c) 2016, Intel Corporation. All rights reserved.
-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. - -**/ - -#ifndef __TLS_AUTH_CONFIG_NV_DATA_H__ -#define __TLS_AUTH_CONFIG_NV_DATA_H__ - -#include - -#define TLS_AUTH_CONFIG_GUID_SIZE 36 -#define TLS_AUTH_CONFIG_GUID_STORAGE_SIZE 37 - -#define TLS_AUTH_CONFIG_FORMID1_FORM 1 -#define TLS_AUTH_CONFIG_FORMID2_FORM 2 -#define TLS_AUTH_CONFIG_FORMID3_FORM 3 -#define TLS_AUTH_CONFIG_FORMID4_FORM 4 -#define TLS_AUTH_CONFIG_FORMID5_FORM 5 - - -#define KEY_TLS_AUTH_CONFIG_SERVER_CA 0x1000 -#define KEY_TLS_AUTH_CONFIG_CLIENT_CERT 0x1001 -#define KEY_TLS_AUTH_CONFIG_ENROLL_CERT 0x1002 -#define KEY_TLS_AUTH_CONFIG_DELETE_CERT 0x1003 -#define KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE 0x1004 -#define KEY_TLS_AUTH_CONFIG_CERT_GUID 0x1005 -#define KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT 0x1006 -#define KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT 0x1007 - -#define OPTION_DEL_CA_ESTION_ID 0x2000 -#define OPTION_CONFIG_RANGE 0x1000 - -#define LABEL_CA_DELETE 0x1101 -#define LABEL_END 0xffff - -typedef struct { - CHAR16 CertGuid[TLS_AUTH_CONFIG_GUID_STORAGE_SIZE]; -} TLS_AUTH_CONFIG_IFR_NVDATA; - -#endif +/** @file + Header file for NV data structure definition. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+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. + +**/ + +#ifndef __TLS_AUTH_CONFIG_NV_DATA_H__ +#define __TLS_AUTH_CONFIG_NV_DATA_H__ + +#include + +#define TLS_AUTH_CONFIG_GUID_SIZE 36 +#define TLS_AUTH_CONFIG_GUID_STORAGE_SIZE 37 + +#define TLS_AUTH_CONFIG_FORMID1_FORM 1 +#define TLS_AUTH_CONFIG_FORMID2_FORM 2 +#define TLS_AUTH_CONFIG_FORMID3_FORM 3 +#define TLS_AUTH_CONFIG_FORMID4_FORM 4 +#define TLS_AUTH_CONFIG_FORMID5_FORM 5 + + +#define KEY_TLS_AUTH_CONFIG_SERVER_CA 0x1000 +#define KEY_TLS_AUTH_CONFIG_CLIENT_CERT 0x1001 +#define KEY_TLS_AUTH_CONFIG_ENROLL_CERT 0x1002 +#define KEY_TLS_AUTH_CONFIG_DELETE_CERT 0x1003 +#define KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE 0x1004 +#define KEY_TLS_AUTH_CONFIG_CERT_GUID 0x1005 +#define KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT 0x1006 +#define KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT 0x1007 + +#define OPTION_DEL_CA_ESTION_ID 0x2000 +#define OPTION_CONFIG_RANGE 0x1000 + +#define LABEL_CA_DELETE 0x1101 +#define LABEL_END 0xffff + +typedef struct { + CHAR16 CertGuid[TLS_AUTH_CONFIG_GUID_STORAGE_SIZE]; +} TLS_AUTH_CONFIG_IFR_NVDATA; + +#endif + diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr index fb130d9d9d..9bca2c119f 100644 --- a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr @@ -1,152 +1,153 @@ -/** @file - VFR file used by TlsAuthConfigDxe driver. - - Copyright (c) 2016, Intel Corporation. All rights reserved.
- - 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 "TlsAuthConfigNvData.h" - -formset - guid = TLS_AUTH_CONFIG_GUID, - title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_TITLE), - help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_HELP), - - varstore TLS_AUTH_CONFIG_IFR_NVDATA, - name = TLS_AUTH_CONFIG_IFR_NVDATA, - guid = TLS_AUTH_CONFIG_GUID; - - // - // ##1 Form1: Main form for Tls Auth configration - // - form formid = TLS_AUTH_CONFIG_FORMID1_FORM, - title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_TITLE); - - subtitle text = STRING_TOKEN(STR_NULL); - - // - // Display Server CA configration - // - goto TLS_AUTH_CONFIG_FORMID2_FORM, - prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SERVER_CA), - help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SERVER_CA_HELP), - flags = INTERACTIVE, - key = KEY_TLS_AUTH_CONFIG_SERVER_CA; - - subtitle text = STRING_TOKEN(STR_NULL); - - // - // Display Client cert configration - // - grayoutif TRUE; /// Current unsupported. - goto TLS_AUTH_CONFIG_FORMID3_FORM, - prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CLIENT_CERT), - help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CLIENT_CERT_HELP), - flags = INTERACTIVE, - key = KEY_TLS_AUTH_CONFIG_CLIENT_CERT; - endif; - endform; - - // - // ##2 Form2: CA configuration - // - form formid = TLS_AUTH_CONFIG_FORMID2_FORM, - title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SERVER_CA); - - subtitle text = STRING_TOKEN(STR_NULL); - - goto TLS_AUTH_CONFIG_FORMID4_FORM, - prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ENROLL_CERT), - help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ENROLL_CERT_HELP), - flags = INTERACTIVE, - key = KEY_TLS_AUTH_CONFIG_ENROLL_CERT; - - subtitle text = STRING_TOKEN(STR_NULL); - - goto TLS_AUTH_CONFIG_FORMID5_FORM, - prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_DELETE_CERT), - help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_DELETE_CERT_HELP), - flags = INTERACTIVE, - key = KEY_TLS_AUTH_CONFIG_DELETE_CERT; - endform; - - // - // ##3 Form3 : Client cert configuration - // - form formid = TLS_AUTH_CONFIG_FORMID3_FORM, - title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CLIENT_CERT); - - subtitle text = STRING_TOKEN(STR_NULL); - - // - // TODO... - // - endform; - - // - // ##4 Form4: Enroll cert for CA - // - form formid = TLS_AUTH_CONFIG_FORMID4_FORM, - title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ENROLL_CERT); - - subtitle text = STRING_TOKEN(STR_NULL); - - goto TLS_AUTH_CONFIG_FORMID4_FORM, - prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ADD_CERT_FILE), - help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ADD_CERT_FILE), - flags = INTERACTIVE, - key = KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE; - - subtitle text = STRING_TOKEN(STR_NULL); - label TLS_AUTH_CONFIG_FORMID4_FORM; - label LABEL_END; - subtitle text = STRING_TOKEN(STR_NULL); - - string varid = TLS_AUTH_CONFIG_IFR_NVDATA.CertGuid, - prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CERT_GUID), - help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CERT_GUID_HELP), - flags = INTERACTIVE, - key = KEY_TLS_AUTH_CONFIG_CERT_GUID, - minsize = TLS_AUTH_CONFIG_GUID_SIZE, - maxsize = TLS_AUTH_CONFIG_GUID_SIZE, - endstring; - - subtitle text = STRING_TOKEN(STR_NULL); - subtitle text = STRING_TOKEN(STR_NULL); - - goto TLS_AUTH_CONFIG_FORMID1_FORM, - prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SAVE_AND_EXIT), - help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SAVE_AND_EXIT), - flags = INTERACTIVE, - key = KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT; - - goto TLS_AUTH_CONFIG_FORMID1_FORM, - prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_NO_SAVE_AND_EXIT), - help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_NO_SAVE_AND_EXIT), - flags = INTERACTIVE, - key = KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT; - - endform; - - // - // ##5 Form5: Delete cert for CA - // - form formid = TLS_AUTH_CONFIG_FORMID5_FORM, - title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_DELETE_CERT); - - label LABEL_CA_DELETE; - label LABEL_END; - - subtitle text = STRING_TOKEN(STR_NULL); - - endform; - -endformset; +/** @file + VFR file used by TlsAuthConfigDxe driver. + + Copyright (c) 2016, Intel Corporation. All rights reserved.
+ + 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 "TlsAuthConfigNvData.h" + +formset + guid = TLS_AUTH_CONFIG_GUID, + title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_TITLE), + help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_HELP), + + varstore TLS_AUTH_CONFIG_IFR_NVDATA, + name = TLS_AUTH_CONFIG_IFR_NVDATA, + guid = TLS_AUTH_CONFIG_GUID; + + // + // ##1 Form1: Main form for Tls Auth configration + // + form formid = TLS_AUTH_CONFIG_FORMID1_FORM, + title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_TITLE); + + subtitle text = STRING_TOKEN(STR_NULL); + + // + // Display Server CA configration + // + goto TLS_AUTH_CONFIG_FORMID2_FORM, + prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SERVER_CA), + help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SERVER_CA_HELP), + flags = INTERACTIVE, + key = KEY_TLS_AUTH_CONFIG_SERVER_CA; + + subtitle text = STRING_TOKEN(STR_NULL); + + // + // Display Client cert configration + // + grayoutif TRUE; /// Current unsupported. + goto TLS_AUTH_CONFIG_FORMID3_FORM, + prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CLIENT_CERT), + help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CLIENT_CERT_HELP), + flags = INTERACTIVE, + key = KEY_TLS_AUTH_CONFIG_CLIENT_CERT; + endif; + endform; + + // + // ##2 Form2: CA configuration + // + form formid = TLS_AUTH_CONFIG_FORMID2_FORM, + title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SERVER_CA); + + subtitle text = STRING_TOKEN(STR_NULL); + + goto TLS_AUTH_CONFIG_FORMID4_FORM, + prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ENROLL_CERT), + help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ENROLL_CERT_HELP), + flags = INTERACTIVE, + key = KEY_TLS_AUTH_CONFIG_ENROLL_CERT; + + subtitle text = STRING_TOKEN(STR_NULL); + + goto TLS_AUTH_CONFIG_FORMID5_FORM, + prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_DELETE_CERT), + help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_DELETE_CERT_HELP), + flags = INTERACTIVE, + key = KEY_TLS_AUTH_CONFIG_DELETE_CERT; + endform; + + // + // ##3 Form3 : Client cert configuration + // + form formid = TLS_AUTH_CONFIG_FORMID3_FORM, + title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CLIENT_CERT); + + subtitle text = STRING_TOKEN(STR_NULL); + + // + // TODO... + // + endform; + + // + // ##4 Form4: Enroll cert for CA + // + form formid = TLS_AUTH_CONFIG_FORMID4_FORM, + title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ENROLL_CERT); + + subtitle text = STRING_TOKEN(STR_NULL); + + goto TLS_AUTH_CONFIG_FORMID4_FORM, + prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ADD_CERT_FILE), + help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ADD_CERT_FILE), + flags = INTERACTIVE, + key = KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE; + + subtitle text = STRING_TOKEN(STR_NULL); + label TLS_AUTH_CONFIG_FORMID4_FORM; + label LABEL_END; + subtitle text = STRING_TOKEN(STR_NULL); + + string varid = TLS_AUTH_CONFIG_IFR_NVDATA.CertGuid, + prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CERT_GUID), + help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CERT_GUID_HELP), + flags = INTERACTIVE, + key = KEY_TLS_AUTH_CONFIG_CERT_GUID, + minsize = TLS_AUTH_CONFIG_GUID_SIZE, + maxsize = TLS_AUTH_CONFIG_GUID_SIZE, + endstring; + + subtitle text = STRING_TOKEN(STR_NULL); + subtitle text = STRING_TOKEN(STR_NULL); + + goto TLS_AUTH_CONFIG_FORMID1_FORM, + prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SAVE_AND_EXIT), + help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SAVE_AND_EXIT), + flags = INTERACTIVE, + key = KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT; + + goto TLS_AUTH_CONFIG_FORMID1_FORM, + prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_NO_SAVE_AND_EXIT), + help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_NO_SAVE_AND_EXIT), + flags = INTERACTIVE, + key = KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT; + + endform; + + // + // ##5 Form5: Delete cert for CA + // + form formid = TLS_AUTH_CONFIG_FORMID5_FORM, + title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_DELETE_CERT); + + label LABEL_CA_DELETE; + label LABEL_END; + + subtitle text = STRING_TOKEN(STR_NULL); + + endform; + +endformset; + diff --git a/NetworkPkg/TlsDxe/TlsConfigProtocol.c b/NetworkPkg/TlsDxe/TlsConfigProtocol.c index 5292433da3..15a865e386 100644 --- a/NetworkPkg/TlsDxe/TlsConfigProtocol.c +++ b/NetworkPkg/TlsDxe/TlsConfigProtocol.c @@ -1,152 +1,153 @@ -/** @file - Implementation of EFI TLS Configuration Protocol Interfaces. - - Copyright (c) 2016, Intel Corporation. All rights reserved.
- - 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 "TlsImpl.h" - -EFI_TLS_CONFIGURATION_PROTOCOL mTlsConfigurationProtocol = { - TlsConfigurationSetData, - TlsConfigurationGetData -}; - -/** - Set TLS configuration data. - - The SetData() function sets TLS configuration to non-volatile storage or volatile - storage. - - @param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance. - @param[in] DataType Configuration data type. - @param[in] Data Pointer to configuration data. - @param[in] DataSize Total size of configuration data. - - @retval EFI_SUCCESS The TLS configuration data is set successfully. - @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - Data is NULL. - DataSize is 0. - @retval EFI_UNSUPPORTED The DataType is unsupported. - @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. - -**/ -EFI_STATUS -EFIAPI -TlsConfigurationSetData ( - IN EFI_TLS_CONFIGURATION_PROTOCOL *This, - IN EFI_TLS_CONFIG_DATA_TYPE DataType, - IN VOID *Data, - IN UINTN DataSize - ) -{ - EFI_STATUS Status; - TLS_INSTANCE *Instance; - EFI_TPL OldTpl; - - Status = EFI_SUCCESS; - - if (This == NULL || Data == NULL || DataSize == 0) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Instance = TLS_INSTANCE_FROM_CONFIGURATION (This); - - switch (DataType) { - case EfiTlsConfigDataTypeCACertificate: - Status = TlsSetCaCertificate (Instance->TlsConn, Data, DataSize); - break; - case EfiTlsConfigDataTypeHostPublicCert: - Status = TlsSetHostPublicCert (Instance->TlsConn, Data, DataSize); - break; - case EfiTlsConfigDataTypeHostPrivateKey: - Status = TlsSetHostPrivateKey (Instance->TlsConn, Data, DataSize); - break; - case EfiTlsConfigDataTypeCertRevocationList: - Status = TlsSetCertRevocationList (Data, DataSize); - break; - default: - Status = EFI_UNSUPPORTED; - } - - gBS->RestoreTPL (OldTpl); - return Status; -} - -/** - Get TLS configuration data. - - The GetData() function gets TLS configuration. - - @param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance. - @param[in] DataType Configuration data type. - @param[in, out] Data Pointer to configuration data. - @param[in, out] DataSize Total size of configuration data. On input, it means - the size of Data buffer. On output, it means the size - of copied Data buffer if EFI_SUCCESS, and means the - size of desired Data buffer if EFI_BUFFER_TOO_SMALL. - - @retval EFI_SUCCESS The TLS configuration data is got successfully. - @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - DataSize is NULL. - Data is NULL if *DataSize is not zero. - @retval EFI_UNSUPPORTED The DataType is unsupported. - @retval EFI_NOT_FOUND The TLS configuration data is not found. - @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data. -**/ -EFI_STATUS -EFIAPI -TlsConfigurationGetData ( - IN EFI_TLS_CONFIGURATION_PROTOCOL *This, - IN EFI_TLS_CONFIG_DATA_TYPE DataType, - IN OUT VOID *Data, OPTIONAL - IN OUT UINTN *DataSize - ) -{ - EFI_STATUS Status; - TLS_INSTANCE *Instance; - - EFI_TPL OldTpl; - - Status = EFI_SUCCESS; - - if (This == NULL || DataSize == NULL || (Data == NULL && *DataSize != 0)) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Instance = TLS_INSTANCE_FROM_CONFIGURATION (This); - - switch (DataType) { - case EfiTlsConfigDataTypeCACertificate: - Status = TlsGetCaCertificate (Instance->TlsConn, Data, DataSize); - break; - case EfiTlsConfigDataTypeHostPublicCert: - Status = TlsGetHostPublicCert (Instance->TlsConn, Data, DataSize); - break; - case EfiTlsConfigDataTypeHostPrivateKey: - Status = TlsGetHostPrivateKey (Instance->TlsConn, Data, DataSize); - break; - case EfiTlsConfigDataTypeCertRevocationList: - Status = TlsGetCertRevocationList (Data, DataSize); - break; - default: - Status = EFI_UNSUPPORTED; - } - - gBS->RestoreTPL (OldTpl); - return Status; -} +/** @file + Implementation of EFI TLS Configuration Protocol Interfaces. + + Copyright (c) 2016, Intel Corporation. All rights reserved.
+ + 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 "TlsImpl.h" + +EFI_TLS_CONFIGURATION_PROTOCOL mTlsConfigurationProtocol = { + TlsConfigurationSetData, + TlsConfigurationGetData +}; + +/** + Set TLS configuration data. + + The SetData() function sets TLS configuration to non-volatile storage or volatile + storage. + + @param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance. + @param[in] DataType Configuration data type. + @param[in] Data Pointer to configuration data. + @param[in] DataSize Total size of configuration data. + + @retval EFI_SUCCESS The TLS configuration data is set successfully. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + This is NULL. + Data is NULL. + DataSize is 0. + @retval EFI_UNSUPPORTED The DataType is unsupported. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. + +**/ +EFI_STATUS +EFIAPI +TlsConfigurationSetData ( + IN EFI_TLS_CONFIGURATION_PROTOCOL *This, + IN EFI_TLS_CONFIG_DATA_TYPE DataType, + IN VOID *Data, + IN UINTN DataSize + ) +{ + EFI_STATUS Status; + TLS_INSTANCE *Instance; + EFI_TPL OldTpl; + + Status = EFI_SUCCESS; + + if (This == NULL || Data == NULL || DataSize == 0) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + Instance = TLS_INSTANCE_FROM_CONFIGURATION (This); + + switch (DataType) { + case EfiTlsConfigDataTypeCACertificate: + Status = TlsSetCaCertificate (Instance->TlsConn, Data, DataSize); + break; + case EfiTlsConfigDataTypeHostPublicCert: + Status = TlsSetHostPublicCert (Instance->TlsConn, Data, DataSize); + break; + case EfiTlsConfigDataTypeHostPrivateKey: + Status = TlsSetHostPrivateKey (Instance->TlsConn, Data, DataSize); + break; + case EfiTlsConfigDataTypeCertRevocationList: + Status = TlsSetCertRevocationList (Data, DataSize); + break; + default: + Status = EFI_UNSUPPORTED; + } + + gBS->RestoreTPL (OldTpl); + return Status; +} + +/** + Get TLS configuration data. + + The GetData() function gets TLS configuration. + + @param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance. + @param[in] DataType Configuration data type. + @param[in, out] Data Pointer to configuration data. + @param[in, out] DataSize Total size of configuration data. On input, it means + the size of Data buffer. On output, it means the size + of copied Data buffer if EFI_SUCCESS, and means the + size of desired Data buffer if EFI_BUFFER_TOO_SMALL. + + @retval EFI_SUCCESS The TLS configuration data is got successfully. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + This is NULL. + DataSize is NULL. + Data is NULL if *DataSize is not zero. + @retval EFI_UNSUPPORTED The DataType is unsupported. + @retval EFI_NOT_FOUND The TLS configuration data is not found. + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data. +**/ +EFI_STATUS +EFIAPI +TlsConfigurationGetData ( + IN EFI_TLS_CONFIGURATION_PROTOCOL *This, + IN EFI_TLS_CONFIG_DATA_TYPE DataType, + IN OUT VOID *Data, OPTIONAL + IN OUT UINTN *DataSize + ) +{ + EFI_STATUS Status; + TLS_INSTANCE *Instance; + + EFI_TPL OldTpl; + + Status = EFI_SUCCESS; + + if (This == NULL || DataSize == NULL || (Data == NULL && *DataSize != 0)) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + Instance = TLS_INSTANCE_FROM_CONFIGURATION (This); + + switch (DataType) { + case EfiTlsConfigDataTypeCACertificate: + Status = TlsGetCaCertificate (Instance->TlsConn, Data, DataSize); + break; + case EfiTlsConfigDataTypeHostPublicCert: + Status = TlsGetHostPublicCert (Instance->TlsConn, Data, DataSize); + break; + case EfiTlsConfigDataTypeHostPrivateKey: + Status = TlsGetHostPrivateKey (Instance->TlsConn, Data, DataSize); + break; + case EfiTlsConfigDataTypeCertRevocationList: + Status = TlsGetCertRevocationList (Data, DataSize); + break; + default: + Status = EFI_UNSUPPORTED; + } + + gBS->RestoreTPL (OldTpl); + return Status; +} + diff --git a/NetworkPkg/TlsDxe/TlsDriver.c b/NetworkPkg/TlsDxe/TlsDriver.c index 38bf5993ce..29bc966c3e 100644 --- a/NetworkPkg/TlsDxe/TlsDriver.c +++ b/NetworkPkg/TlsDxe/TlsDriver.c @@ -1,496 +1,497 @@ -/** @file - The Driver Binding and Service Binding Protocol for TlsDxe driver. - - Copyright (c) 2016, Intel Corporation. All rights reserved.
- - 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 "TlsImpl.h" - -EFI_SERVICE_BINDING_PROTOCOL mTlsServiceBinding = { - TlsServiceBindingCreateChild, - TlsServiceBindingDestroyChild -}; - -/** - Release all the resources used by the TLS instance. - - @param[in] Instance The TLS instance data. - -**/ -VOID -TlsCleanInstance ( - IN TLS_INSTANCE *Instance - ) -{ - if (Instance != NULL) { - if (Instance->TlsConn != NULL) { - TlsFree (Instance->TlsConn); - } - - FreePool (Instance); - } -} - -/** - Create the TLS instance and initialize it. - - @param[in] Service The pointer to the TLS service. - @param[out] Instance The pointer to the TLS instance. - - @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. - @retval EFI_SUCCESS The TLS instance is created. - -**/ -EFI_STATUS -TlsCreateInstance ( - IN TLS_SERVICE *Service, - OUT TLS_INSTANCE **Instance - ) -{ - TLS_INSTANCE *TlsInstance; - - *Instance = NULL; - - TlsInstance = AllocateZeroPool (sizeof (TLS_INSTANCE)); - if (TlsInstance == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - TlsInstance->Signature = TLS_INSTANCE_SIGNATURE; - InitializeListHead (&TlsInstance->Link); - TlsInstance->InDestroy = FALSE; - TlsInstance->Service = Service; - - CopyMem (&TlsInstance->Tls, &mTlsProtocol, sizeof (TlsInstance->Tls)); - CopyMem (&TlsInstance->TlsConfig, &mTlsConfigurationProtocol, sizeof (TlsInstance->TlsConfig)); - - TlsInstance->TlsSessionState = EfiTlsSessionNotStarted; - - *Instance = TlsInstance; - - return EFI_SUCCESS; -} - -/** - Release all the resources used by the TLS service binding instance. - - @param[in] Service The TLS service data. - -**/ -VOID -TlsCleanService ( - IN TLS_SERVICE *Service - ) -{ - if (Service != NULL) { - if (Service->TlsCtx != NULL) { - TlsCtxFree (Service->TlsCtx); - } - - FreePool (Service); - } -} - -/** - Create then initialize a TLS service. - - @param[in] Image ImageHandle of the TLS driver - @param[out] Service The service for TLS driver - - @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the service. - @retval EFI_SUCCESS The service is created for the driver. - -**/ -EFI_STATUS -TlsCreateService ( - IN EFI_HANDLE Image, - OUT TLS_SERVICE **Service - ) -{ - TLS_SERVICE *TlsService; - - ASSERT (Service != NULL); - - *Service = NULL; - - // - // Allocate a TLS Service Data - // - TlsService = AllocateZeroPool (sizeof (TLS_SERVICE)); - if (TlsService == NULL) { - return EFI_OUT_OF_RESOURCES; - } - - // - // Initialize TLS Service Data - // - TlsService->Signature = TLS_SERVICE_SIGNATURE; - CopyMem (&TlsService->ServiceBinding, &mTlsServiceBinding, sizeof (TlsService->ServiceBinding)); - TlsService->TlsChildrenNum = 0; - InitializeListHead (&TlsService->TlsChildrenList); - TlsService->ImageHandle = Image; - - *Service = TlsService; - - return EFI_SUCCESS; -} - -/** - Unloads an image. - - @param[in] ImageHandle Handle that identifies the image to be unloaded. - - @retval EFI_SUCCESS The image has been unloaded. - @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle. - -**/ -EFI_STATUS -EFIAPI -TlsUnload ( - IN EFI_HANDLE ImageHandle - ) -{ - EFI_STATUS Status; - UINTN HandleNum; - EFI_HANDLE *HandleBuffer; - UINT32 Index; - EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; - TLS_SERVICE *TlsService; - - HandleBuffer = NULL; - ServiceBinding = NULL; - TlsService = NULL; - - // - // Locate all the handles with Tls service binding protocol. - // - Status = gBS->LocateHandleBuffer ( - ByProtocol, - &gEfiTlsServiceBindingProtocolGuid, - NULL, - &HandleNum, - &HandleBuffer - ); - if (EFI_ERROR (Status)) { - return Status; - } - - for (Index = 0; Index < HandleNum; Index++) { - // - // Firstly, find ServiceBinding interface - // - Status = gBS->OpenProtocol ( - HandleBuffer[Index], - &gEfiTlsServiceBindingProtocolGuid, - (VOID **) &ServiceBinding, - ImageHandle, - NULL, - EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return Status; - } - - TlsService = TLS_SERVICE_FROM_THIS (ServiceBinding); - - // - // Then, uninstall ServiceBinding interface - // - Status = gBS->UninstallMultipleProtocolInterfaces ( - HandleBuffer[Index], - &gEfiTlsServiceBindingProtocolGuid, ServiceBinding, - NULL - ); - if (EFI_ERROR (Status)) { - return Status; - } - - TlsCleanService (TlsService); - } - - if (HandleBuffer != NULL) { - FreePool (HandleBuffer); - } - - return EFI_SUCCESS; -} - -/** - This is the declaration of an EFI image entry point. This entry point is - the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including - both device drivers and bus drivers. - - @param ImageHandle The firmware allocated handle for the UEFI image. - @param SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The operation completed successfully. - @retval Others An unexpected error occurred. -**/ -EFI_STATUS -EFIAPI -TlsDriverEntryPoint ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - - TLS_SERVICE *TlsService; - - // - // Create TLS Service - // - Status = TlsCreateService (ImageHandle, &TlsService); - if (EFI_ERROR (Status)) { - return Status; - } - - ASSERT (TlsService != NULL); - - // - // Initializes the OpenSSL library. - // - TlsInitialize (); - - // - // Create a new SSL_CTX object as framework to establish TLS/SSL enabled - // connections. TLS 1.0 is used as the default version. - // - TlsService->TlsCtx = TlsCtxNew (TLS10_PROTOCOL_VERSION_MAJOR, TLS10_PROTOCOL_VERSION_MINOR); - if (TlsService->TlsCtx == NULL) { - FreePool (TlsService); - return EFI_ABORTED; - } - - // - // Install the TlsServiceBinding Protocol onto Handle - // - Status = gBS->InstallMultipleProtocolInterfaces ( - &TlsService->Handle, - &gEfiTlsServiceBindingProtocolGuid, - &TlsService->ServiceBinding, - NULL - ); - if (EFI_ERROR (Status)) { - goto ON_CLEAN_SERVICE; - } - - return Status; - -ON_CLEAN_SERVICE: - TlsCleanService (TlsService); - - return Status; -} - -/** - Creates a child handle and installs a protocol. - - The CreateChild() function installs a protocol on ChildHandle. - If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle. - If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle. - - @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance. - @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL, - then a new handle is created. If it is a pointer to an existing UEFI handle, - then the protocol is added to the existing UEFI handle. - - @retval EFI_SUCCES The protocol was added to ChildHandle. - @retval EFI_INVALID_PARAMETER ChildHandle is NULL. - @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create - the child. - @retval other The child handle was not created. - -**/ -EFI_STATUS -EFIAPI -TlsServiceBindingCreateChild ( - IN EFI_SERVICE_BINDING_PROTOCOL *This, - IN EFI_HANDLE *ChildHandle - ) -{ - TLS_SERVICE *TlsService; - TLS_INSTANCE *TlsInstance; - EFI_STATUS Status; - EFI_TPL OldTpl; - - if ((This == NULL) || (ChildHandle == NULL)) { - return EFI_INVALID_PARAMETER; - } - - TlsService = TLS_SERVICE_FROM_THIS (This); - - Status = TlsCreateInstance (TlsService, &TlsInstance); - if (EFI_ERROR (Status)) { - return Status; - } - - ASSERT (TlsInstance != NULL); - - // - // Create a new TLS connection object. - // - TlsInstance->TlsConn = TlsNew (TlsService->TlsCtx); - if (TlsInstance->TlsConn == NULL) { - Status = EFI_ABORTED; - goto ON_ERROR; - } - - // - // Set default ConnectionEnd to EfiTlsClient - // - Status = TlsSetConnectionEnd (TlsInstance->TlsConn, EfiTlsClient); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - // - // Install TLS protocol and configuration protocol onto ChildHandle - // - Status = gBS->InstallMultipleProtocolInterfaces ( - ChildHandle, - &gEfiTlsProtocolGuid, - &TlsInstance->Tls, - &gEfiTlsConfigurationProtocolGuid, - &TlsInstance->TlsConfig, - NULL - ); - if (EFI_ERROR (Status)) { - goto ON_ERROR; - } - - TlsInstance->ChildHandle = *ChildHandle; - - // - // Add it to the TLS service's child list. - // - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - InsertTailList (&TlsService->TlsChildrenList, &TlsInstance->Link); - TlsService->TlsChildrenNum++; - - gBS->RestoreTPL (OldTpl); - - return EFI_SUCCESS; - -ON_ERROR: - TlsCleanInstance (TlsInstance); - return Status; -} - -/** - Destroys a child handle with a protocol installed on it. - - The DestroyChild() function does the opposite of CreateChild(). It removes a protocol - that was installed by CreateChild() from ChildHandle. If the removed protocol is the - last protocol on ChildHandle, then ChildHandle is destroyed. - - @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance. - @param ChildHandle Handle of the child to destroy. - - @retval EFI_SUCCES The protocol was removed from ChildHandle. - @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed. - @retval EFI_INVALID_PARAMETER Child handle is NULL. - @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle - because its services are being used. - @retval other The child handle was not destroyed. - -**/ -EFI_STATUS -EFIAPI -TlsServiceBindingDestroyChild ( - IN EFI_SERVICE_BINDING_PROTOCOL *This, - IN EFI_HANDLE ChildHandle - ) -{ - TLS_SERVICE *TlsService; - TLS_INSTANCE *TlsInstance; - - EFI_TLS_PROTOCOL *Tls; - EFI_TLS_CONFIGURATION_PROTOCOL *TlsConfig; - EFI_STATUS Status; - EFI_TPL OldTpl; - - if ((This == NULL) || (ChildHandle == NULL)) { - return EFI_INVALID_PARAMETER; - } - - TlsService = TLS_SERVICE_FROM_THIS (This); - - // - // Find TLS protocol interface installed in ChildHandle - // - Status = gBS->OpenProtocol ( - ChildHandle, - &gEfiTlsProtocolGuid, - (VOID **) &Tls, - TlsService->ImageHandle, - NULL, - EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return Status; - } - - // - // Find TLS configuration protocol interface installed in ChildHandle - // - Status = gBS->OpenProtocol ( - ChildHandle, - &gEfiTlsConfigurationProtocolGuid, - (VOID **) &TlsConfig, - TlsService->ImageHandle, - NULL, - EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL - ); - if (EFI_ERROR (Status)) { - return Status; - } - - TlsInstance = TLS_INSTANCE_FROM_PROTOCOL (Tls); - - if (TlsInstance->Service != TlsService) { - return EFI_INVALID_PARAMETER; - } - - if (TlsInstance->InDestroy) { - return EFI_SUCCESS; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - TlsInstance->InDestroy = TRUE; - - // - // Uninstall the TLS protocol and TLS Configuration Protocol interface installed in ChildHandle. - // - Status = gBS->UninstallMultipleProtocolInterfaces ( - ChildHandle, - &gEfiTlsProtocolGuid, - Tls, - &gEfiTlsConfigurationProtocolGuid, - TlsConfig, - NULL - ); - if (EFI_ERROR (Status)) { - return Status; - } - - RemoveEntryList (&TlsInstance->Link); - TlsService->TlsChildrenNum--; - - gBS->RestoreTPL (OldTpl); - - TlsCleanInstance (TlsInstance); - - return EFI_SUCCESS; -} +/** @file + The Driver Binding and Service Binding Protocol for TlsDxe driver. + + Copyright (c) 2016, Intel Corporation. All rights reserved.
+ + 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 "TlsImpl.h" + +EFI_SERVICE_BINDING_PROTOCOL mTlsServiceBinding = { + TlsServiceBindingCreateChild, + TlsServiceBindingDestroyChild +}; + +/** + Release all the resources used by the TLS instance. + + @param[in] Instance The TLS instance data. + +**/ +VOID +TlsCleanInstance ( + IN TLS_INSTANCE *Instance + ) +{ + if (Instance != NULL) { + if (Instance->TlsConn != NULL) { + TlsFree (Instance->TlsConn); + } + + FreePool (Instance); + } +} + +/** + Create the TLS instance and initialize it. + + @param[in] Service The pointer to the TLS service. + @param[out] Instance The pointer to the TLS instance. + + @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. + @retval EFI_SUCCESS The TLS instance is created. + +**/ +EFI_STATUS +TlsCreateInstance ( + IN TLS_SERVICE *Service, + OUT TLS_INSTANCE **Instance + ) +{ + TLS_INSTANCE *TlsInstance; + + *Instance = NULL; + + TlsInstance = AllocateZeroPool (sizeof (TLS_INSTANCE)); + if (TlsInstance == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + TlsInstance->Signature = TLS_INSTANCE_SIGNATURE; + InitializeListHead (&TlsInstance->Link); + TlsInstance->InDestroy = FALSE; + TlsInstance->Service = Service; + + CopyMem (&TlsInstance->Tls, &mTlsProtocol, sizeof (TlsInstance->Tls)); + CopyMem (&TlsInstance->TlsConfig, &mTlsConfigurationProtocol, sizeof (TlsInstance->TlsConfig)); + + TlsInstance->TlsSessionState = EfiTlsSessionNotStarted; + + *Instance = TlsInstance; + + return EFI_SUCCESS; +} + +/** + Release all the resources used by the TLS service binding instance. + + @param[in] Service The TLS service data. + +**/ +VOID +TlsCleanService ( + IN TLS_SERVICE *Service + ) +{ + if (Service != NULL) { + if (Service->TlsCtx != NULL) { + TlsCtxFree (Service->TlsCtx); + } + + FreePool (Service); + } +} + +/** + Create then initialize a TLS service. + + @param[in] Image ImageHandle of the TLS driver + @param[out] Service The service for TLS driver + + @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the service. + @retval EFI_SUCCESS The service is created for the driver. + +**/ +EFI_STATUS +TlsCreateService ( + IN EFI_HANDLE Image, + OUT TLS_SERVICE **Service + ) +{ + TLS_SERVICE *TlsService; + + ASSERT (Service != NULL); + + *Service = NULL; + + // + // Allocate a TLS Service Data + // + TlsService = AllocateZeroPool (sizeof (TLS_SERVICE)); + if (TlsService == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + // + // Initialize TLS Service Data + // + TlsService->Signature = TLS_SERVICE_SIGNATURE; + CopyMem (&TlsService->ServiceBinding, &mTlsServiceBinding, sizeof (TlsService->ServiceBinding)); + TlsService->TlsChildrenNum = 0; + InitializeListHead (&TlsService->TlsChildrenList); + TlsService->ImageHandle = Image; + + *Service = TlsService; + + return EFI_SUCCESS; +} + +/** + Unloads an image. + + @param[in] ImageHandle Handle that identifies the image to be unloaded. + + @retval EFI_SUCCESS The image has been unloaded. + @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle. + +**/ +EFI_STATUS +EFIAPI +TlsUnload ( + IN EFI_HANDLE ImageHandle + ) +{ + EFI_STATUS Status; + UINTN HandleNum; + EFI_HANDLE *HandleBuffer; + UINT32 Index; + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding; + TLS_SERVICE *TlsService; + + HandleBuffer = NULL; + ServiceBinding = NULL; + TlsService = NULL; + + // + // Locate all the handles with Tls service binding protocol. + // + Status = gBS->LocateHandleBuffer ( + ByProtocol, + &gEfiTlsServiceBindingProtocolGuid, + NULL, + &HandleNum, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return Status; + } + + for (Index = 0; Index < HandleNum; Index++) { + // + // Firstly, find ServiceBinding interface + // + Status = gBS->OpenProtocol ( + HandleBuffer[Index], + &gEfiTlsServiceBindingProtocolGuid, + (VOID **) &ServiceBinding, + ImageHandle, + NULL, + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + TlsService = TLS_SERVICE_FROM_THIS (ServiceBinding); + + // + // Then, uninstall ServiceBinding interface + // + Status = gBS->UninstallMultipleProtocolInterfaces ( + HandleBuffer[Index], + &gEfiTlsServiceBindingProtocolGuid, ServiceBinding, + NULL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + TlsCleanService (TlsService); + } + + if (HandleBuffer != NULL) { + FreePool (HandleBuffer); + } + + return EFI_SUCCESS; +} + +/** + This is the declaration of an EFI image entry point. This entry point is + the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including + both device drivers and bus drivers. + + @param ImageHandle The firmware allocated handle for the UEFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The operation completed successfully. + @retval Others An unexpected error occurred. +**/ +EFI_STATUS +EFIAPI +TlsDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + TLS_SERVICE *TlsService; + + // + // Create TLS Service + // + Status = TlsCreateService (ImageHandle, &TlsService); + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (TlsService != NULL); + + // + // Initializes the OpenSSL library. + // + TlsInitialize (); + + // + // Create a new SSL_CTX object as framework to establish TLS/SSL enabled + // connections. TLS 1.0 is used as the default version. + // + TlsService->TlsCtx = TlsCtxNew (TLS10_PROTOCOL_VERSION_MAJOR, TLS10_PROTOCOL_VERSION_MINOR); + if (TlsService->TlsCtx == NULL) { + FreePool (TlsService); + return EFI_ABORTED; + } + + // + // Install the TlsServiceBinding Protocol onto Handle + // + Status = gBS->InstallMultipleProtocolInterfaces ( + &TlsService->Handle, + &gEfiTlsServiceBindingProtocolGuid, + &TlsService->ServiceBinding, + NULL + ); + if (EFI_ERROR (Status)) { + goto ON_CLEAN_SERVICE; + } + + return Status; + +ON_CLEAN_SERVICE: + TlsCleanService (TlsService); + + return Status; +} + +/** + Creates a child handle and installs a protocol. + + The CreateChild() function installs a protocol on ChildHandle. + If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle. + If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle. + + @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance. + @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL, + then a new handle is created. If it is a pointer to an existing UEFI handle, + then the protocol is added to the existing UEFI handle. + + @retval EFI_SUCCES The protocol was added to ChildHandle. + @retval EFI_INVALID_PARAMETER ChildHandle is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create + the child. + @retval other The child handle was not created. + +**/ +EFI_STATUS +EFIAPI +TlsServiceBindingCreateChild ( + IN EFI_SERVICE_BINDING_PROTOCOL *This, + IN EFI_HANDLE *ChildHandle + ) +{ + TLS_SERVICE *TlsService; + TLS_INSTANCE *TlsInstance; + EFI_STATUS Status; + EFI_TPL OldTpl; + + if ((This == NULL) || (ChildHandle == NULL)) { + return EFI_INVALID_PARAMETER; + } + + TlsService = TLS_SERVICE_FROM_THIS (This); + + Status = TlsCreateInstance (TlsService, &TlsInstance); + if (EFI_ERROR (Status)) { + return Status; + } + + ASSERT (TlsInstance != NULL); + + // + // Create a new TLS connection object. + // + TlsInstance->TlsConn = TlsNew (TlsService->TlsCtx); + if (TlsInstance->TlsConn == NULL) { + Status = EFI_ABORTED; + goto ON_ERROR; + } + + // + // Set default ConnectionEnd to EfiTlsClient + // + Status = TlsSetConnectionEnd (TlsInstance->TlsConn, EfiTlsClient); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + + // + // Install TLS protocol and configuration protocol onto ChildHandle + // + Status = gBS->InstallMultipleProtocolInterfaces ( + ChildHandle, + &gEfiTlsProtocolGuid, + &TlsInstance->Tls, + &gEfiTlsConfigurationProtocolGuid, + &TlsInstance->TlsConfig, + NULL + ); + if (EFI_ERROR (Status)) { + goto ON_ERROR; + } + + TlsInstance->ChildHandle = *ChildHandle; + + // + // Add it to the TLS service's child list. + // + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + InsertTailList (&TlsService->TlsChildrenList, &TlsInstance->Link); + TlsService->TlsChildrenNum++; + + gBS->RestoreTPL (OldTpl); + + return EFI_SUCCESS; + +ON_ERROR: + TlsCleanInstance (TlsInstance); + return Status; +} + +/** + Destroys a child handle with a protocol installed on it. + + The DestroyChild() function does the opposite of CreateChild(). It removes a protocol + that was installed by CreateChild() from ChildHandle. If the removed protocol is the + last protocol on ChildHandle, then ChildHandle is destroyed. + + @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance. + @param ChildHandle Handle of the child to destroy. + + @retval EFI_SUCCES The protocol was removed from ChildHandle. + @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed. + @retval EFI_INVALID_PARAMETER Child handle is NULL. + @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle + because its services are being used. + @retval other The child handle was not destroyed. + +**/ +EFI_STATUS +EFIAPI +TlsServiceBindingDestroyChild ( + IN EFI_SERVICE_BINDING_PROTOCOL *This, + IN EFI_HANDLE ChildHandle + ) +{ + TLS_SERVICE *TlsService; + TLS_INSTANCE *TlsInstance; + + EFI_TLS_PROTOCOL *Tls; + EFI_TLS_CONFIGURATION_PROTOCOL *TlsConfig; + EFI_STATUS Status; + EFI_TPL OldTpl; + + if ((This == NULL) || (ChildHandle == NULL)) { + return EFI_INVALID_PARAMETER; + } + + TlsService = TLS_SERVICE_FROM_THIS (This); + + // + // Find TLS protocol interface installed in ChildHandle + // + Status = gBS->OpenProtocol ( + ChildHandle, + &gEfiTlsProtocolGuid, + (VOID **) &Tls, + TlsService->ImageHandle, + NULL, + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Find TLS configuration protocol interface installed in ChildHandle + // + Status = gBS->OpenProtocol ( + ChildHandle, + &gEfiTlsConfigurationProtocolGuid, + (VOID **) &TlsConfig, + TlsService->ImageHandle, + NULL, + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + TlsInstance = TLS_INSTANCE_FROM_PROTOCOL (Tls); + + if (TlsInstance->Service != TlsService) { + return EFI_INVALID_PARAMETER; + } + + if (TlsInstance->InDestroy) { + return EFI_SUCCESS; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + TlsInstance->InDestroy = TRUE; + + // + // Uninstall the TLS protocol and TLS Configuration Protocol interface installed in ChildHandle. + // + Status = gBS->UninstallMultipleProtocolInterfaces ( + ChildHandle, + &gEfiTlsProtocolGuid, + Tls, + &gEfiTlsConfigurationProtocolGuid, + TlsConfig, + NULL + ); + if (EFI_ERROR (Status)) { + return Status; + } + + RemoveEntryList (&TlsInstance->Link); + TlsService->TlsChildrenNum--; + + gBS->RestoreTPL (OldTpl); + + TlsCleanInstance (TlsInstance); + + return EFI_SUCCESS; +} + diff --git a/NetworkPkg/TlsDxe/TlsDriver.h b/NetworkPkg/TlsDxe/TlsDriver.h index a9e55ba752..950429af8f 100644 --- a/NetworkPkg/TlsDxe/TlsDriver.h +++ b/NetworkPkg/TlsDxe/TlsDriver.h @@ -1,237 +1,238 @@ -/** @file - Header file of the Driver Binding and Service Binding Protocol for TlsDxe driver. - - Copyright (c) 2016, Intel Corporation. All rights reserved.
- - 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. - -**/ - -#ifndef __EFI_TLS_DRIVER_H__ -#define __EFI_TLS_DRIVER_H__ - -#include - -// -// Driver Protocols -// -#include - -// -// Driver Version -// -#define TLS_VERSION 0x00000000 - -#define TLS_SERVICE_SIGNATURE SIGNATURE_32 ('T', 'L', 'S', 'S') - -#define TLS_INSTANCE_SIGNATURE SIGNATURE_32 ('T', 'L', 'S', 'I') - -/// -/// TLS Service Data -/// -typedef struct _TLS_SERVICE TLS_SERVICE; - -/// -/// TLS Instance Data -/// -typedef struct _TLS_INSTANCE TLS_INSTANCE; - - -struct _TLS_SERVICE { - UINT32 Signature; - EFI_SERVICE_BINDING_PROTOCOL ServiceBinding; - - UINT16 TlsChildrenNum; - LIST_ENTRY TlsChildrenList; - - // - // Handle to install TlsServiceBinding protocol. - // - EFI_HANDLE Handle; - EFI_HANDLE ImageHandle; - - // - // Main SSL Context object which is created by a server or client once per program - // life-time and which holds mainly default values for the SSL object which are later - // created for the connections. - // - VOID *TlsCtx; -}; - -struct _TLS_INSTANCE { - UINT32 Signature; - LIST_ENTRY Link; - - BOOLEAN InDestroy; - - TLS_SERVICE *Service; - EFI_HANDLE ChildHandle; - - EFI_TLS_PROTOCOL Tls; - EFI_TLS_CONFIGURATION_PROTOCOL TlsConfig; - - EFI_TLS_SESSION_STATE TlsSessionState; - - // - // Main SSL Connection which is created by a server or a client - // per established connection. - // - VOID *TlsConn; -}; - - -#define TLS_SERVICE_FROM_THIS(a) \ - CR (a, TLS_SERVICE, ServiceBinding, TLS_SERVICE_SIGNATURE) - -#define TLS_INSTANCE_FROM_PROTOCOL(a) \ - CR (a, TLS_INSTANCE, Tls, TLS_INSTANCE_SIGNATURE) - -#define TLS_INSTANCE_FROM_CONFIGURATION(a) \ - CR (a, TLS_INSTANCE, TlsConfig, TLS_INSTANCE_SIGNATURE) - - -/** - Release all the resources used by the TLS instance. - - @param[in] Instance The TLS instance data. - -**/ -VOID -TlsCleanInstance ( - IN TLS_INSTANCE *Instance - ); - -/** - Create the TLS instance and initialize it. - - @param[in] Service The pointer to the TLS service. - @param[out] Instance The pointer to the TLS instance. - - @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. - @retval EFI_SUCCESS The TLS instance is created. - -**/ -EFI_STATUS -TlsCreateInstance ( - IN TLS_SERVICE *Service, - OUT TLS_INSTANCE **Instance - ); - -/** - Release all the resources used by the TLS service binding instance. - - @param[in] Service The TLS service data. - -**/ -VOID -TlsCleanService ( - IN TLS_SERVICE *Service - ); - -/** - Create then initialize a TLS service. - - @param[in] Image ImageHandle of the TLS driver - @param[out] Service The service for TLS driver - - @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the service. - @retval EFI_SUCCESS The service is created for the driver. - -**/ -EFI_STATUS -TlsCreateService ( - IN EFI_HANDLE Image, - OUT TLS_SERVICE **Service - ); - -/** - Unloads an image. - - @param[in] ImageHandle Handle that identifies the image to be unloaded. - - @retval EFI_SUCCESS The image has been unloaded. - @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle. - -**/ -EFI_STATUS -EFIAPI -TlsUnload ( - IN EFI_HANDLE ImageHandle - ); - -/** - This is the declaration of an EFI image entry point. This entry point is - the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including - both device drivers and bus drivers. - - @param ImageHandle The firmware allocated handle for the UEFI image. - @param SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The operation completed successfully. - @retval Others An unexpected error occurred. -**/ -EFI_STATUS -EFIAPI -TlsDriverEntryPoint ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ); - -/** - Creates a child handle and installs a protocol. - - The CreateChild() function installs a protocol on ChildHandle. - If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle. - If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle. - - @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance. - @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL, - then a new handle is created. If it is a pointer to an existing UEFI handle, - then the protocol is added to the existing UEFI handle. - - @retval EFI_SUCCES The protocol was added to ChildHandle. - @retval EFI_INVALID_PARAMETER ChildHandle is NULL. - @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create - the child. - @retval other The child handle was not created. - -**/ -EFI_STATUS -EFIAPI -TlsServiceBindingCreateChild ( - IN EFI_SERVICE_BINDING_PROTOCOL *This, - IN EFI_HANDLE *ChildHandle - ); - -/** - Destroys a child handle with a protocol installed on it. - - The DestroyChild() function does the opposite of CreateChild(). It removes a protocol - that was installed by CreateChild() from ChildHandle. If the removed protocol is the - last protocol on ChildHandle, then ChildHandle is destroyed. - - @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance. - @param ChildHandle Handle of the child to destroy. - - @retval EFI_SUCCES The protocol was removed from ChildHandle. - @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed. - @retval EFI_INVALID_PARAMETER Child handle is NULL. - @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle - because its services are being used. - @retval other The child handle was not destroyed. - -**/ -EFI_STATUS -EFIAPI -TlsServiceBindingDestroyChild ( - IN EFI_SERVICE_BINDING_PROTOCOL *This, - IN EFI_HANDLE ChildHandle - ); - -#endif +/** @file + Header file of the Driver Binding and Service Binding Protocol for TlsDxe driver. + + Copyright (c) 2016, Intel Corporation. All rights reserved.
+ + 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. + +**/ + +#ifndef __EFI_TLS_DRIVER_H__ +#define __EFI_TLS_DRIVER_H__ + +#include + +// +// Driver Protocols +// +#include + +// +// Driver Version +// +#define TLS_VERSION 0x00000000 + +#define TLS_SERVICE_SIGNATURE SIGNATURE_32 ('T', 'L', 'S', 'S') + +#define TLS_INSTANCE_SIGNATURE SIGNATURE_32 ('T', 'L', 'S', 'I') + +/// +/// TLS Service Data +/// +typedef struct _TLS_SERVICE TLS_SERVICE; + +/// +/// TLS Instance Data +/// +typedef struct _TLS_INSTANCE TLS_INSTANCE; + + +struct _TLS_SERVICE { + UINT32 Signature; + EFI_SERVICE_BINDING_PROTOCOL ServiceBinding; + + UINT16 TlsChildrenNum; + LIST_ENTRY TlsChildrenList; + + // + // Handle to install TlsServiceBinding protocol. + // + EFI_HANDLE Handle; + EFI_HANDLE ImageHandle; + + // + // Main SSL Context object which is created by a server or client once per program + // life-time and which holds mainly default values for the SSL object which are later + // created for the connections. + // + VOID *TlsCtx; +}; + +struct _TLS_INSTANCE { + UINT32 Signature; + LIST_ENTRY Link; + + BOOLEAN InDestroy; + + TLS_SERVICE *Service; + EFI_HANDLE ChildHandle; + + EFI_TLS_PROTOCOL Tls; + EFI_TLS_CONFIGURATION_PROTOCOL TlsConfig; + + EFI_TLS_SESSION_STATE TlsSessionState; + + // + // Main SSL Connection which is created by a server or a client + // per established connection. + // + VOID *TlsConn; +}; + + +#define TLS_SERVICE_FROM_THIS(a) \ + CR (a, TLS_SERVICE, ServiceBinding, TLS_SERVICE_SIGNATURE) + +#define TLS_INSTANCE_FROM_PROTOCOL(a) \ + CR (a, TLS_INSTANCE, Tls, TLS_INSTANCE_SIGNATURE) + +#define TLS_INSTANCE_FROM_CONFIGURATION(a) \ + CR (a, TLS_INSTANCE, TlsConfig, TLS_INSTANCE_SIGNATURE) + + +/** + Release all the resources used by the TLS instance. + + @param[in] Instance The TLS instance data. + +**/ +VOID +TlsCleanInstance ( + IN TLS_INSTANCE *Instance + ); + +/** + Create the TLS instance and initialize it. + + @param[in] Service The pointer to the TLS service. + @param[out] Instance The pointer to the TLS instance. + + @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. + @retval EFI_SUCCESS The TLS instance is created. + +**/ +EFI_STATUS +TlsCreateInstance ( + IN TLS_SERVICE *Service, + OUT TLS_INSTANCE **Instance + ); + +/** + Release all the resources used by the TLS service binding instance. + + @param[in] Service The TLS service data. + +**/ +VOID +TlsCleanService ( + IN TLS_SERVICE *Service + ); + +/** + Create then initialize a TLS service. + + @param[in] Image ImageHandle of the TLS driver + @param[out] Service The service for TLS driver + + @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the service. + @retval EFI_SUCCESS The service is created for the driver. + +**/ +EFI_STATUS +TlsCreateService ( + IN EFI_HANDLE Image, + OUT TLS_SERVICE **Service + ); + +/** + Unloads an image. + + @param[in] ImageHandle Handle that identifies the image to be unloaded. + + @retval EFI_SUCCESS The image has been unloaded. + @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle. + +**/ +EFI_STATUS +EFIAPI +TlsUnload ( + IN EFI_HANDLE ImageHandle + ); + +/** + This is the declaration of an EFI image entry point. This entry point is + the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including + both device drivers and bus drivers. + + @param ImageHandle The firmware allocated handle for the UEFI image. + @param SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The operation completed successfully. + @retval Others An unexpected error occurred. +**/ +EFI_STATUS +EFIAPI +TlsDriverEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ); + +/** + Creates a child handle and installs a protocol. + + The CreateChild() function installs a protocol on ChildHandle. + If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle. + If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle. + + @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance. + @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL, + then a new handle is created. If it is a pointer to an existing UEFI handle, + then the protocol is added to the existing UEFI handle. + + @retval EFI_SUCCES The protocol was added to ChildHandle. + @retval EFI_INVALID_PARAMETER ChildHandle is NULL. + @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create + the child. + @retval other The child handle was not created. + +**/ +EFI_STATUS +EFIAPI +TlsServiceBindingCreateChild ( + IN EFI_SERVICE_BINDING_PROTOCOL *This, + IN EFI_HANDLE *ChildHandle + ); + +/** + Destroys a child handle with a protocol installed on it. + + The DestroyChild() function does the opposite of CreateChild(). It removes a protocol + that was installed by CreateChild() from ChildHandle. If the removed protocol is the + last protocol on ChildHandle, then ChildHandle is destroyed. + + @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance. + @param ChildHandle Handle of the child to destroy. + + @retval EFI_SUCCES The protocol was removed from ChildHandle. + @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed. + @retval EFI_INVALID_PARAMETER Child handle is NULL. + @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle + because its services are being used. + @retval other The child handle was not destroyed. + +**/ +EFI_STATUS +EFIAPI +TlsServiceBindingDestroyChild ( + IN EFI_SERVICE_BINDING_PROTOCOL *This, + IN EFI_HANDLE ChildHandle + ); + +#endif + diff --git a/NetworkPkg/TlsDxe/TlsDxe.inf b/NetworkPkg/TlsDxe/TlsDxe.inf index dba3257203..907feb735b 100644 --- a/NetworkPkg/TlsDxe/TlsDxe.inf +++ b/NetworkPkg/TlsDxe/TlsDxe.inf @@ -1,65 +1,66 @@ -## @file -# This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol and -# EFI TLS Configuration Protocol. -# -# This module produces EFI TLS (Transport Layer Security) Protocol and EFI TLS -# Service Binding Protocol, to provide TLS services. -# -# Copyright (c) 2016, Intel Corporation. All rights reserved.
-# -# 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. -# -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = TlsDxe - FILE_GUID = 3aceb0c0-3c72-11e4-9a56-74d435052646 - MODULE_TYPE = UEFI_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = TlsDriverEntryPoint - UNLOAD_IMAGE = TlsUnload - MODULE_UNI_FILE = TlsDxe.uni - -# -# VALID_ARCHITECTURES = IA32 X64 -# - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - CryptoPkg/CryptoPkg.dec - -[Sources] - TlsDriver.h - TlsDriver.c - TlsProtocol.c - TlsConfigProtocol.c - TlsImpl.h - TlsImpl.c - -[LibraryClasses] - UefiDriverEntryPoint - UefiBootServicesTableLib - MemoryAllocationLib - BaseMemoryLib - BaseLib - UefiLib - DebugLib - NetLib - BaseCryptLib - TlsLib - -[Protocols] - gEfiTlsServiceBindingProtocolGuid ## PRODUCES - gEfiTlsProtocolGuid ## PRODUCES - gEfiTlsConfigurationProtocolGuid ## PRODUCES - -[UserExtensions.TianoCore."ExtraFiles"] - TlsDxeExtra.uni +## @file +# This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol and +# EFI TLS Configuration Protocol. +# +# This module produces EFI TLS (Transport Layer Security) Protocol and EFI TLS +# Service Binding Protocol, to provide TLS services. +# +# Copyright (c) 2016, Intel Corporation. All rights reserved.
+# +# 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. +# +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = TlsDxe + FILE_GUID = 3aceb0c0-3c72-11e4-9a56-74d435052646 + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = TlsDriverEntryPoint + UNLOAD_IMAGE = TlsUnload + MODULE_UNI_FILE = TlsDxe.uni + +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + CryptoPkg/CryptoPkg.dec + +[Sources] + TlsDriver.h + TlsDriver.c + TlsProtocol.c + TlsConfigProtocol.c + TlsImpl.h + TlsImpl.c + +[LibraryClasses] + UefiDriverEntryPoint + UefiBootServicesTableLib + MemoryAllocationLib + BaseMemoryLib + BaseLib + UefiLib + DebugLib + NetLib + BaseCryptLib + TlsLib + +[Protocols] + gEfiTlsServiceBindingProtocolGuid ## PRODUCES + gEfiTlsProtocolGuid ## PRODUCES + gEfiTlsConfigurationProtocolGuid ## PRODUCES + +[UserExtensions.TianoCore."ExtraFiles"] + TlsDxeExtra.uni + diff --git a/NetworkPkg/TlsDxe/TlsDxe.uni b/NetworkPkg/TlsDxe/TlsDxe.uni index 98c41ca7c5..e2b1f5cd0b 100644 --- a/NetworkPkg/TlsDxe/TlsDxe.uni +++ b/NetworkPkg/TlsDxe/TlsDxe.uni @@ -1,25 +1,25 @@ -// /** @file -// This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol and -// EFI TLS Configuration Protocol. -// -// This module produces EFI TLS (Transport Layer Security) Protocol, EFI TLS -// Service Binding Protocol, and EFI TLS Configuration Protocol to provide TLS -// services. -// -// Copyright (c) 2016, Intel Corporation. All rights reserved.
-// -// 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. -// -// **/ - - -#string STR_MODULE_ABSTRACT #language en-US "UEFI TLS service" - -#string STR_MODULE_DESCRIPTION #language en-US "This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol and EFI TLS Configuration Protocol to provide EFI TLS services." - +// /** @file +// This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol and +// EFI TLS Configuration Protocol. +// +// This module produces EFI TLS (Transport Layer Security) Protocol, EFI TLS +// Service Binding Protocol, and EFI TLS Configuration Protocol to provide TLS +// services. +// +// Copyright (c) 2016, Intel Corporation. All rights reserved.
+// +// 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. +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "UEFI TLS service" + +#string STR_MODULE_DESCRIPTION #language en-US "This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol and EFI TLS Configuration Protocol to provide EFI TLS services." + diff --git a/NetworkPkg/TlsDxe/TlsDxeExtra.uni b/NetworkPkg/TlsDxe/TlsDxeExtra.uni index a38582a887..a5663c3279 100644 --- a/NetworkPkg/TlsDxe/TlsDxeExtra.uni +++ b/NetworkPkg/TlsDxe/TlsDxeExtra.uni @@ -1,18 +1,19 @@ -// /** @file -// TlsDxe Localized Strings and Content -// -// Copyright (c) 2016, Intel Corporation. All rights reserved.
-// -// 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. -// -// **/ - -#string STR_PROPERTIES_MODULE_NAME -#language en-US -"EFI TLS DXE Driver" +// /** @file +// TlsDxe Localized Strings and Content +// +// Copyright (c) 2016, Intel Corporation. All rights reserved.
+// +// 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. +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"EFI TLS DXE Driver" + diff --git a/NetworkPkg/TlsDxe/TlsImpl.c b/NetworkPkg/TlsDxe/TlsImpl.c index efdec2d92d..8e1238216b 100644 --- a/NetworkPkg/TlsDxe/TlsImpl.c +++ b/NetworkPkg/TlsDxe/TlsImpl.c @@ -1,326 +1,327 @@ -/** @file - The Miscellaneous Routines for TlsDxe driver. - -Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- -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 "TlsImpl.h" - -/** - Encrypt the message listed in fragment. - - @param[in] TlsInstance The pointer to the TLS instance. - @param[in, out] FragmentTable Pointer to a list of fragment. - On input these fragments contain the TLS header and - plain text TLS payload; - On output these fragments contain the TLS header and - cipher text TLS payload. - @param[in] FragmentCount Number of fragment. - - @retval EFI_SUCCESS The operation completed successfully. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_ABORTED TLS session state is incorrect. - @retval Others Other errors as indicated. -**/ -EFI_STATUS -TlsEncryptPacket ( - IN TLS_INSTANCE *TlsInstance, - IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable, - IN UINT32 *FragmentCount - ) -{ - EFI_STATUS Status; - UINTN Index; - UINT32 BytesCopied; - UINT32 BufferInSize; - UINT8 *BufferIn; - UINT8 *BufferInPtr; - TLS_RECORD_HEADER *RecordHeaderIn; - UINT16 ThisPlainMessageSize; - TLS_RECORD_HEADER *TempRecordHeader; - UINT16 ThisMessageSize; - UINT32 BufferOutSize; - UINT8 *BufferOut; - INTN Ret; - - Status = EFI_SUCCESS; - BytesCopied = 0; - BufferInSize = 0; - BufferIn = NULL; - BufferInPtr = NULL; - RecordHeaderIn = NULL; - TempRecordHeader = NULL; - BufferOutSize = 0; - BufferOut = NULL; - Ret = 0; - - // - // Calculate the size according to the fragment table. - // - for (Index = 0; Index < *FragmentCount; Index++) { - BufferInSize += (*FragmentTable)[Index].FragmentLength; - } - - // - // Allocate buffer for processing data. - // - BufferIn = AllocateZeroPool (BufferInSize); - if (BufferIn == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ERROR; - } - - // - // Copy all TLS plain record header and payload into BufferIn. - // - for (Index = 0; Index < *FragmentCount; Index++) { - CopyMem ( - (BufferIn + BytesCopied), - (*FragmentTable)[Index].FragmentBuffer, - (*FragmentTable)[Index].FragmentLength - ); - BytesCopied += (*FragmentTable)[Index].FragmentLength; - } - - BufferOut = AllocateZeroPool (MAX_BUFFER_SIZE); - if (BufferOut == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ERROR; - } - - // - // Parsing buffer. - // - BufferInPtr = BufferIn; - TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut; - while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) { - RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr; - - if (RecordHeaderIn->ContentType != TlsContentTypeApplicationData) { - Status = EFI_INVALID_PARAMETER; - goto ERROR; - } - - ThisPlainMessageSize = RecordHeaderIn->Length; - - TlsWrite (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn + 1), ThisPlainMessageSize); - - Ret = TlsCtrlTrafficOut (TlsInstance->TlsConn, (UINT8 *)(TempRecordHeader), MAX_BUFFER_SIZE - BufferOutSize); - - if (Ret > 0) { - ThisMessageSize = (UINT16) Ret; - } else { - // - // No data was successfully encrypted, continue to encrypt other messages. - // - DEBUG ((EFI_D_WARN, "TlsEncryptPacket: No data read from TLS object.\n")); - - ThisMessageSize = 0; - } - - BufferOutSize += ThisMessageSize; - - BufferInPtr += RECORD_HEADER_LEN + ThisPlainMessageSize; - TempRecordHeader += ThisMessageSize; - } - - FreePool (BufferIn); - BufferIn = NULL; - - // - // The caller will be responsible to handle the original fragment table. - // - *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA)); - if (*FragmentTable == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ERROR; - } - - (*FragmentTable)[0].FragmentBuffer = BufferOut; - (*FragmentTable)[0].FragmentLength = BufferOutSize; - *FragmentCount = 1; - - return Status; - -ERROR: - - if (BufferIn != NULL) { - FreePool (BufferIn); - BufferIn = NULL; - } - - if (BufferOut != NULL) { - FreePool (BufferOut); - BufferOut = NULL; - } - - return Status; -} - -/** - Decrypt the message listed in fragment. - - @param[in] TlsInstance The pointer to the TLS instance. - @param[in, out] FragmentTable Pointer to a list of fragment. - On input these fragments contain the TLS header and - cipher text TLS payload; - On output these fragments contain the TLS header and - plain text TLS payload. - @param[in] FragmentCount Number of fragment. - - @retval EFI_SUCCESS The operation completed successfully. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_ABORTED TLS session state is incorrect. - @retval Others Other errors as indicated. -**/ -EFI_STATUS -TlsDecryptPacket ( - IN TLS_INSTANCE *TlsInstance, - IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable, - IN UINT32 *FragmentCount - ) -{ - EFI_STATUS Status; - UINTN Index; - UINT32 BytesCopied; - UINT8 *BufferIn; - UINT32 BufferInSize; - UINT8 *BufferInPtr; - TLS_RECORD_HEADER *RecordHeaderIn; - UINT16 ThisCipherMessageSize; - TLS_RECORD_HEADER *TempRecordHeader; - UINT16 ThisPlainMessageSize; - UINT8 *BufferOut; - UINT32 BufferOutSize; - INTN Ret; - - Status = EFI_SUCCESS; - BytesCopied = 0; - BufferIn = NULL; - BufferInSize = 0; - BufferInPtr = NULL; - RecordHeaderIn = NULL; - TempRecordHeader = NULL; - BufferOut = NULL; - BufferOutSize = 0; - Ret = 0; - - // - // Calculate the size according to the fragment table. - // - for (Index = 0; Index < *FragmentCount; Index++) { - BufferInSize += (*FragmentTable)[Index].FragmentLength; - } - - // - // Allocate buffer for processing data - // - BufferIn = AllocateZeroPool (BufferInSize); - if (BufferIn == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ERROR; - } - - // - // Copy all TLS plain record header and payload to BufferIn - // - for (Index = 0; Index < *FragmentCount; Index++) { - CopyMem ( - (BufferIn + BytesCopied), - (*FragmentTable)[Index].FragmentBuffer, - (*FragmentTable)[Index].FragmentLength - ); - BytesCopied += (*FragmentTable)[Index].FragmentLength; - } - - BufferOut = AllocateZeroPool (MAX_BUFFER_SIZE); - if (BufferOut == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ERROR; - } - - // - // Parsing buffer. Received packet may have multiple TLS record messages. - // - BufferInPtr = BufferIn; - TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut; - while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) { - RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr; - - if (RecordHeaderIn->ContentType != TlsContentTypeApplicationData) { - Status = EFI_INVALID_PARAMETER; - goto ERROR; - } - - ThisCipherMessageSize = NTOHS (RecordHeaderIn->Length); - - Ret = TlsCtrlTrafficIn (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn), RECORD_HEADER_LEN + ThisCipherMessageSize); - if (Ret != RECORD_HEADER_LEN + ThisCipherMessageSize) { - TlsInstance->TlsSessionState = EfiTlsSessionError; - Status = EFI_ABORTED; - goto ERROR; - } - - Ret = 0; - Ret = TlsRead (TlsInstance->TlsConn, (UINT8 *) (TempRecordHeader + 1), MAX_BUFFER_SIZE - BufferOutSize); - - if (Ret > 0) { - ThisPlainMessageSize = (UINT16) Ret; - } else { - // - // No data was successfully decrypted, continue to decrypt other messages. - // - DEBUG ((EFI_D_WARN, "TlsDecryptPacket: No data read from TLS object.\n")); - - ThisPlainMessageSize = 0; - } - - CopyMem (TempRecordHeader, RecordHeaderIn, RECORD_HEADER_LEN); - TempRecordHeader->Length = ThisPlainMessageSize; - BufferOutSize += RECORD_HEADER_LEN + ThisPlainMessageSize; - - BufferInPtr += RECORD_HEADER_LEN + ThisCipherMessageSize; - TempRecordHeader += RECORD_HEADER_LEN + ThisPlainMessageSize; - } - - FreePool (BufferIn); - BufferIn = NULL; - - // - // The caller will be responsible to handle the original fragment table - // - *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA)); - if (*FragmentTable == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ERROR; - } - - (*FragmentTable)[0].FragmentBuffer = BufferOut; - (*FragmentTable)[0].FragmentLength = BufferOutSize; - *FragmentCount = 1; - - return Status; - -ERROR: - - if (BufferIn != NULL) { - FreePool (BufferIn); - BufferIn = NULL; - } - - if (BufferOut != NULL) { - FreePool (BufferOut); - BufferOut = NULL; - } - - return Status; -} +/** @file + The Miscellaneous Routines for TlsDxe driver. + +Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
+ +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 "TlsImpl.h" + +/** + Encrypt the message listed in fragment. + + @param[in] TlsInstance The pointer to the TLS instance. + @param[in, out] FragmentTable Pointer to a list of fragment. + On input these fragments contain the TLS header and + plain text TLS payload; + On output these fragments contain the TLS header and + cipher text TLS payload. + @param[in] FragmentCount Number of fragment. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. + @retval EFI_ABORTED TLS session state is incorrect. + @retval Others Other errors as indicated. +**/ +EFI_STATUS +TlsEncryptPacket ( + IN TLS_INSTANCE *TlsInstance, + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable, + IN UINT32 *FragmentCount + ) +{ + EFI_STATUS Status; + UINTN Index; + UINT32 BytesCopied; + UINT32 BufferInSize; + UINT8 *BufferIn; + UINT8 *BufferInPtr; + TLS_RECORD_HEADER *RecordHeaderIn; + UINT16 ThisPlainMessageSize; + TLS_RECORD_HEADER *TempRecordHeader; + UINT16 ThisMessageSize; + UINT32 BufferOutSize; + UINT8 *BufferOut; + INTN Ret; + + Status = EFI_SUCCESS; + BytesCopied = 0; + BufferInSize = 0; + BufferIn = NULL; + BufferInPtr = NULL; + RecordHeaderIn = NULL; + TempRecordHeader = NULL; + BufferOutSize = 0; + BufferOut = NULL; + Ret = 0; + + // + // Calculate the size according to the fragment table. + // + for (Index = 0; Index < *FragmentCount; Index++) { + BufferInSize += (*FragmentTable)[Index].FragmentLength; + } + + // + // Allocate buffer for processing data. + // + BufferIn = AllocateZeroPool (BufferInSize); + if (BufferIn == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ERROR; + } + + // + // Copy all TLS plain record header and payload into BufferIn. + // + for (Index = 0; Index < *FragmentCount; Index++) { + CopyMem ( + (BufferIn + BytesCopied), + (*FragmentTable)[Index].FragmentBuffer, + (*FragmentTable)[Index].FragmentLength + ); + BytesCopied += (*FragmentTable)[Index].FragmentLength; + } + + BufferOut = AllocateZeroPool (MAX_BUFFER_SIZE); + if (BufferOut == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ERROR; + } + + // + // Parsing buffer. + // + BufferInPtr = BufferIn; + TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut; + while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) { + RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr; + + if (RecordHeaderIn->ContentType != TlsContentTypeApplicationData) { + Status = EFI_INVALID_PARAMETER; + goto ERROR; + } + + ThisPlainMessageSize = RecordHeaderIn->Length; + + TlsWrite (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn + 1), ThisPlainMessageSize); + + Ret = TlsCtrlTrafficOut (TlsInstance->TlsConn, (UINT8 *)(TempRecordHeader), MAX_BUFFER_SIZE - BufferOutSize); + + if (Ret > 0) { + ThisMessageSize = (UINT16) Ret; + } else { + // + // No data was successfully encrypted, continue to encrypt other messages. + // + DEBUG ((EFI_D_WARN, "TlsEncryptPacket: No data read from TLS object.\n")); + + ThisMessageSize = 0; + } + + BufferOutSize += ThisMessageSize; + + BufferInPtr += RECORD_HEADER_LEN + ThisPlainMessageSize; + TempRecordHeader += ThisMessageSize; + } + + FreePool (BufferIn); + BufferIn = NULL; + + // + // The caller will be responsible to handle the original fragment table. + // + *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA)); + if (*FragmentTable == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ERROR; + } + + (*FragmentTable)[0].FragmentBuffer = BufferOut; + (*FragmentTable)[0].FragmentLength = BufferOutSize; + *FragmentCount = 1; + + return Status; + +ERROR: + + if (BufferIn != NULL) { + FreePool (BufferIn); + BufferIn = NULL; + } + + if (BufferOut != NULL) { + FreePool (BufferOut); + BufferOut = NULL; + } + + return Status; +} + +/** + Decrypt the message listed in fragment. + + @param[in] TlsInstance The pointer to the TLS instance. + @param[in, out] FragmentTable Pointer to a list of fragment. + On input these fragments contain the TLS header and + cipher text TLS payload; + On output these fragments contain the TLS header and + plain text TLS payload. + @param[in] FragmentCount Number of fragment. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. + @retval EFI_ABORTED TLS session state is incorrect. + @retval Others Other errors as indicated. +**/ +EFI_STATUS +TlsDecryptPacket ( + IN TLS_INSTANCE *TlsInstance, + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable, + IN UINT32 *FragmentCount + ) +{ + EFI_STATUS Status; + UINTN Index; + UINT32 BytesCopied; + UINT8 *BufferIn; + UINT32 BufferInSize; + UINT8 *BufferInPtr; + TLS_RECORD_HEADER *RecordHeaderIn; + UINT16 ThisCipherMessageSize; + TLS_RECORD_HEADER *TempRecordHeader; + UINT16 ThisPlainMessageSize; + UINT8 *BufferOut; + UINT32 BufferOutSize; + INTN Ret; + + Status = EFI_SUCCESS; + BytesCopied = 0; + BufferIn = NULL; + BufferInSize = 0; + BufferInPtr = NULL; + RecordHeaderIn = NULL; + TempRecordHeader = NULL; + BufferOut = NULL; + BufferOutSize = 0; + Ret = 0; + + // + // Calculate the size according to the fragment table. + // + for (Index = 0; Index < *FragmentCount; Index++) { + BufferInSize += (*FragmentTable)[Index].FragmentLength; + } + + // + // Allocate buffer for processing data + // + BufferIn = AllocateZeroPool (BufferInSize); + if (BufferIn == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ERROR; + } + + // + // Copy all TLS plain record header and payload to BufferIn + // + for (Index = 0; Index < *FragmentCount; Index++) { + CopyMem ( + (BufferIn + BytesCopied), + (*FragmentTable)[Index].FragmentBuffer, + (*FragmentTable)[Index].FragmentLength + ); + BytesCopied += (*FragmentTable)[Index].FragmentLength; + } + + BufferOut = AllocateZeroPool (MAX_BUFFER_SIZE); + if (BufferOut == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ERROR; + } + + // + // Parsing buffer. Received packet may have multiple TLS record messages. + // + BufferInPtr = BufferIn; + TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut; + while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) { + RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr; + + if (RecordHeaderIn->ContentType != TlsContentTypeApplicationData) { + Status = EFI_INVALID_PARAMETER; + goto ERROR; + } + + ThisCipherMessageSize = NTOHS (RecordHeaderIn->Length); + + Ret = TlsCtrlTrafficIn (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn), RECORD_HEADER_LEN + ThisCipherMessageSize); + if (Ret != RECORD_HEADER_LEN + ThisCipherMessageSize) { + TlsInstance->TlsSessionState = EfiTlsSessionError; + Status = EFI_ABORTED; + goto ERROR; + } + + Ret = 0; + Ret = TlsRead (TlsInstance->TlsConn, (UINT8 *) (TempRecordHeader + 1), MAX_BUFFER_SIZE - BufferOutSize); + + if (Ret > 0) { + ThisPlainMessageSize = (UINT16) Ret; + } else { + // + // No data was successfully decrypted, continue to decrypt other messages. + // + DEBUG ((EFI_D_WARN, "TlsDecryptPacket: No data read from TLS object.\n")); + + ThisPlainMessageSize = 0; + } + + CopyMem (TempRecordHeader, RecordHeaderIn, RECORD_HEADER_LEN); + TempRecordHeader->Length = ThisPlainMessageSize; + BufferOutSize += RECORD_HEADER_LEN + ThisPlainMessageSize; + + BufferInPtr += RECORD_HEADER_LEN + ThisCipherMessageSize; + TempRecordHeader += RECORD_HEADER_LEN + ThisPlainMessageSize; + } + + FreePool (BufferIn); + BufferIn = NULL; + + // + // The caller will be responsible to handle the original fragment table + // + *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA)); + if (*FragmentTable == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ERROR; + } + + (*FragmentTable)[0].FragmentBuffer = BufferOut; + (*FragmentTable)[0].FragmentLength = BufferOutSize; + *FragmentCount = 1; + + return Status; + +ERROR: + + if (BufferIn != NULL) { + FreePool (BufferIn); + BufferIn = NULL; + } + + if (BufferOut != NULL) { + FreePool (BufferOut); + BufferOut = NULL; + } + + return Status; +} + diff --git a/NetworkPkg/TlsDxe/TlsImpl.h b/NetworkPkg/TlsDxe/TlsImpl.h index 71b1bdb7dc..3ae9d0d546 100644 --- a/NetworkPkg/TlsDxe/TlsImpl.h +++ b/NetworkPkg/TlsDxe/TlsImpl.h @@ -1,315 +1,316 @@ -/** @file - Header file of Miscellaneous Routines for TlsDxe driver. - -Copyright (c) 2016, Intel Corporation. All rights reserved.
- -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. - -**/ - -#ifndef __EFI_TLS_IMPL_H__ -#define __EFI_TLS_IMPL_H__ - -// -// Libraries -// -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// -// Consumed Protocols -// -#include -#include - -#include - -#include "TlsDriver.h" - -// -// Protocol instances -// -extern EFI_SERVICE_BINDING_PROTOCOL mTlsServiceBinding; -extern EFI_TLS_PROTOCOL mTlsProtocol; -extern EFI_TLS_CONFIGURATION_PROTOCOL mTlsConfigurationProtocol; - -#define RECORD_HEADER_LEN 5 /// ContentType(1) + Version(2) + Length(2) - -#define MAX_BUFFER_SIZE 32768 - -/** - Encrypt the message listed in fragment. - - @param[in] TlsInstance The pointer to the TLS instance. - @param[in, out] FragmentTable Pointer to a list of fragment. - On input these fragments contain the TLS header and - plain text TLS payload; - On output these fragments contain the TLS header and - cipher text TLS payload. - @param[in] FragmentCount Number of fragment. - - @retval EFI_SUCCESS The operation completed successfully. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_ABORTED TLS session state is incorrect. - @retval Others Other errors as indicated. -**/ -EFI_STATUS -TlsEncryptPacket ( - IN TLS_INSTANCE *TlsInstance, - IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable, - IN UINT32 *FragmentCount - ); - -/** - Decrypt the message listed in fragment. - - @param[in] TlsInstance The pointer to the TLS instance. - @param[in, out] FragmentTable Pointer to a list of fragment. - On input these fragments contain the TLS header and - cipher text TLS payload; - On output these fragments contain the TLS header and - plain text TLS payload. - @param[in] FragmentCount Number of fragment. - - @retval EFI_SUCCESS The operation completed successfully. - @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. - @retval EFI_ABORTED TLS session state is incorrect. - @retval Others Other errors as indicated. -**/ -EFI_STATUS -TlsDecryptPacket ( - IN TLS_INSTANCE *TlsInstance, - IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable, - IN UINT32 *FragmentCount - ); - -/** - Set TLS session data. - - The SetSessionData() function set data for a new TLS session. All session data should - be set before BuildResponsePacket() invoked. - - @param[in] This Pointer to the EFI_TLS_PROTOCOL instance. - @param[in] DataType TLS session data type. - @param[in] Data Pointer to session data. - @param[in] DataSize Total size of session data. - - @retval EFI_SUCCESS The TLS session data is set successfully. - @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - Data is NULL. - DataSize is 0. - @retval EFI_UNSUPPORTED The DataType is unsupported. - @retval EFI_ACCESS_DENIED If the DataType is one of below: - EfiTlsClientRandom - EfiTlsServerRandom - EfiTlsKeyMaterial - @retval EFI_NOT_READY Current TLS session state is NOT - EfiTlsSessionStateNotStarted. - @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. -**/ -EFI_STATUS -EFIAPI -TlsSetSessionData ( - IN EFI_TLS_PROTOCOL *This, - IN EFI_TLS_SESSION_DATA_TYPE DataType, - IN VOID *Data, - IN UINTN DataSize - ); - -/** - Get TLS session data. - - The GetSessionData() function return the TLS session information. - - @param[in] This Pointer to the EFI_TLS_PROTOCOL instance. - @param[in] DataType TLS session data type. - @param[in, out] Data Pointer to session data. - @param[in, out] DataSize Total size of session data. On input, it means - the size of Data buffer. On output, it means the size - of copied Data buffer if EFI_SUCCESS, and means the - size of desired Data buffer if EFI_BUFFER_TOO_SMALL. - - @retval EFI_SUCCESS The TLS session data is got successfully. - @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - DataSize is NULL. - Data is NULL if *DataSize is not zero. - @retval EFI_UNSUPPORTED The DataType is unsupported. - @retval EFI_NOT_FOUND The TLS session data is not found. - @retval EFI_NOT_READY The DataType is not ready in current session state. - @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data. -**/ -EFI_STATUS -EFIAPI -TlsGetSessionData ( - IN EFI_TLS_PROTOCOL *This, - IN EFI_TLS_SESSION_DATA_TYPE DataType, - IN OUT VOID *Data, OPTIONAL - IN OUT UINTN *DataSize - ); - -/** - Build response packet according to TLS state machine. This function is only valid for - alert, handshake and change_cipher_spec content type. - - The BuildResponsePacket() function builds TLS response packet in response to the TLS - request packet specified by RequestBuffer and RequestSize. If RequestBuffer is NULL and - RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS session - will be initiated and the response packet needs to be ClientHello. If RequestBuffer is - NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing, the TLS - session will be closed and response packet needs to be CloseNotify. If RequestBuffer is - NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the TLS - session has errors and the response packet needs to be Alert message based on error - type. - - @param[in] This Pointer to the EFI_TLS_PROTOCOL instance. - @param[in] RequestBuffer Pointer to the most recently received TLS packet. NULL - means TLS need initiate the TLS session and response - packet need to be ClientHello. - @param[in] RequestSize Packet size in bytes for the most recently received TLS - packet. 0 is only valid when RequestBuffer is NULL. - @param[out] Buffer Pointer to the buffer to hold the built packet. - @param[in, out] BufferSize Pointer to the buffer size in bytes. On input, it is - the buffer size provided by the caller. On output, it - is the buffer size in fact needed to contain the - packet. - - @retval EFI_SUCCESS The required TLS packet is built successfully. - @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - RequestBuffer is NULL but RequestSize is NOT 0. - RequestSize is 0 but RequestBuffer is NOT NULL. - BufferSize is NULL. - Buffer is NULL if *BufferSize is not zero. - @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the response packet. - @retval EFI_NOT_READY Current TLS session state is NOT ready to build - ResponsePacket. - @retval EFI_ABORTED Something wrong build response packet. -**/ -EFI_STATUS -EFIAPI -TlsBuildResponsePacket ( - IN EFI_TLS_PROTOCOL *This, - IN UINT8 *RequestBuffer, OPTIONAL - IN UINTN RequestSize, OPTIONAL - OUT UINT8 *Buffer, OPTIONAL - IN OUT UINTN *BufferSize - ); - -/** - Decrypt or encrypt TLS packet during session. This function is only valid after - session connected and for application_data content type. - - The ProcessPacket () function process each inbound or outbound TLS APP packet. - - @param[in] This Pointer to the EFI_TLS_PROTOCOL instance. - @param[in, out] FragmentTable Pointer to a list of fragment. The caller will take - responsible to handle the original FragmentTable while - it may be reallocated in TLS driver. If CryptMode is - EfiTlsEncrypt, on input these fragments contain the TLS - header and plain text TLS APP payload; on output these - fragments contain the TLS header and cipher text TLS - APP payload. If CryptMode is EfiTlsDecrypt, on input - these fragments contain the TLS header and cipher text - TLS APP payload; on output these fragments contain the - TLS header and plain text TLS APP payload. - @param[in] FragmentCount Number of fragment. - @param[in] CryptMode Crypt mode. - - @retval EFI_SUCCESS The operation completed successfully. - @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - FragmentTable is NULL. - FragmentCount is NULL. - CryptoMode is invalid. - @retval EFI_NOT_READY Current TLS session state is NOT - EfiTlsSessionDataTransferring. - @retval EFI_ABORTED Something wrong decryption the message. TLS session - status will become EfiTlsSessionError. The caller need - call BuildResponsePacket() to generate Error Alert - message and send it out. - @retval EFI_OUT_OF_RESOURCES No enough resource to finish the operation. -**/ -EFI_STATUS -EFIAPI -TlsProcessPacket ( - IN EFI_TLS_PROTOCOL *This, - IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable, - IN UINT32 *FragmentCount, - IN EFI_TLS_CRYPT_MODE CryptMode - ); - -/** - Set TLS configuration data. - - The SetData() function sets TLS configuration to non-volatile storage or volatile - storage. - - @param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance. - @param[in] DataType Configuration data type. - @param[in] Data Pointer to configuration data. - @param[in] DataSize Total size of configuration data. - - @retval EFI_SUCCESS The TLS configuration data is set successfully. - @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - Data is NULL. - DataSize is 0. - @retval EFI_UNSUPPORTED The DataType is unsupported. - @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. -**/ -EFI_STATUS -EFIAPI -TlsConfigurationSetData ( - IN EFI_TLS_CONFIGURATION_PROTOCOL *This, - IN EFI_TLS_CONFIG_DATA_TYPE DataType, - IN VOID *Data, - IN UINTN DataSize - ); - -/** - Get TLS configuration data. - - The GetData() function gets TLS configuration. - - @param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance. - @param[in] DataType Configuration data type. - @param[in, out] Data Pointer to configuration data. - @param[in, out] DataSize Total size of configuration data. On input, it means - the size of Data buffer. On output, it means the size - of copied Data buffer if EFI_SUCCESS, and means the - size of desired Data buffer if EFI_BUFFER_TOO_SMALL. - - @retval EFI_SUCCESS The TLS configuration data is got successfully. - @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - DataSize is NULL. - Data is NULL if *DataSize is not zero. - @retval EFI_UNSUPPORTED The DataType is unsupported. - @retval EFI_NOT_FOUND The TLS configuration data is not found. - @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data. -**/ -EFI_STATUS -EFIAPI -TlsConfigurationGetData ( - IN EFI_TLS_CONFIGURATION_PROTOCOL *This, - IN EFI_TLS_CONFIG_DATA_TYPE DataType, - IN OUT VOID *Data, OPTIONAL - IN OUT UINTN *DataSize - ); - -#endif +/** @file + Header file of Miscellaneous Routines for TlsDxe driver. + +Copyright (c) 2016, Intel Corporation. All rights reserved.
+ +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. + +**/ + +#ifndef __EFI_TLS_IMPL_H__ +#define __EFI_TLS_IMPL_H__ + +// +// Libraries +// +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// Consumed Protocols +// +#include +#include + +#include + +#include "TlsDriver.h" + +// +// Protocol instances +// +extern EFI_SERVICE_BINDING_PROTOCOL mTlsServiceBinding; +extern EFI_TLS_PROTOCOL mTlsProtocol; +extern EFI_TLS_CONFIGURATION_PROTOCOL mTlsConfigurationProtocol; + +#define RECORD_HEADER_LEN 5 /// ContentType(1) + Version(2) + Length(2) + +#define MAX_BUFFER_SIZE 32768 + +/** + Encrypt the message listed in fragment. + + @param[in] TlsInstance The pointer to the TLS instance. + @param[in, out] FragmentTable Pointer to a list of fragment. + On input these fragments contain the TLS header and + plain text TLS payload; + On output these fragments contain the TLS header and + cipher text TLS payload. + @param[in] FragmentCount Number of fragment. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. + @retval EFI_ABORTED TLS session state is incorrect. + @retval Others Other errors as indicated. +**/ +EFI_STATUS +TlsEncryptPacket ( + IN TLS_INSTANCE *TlsInstance, + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable, + IN UINT32 *FragmentCount + ); + +/** + Decrypt the message listed in fragment. + + @param[in] TlsInstance The pointer to the TLS instance. + @param[in, out] FragmentTable Pointer to a list of fragment. + On input these fragments contain the TLS header and + cipher text TLS payload; + On output these fragments contain the TLS header and + plain text TLS payload. + @param[in] FragmentCount Number of fragment. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources. + @retval EFI_ABORTED TLS session state is incorrect. + @retval Others Other errors as indicated. +**/ +EFI_STATUS +TlsDecryptPacket ( + IN TLS_INSTANCE *TlsInstance, + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable, + IN UINT32 *FragmentCount + ); + +/** + Set TLS session data. + + The SetSessionData() function set data for a new TLS session. All session data should + be set before BuildResponsePacket() invoked. + + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance. + @param[in] DataType TLS session data type. + @param[in] Data Pointer to session data. + @param[in] DataSize Total size of session data. + + @retval EFI_SUCCESS The TLS session data is set successfully. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + This is NULL. + Data is NULL. + DataSize is 0. + @retval EFI_UNSUPPORTED The DataType is unsupported. + @retval EFI_ACCESS_DENIED If the DataType is one of below: + EfiTlsClientRandom + EfiTlsServerRandom + EfiTlsKeyMaterial + @retval EFI_NOT_READY Current TLS session state is NOT + EfiTlsSessionStateNotStarted. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. +**/ +EFI_STATUS +EFIAPI +TlsSetSessionData ( + IN EFI_TLS_PROTOCOL *This, + IN EFI_TLS_SESSION_DATA_TYPE DataType, + IN VOID *Data, + IN UINTN DataSize + ); + +/** + Get TLS session data. + + The GetSessionData() function return the TLS session information. + + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance. + @param[in] DataType TLS session data type. + @param[in, out] Data Pointer to session data. + @param[in, out] DataSize Total size of session data. On input, it means + the size of Data buffer. On output, it means the size + of copied Data buffer if EFI_SUCCESS, and means the + size of desired Data buffer if EFI_BUFFER_TOO_SMALL. + + @retval EFI_SUCCESS The TLS session data is got successfully. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + This is NULL. + DataSize is NULL. + Data is NULL if *DataSize is not zero. + @retval EFI_UNSUPPORTED The DataType is unsupported. + @retval EFI_NOT_FOUND The TLS session data is not found. + @retval EFI_NOT_READY The DataType is not ready in current session state. + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data. +**/ +EFI_STATUS +EFIAPI +TlsGetSessionData ( + IN EFI_TLS_PROTOCOL *This, + IN EFI_TLS_SESSION_DATA_TYPE DataType, + IN OUT VOID *Data, OPTIONAL + IN OUT UINTN *DataSize + ); + +/** + Build response packet according to TLS state machine. This function is only valid for + alert, handshake and change_cipher_spec content type. + + The BuildResponsePacket() function builds TLS response packet in response to the TLS + request packet specified by RequestBuffer and RequestSize. If RequestBuffer is NULL and + RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS session + will be initiated and the response packet needs to be ClientHello. If RequestBuffer is + NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing, the TLS + session will be closed and response packet needs to be CloseNotify. If RequestBuffer is + NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the TLS + session has errors and the response packet needs to be Alert message based on error + type. + + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance. + @param[in] RequestBuffer Pointer to the most recently received TLS packet. NULL + means TLS need initiate the TLS session and response + packet need to be ClientHello. + @param[in] RequestSize Packet size in bytes for the most recently received TLS + packet. 0 is only valid when RequestBuffer is NULL. + @param[out] Buffer Pointer to the buffer to hold the built packet. + @param[in, out] BufferSize Pointer to the buffer size in bytes. On input, it is + the buffer size provided by the caller. On output, it + is the buffer size in fact needed to contain the + packet. + + @retval EFI_SUCCESS The required TLS packet is built successfully. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + This is NULL. + RequestBuffer is NULL but RequestSize is NOT 0. + RequestSize is 0 but RequestBuffer is NOT NULL. + BufferSize is NULL. + Buffer is NULL if *BufferSize is not zero. + @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the response packet. + @retval EFI_NOT_READY Current TLS session state is NOT ready to build + ResponsePacket. + @retval EFI_ABORTED Something wrong build response packet. +**/ +EFI_STATUS +EFIAPI +TlsBuildResponsePacket ( + IN EFI_TLS_PROTOCOL *This, + IN UINT8 *RequestBuffer, OPTIONAL + IN UINTN RequestSize, OPTIONAL + OUT UINT8 *Buffer, OPTIONAL + IN OUT UINTN *BufferSize + ); + +/** + Decrypt or encrypt TLS packet during session. This function is only valid after + session connected and for application_data content type. + + The ProcessPacket () function process each inbound or outbound TLS APP packet. + + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance. + @param[in, out] FragmentTable Pointer to a list of fragment. The caller will take + responsible to handle the original FragmentTable while + it may be reallocated in TLS driver. If CryptMode is + EfiTlsEncrypt, on input these fragments contain the TLS + header and plain text TLS APP payload; on output these + fragments contain the TLS header and cipher text TLS + APP payload. If CryptMode is EfiTlsDecrypt, on input + these fragments contain the TLS header and cipher text + TLS APP payload; on output these fragments contain the + TLS header and plain text TLS APP payload. + @param[in] FragmentCount Number of fragment. + @param[in] CryptMode Crypt mode. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + This is NULL. + FragmentTable is NULL. + FragmentCount is NULL. + CryptoMode is invalid. + @retval EFI_NOT_READY Current TLS session state is NOT + EfiTlsSessionDataTransferring. + @retval EFI_ABORTED Something wrong decryption the message. TLS session + status will become EfiTlsSessionError. The caller need + call BuildResponsePacket() to generate Error Alert + message and send it out. + @retval EFI_OUT_OF_RESOURCES No enough resource to finish the operation. +**/ +EFI_STATUS +EFIAPI +TlsProcessPacket ( + IN EFI_TLS_PROTOCOL *This, + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable, + IN UINT32 *FragmentCount, + IN EFI_TLS_CRYPT_MODE CryptMode + ); + +/** + Set TLS configuration data. + + The SetData() function sets TLS configuration to non-volatile storage or volatile + storage. + + @param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance. + @param[in] DataType Configuration data type. + @param[in] Data Pointer to configuration data. + @param[in] DataSize Total size of configuration data. + + @retval EFI_SUCCESS The TLS configuration data is set successfully. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + This is NULL. + Data is NULL. + DataSize is 0. + @retval EFI_UNSUPPORTED The DataType is unsupported. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. +**/ +EFI_STATUS +EFIAPI +TlsConfigurationSetData ( + IN EFI_TLS_CONFIGURATION_PROTOCOL *This, + IN EFI_TLS_CONFIG_DATA_TYPE DataType, + IN VOID *Data, + IN UINTN DataSize + ); + +/** + Get TLS configuration data. + + The GetData() function gets TLS configuration. + + @param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance. + @param[in] DataType Configuration data type. + @param[in, out] Data Pointer to configuration data. + @param[in, out] DataSize Total size of configuration data. On input, it means + the size of Data buffer. On output, it means the size + of copied Data buffer if EFI_SUCCESS, and means the + size of desired Data buffer if EFI_BUFFER_TOO_SMALL. + + @retval EFI_SUCCESS The TLS configuration data is got successfully. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + This is NULL. + DataSize is NULL. + Data is NULL if *DataSize is not zero. + @retval EFI_UNSUPPORTED The DataType is unsupported. + @retval EFI_NOT_FOUND The TLS configuration data is not found. + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data. +**/ +EFI_STATUS +EFIAPI +TlsConfigurationGetData ( + IN EFI_TLS_CONFIGURATION_PROTOCOL *This, + IN EFI_TLS_CONFIG_DATA_TYPE DataType, + IN OUT VOID *Data, OPTIONAL + IN OUT UINTN *DataSize + ); + +#endif + diff --git a/NetworkPkg/TlsDxe/TlsProtocol.c b/NetworkPkg/TlsDxe/TlsProtocol.c index 58a83c3ab7..ad4c922c60 100644 --- a/NetworkPkg/TlsDxe/TlsProtocol.c +++ b/NetworkPkg/TlsDxe/TlsProtocol.c @@ -1,632 +1,633 @@ -/** @file - Implementation of EFI TLS Protocol Interfaces. - - Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
- - 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 "TlsImpl.h" - -EFI_TLS_PROTOCOL mTlsProtocol = { - TlsSetSessionData, - TlsGetSessionData, - TlsBuildResponsePacket, - TlsProcessPacket -}; - -/** - Set TLS session data. - - The SetSessionData() function set data for a new TLS session. All session data should - be set before BuildResponsePacket() invoked. - - @param[in] This Pointer to the EFI_TLS_PROTOCOL instance. - @param[in] DataType TLS session data type. - @param[in] Data Pointer to session data. - @param[in] DataSize Total size of session data. - - @retval EFI_SUCCESS The TLS session data is set successfully. - @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - Data is NULL. - DataSize is 0. - @retval EFI_UNSUPPORTED The DataType is unsupported. - @retval EFI_ACCESS_DENIED If the DataType is one of below: - EfiTlsClientRandom - EfiTlsServerRandom - EfiTlsKeyMaterial - @retval EFI_NOT_READY Current TLS session state is NOT - EfiTlsSessionStateNotStarted. - @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. -**/ -EFI_STATUS -EFIAPI -TlsSetSessionData ( - IN EFI_TLS_PROTOCOL *This, - IN EFI_TLS_SESSION_DATA_TYPE DataType, - IN VOID *Data, - IN UINTN DataSize - ) -{ - EFI_STATUS Status; - TLS_INSTANCE *Instance; - UINT16 *CipherId; - UINTN Index; - - EFI_TPL OldTpl; - - Status = EFI_SUCCESS; - CipherId = NULL; - - if (This == NULL || Data == NULL || DataSize == 0) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Instance = TLS_INSTANCE_FROM_PROTOCOL (This); - - if (DataType != EfiTlsSessionState && Instance->TlsSessionState != EfiTlsSessionNotStarted){ - Status = EFI_NOT_READY; - goto ON_EXIT; - } - - switch (DataType) { - // - // Session Configuration - // - case EfiTlsVersion: - if (DataSize != sizeof (EFI_TLS_VERSION)) { - Status = EFI_INVALID_PARAMETER; - goto ON_EXIT; - } - - Status = TlsSetVersion (Instance->TlsConn, ((EFI_TLS_VERSION *) Data)->Major, ((EFI_TLS_VERSION *) Data)->Minor); - break; - case EfiTlsConnectionEnd: - if (DataSize != sizeof (EFI_TLS_CONNECTION_END)) { - Status = EFI_INVALID_PARAMETER; - goto ON_EXIT; - } - - Status = TlsSetConnectionEnd (Instance->TlsConn, *((EFI_TLS_CONNECTION_END *) Data)); - break; - case EfiTlsCipherList: - CipherId = AllocatePool (DataSize); - if (CipherId == NULL) { - Status = EFI_OUT_OF_RESOURCES; - goto ON_EXIT; - } - - for (Index = 0; Index < DataSize / sizeof (EFI_TLS_CIPHER); Index++) { - *(CipherId +Index) = HTONS (*(((UINT16 *) Data) + Index)); - } - - Status = TlsSetCipherList (Instance->TlsConn, CipherId, DataSize / sizeof (EFI_TLS_CIPHER)); - - FreePool (CipherId); - break; - case EfiTlsCompressionMethod: - // - // TLS seems only define one CompressionMethod.null, which specifies that data exchanged via the - // record protocol will not be compressed. - // More information from OpenSSL: http://www.openssl.org/docs/manmaster/ssl/SSL_COMP_add_compression_method.html - // The TLS RFC does however not specify compression methods or their corresponding identifiers, - // so there is currently no compatible way to integrate compression with unknown peers. - // It is therefore currently not recommended to integrate compression into applications. - // Applications for non-public use may agree on certain compression methods. - // Using different compression methods with the same identifier will lead to connection failure. - // - for (Index = 0; Index < DataSize / sizeof (EFI_TLS_COMPRESSION); Index++) { - Status = TlsSetCompressionMethod (*((UINT8 *) Data + Index)); - if (EFI_ERROR (Status)) { - break; - } - } - - break; - case EfiTlsExtensionData: - Status = EFI_UNSUPPORTED; - goto ON_EXIT; - case EfiTlsVerifyMethod: - if (DataSize != sizeof (EFI_TLS_VERIFY)) { - Status = EFI_INVALID_PARAMETER; - goto ON_EXIT; - } - - TlsSetVerify (Instance->TlsConn, *((UINT32 *) Data)); - break; - case EfiTlsSessionID: - if (DataSize != sizeof (EFI_TLS_SESSION_ID)) { - Status = EFI_INVALID_PARAMETER; - goto ON_EXIT; - } - - Status = TlsSetSessionId ( - Instance->TlsConn, - ((EFI_TLS_SESSION_ID *) Data)->Data, - ((EFI_TLS_SESSION_ID *) Data)->Length - ); - break; - case EfiTlsSessionState: - if (DataSize != sizeof (EFI_TLS_SESSION_STATE)) { - Status = EFI_INVALID_PARAMETER; - goto ON_EXIT; - } - - Instance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) Data; - break; - // - // Session information - // - case EfiTlsClientRandom: - Status = EFI_ACCESS_DENIED; - break; - case EfiTlsServerRandom: - Status = EFI_ACCESS_DENIED; - break; - case EfiTlsKeyMaterial: - Status = EFI_ACCESS_DENIED; - break; - // - // Unsupported type. - // - default: - Status = EFI_UNSUPPORTED; - } - -ON_EXIT: - gBS->RestoreTPL (OldTpl); - return Status; -} - -/** - Get TLS session data. - - The GetSessionData() function return the TLS session information. - - @param[in] This Pointer to the EFI_TLS_PROTOCOL instance. - @param[in] DataType TLS session data type. - @param[in, out] Data Pointer to session data. - @param[in, out] DataSize Total size of session data. On input, it means - the size of Data buffer. On output, it means the size - of copied Data buffer if EFI_SUCCESS, and means the - size of desired Data buffer if EFI_BUFFER_TOO_SMALL. - - @retval EFI_SUCCESS The TLS session data is got successfully. - @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - DataSize is NULL. - Data is NULL if *DataSize is not zero. - @retval EFI_UNSUPPORTED The DataType is unsupported. - @retval EFI_NOT_FOUND The TLS session data is not found. - @retval EFI_NOT_READY The DataType is not ready in current session state. - @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data. -**/ -EFI_STATUS -EFIAPI -TlsGetSessionData ( - IN EFI_TLS_PROTOCOL *This, - IN EFI_TLS_SESSION_DATA_TYPE DataType, - IN OUT VOID *Data, OPTIONAL - IN OUT UINTN *DataSize - ) -{ - EFI_STATUS Status; - TLS_INSTANCE *Instance; - - EFI_TPL OldTpl; - - Status = EFI_SUCCESS; - - if (This == NULL || DataSize == NULL || (Data == NULL && *DataSize != 0)) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Instance = TLS_INSTANCE_FROM_PROTOCOL (This); - - if (Instance->TlsSessionState == EfiTlsSessionNotStarted && - (DataType == EfiTlsSessionID || DataType == EfiTlsClientRandom || - DataType == EfiTlsServerRandom || DataType == EfiTlsKeyMaterial)) { - Status = EFI_NOT_READY; - goto ON_EXIT; - } - - switch (DataType) { - case EfiTlsVersion: - if (*DataSize < sizeof (EFI_TLS_VERSION)) { - *DataSize = sizeof (EFI_TLS_VERSION); - Status = EFI_BUFFER_TOO_SMALL; - goto ON_EXIT; - } - *DataSize = sizeof (EFI_TLS_VERSION); - *((UINT16 *) Data) = HTONS (TlsGetVersion (Instance->TlsConn)); - break; - case EfiTlsConnectionEnd: - if (*DataSize < sizeof (EFI_TLS_CONNECTION_END)) { - *DataSize = sizeof (EFI_TLS_CONNECTION_END); - Status = EFI_BUFFER_TOO_SMALL; - goto ON_EXIT; - } - *DataSize = sizeof (EFI_TLS_CONNECTION_END); - *((UINT8 *) Data) = TlsGetConnectionEnd (Instance->TlsConn); - break; - case EfiTlsCipherList: - // - // Get the current session cipher suite. - // - if (*DataSize < sizeof (EFI_TLS_CIPHER)) { - *DataSize = sizeof (EFI_TLS_CIPHER); - Status = EFI_BUFFER_TOO_SMALL; - goto ON_EXIT; - } - *DataSize = sizeof(EFI_TLS_CIPHER); - Status = TlsGetCurrentCipher (Instance->TlsConn, (UINT16 *) Data); - *((UINT16 *) Data) = HTONS (*((UINT16 *) Data)); - break; - case EfiTlsCompressionMethod: - // - // Get the current session compression method. - // - if (*DataSize < sizeof (EFI_TLS_COMPRESSION)) { - *DataSize = sizeof (EFI_TLS_COMPRESSION); - Status = EFI_BUFFER_TOO_SMALL; - goto ON_EXIT; - } - *DataSize = sizeof (EFI_TLS_COMPRESSION); - Status = TlsGetCurrentCompressionId (Instance->TlsConn, (UINT8 *) Data); - break; - case EfiTlsExtensionData: - Status = EFI_UNSUPPORTED; - goto ON_EXIT; - case EfiTlsVerifyMethod: - if (*DataSize < sizeof (EFI_TLS_VERIFY)) { - *DataSize = sizeof (EFI_TLS_VERIFY); - Status = EFI_BUFFER_TOO_SMALL; - goto ON_EXIT; - } - *DataSize = sizeof (EFI_TLS_VERIFY); - *((UINT32 *) Data) = TlsGetVerify (Instance->TlsConn); - break; - case EfiTlsSessionID: - if (*DataSize < sizeof (EFI_TLS_SESSION_ID)) { - *DataSize = sizeof (EFI_TLS_SESSION_ID); - Status = EFI_BUFFER_TOO_SMALL; - goto ON_EXIT; - } - *DataSize = sizeof (EFI_TLS_SESSION_ID); - Status = TlsGetSessionId ( - Instance->TlsConn, - ((EFI_TLS_SESSION_ID *) Data)->Data, - &(((EFI_TLS_SESSION_ID *) Data)->Length) - ); - break; - case EfiTlsSessionState: - if (*DataSize < sizeof (EFI_TLS_SESSION_STATE)) { - *DataSize = sizeof (EFI_TLS_SESSION_STATE); - Status = EFI_BUFFER_TOO_SMALL; - goto ON_EXIT; - } - *DataSize = sizeof (EFI_TLS_SESSION_STATE); - CopyMem (Data, &Instance->TlsSessionState, *DataSize); - break; - case EfiTlsClientRandom: - if (*DataSize < sizeof (EFI_TLS_RANDOM)) { - *DataSize = sizeof (EFI_TLS_RANDOM); - Status = EFI_BUFFER_TOO_SMALL; - goto ON_EXIT; - } - *DataSize = sizeof (EFI_TLS_RANDOM); - TlsGetClientRandom (Instance->TlsConn, (UINT8 *) Data); - break; - case EfiTlsServerRandom: - if (*DataSize < sizeof (EFI_TLS_RANDOM)) { - *DataSize = sizeof (EFI_TLS_RANDOM); - Status = EFI_BUFFER_TOO_SMALL; - goto ON_EXIT; - } - *DataSize = sizeof (EFI_TLS_RANDOM); - TlsGetServerRandom (Instance->TlsConn, (UINT8 *) Data); - break; - case EfiTlsKeyMaterial: - if (*DataSize < sizeof (EFI_TLS_MASTER_SECRET)) { - *DataSize = sizeof (EFI_TLS_MASTER_SECRET); - Status = EFI_BUFFER_TOO_SMALL; - goto ON_EXIT; - } - *DataSize = sizeof (EFI_TLS_MASTER_SECRET); - Status = TlsGetKeyMaterial (Instance->TlsConn, (UINT8 *) Data); - break; - // - // Unsupported type. - // - default: - Status = EFI_UNSUPPORTED; - } - -ON_EXIT: - gBS->RestoreTPL (OldTpl); - return Status; -} - -/** - Build response packet according to TLS state machine. This function is only valid for - alert, handshake and change_cipher_spec content type. - - The BuildResponsePacket() function builds TLS response packet in response to the TLS - request packet specified by RequestBuffer and RequestSize. If RequestBuffer is NULL and - RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS session - will be initiated and the response packet needs to be ClientHello. If RequestBuffer is - NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing, the TLS - session will be closed and response packet needs to be CloseNotify. If RequestBuffer is - NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the TLS - session has errors and the response packet needs to be Alert message based on error - type. - - @param[in] This Pointer to the EFI_TLS_PROTOCOL instance. - @param[in] RequestBuffer Pointer to the most recently received TLS packet. NULL - means TLS need initiate the TLS session and response - packet need to be ClientHello. - @param[in] RequestSize Packet size in bytes for the most recently received TLS - packet. 0 is only valid when RequestBuffer is NULL. - @param[out] Buffer Pointer to the buffer to hold the built packet. - @param[in, out] BufferSize Pointer to the buffer size in bytes. On input, it is - the buffer size provided by the caller. On output, it - is the buffer size in fact needed to contain the - packet. - - @retval EFI_SUCCESS The required TLS packet is built successfully. - @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - RequestBuffer is NULL but RequestSize is NOT 0. - RequestSize is 0 but RequestBuffer is NOT NULL. - BufferSize is NULL. - Buffer is NULL if *BufferSize is not zero. - @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the response packet. - @retval EFI_NOT_READY Current TLS session state is NOT ready to build - ResponsePacket. - @retval EFI_ABORTED Something wrong build response packet. -**/ -EFI_STATUS -EFIAPI -TlsBuildResponsePacket ( - IN EFI_TLS_PROTOCOL *This, - IN UINT8 *RequestBuffer, OPTIONAL - IN UINTN RequestSize, OPTIONAL - OUT UINT8 *Buffer, OPTIONAL - IN OUT UINTN *BufferSize - ) -{ - EFI_STATUS Status; - TLS_INSTANCE *Instance; - EFI_TPL OldTpl; - - Status = EFI_SUCCESS; - - if ((This == NULL) || (BufferSize == NULL) || - (RequestBuffer == NULL && RequestSize != 0) || - (RequestBuffer != NULL && RequestSize == 0) || - (Buffer == NULL && *BufferSize !=0)) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Instance = TLS_INSTANCE_FROM_PROTOCOL (This); - - if(RequestBuffer == NULL && RequestSize == 0) { - switch (Instance->TlsSessionState) { - case EfiTlsSessionNotStarted: - // - // ClientHello. - // - Status = TlsDoHandshake ( - Instance->TlsConn, - NULL, - 0, - Buffer, - BufferSize - ); - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - - // - // *BufferSize should not be zero when ClientHello. - // - if (*BufferSize == 0) { - Status = EFI_ABORTED; - goto ON_EXIT; - } - - Instance->TlsSessionState = EfiTlsSessionHandShaking; - - break; - case EfiTlsSessionClosing: - // - // TLS session will be closed and response packet needs to be CloseNotify. - // - Status = TlsCloseNotify ( - Instance->TlsConn, - Buffer, - BufferSize - ); - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - - // - // *BufferSize should not be zero when build CloseNotify message. - // - if (*BufferSize == 0) { - Status = EFI_ABORTED; - goto ON_EXIT; - } - - break; - case EfiTlsSessionError: - // - // TLS session has errors and the response packet needs to be Alert - // message based on error type. - // - Status = TlsHandleAlert ( - Instance->TlsConn, - NULL, - 0, - Buffer, - BufferSize - ); - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - - break; - default: - // - // Current TLS session state is NOT ready to build ResponsePacket. - // - Status = EFI_NOT_READY; - } - } else { - // - // 1. Received packet may have multiple TLS record messages. - // 2. One TLS record message may have multiple handshake protocol. - // 3. Some errors may be happened in handshake. - // TlsDoHandshake() can handle all of those cases. - // - if (TlsInHandshake (Instance->TlsConn)) { - Status = TlsDoHandshake ( - Instance->TlsConn, - RequestBuffer, - RequestSize, - Buffer, - BufferSize - ); - if (EFI_ERROR (Status)) { - goto ON_EXIT; - } - - if (!TlsInHandshake (Instance->TlsConn)) { - Instance->TlsSessionState = EfiTlsSessionDataTransferring; - } - } else { - // - // Must be alert message, Decrypt it and build the ResponsePacket. - // - ASSERT (((TLS_RECORD_HEADER *) RequestBuffer)->ContentType == TlsContentTypeAlert); - - Status = TlsHandleAlert ( - Instance->TlsConn, - RequestBuffer, - RequestSize, - Buffer, - BufferSize - ); - if (EFI_ERROR (Status)) { - if (Status != EFI_BUFFER_TOO_SMALL) { - Instance->TlsSessionState = EfiTlsSessionError; - } - - goto ON_EXIT; - } - } - } - -ON_EXIT: - gBS->RestoreTPL (OldTpl); - return Status; -} - -/** - Decrypt or encrypt TLS packet during session. This function is only valid after - session connected and for application_data content type. - - The ProcessPacket () function process each inbound or outbound TLS APP packet. - - @param[in] This Pointer to the EFI_TLS_PROTOCOL instance. - @param[in, out] FragmentTable Pointer to a list of fragment. The caller will take - responsible to handle the original FragmentTable while - it may be reallocated in TLS driver. If CryptMode is - EfiTlsEncrypt, on input these fragments contain the TLS - header and plain text TLS APP payload; on output these - fragments contain the TLS header and cipher text TLS - APP payload. If CryptMode is EfiTlsDecrypt, on input - these fragments contain the TLS header and cipher text - TLS APP payload; on output these fragments contain the - TLS header and plain text TLS APP payload. - @param[in] FragmentCount Number of fragment. - @param[in] CryptMode Crypt mode. - - @retval EFI_SUCCESS The operation completed successfully. - @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: - This is NULL. - FragmentTable is NULL. - FragmentCount is NULL. - CryptoMode is invalid. - @retval EFI_NOT_READY Current TLS session state is NOT - EfiTlsSessionDataTransferring. - @retval EFI_ABORTED Something wrong decryption the message. TLS session - status will become EfiTlsSessionError. The caller need - call BuildResponsePacket() to generate Error Alert - message and send it out. - @retval EFI_OUT_OF_RESOURCES No enough resource to finish the operation. -**/ -EFI_STATUS -EFIAPI -TlsProcessPacket ( - IN EFI_TLS_PROTOCOL *This, - IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable, - IN UINT32 *FragmentCount, - IN EFI_TLS_CRYPT_MODE CryptMode - ) -{ - EFI_STATUS Status; - TLS_INSTANCE *Instance; - - EFI_TPL OldTpl; - - Status = EFI_SUCCESS; - - if (This == NULL || FragmentTable == NULL || FragmentCount == NULL) { - return EFI_INVALID_PARAMETER; - } - - OldTpl = gBS->RaiseTPL (TPL_CALLBACK); - - Instance = TLS_INSTANCE_FROM_PROTOCOL (This); - - if (Instance->TlsSessionState != EfiTlsSessionDataTransferring) { - Status = EFI_NOT_READY; - goto ON_EXIT; - } - - // - // Packet sent or received may have multiple TLS record messages (Application data type). - // So,on input these fragments contain the TLS header and TLS APP payload; - // on output these fragments also contain the TLS header and TLS APP payload. - // - switch (CryptMode) { - case EfiTlsEncrypt: - Status = TlsEncryptPacket (Instance, FragmentTable, FragmentCount); - break; - case EfiTlsDecrypt: - Status = TlsDecryptPacket (Instance, FragmentTable, FragmentCount); - break; - default: - return EFI_INVALID_PARAMETER; - } - -ON_EXIT: - gBS->RestoreTPL (OldTpl); - return Status; -} +/** @file + Implementation of EFI TLS Protocol Interfaces. + + Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
+ + 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 "TlsImpl.h" + +EFI_TLS_PROTOCOL mTlsProtocol = { + TlsSetSessionData, + TlsGetSessionData, + TlsBuildResponsePacket, + TlsProcessPacket +}; + +/** + Set TLS session data. + + The SetSessionData() function set data for a new TLS session. All session data should + be set before BuildResponsePacket() invoked. + + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance. + @param[in] DataType TLS session data type. + @param[in] Data Pointer to session data. + @param[in] DataSize Total size of session data. + + @retval EFI_SUCCESS The TLS session data is set successfully. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + This is NULL. + Data is NULL. + DataSize is 0. + @retval EFI_UNSUPPORTED The DataType is unsupported. + @retval EFI_ACCESS_DENIED If the DataType is one of below: + EfiTlsClientRandom + EfiTlsServerRandom + EfiTlsKeyMaterial + @retval EFI_NOT_READY Current TLS session state is NOT + EfiTlsSessionStateNotStarted. + @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated. +**/ +EFI_STATUS +EFIAPI +TlsSetSessionData ( + IN EFI_TLS_PROTOCOL *This, + IN EFI_TLS_SESSION_DATA_TYPE DataType, + IN VOID *Data, + IN UINTN DataSize + ) +{ + EFI_STATUS Status; + TLS_INSTANCE *Instance; + UINT16 *CipherId; + UINTN Index; + + EFI_TPL OldTpl; + + Status = EFI_SUCCESS; + CipherId = NULL; + + if (This == NULL || Data == NULL || DataSize == 0) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + Instance = TLS_INSTANCE_FROM_PROTOCOL (This); + + if (DataType != EfiTlsSessionState && Instance->TlsSessionState != EfiTlsSessionNotStarted){ + Status = EFI_NOT_READY; + goto ON_EXIT; + } + + switch (DataType) { + // + // Session Configuration + // + case EfiTlsVersion: + if (DataSize != sizeof (EFI_TLS_VERSION)) { + Status = EFI_INVALID_PARAMETER; + goto ON_EXIT; + } + + Status = TlsSetVersion (Instance->TlsConn, ((EFI_TLS_VERSION *) Data)->Major, ((EFI_TLS_VERSION *) Data)->Minor); + break; + case EfiTlsConnectionEnd: + if (DataSize != sizeof (EFI_TLS_CONNECTION_END)) { + Status = EFI_INVALID_PARAMETER; + goto ON_EXIT; + } + + Status = TlsSetConnectionEnd (Instance->TlsConn, *((EFI_TLS_CONNECTION_END *) Data)); + break; + case EfiTlsCipherList: + CipherId = AllocatePool (DataSize); + if (CipherId == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto ON_EXIT; + } + + for (Index = 0; Index < DataSize / sizeof (EFI_TLS_CIPHER); Index++) { + *(CipherId +Index) = HTONS (*(((UINT16 *) Data) + Index)); + } + + Status = TlsSetCipherList (Instance->TlsConn, CipherId, DataSize / sizeof (EFI_TLS_CIPHER)); + + FreePool (CipherId); + break; + case EfiTlsCompressionMethod: + // + // TLS seems only define one CompressionMethod.null, which specifies that data exchanged via the + // record protocol will not be compressed. + // More information from OpenSSL: http://www.openssl.org/docs/manmaster/ssl/SSL_COMP_add_compression_method.html + // The TLS RFC does however not specify compression methods or their corresponding identifiers, + // so there is currently no compatible way to integrate compression with unknown peers. + // It is therefore currently not recommended to integrate compression into applications. + // Applications for non-public use may agree on certain compression methods. + // Using different compression methods with the same identifier will lead to connection failure. + // + for (Index = 0; Index < DataSize / sizeof (EFI_TLS_COMPRESSION); Index++) { + Status = TlsSetCompressionMethod (*((UINT8 *) Data + Index)); + if (EFI_ERROR (Status)) { + break; + } + } + + break; + case EfiTlsExtensionData: + Status = EFI_UNSUPPORTED; + goto ON_EXIT; + case EfiTlsVerifyMethod: + if (DataSize != sizeof (EFI_TLS_VERIFY)) { + Status = EFI_INVALID_PARAMETER; + goto ON_EXIT; + } + + TlsSetVerify (Instance->TlsConn, *((UINT32 *) Data)); + break; + case EfiTlsSessionID: + if (DataSize != sizeof (EFI_TLS_SESSION_ID)) { + Status = EFI_INVALID_PARAMETER; + goto ON_EXIT; + } + + Status = TlsSetSessionId ( + Instance->TlsConn, + ((EFI_TLS_SESSION_ID *) Data)->Data, + ((EFI_TLS_SESSION_ID *) Data)->Length + ); + break; + case EfiTlsSessionState: + if (DataSize != sizeof (EFI_TLS_SESSION_STATE)) { + Status = EFI_INVALID_PARAMETER; + goto ON_EXIT; + } + + Instance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) Data; + break; + // + // Session information + // + case EfiTlsClientRandom: + Status = EFI_ACCESS_DENIED; + break; + case EfiTlsServerRandom: + Status = EFI_ACCESS_DENIED; + break; + case EfiTlsKeyMaterial: + Status = EFI_ACCESS_DENIED; + break; + // + // Unsupported type. + // + default: + Status = EFI_UNSUPPORTED; + } + +ON_EXIT: + gBS->RestoreTPL (OldTpl); + return Status; +} + +/** + Get TLS session data. + + The GetSessionData() function return the TLS session information. + + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance. + @param[in] DataType TLS session data type. + @param[in, out] Data Pointer to session data. + @param[in, out] DataSize Total size of session data. On input, it means + the size of Data buffer. On output, it means the size + of copied Data buffer if EFI_SUCCESS, and means the + size of desired Data buffer if EFI_BUFFER_TOO_SMALL. + + @retval EFI_SUCCESS The TLS session data is got successfully. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + This is NULL. + DataSize is NULL. + Data is NULL if *DataSize is not zero. + @retval EFI_UNSUPPORTED The DataType is unsupported. + @retval EFI_NOT_FOUND The TLS session data is not found. + @retval EFI_NOT_READY The DataType is not ready in current session state. + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data. +**/ +EFI_STATUS +EFIAPI +TlsGetSessionData ( + IN EFI_TLS_PROTOCOL *This, + IN EFI_TLS_SESSION_DATA_TYPE DataType, + IN OUT VOID *Data, OPTIONAL + IN OUT UINTN *DataSize + ) +{ + EFI_STATUS Status; + TLS_INSTANCE *Instance; + + EFI_TPL OldTpl; + + Status = EFI_SUCCESS; + + if (This == NULL || DataSize == NULL || (Data == NULL && *DataSize != 0)) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + Instance = TLS_INSTANCE_FROM_PROTOCOL (This); + + if (Instance->TlsSessionState == EfiTlsSessionNotStarted && + (DataType == EfiTlsSessionID || DataType == EfiTlsClientRandom || + DataType == EfiTlsServerRandom || DataType == EfiTlsKeyMaterial)) { + Status = EFI_NOT_READY; + goto ON_EXIT; + } + + switch (DataType) { + case EfiTlsVersion: + if (*DataSize < sizeof (EFI_TLS_VERSION)) { + *DataSize = sizeof (EFI_TLS_VERSION); + Status = EFI_BUFFER_TOO_SMALL; + goto ON_EXIT; + } + *DataSize = sizeof (EFI_TLS_VERSION); + *((UINT16 *) Data) = HTONS (TlsGetVersion (Instance->TlsConn)); + break; + case EfiTlsConnectionEnd: + if (*DataSize < sizeof (EFI_TLS_CONNECTION_END)) { + *DataSize = sizeof (EFI_TLS_CONNECTION_END); + Status = EFI_BUFFER_TOO_SMALL; + goto ON_EXIT; + } + *DataSize = sizeof (EFI_TLS_CONNECTION_END); + *((UINT8 *) Data) = TlsGetConnectionEnd (Instance->TlsConn); + break; + case EfiTlsCipherList: + // + // Get the current session cipher suite. + // + if (*DataSize < sizeof (EFI_TLS_CIPHER)) { + *DataSize = sizeof (EFI_TLS_CIPHER); + Status = EFI_BUFFER_TOO_SMALL; + goto ON_EXIT; + } + *DataSize = sizeof(EFI_TLS_CIPHER); + Status = TlsGetCurrentCipher (Instance->TlsConn, (UINT16 *) Data); + *((UINT16 *) Data) = HTONS (*((UINT16 *) Data)); + break; + case EfiTlsCompressionMethod: + // + // Get the current session compression method. + // + if (*DataSize < sizeof (EFI_TLS_COMPRESSION)) { + *DataSize = sizeof (EFI_TLS_COMPRESSION); + Status = EFI_BUFFER_TOO_SMALL; + goto ON_EXIT; + } + *DataSize = sizeof (EFI_TLS_COMPRESSION); + Status = TlsGetCurrentCompressionId (Instance->TlsConn, (UINT8 *) Data); + break; + case EfiTlsExtensionData: + Status = EFI_UNSUPPORTED; + goto ON_EXIT; + case EfiTlsVerifyMethod: + if (*DataSize < sizeof (EFI_TLS_VERIFY)) { + *DataSize = sizeof (EFI_TLS_VERIFY); + Status = EFI_BUFFER_TOO_SMALL; + goto ON_EXIT; + } + *DataSize = sizeof (EFI_TLS_VERIFY); + *((UINT32 *) Data) = TlsGetVerify (Instance->TlsConn); + break; + case EfiTlsSessionID: + if (*DataSize < sizeof (EFI_TLS_SESSION_ID)) { + *DataSize = sizeof (EFI_TLS_SESSION_ID); + Status = EFI_BUFFER_TOO_SMALL; + goto ON_EXIT; + } + *DataSize = sizeof (EFI_TLS_SESSION_ID); + Status = TlsGetSessionId ( + Instance->TlsConn, + ((EFI_TLS_SESSION_ID *) Data)->Data, + &(((EFI_TLS_SESSION_ID *) Data)->Length) + ); + break; + case EfiTlsSessionState: + if (*DataSize < sizeof (EFI_TLS_SESSION_STATE)) { + *DataSize = sizeof (EFI_TLS_SESSION_STATE); + Status = EFI_BUFFER_TOO_SMALL; + goto ON_EXIT; + } + *DataSize = sizeof (EFI_TLS_SESSION_STATE); + CopyMem (Data, &Instance->TlsSessionState, *DataSize); + break; + case EfiTlsClientRandom: + if (*DataSize < sizeof (EFI_TLS_RANDOM)) { + *DataSize = sizeof (EFI_TLS_RANDOM); + Status = EFI_BUFFER_TOO_SMALL; + goto ON_EXIT; + } + *DataSize = sizeof (EFI_TLS_RANDOM); + TlsGetClientRandom (Instance->TlsConn, (UINT8 *) Data); + break; + case EfiTlsServerRandom: + if (*DataSize < sizeof (EFI_TLS_RANDOM)) { + *DataSize = sizeof (EFI_TLS_RANDOM); + Status = EFI_BUFFER_TOO_SMALL; + goto ON_EXIT; + } + *DataSize = sizeof (EFI_TLS_RANDOM); + TlsGetServerRandom (Instance->TlsConn, (UINT8 *) Data); + break; + case EfiTlsKeyMaterial: + if (*DataSize < sizeof (EFI_TLS_MASTER_SECRET)) { + *DataSize = sizeof (EFI_TLS_MASTER_SECRET); + Status = EFI_BUFFER_TOO_SMALL; + goto ON_EXIT; + } + *DataSize = sizeof (EFI_TLS_MASTER_SECRET); + Status = TlsGetKeyMaterial (Instance->TlsConn, (UINT8 *) Data); + break; + // + // Unsupported type. + // + default: + Status = EFI_UNSUPPORTED; + } + +ON_EXIT: + gBS->RestoreTPL (OldTpl); + return Status; +} + +/** + Build response packet according to TLS state machine. This function is only valid for + alert, handshake and change_cipher_spec content type. + + The BuildResponsePacket() function builds TLS response packet in response to the TLS + request packet specified by RequestBuffer and RequestSize. If RequestBuffer is NULL and + RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS session + will be initiated and the response packet needs to be ClientHello. If RequestBuffer is + NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing, the TLS + session will be closed and response packet needs to be CloseNotify. If RequestBuffer is + NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the TLS + session has errors and the response packet needs to be Alert message based on error + type. + + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance. + @param[in] RequestBuffer Pointer to the most recently received TLS packet. NULL + means TLS need initiate the TLS session and response + packet need to be ClientHello. + @param[in] RequestSize Packet size in bytes for the most recently received TLS + packet. 0 is only valid when RequestBuffer is NULL. + @param[out] Buffer Pointer to the buffer to hold the built packet. + @param[in, out] BufferSize Pointer to the buffer size in bytes. On input, it is + the buffer size provided by the caller. On output, it + is the buffer size in fact needed to contain the + packet. + + @retval EFI_SUCCESS The required TLS packet is built successfully. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + This is NULL. + RequestBuffer is NULL but RequestSize is NOT 0. + RequestSize is 0 but RequestBuffer is NOT NULL. + BufferSize is NULL. + Buffer is NULL if *BufferSize is not zero. + @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the response packet. + @retval EFI_NOT_READY Current TLS session state is NOT ready to build + ResponsePacket. + @retval EFI_ABORTED Something wrong build response packet. +**/ +EFI_STATUS +EFIAPI +TlsBuildResponsePacket ( + IN EFI_TLS_PROTOCOL *This, + IN UINT8 *RequestBuffer, OPTIONAL + IN UINTN RequestSize, OPTIONAL + OUT UINT8 *Buffer, OPTIONAL + IN OUT UINTN *BufferSize + ) +{ + EFI_STATUS Status; + TLS_INSTANCE *Instance; + EFI_TPL OldTpl; + + Status = EFI_SUCCESS; + + if ((This == NULL) || (BufferSize == NULL) || + (RequestBuffer == NULL && RequestSize != 0) || + (RequestBuffer != NULL && RequestSize == 0) || + (Buffer == NULL && *BufferSize !=0)) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + Instance = TLS_INSTANCE_FROM_PROTOCOL (This); + + if(RequestBuffer == NULL && RequestSize == 0) { + switch (Instance->TlsSessionState) { + case EfiTlsSessionNotStarted: + // + // ClientHello. + // + Status = TlsDoHandshake ( + Instance->TlsConn, + NULL, + 0, + Buffer, + BufferSize + ); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + // + // *BufferSize should not be zero when ClientHello. + // + if (*BufferSize == 0) { + Status = EFI_ABORTED; + goto ON_EXIT; + } + + Instance->TlsSessionState = EfiTlsSessionHandShaking; + + break; + case EfiTlsSessionClosing: + // + // TLS session will be closed and response packet needs to be CloseNotify. + // + Status = TlsCloseNotify ( + Instance->TlsConn, + Buffer, + BufferSize + ); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + // + // *BufferSize should not be zero when build CloseNotify message. + // + if (*BufferSize == 0) { + Status = EFI_ABORTED; + goto ON_EXIT; + } + + break; + case EfiTlsSessionError: + // + // TLS session has errors and the response packet needs to be Alert + // message based on error type. + // + Status = TlsHandleAlert ( + Instance->TlsConn, + NULL, + 0, + Buffer, + BufferSize + ); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + break; + default: + // + // Current TLS session state is NOT ready to build ResponsePacket. + // + Status = EFI_NOT_READY; + } + } else { + // + // 1. Received packet may have multiple TLS record messages. + // 2. One TLS record message may have multiple handshake protocol. + // 3. Some errors may be happened in handshake. + // TlsDoHandshake() can handle all of those cases. + // + if (TlsInHandshake (Instance->TlsConn)) { + Status = TlsDoHandshake ( + Instance->TlsConn, + RequestBuffer, + RequestSize, + Buffer, + BufferSize + ); + if (EFI_ERROR (Status)) { + goto ON_EXIT; + } + + if (!TlsInHandshake (Instance->TlsConn)) { + Instance->TlsSessionState = EfiTlsSessionDataTransferring; + } + } else { + // + // Must be alert message, Decrypt it and build the ResponsePacket. + // + ASSERT (((TLS_RECORD_HEADER *) RequestBuffer)->ContentType == TlsContentTypeAlert); + + Status = TlsHandleAlert ( + Instance->TlsConn, + RequestBuffer, + RequestSize, + Buffer, + BufferSize + ); + if (EFI_ERROR (Status)) { + if (Status != EFI_BUFFER_TOO_SMALL) { + Instance->TlsSessionState = EfiTlsSessionError; + } + + goto ON_EXIT; + } + } + } + +ON_EXIT: + gBS->RestoreTPL (OldTpl); + return Status; +} + +/** + Decrypt or encrypt TLS packet during session. This function is only valid after + session connected and for application_data content type. + + The ProcessPacket () function process each inbound or outbound TLS APP packet. + + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance. + @param[in, out] FragmentTable Pointer to a list of fragment. The caller will take + responsible to handle the original FragmentTable while + it may be reallocated in TLS driver. If CryptMode is + EfiTlsEncrypt, on input these fragments contain the TLS + header and plain text TLS APP payload; on output these + fragments contain the TLS header and cipher text TLS + APP payload. If CryptMode is EfiTlsDecrypt, on input + these fragments contain the TLS header and cipher text + TLS APP payload; on output these fragments contain the + TLS header and plain text TLS APP payload. + @param[in] FragmentCount Number of fragment. + @param[in] CryptMode Crypt mode. + + @retval EFI_SUCCESS The operation completed successfully. + @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE: + This is NULL. + FragmentTable is NULL. + FragmentCount is NULL. + CryptoMode is invalid. + @retval EFI_NOT_READY Current TLS session state is NOT + EfiTlsSessionDataTransferring. + @retval EFI_ABORTED Something wrong decryption the message. TLS session + status will become EfiTlsSessionError. The caller need + call BuildResponsePacket() to generate Error Alert + message and send it out. + @retval EFI_OUT_OF_RESOURCES No enough resource to finish the operation. +**/ +EFI_STATUS +EFIAPI +TlsProcessPacket ( + IN EFI_TLS_PROTOCOL *This, + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable, + IN UINT32 *FragmentCount, + IN EFI_TLS_CRYPT_MODE CryptMode + ) +{ + EFI_STATUS Status; + TLS_INSTANCE *Instance; + + EFI_TPL OldTpl; + + Status = EFI_SUCCESS; + + if (This == NULL || FragmentTable == NULL || FragmentCount == NULL) { + return EFI_INVALID_PARAMETER; + } + + OldTpl = gBS->RaiseTPL (TPL_CALLBACK); + + Instance = TLS_INSTANCE_FROM_PROTOCOL (This); + + if (Instance->TlsSessionState != EfiTlsSessionDataTransferring) { + Status = EFI_NOT_READY; + goto ON_EXIT; + } + + // + // Packet sent or received may have multiple TLS record messages (Application data type). + // So,on input these fragments contain the TLS header and TLS APP payload; + // on output these fragments also contain the TLS header and TLS APP payload. + // + switch (CryptMode) { + case EfiTlsEncrypt: + Status = TlsEncryptPacket (Instance, FragmentTable, FragmentCount); + break; + case EfiTlsDecrypt: + Status = TlsDecryptPacket (Instance, FragmentTable, FragmentCount); + break; + default: + return EFI_INVALID_PARAMETER; + } + +ON_EXIT: + gBS->RestoreTPL (OldTpl); + return Status; +} +