/** @file\r
Miscellaneous routines for HttpDxe driver.\r
\r
-Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include "HttpDriver.h"\r
\r
/**\r
- The common notify function used in HTTP driver. \r
+ The common notify function used in HTTP driver.\r
\r
@param[in] Event The event signaled.\r
@param[in] Context The context.\r
if (Context == NULL) {\r
return ;\r
}\r
- \r
+\r
Wrap = (HTTP_TOKEN_WRAP *) Context;\r
HttpInstance = Wrap->HttpInstance;\r
- \r
+\r
if (!HttpInstance->LocalAddressIsIPv6) {\r
Wrap->HttpToken->Status = Wrap->TcpWrap.Tx4Token.CompletionToken.Status;\r
gBS->SignalEvent (Wrap->HttpToken->Event);\r
if (Wrap->TcpWrap.Tx4Token.CompletionToken.Event != NULL) {\r
gBS->CloseEvent (Wrap->TcpWrap.Tx4Token.CompletionToken.Event);\r
}\r
- \r
+\r
} else {\r
Wrap->HttpToken->Status = Wrap->TcpWrap.Tx6Token.CompletionToken.Status;\r
gBS->SignalEvent (Wrap->HttpToken->Event);\r
- \r
+\r
//\r
// Free resources.\r
//\r
\r
if (Wrap->TcpWrap.Tx6Token.CompletionToken.Event != NULL) {\r
gBS->CloseEvent (Wrap->TcpWrap.Tx6Token.CompletionToken.Event);\r
- } \r
+ }\r
}\r
\r
\r
Wrap = (HTTP_TOKEN_WRAP *) Context;\r
HttpInstance = Wrap->HttpInstance;\r
UsingIpv6 = HttpInstance->LocalAddressIsIPv6;\r
- \r
+\r
if (UsingIpv6) {\r
gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event);\r
Wrap->TcpWrap.Rx6Token.CompletionToken.Event = NULL;\r
- \r
+\r
if (EFI_ERROR (Wrap->TcpWrap.Rx6Token.CompletionToken.Status)) {\r
DEBUG ((EFI_D_ERROR, "HttpTcpReceiveNotifyDpc: %r!\n", Wrap->TcpWrap.Rx6Token.CompletionToken.Status));\r
Wrap->HttpToken->Status = Wrap->TcpWrap.Rx6Token.CompletionToken.Status;\r
if (Item != NULL) {\r
NetMapRemoveItem (&HttpInstance->RxTokens, Item, NULL);\r
}\r
- \r
+\r
FreePool (Wrap);\r
Wrap = NULL;\r
- \r
+\r
return ;\r
}\r
\r
} else {\r
gBS->CloseEvent (Wrap->TcpWrap.Rx4Token.CompletionToken.Event);\r
Wrap->TcpWrap.Rx4Token.CompletionToken.Event = NULL;\r
- \r
+\r
if (EFI_ERROR (Wrap->TcpWrap.Rx4Token.CompletionToken.Status)) {\r
DEBUG ((EFI_D_ERROR, "HttpTcpReceiveNotifyDpc: %r!\n", Wrap->TcpWrap.Rx4Token.CompletionToken.Status));\r
Wrap->HttpToken->Status = Wrap->TcpWrap.Rx4Token.CompletionToken.Status;\r
gBS->SignalEvent (Wrap->HttpToken->Event);\r
- \r
+\r
Item = NetMapFindKey (&HttpInstance->RxTokens, Wrap->HttpToken);\r
if (Item != NULL) {\r
NetMapRemoveItem (&HttpInstance->RxTokens, Item, NULL);\r
}\r
- \r
+\r
FreePool (Wrap);\r
Wrap = NULL;\r
- \r
+\r
return ;\r
}\r
}\r
Length = (UINTN) Wrap->TcpWrap.Rx4Data.FragmentTable[0].FragmentLength;\r
}\r
\r
+ //\r
+ // Record the CallbackData data.\r
+ //\r
+ HttpInstance->CallbackData.Wrap = (VOID *) Wrap;\r
+ HttpInstance->CallbackData.ParseData = Wrap->HttpToken->Message->Body;\r
+ HttpInstance->CallbackData.ParseDataLength = Length;\r
+\r
+ //\r
+ // Parse Body with CallbackData data.\r
+ //\r
Status = HttpParseMessageBody (\r
HttpInstance->MsgParser,\r
Length,\r
// We receive part of header of next HTTP msg.\r
//\r
if (HttpInstance->NextMsg != NULL) {\r
- Wrap->HttpToken->Message->BodyLength = HttpInstance->NextMsg - \r
+ Wrap->HttpToken->Message->BodyLength = HttpInstance->NextMsg -\r
(CHAR8 *) Wrap->HttpToken->Message->Body;\r
HttpInstance->CacheLen = Length - Wrap->HttpToken->Message->BodyLength;\r
if (HttpInstance->CacheLen != 0) {\r
} else {\r
Wrap->HttpToken->Status = Wrap->TcpWrap.Rx4Token.CompletionToken.Status;\r
}\r
- \r
+\r
\r
gBS->SignalEvent (Wrap->HttpToken->Event);\r
\r
if (EFI_ERROR (Status)) {\r
goto ERROR;\r
}\r
- \r
+\r
} else {\r
//\r
// Create events for variuos asynchronous operations.\r
goto ERROR;\r
}\r
}\r
- \r
+\r
return EFI_SUCCESS;\r
\r
ERROR:\r
HttpInstance->Tcp4CloseToken.CompletionToken.Event = NULL;\r
}\r
}\r
- \r
+\r
}\r
\r
/**\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- \r
+\r
TcpWrap->Tx4Data.Push = TRUE;\r
TcpWrap->Tx4Data.Urgent = FALSE;\r
TcpWrap->Tx4Data.FragmentCount = 1;\r
TcpWrap->Tx6Data.FragmentCount = 1;\r
TcpWrap->Tx6Token.Packet.TxData = &Wrap->TcpWrap.Tx6Data;\r
TcpWrap->Tx6Token.CompletionToken.Status =EFI_NOT_READY;\r
- \r
+\r
}\r
- \r
+\r
return EFI_SUCCESS;\r
}\r
\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- \r
+\r
HttpInstance->Rx4Data.FragmentCount = 1;\r
HttpInstance->Rx4Token.Packet.RxData = &HttpInstance->Rx4Data;\r
HttpInstance->Rx4Token.CompletionToken.Status = EFI_NOT_READY;\r
HttpInstance->Rx6Data.FragmentCount =1;\r
HttpInstance->Rx6Token.Packet.RxData = &HttpInstance->Rx6Data;\r
HttpInstance->Rx6Token.CompletionToken.Status = EFI_NOT_READY;\r
- \r
+\r
}\r
\r
\r
**/\r
EFI_STATUS\r
HttpCreateTcpRxEvent (\r
- IN HTTP_TOKEN_WRAP *Wrap \r
+ IN HTTP_TOKEN_WRAP *Wrap\r
)\r
{\r
EFI_STATUS Status;\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- \r
+\r
TcpWrap->Rx4Data.FragmentCount = 1;\r
TcpWrap->Rx4Token.Packet.RxData = &Wrap->TcpWrap.Rx4Data;\r
TcpWrap->Rx4Token.CompletionToken.Status = EFI_NOT_READY;\r
HttpTcpReceiveNotify,\r
Wrap,\r
&TcpWrap->Rx6Token.CompletionToken.Event\r
- ); \r
+ );\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
TcpWrap->Rx6Token.Packet.RxData = &Wrap->TcpWrap.Rx6Data;\r
TcpWrap->Rx6Token.CompletionToken.Status = EFI_NOT_READY;\r
}\r
- \r
+\r
return EFI_SUCCESS;\r
}\r
\r
Close Events for Tcp Receive Tokens for HTTP body and HTTP header.\r
\r
@param[in] Wrap Pointer to HTTP token's wrap data.\r
- \r
+\r
**/\r
VOID\r
HttpCloseTcpRxEvent (\r
\r
ASSERT (Wrap != NULL);\r
HttpInstance = Wrap->HttpInstance;\r
- \r
+\r
if (HttpInstance->LocalAddressIsIPv6) {\r
if (Wrap->TcpWrap.Rx6Token.CompletionToken.Event != NULL) {\r
gBS->CloseEvent (Wrap->TcpWrap.Rx6Token.CompletionToken.Event);\r
if (Wrap->TcpWrap.Rx4Token.CompletionToken.Event != NULL) {\r
gBS->CloseEvent (Wrap->TcpWrap.Rx4Token.CompletionToken.Event);\r
}\r
- \r
+\r
if (HttpInstance->Rx4Token.CompletionToken.Event != NULL) {\r
gBS->CloseEvent (HttpInstance->Rx4Token.CompletionToken.Event);\r
HttpInstance->Rx4Token.CompletionToken.Event = NULL;\r
@param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.\r
@param[in] IpVersion Indicate us TCP4 protocol or TCP6 protocol.\r
\r
- @retval EFI_SUCCESS HTTP_PROTOCOL structure is initialized successfully. \r
+ @retval EFI_SUCCESS HTTP_PROTOCOL structure is initialized successfully.\r
@retval Others Other error as indicated.\r
\r
**/\r
EFI_STATUS Status;\r
VOID *Interface;\r
BOOLEAN UsingIpv6;\r
- \r
+\r
ASSERT (HttpInstance != NULL);\r
UsingIpv6 = IpVersion;\r
- \r
+\r
if (!UsingIpv6) {\r
//\r
// Create TCP4 child.\r
HttpInstance->Service->ControllerHandle,\r
EFI_OPEN_PROTOCOL_BY_DRIVER\r
);\r
- \r
+\r
if (EFI_ERROR (Status)) {\r
goto ON_ERROR;\r
}\r
HttpInstance->Service->ControllerHandle,\r
EFI_OPEN_PROTOCOL_BY_DRIVER\r
);\r
- \r
+\r
if (EFI_ERROR (Status)) {\r
goto ON_ERROR;\r
}\r
HttpInstance->Handle,\r
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
);\r
- \r
+\r
if (EFI_ERROR(Status)) {\r
goto ON_ERROR;\r
- } \r
+ }\r
\r
Status = gBS->OpenProtocol (\r
HttpInstance->Service->Tcp6ChildHandle,\r
goto ON_ERROR;\r
}\r
}\r
- \r
+\r
HttpInstance->Url = AllocateZeroPool (HTTP_URL_BUFFER_LEN);\r
if (HttpInstance->Url == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
return EFI_SUCCESS;\r
\r
ON_ERROR:\r
- \r
+\r
if (HttpInstance->Tcp4ChildHandle != NULL) {\r
gBS->CloseProtocol (\r
HttpInstance->Tcp4ChildHandle,\r
&gEfiTcp4ProtocolGuid,\r
HttpInstance->Service->Ip4DriverBindingHandle,\r
HttpInstance->Handle\r
- ); \r
- \r
+ );\r
+\r
NetLibDestroyServiceChild (\r
HttpInstance->Service->ControllerHandle,\r
HttpInstance->Service->Ip4DriverBindingHandle,\r
HttpInstance->Tcp4ChildHandle\r
);\r
}\r
- \r
+\r
if (HttpInstance->Service->Tcp4ChildHandle != NULL) {\r
gBS->CloseProtocol (\r
HttpInstance->Service->Tcp4ChildHandle,\r
HttpInstance->Handle\r
);\r
}\r
- \r
+\r
if (HttpInstance->Tcp6ChildHandle != NULL) {\r
gBS->CloseProtocol (\r
HttpInstance->Tcp6ChildHandle,\r
HttpInstance->Service->Ip6DriverBindingHandle,\r
HttpInstance->Handle\r
);\r
- \r
+\r
NetLibDestroyServiceChild (\r
HttpInstance->Service->ControllerHandle,\r
HttpInstance->Service->Ip6DriverBindingHandle,\r
HttpInstance->Tcp6ChildHandle\r
);\r
}\r
- \r
+\r
if (HttpInstance->Service->Tcp6ChildHandle != NULL) {\r
gBS->CloseProtocol (\r
HttpInstance->Service->Tcp6ChildHandle,\r
}\r
\r
return EFI_UNSUPPORTED;\r
- \r
+\r
}\r
\r
/**\r
)\r
{\r
HttpCloseConnection (HttpInstance);\r
- \r
+\r
HttpCloseTcpConnCloseEvent (HttpInstance);\r
\r
if (HttpInstance->TimeoutEvent != NULL) {\r
HttpFreeMsgParser (HttpInstance->MsgParser);\r
HttpInstance->MsgParser = NULL;\r
}\r
- \r
+\r
if (HttpInstance->Url != NULL) {\r
FreePool (HttpInstance->Url);\r
HttpInstance->Url = NULL;\r
}\r
- \r
+\r
NetMapClean (&HttpInstance->TxTokens);\r
NetMapClean (&HttpInstance->RxTokens);\r
\r
if (HttpInstance->TlsSb != NULL && HttpInstance->TlsChildHandle != NULL) {\r
//\r
- // Destroy the TLS instance. \r
- //
+ // Destroy the TLS instance.\r
+ //\r
HttpInstance->TlsSb->DestroyChild (HttpInstance->TlsSb, HttpInstance->TlsChildHandle);\r
}\r
\r
HttpInstance->Service->Ip4DriverBindingHandle,\r
HttpInstance->Handle\r
);\r
- \r
+\r
NetLibDestroyServiceChild (\r
HttpInstance->Service->ControllerHandle,\r
HttpInstance->Service->Ip4DriverBindingHandle,\r
HttpInstance->Service->Ip4DriverBindingHandle,\r
HttpInstance->Handle\r
);\r
- } \r
+ }\r
\r
if (HttpInstance->Tcp6ChildHandle != NULL) {\r
gBS->CloseProtocol (\r
HttpInstance->Service->Ip6DriverBindingHandle,\r
HttpInstance->Handle\r
);\r
- \r
+\r
NetLibDestroyServiceChild (\r
HttpInstance->Service->ControllerHandle,\r
HttpInstance->Service->Ip6DriverBindingHandle,\r
HttpInstance->Tcp6ChildHandle\r
);\r
}\r
- \r
+\r
if (HttpInstance->Service->Tcp6ChildHandle != NULL) {\r
gBS->CloseProtocol (\r
HttpInstance->Service->Tcp6ChildHandle,\r
);\r
}\r
\r
- TlsCloseTxRxEvent (HttpInstance); \r
+ TlsCloseTxRxEvent (HttpInstance);\r
}\r
\r
/**\r
DEBUG ((EFI_D_ERROR, "HttpCreateConnection: Tcp4->Connect() = %r\n", Status));\r
return Status;\r
}\r
- \r
+\r
while (!HttpInstance->IsTcp4ConnDone) {\r
HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);\r
}\r
- \r
+\r
Status = HttpInstance->Tcp4ConnToken.CompletionToken.Status;\r
- \r
+\r
} else {\r
HttpInstance->IsTcp6ConnDone = FALSE;\r
HttpInstance->Tcp6ConnToken.CompletionToken.Status = EFI_NOT_READY;\r
HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);\r
}\r
\r
- Status = HttpInstance->Tcp6ConnToken.CompletionToken.Status; \r
+ Status = HttpInstance->Tcp6ConnToken.CompletionToken.Status;\r
}\r
- \r
+\r
if (!EFI_ERROR (Status)) {\r
HttpInstance->State = HTTP_STATE_TCP_CONNECTED;\r
}\r
while (!HttpInstance->IsTcp6CloseDone) {\r
HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);\r
}\r
- \r
+\r
} else {\r
HttpInstance->Tcp4CloseToken.AbortOnClose = TRUE;\r
HttpInstance->IsTcp4CloseDone = FALSE;\r
\r
Tcp4CfgData = &HttpInstance->Tcp4CfgData;\r
ZeroMem (Tcp4CfgData, sizeof (EFI_TCP4_CONFIG_DATA));\r
- \r
+\r
Tcp4CfgData->TypeOfService = HTTP_TOS_DEAULT;\r
Tcp4CfgData->TimeToLive = HTTP_TTL_DEAULT;\r
Tcp4CfgData->ControlOption = &HttpInstance->Tcp4Option;\r
IP4_COPY_ADDRESS (&Tcp4AP->StationAddress, &HttpInstance->IPv4Node.LocalAddress);\r
IP4_COPY_ADDRESS (&Tcp4AP->SubnetMask, &HttpInstance->IPv4Node.LocalSubnet);\r
}\r
- \r
+\r
Tcp4AP->StationPort = HttpInstance->IPv4Node.LocalPort;\r
Tcp4AP->RemotePort = HttpInstance->RemotePort;\r
Tcp4AP->ActiveFlag = TRUE;\r
EFI_TCP6_CONFIG_DATA *Tcp6CfgData;\r
EFI_TCP6_ACCESS_POINT *Tcp6Ap;\r
EFI_TCP6_OPTION *Tcp6Option;\r
- \r
+\r
ASSERT (HttpInstance != NULL);\r
- \r
+\r
Tcp6CfgData = &HttpInstance->Tcp6CfgData;\r
ZeroMem (Tcp6CfgData, sizeof (EFI_TCP6_CONFIG_DATA));\r
\r
Tcp6CfgData->TrafficClass = 0;\r
Tcp6CfgData->HopLimit = 255;\r
Tcp6CfgData->ControlOption = &HttpInstance->Tcp6Option;\r
- \r
+\r
Tcp6Ap = &Tcp6CfgData->AccessPoint;\r
Tcp6Ap->ActiveFlag = TRUE;\r
Tcp6Ap->StationPort = HttpInstance->Ipv6Node.LocalPort;\r
DEBUG ((EFI_D_ERROR, "HttpConfigureTcp6 - %r\n", Status));\r
return Status;\r
}\r
- \r
+\r
Status = HttpCreateTcpConnCloseEvent (HttpInstance);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
HttpInstance->State = HTTP_STATE_TCP_CONFIGED;\r
\r
return EFI_SUCCESS;\r
- \r
+\r
}\r
\r
/**\r
- Check existing TCP connection, if in error state, recover TCP4 connection. Then, \r
+ Check existing TCP connection, if in error state, recover TCP4 connection. Then,\r
connect one TLS session if required.\r
\r
@param[in] HttpInstance The HTTP instance private data.\r
}\r
\r
Status = HttpInstance->Tcp4->GetModeData(\r
- HttpInstance->Tcp4, \r
- &Tcp4State, \r
+ HttpInstance->Tcp4,\r
+ &Tcp4State,\r
NULL,\r
NULL,\r
NULL,\r
DEBUG ((EFI_D_ERROR, "Tcp4 Connection fail - %x\n", Status));\r
return Status;\r
}\r
- \r
+\r
//\r
// Tls session connection.\r
//\r
TlsCloseTxRxEvent (HttpInstance);\r
return Status;\r
}\r
- \r
+\r
Status = TlsConnectSession (HttpInstance, HttpInstance->TimeoutEvent);\r
\r
gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);\r
- \r
+\r
if (EFI_ERROR (Status)) {\r
TlsCloseTxRxEvent (HttpInstance);\r
return Status;\r
}\r
\r
/**\r
- Check existing TCP connection, if in error state, recover TCP6 connection. Then, \r
+ Check existing TCP connection, if in error state, recover TCP6 connection. Then,\r
connect one TLS session if required.\r
\r
@param[in] HttpInstance The HTTP instance private data.\r
NULL,\r
NULL\r
);\r
- \r
+\r
if (EFI_ERROR(Status)){\r
DEBUG ((EFI_D_ERROR, "Tcp6 GetModeData fail - %x\n", Status));\r
return Status;\r
DEBUG ((EFI_D_ERROR, "Tcp6 Connection fail - %x\n", Status));\r
return Status;\r
}\r
- \r
+\r
//\r
// Tls session connection.\r
//\r
TlsCloseTxRxEvent (HttpInstance);\r
return Status;\r
}\r
- \r
+\r
Status = TlsConnectSession (HttpInstance, HttpInstance->TimeoutEvent);\r
\r
gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);\r
- \r
+\r
if (EFI_ERROR (Status)) {\r
TlsCloseTxRxEvent (HttpInstance);\r
return Status;\r
@param[in] Configure The Flag indicates whether need to initialize session.\r
@param[in] TlsConfigure The Flag indicates whether it's the new Tls session.\r
\r
- @retval EFI_SUCCESS The initialization of session is done. \r
+ @retval EFI_SUCCESS The initialization of session is done.\r
@retval Others Other error as indicated.\r
\r
**/\r
return Status;\r
}\r
}\r
- \r
+\r
return EFI_SUCCESS;\r
- \r
+\r
}\r
\r
/**\r
EFI_TCP4_PROTOCOL *Tcp4;\r
EFI_TCP6_IO_TOKEN *Tx6Token;\r
EFI_TCP6_PROTOCOL *Tcp6;\r
- UINT8 *Buffer; \r
- UINTN BufferSize;\r
+ UINT8 *TlsRecord;\r
+ UINT16 PayloadSize;\r
NET_FRAGMENT TempFragment;\r
+ NET_FRAGMENT Fragment;\r
+ UINTN RecordCount;\r
+ UINTN RemainingLen;\r
\r
Status = EFI_SUCCESS;\r
- Buffer = NULL;\r
+ TlsRecord = NULL;\r
+ PayloadSize = 0;\r
TempFragment.Len = 0;\r
TempFragment.Bulk = NULL;\r
+ Fragment.Len = 0;\r
+ Fragment.Bulk = NULL;\r
+ RecordCount = 0;\r
+ RemainingLen = 0;\r
\r
//\r
// Need to encrypt data.\r
//\r
if (HttpInstance->UseHttps) {\r
//\r
- // Build BufferOut data\r
+ // Allocate enough buffer for each TLS plaintext records.\r
//\r
- BufferSize = sizeof (TLS_RECORD_HEADER) + TxStringLen;\r
- Buffer = AllocateZeroPool (BufferSize);\r
- if (Buffer == NULL) {\r
+ TlsRecord = AllocateZeroPool (TLS_RECORD_HEADER_LENGTH + TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH);\r
+ if (TlsRecord == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
return Status;\r
}\r
- ((TLS_RECORD_HEADER *) Buffer)->ContentType = TlsContentTypeApplicationData;\r
- ((TLS_RECORD_HEADER *) Buffer)->Version.Major = HttpInstance->TlsConfigData.Version.Major;\r
- ((TLS_RECORD_HEADER *) Buffer)->Version.Minor = HttpInstance->TlsConfigData.Version.Minor;\r
- ((TLS_RECORD_HEADER *) Buffer)->Length = (UINT16) (TxStringLen);\r
- CopyMem (Buffer + sizeof (TLS_RECORD_HEADER), TxString, TxStringLen);\r
- \r
+\r
//\r
- // Encrypt Packet.\r
+ // Allocate enough buffer for all TLS ciphertext records.\r
//\r
- Status = TlsProcessMessage (\r
- HttpInstance, \r
- Buffer, \r
- BufferSize, \r
- EfiTlsEncrypt, \r
- &TempFragment\r
- );\r
- \r
- FreePool (Buffer);\r
+ RecordCount = TxStringLen / TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH + 1;\r
+ Fragment.Bulk = AllocateZeroPool (RecordCount * (TLS_RECORD_HEADER_LENGTH + TLS_CIPHERTEXT_RECORD_MAX_PAYLOAD_LENGTH));\r
+ if (Fragment.Bulk == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto ON_ERROR;\r
+ }\r
\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
+ //\r
+ // Encrypt each TLS plaintext records.\r
+ //\r
+ RemainingLen = TxStringLen;\r
+ while (RemainingLen != 0) {\r
+ PayloadSize = (UINT16) MIN (TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH, RemainingLen);\r
+\r
+ ((TLS_RECORD_HEADER *) TlsRecord)->ContentType = TlsContentTypeApplicationData;\r
+ ((TLS_RECORD_HEADER *) TlsRecord)->Version.Major = HttpInstance->TlsConfigData.Version.Major;\r
+ ((TLS_RECORD_HEADER *) TlsRecord)->Version.Minor = HttpInstance->TlsConfigData.Version.Minor;\r
+ ((TLS_RECORD_HEADER *) TlsRecord)->Length = PayloadSize;\r
+\r
+ CopyMem (TlsRecord + TLS_RECORD_HEADER_LENGTH, TxString + (TxStringLen - RemainingLen), PayloadSize);\r
+\r
+ Status = TlsProcessMessage (\r
+ HttpInstance,\r
+ TlsRecord,\r
+ TLS_RECORD_HEADER_LENGTH + PayloadSize,\r
+ EfiTlsEncrypt,\r
+ &TempFragment\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_ERROR;\r
+ }\r
+\r
+ //\r
+ // Record the processed/encrypted Packet.\r
+ //\r
+ CopyMem (Fragment.Bulk + Fragment.Len, TempFragment.Bulk, TempFragment.Len);\r
+ Fragment.Len += TempFragment.Len;\r
+\r
+ FreePool (TempFragment.Bulk);\r
+ TempFragment.Len = 0;\r
+ TempFragment.Bulk = NULL;\r
+\r
+ RemainingLen -= (UINTN) PayloadSize;\r
+ ZeroMem (TlsRecord, TLS_RECORD_HEADER_LENGTH + TLS_PLAINTEXT_RECORD_MAX_PAYLOAD_LENGTH);\r
}\r
+\r
+ FreePool (TlsRecord);\r
+ TlsRecord = NULL;\r
}\r
- \r
+\r
if (!HttpInstance->LocalAddressIsIPv6) {\r
Tcp4 = HttpInstance->Tcp4;\r
Tx4Token = &Wrap->TcpWrap.Tx4Token;\r
\r
if (HttpInstance->UseHttps) {\r
- Tx4Token->Packet.TxData->DataLength = TempFragment.Len;\r
- Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = TempFragment.Len;\r
- Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TempFragment.Bulk;\r
+ Tx4Token->Packet.TxData->DataLength = Fragment.Len;\r
+ Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = Fragment.Len;\r
+ Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) Fragment.Bulk;\r
} else {\r
Tx4Token->Packet.TxData->DataLength = (UINT32) TxStringLen;\r
Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;\r
Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString;\r
}\r
- \r
- Tx4Token->CompletionToken.Status = EFI_NOT_READY; \r
- \r
+\r
+ Tx4Token->CompletionToken.Status = EFI_NOT_READY;\r
+\r
Wrap->TcpWrap.IsTxDone = FALSE;\r
Status = Tcp4->Transmit (Tcp4, Tx4Token);\r
if (EFI_ERROR (Status)) {\r
DEBUG ((EFI_D_ERROR, "Transmit failed: %r\n", Status));\r
- return Status;\r
+ goto ON_ERROR;\r
}\r
\r
} else {\r
Tcp6 = HttpInstance->Tcp6;\r
Tx6Token = &Wrap->TcpWrap.Tx6Token;\r
- \r
+\r
if (HttpInstance->UseHttps) {\r
- Tx6Token->Packet.TxData->DataLength = TempFragment.Len;\r
- Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = TempFragment.Len;\r
- Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TempFragment.Bulk;\r
+ Tx6Token->Packet.TxData->DataLength = Fragment.Len;\r
+ Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = Fragment.Len;\r
+ Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) Fragment.Bulk;\r
} else {\r
Tx6Token->Packet.TxData->DataLength = (UINT32) TxStringLen;\r
Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;\r
Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString;\r
}\r
- \r
+\r
Tx6Token->CompletionToken.Status = EFI_NOT_READY;\r
\r
Wrap->TcpWrap.IsTxDone = FALSE;\r
Status = Tcp6->Transmit (Tcp6, Tx6Token);\r
if (EFI_ERROR (Status)) {\r
DEBUG ((EFI_D_ERROR, "Transmit failed: %r\n", Status));\r
- return Status;\r
+ goto ON_ERROR;\r
+ }\r
+ }\r
+\r
+ return Status;\r
+\r
+ON_ERROR:\r
+\r
+ if (HttpInstance->UseHttps) {\r
+ if (TlsRecord != NULL) {\r
+ FreePool (TlsRecord);\r
+ TlsRecord = NULL;\r
+ }\r
+\r
+ if (Fragment.Bulk != NULL) {\r
+ FreePool (Fragment.Bulk);\r
+ Fragment.Bulk = NULL;\r
}\r
}\r
- \r
+\r
return Status;\r
}\r
\r
if (!ValueInItem->TcpWrap.IsTxDone) {\r
return EFI_NOT_READY;\r
}\r
- \r
+\r
return EFI_SUCCESS;\r
}\r
\r
@param[in, out] SizeofHeaders The HTTP header length.\r
@param[in, out] BufferSize The size of buffer to cacahe the header message.\r
@param[in] Timeout The time to wait for receiving the header packet.\r
- \r
- @retval EFI_SUCCESS The HTTP header is received. \r
+\r
+ @retval EFI_SUCCESS The HTTP header is received.\r
@retval Others Other errors as indicated.\r
\r
**/\r
Rx6Token = NULL;\r
Fragment.Len = 0;\r
Fragment.Bulk = NULL;\r
- \r
+\r
if (HttpInstance->LocalAddressIsIPv6) {\r
ASSERT (Tcp6 != NULL);\r
} else {\r
return Status;\r
}\r
}\r
- \r
+\r
//\r
// Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not NULL.\r
//\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- \r
+\r
Fragment.Len = Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength;\r
Fragment.Bulk = (UINT8 *) Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer;\r
} else {\r
FreePool (Fragment.Bulk);\r
Fragment.Bulk = NULL;\r
}\r
- \r
+\r
Status = HttpsReceive (HttpInstance, &Fragment, Timeout);\r
if (EFI_ERROR (Status)) {\r
DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));\r
}\r
\r
//\r
- // Append the response string.\r
+ // Append the response string along with a Null-terminator.\r
//\r
*BufferSize = *SizeofHeaders + Fragment.Len;\r
- Buffer = AllocateZeroPool (*BufferSize);\r
+ Buffer = AllocatePool (*BufferSize + 1);\r
if (Buffer == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
return Status;\r
Fragment.Bulk,\r
Fragment.Len\r
);\r
+ *(Buffer + *BufferSize) = '\0';\r
*HttpHeaders = Buffer;\r
*SizeofHeaders = *BufferSize;\r
\r
//\r
// Check whether we received end of HTTP headers.\r
//\r
- *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR); \r
+ *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);\r
};\r
- \r
+\r
//\r
// Free the buffer.\r
//\r
if (Fragment.Bulk != NULL) {\r
FreePool (Fragment.Bulk);\r
Fragment.Bulk = NULL;\r
- } \r
+ }\r
} else {\r
if (!HttpInstance->UseHttps) {\r
Rx6Token = &HttpInstance->Rx6Token;\r
return Status;\r
}\r
}\r
- \r
+\r
//\r
// Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not NULL.\r
//\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- \r
+\r
Fragment.Len = Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength;\r
Fragment.Bulk = (UINT8 *) Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer;\r
} else {\r
FreePool (Fragment.Bulk);\r
Fragment.Bulk = NULL;\r
}\r
- \r
+\r
Status = HttpsReceive (HttpInstance, &Fragment, Timeout);\r
if (EFI_ERROR (Status)) {\r
DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));\r
}\r
\r
//\r
- // Append the response string.\r
+ // Append the response string along with a Null-terminator.\r
//\r
*BufferSize = *SizeofHeaders + Fragment.Len;\r
- Buffer = AllocateZeroPool (*BufferSize);\r
+ Buffer = AllocatePool (*BufferSize + 1);\r
if (Buffer == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
return Status;\r
Fragment.Bulk,\r
Fragment.Len\r
);\r
+ *(Buffer + *BufferSize) = '\0';\r
*HttpHeaders = Buffer;\r
*SizeofHeaders = *BufferSize;\r
\r
//\r
// Check whether we received end of HTTP headers.\r
//\r
- *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR); \r
+ *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);\r
};\r
\r
//\r
FreePool (Fragment.Bulk);\r
Fragment.Bulk = NULL;\r
}\r
- } \r
+ }\r
\r
//\r
// Skip the CRLF after the HTTP headers.\r
//\r
- *EndofHeader = *EndofHeader + AsciiStrLen (HTTP_END_OF_HDR_STR); \r
+ *EndofHeader = *EndofHeader + AsciiStrLen (HTTP_END_OF_HDR_STR);\r
+\r
+ *SizeofHeaders = *EndofHeader - *HttpHeaders;\r
\r
return EFI_SUCCESS;\r
}\r
@param[in] Wrap The HTTP token's wrap data.\r
@param[in] HttpMsg The HTTP message data.\r
\r
- @retval EFI_SUCCESS The HTTP body is received. \r
+ @retval EFI_SUCCESS The HTTP body is received.\r
@retval Others Other error as indicated.\r
\r
**/\r
EFI_TCP6_IO_TOKEN *Rx6Token;\r
EFI_TCP4_PROTOCOL *Tcp4;\r
EFI_TCP4_IO_TOKEN *Rx4Token;\r
- \r
+\r
HttpInstance = Wrap->HttpInstance;\r
Tcp4 = HttpInstance->Tcp4;\r
Tcp6 = HttpInstance->Tcp6;\r
Rx4Token = NULL;\r
Rx6Token = NULL;\r
- \r
+\r
if (HttpInstance->LocalAddressIsIPv6) {\r
ASSERT (Tcp6 != NULL);\r
} else {\r
ASSERT (Tcp4 != NULL);\r
}\r
- \r
+\r
if (HttpInstance->LocalAddressIsIPv6) {\r
Rx6Token = &Wrap->TcpWrap.Rx6Token;\r
Rx6Token ->Packet.RxData->DataLength = (UINT32) MIN (MAX_UINT32, HttpMsg->BodyLength);\r
Rx4Token->Packet.RxData->DataLength = (UINT32) MIN (MAX_UINT32, HttpMsg->BodyLength);\r
Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength = (UINT32) MIN (MAX_UINT32, HttpMsg->BodyLength);\r
Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = (VOID *) HttpMsg->Body;\r
- \r
+\r
Rx4Token->CompletionToken.Status = EFI_NOT_READY;\r
Status = Tcp4->Receive (Tcp4, Rx4Token);\r
if (EFI_ERROR (Status)) {\r
Clean up Tcp Tokens while the Tcp transmission error occurs.\r
\r
@param[in] Wrap Pointer to HTTP token's wrap data.\r
- \r
+\r
**/\r
VOID\r
HttpTcpTokenCleanup (\r
IN HTTP_TOKEN_WRAP *Wrap\r
)\r
-{ \r
+{\r
HTTP_PROTOCOL *HttpInstance;\r
EFI_TCP4_IO_TOKEN *Rx4Token;\r
EFI_TCP6_IO_TOKEN *Rx6Token;\r
HttpInstance = Wrap->HttpInstance;\r
Rx4Token = NULL;\r
Rx6Token = NULL;\r
- \r
+\r
if (HttpInstance->LocalAddressIsIPv6) {\r
Rx6Token = &Wrap->TcpWrap.Rx6Token;\r
- \r
+\r
if (Rx6Token->CompletionToken.Event != NULL) {\r
gBS->CloseEvent (Rx6Token->CompletionToken.Event);\r
Rx6Token->CompletionToken.Event = NULL;\r
FreePool (Wrap);\r
\r
Rx6Token = &HttpInstance->Rx6Token;\r
- \r
+\r
if (Rx6Token->CompletionToken.Event != NULL) {\r
gBS->CloseEvent (Rx6Token->CompletionToken.Event);\r
Rx6Token->CompletionToken.Event = NULL;\r
}\r
- \r
+\r
if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {\r
FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);\r
Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;\r
}\r
- \r
+\r
} else {\r
Rx4Token = &Wrap->TcpWrap.Rx4Token;\r
- \r
+\r
if (Rx4Token->CompletionToken.Event != NULL) {\r
gBS->CloseEvent (Rx4Token->CompletionToken.Event);\r
Rx4Token->CompletionToken.Event = NULL;\r
}\r
- \r
+\r
FreePool (Wrap);\r
\r
Rx4Token = &HttpInstance->Rx4Token;\r
gBS->CloseEvent (Rx4Token->CompletionToken.Event);\r
Rx4Token->CompletionToken.Event = NULL;\r
}\r
- \r
- \r
+\r
+\r
if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {\r
FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);\r
Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;\r