/** @file\r
Miscellaneous routines for HttpDxe driver.\r
\r
-Copyright (c) 2015 - 2016, 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
//\r
Status = NetLibCreateServiceChild (\r
HttpInstance->Service->ControllerHandle,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
&gEfiTcp4ServiceBindingProtocolGuid,\r
&HttpInstance->Tcp4ChildHandle\r
);\r
HttpInstance->Tcp4ChildHandle,\r
&gEfiTcp4ProtocolGuid,\r
(VOID **) &Interface,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
HttpInstance->Service->ControllerHandle,\r
EFI_OPEN_PROTOCOL_BY_DRIVER\r
);\r
HttpInstance->Tcp4ChildHandle,\r
&gEfiTcp4ProtocolGuid,\r
(VOID **) &HttpInstance->Tcp4,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
HttpInstance->Handle,\r
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
);\r
HttpInstance->Service->Tcp4ChildHandle,\r
&gEfiTcp4ProtocolGuid,\r
(VOID **) &Interface,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
HttpInstance->Handle,\r
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
);\r
//\r
Status = NetLibCreateServiceChild (\r
HttpInstance->Service->ControllerHandle,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
&gEfiTcp6ServiceBindingProtocolGuid,\r
&HttpInstance->Tcp6ChildHandle\r
);\r
HttpInstance->Tcp6ChildHandle,\r
&gEfiTcp6ProtocolGuid,\r
(VOID **) &Interface,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
HttpInstance->Service->ControllerHandle,\r
EFI_OPEN_PROTOCOL_BY_DRIVER\r
);\r
HttpInstance->Tcp6ChildHandle,\r
&gEfiTcp6ProtocolGuid,\r
(VOID **) &HttpInstance->Tcp6,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
HttpInstance->Handle,\r
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
);\r
HttpInstance->Service->Tcp6ChildHandle,\r
&gEfiTcp6ProtocolGuid,\r
(VOID **) &Interface,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
HttpInstance->Handle,\r
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
);\r
gBS->CloseProtocol (\r
HttpInstance->Tcp4ChildHandle,\r
&gEfiTcp4ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
HttpInstance->Service->ControllerHandle\r
);\r
\r
gBS->CloseProtocol (\r
HttpInstance->Tcp4ChildHandle,\r
&gEfiTcp4ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
HttpInstance->Handle\r
); \r
\r
NetLibDestroyServiceChild (\r
HttpInstance->Service->ControllerHandle,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
&gEfiTcp4ServiceBindingProtocolGuid,\r
HttpInstance->Tcp4ChildHandle\r
);\r
gBS->CloseProtocol (\r
HttpInstance->Service->Tcp4ChildHandle,\r
&gEfiTcp4ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
HttpInstance->Handle\r
);\r
}\r
gBS->CloseProtocol (\r
HttpInstance->Tcp6ChildHandle,\r
&gEfiTcp6ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
HttpInstance->Service->ControllerHandle\r
);\r
\r
gBS->CloseProtocol (\r
HttpInstance->Tcp6ChildHandle,\r
&gEfiTcp6ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
HttpInstance->Handle\r
);\r
\r
NetLibDestroyServiceChild (\r
HttpInstance->Service->ControllerHandle,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
&gEfiTcp6ServiceBindingProtocolGuid,\r
HttpInstance->Tcp6ChildHandle\r
);\r
gBS->CloseProtocol (\r
HttpInstance->Service->Tcp6ChildHandle,\r
&gEfiTcp6ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
HttpInstance->Handle\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
+ //\r
+ HttpInstance->TlsSb->DestroyChild (HttpInstance->TlsSb, HttpInstance->TlsChildHandle);\r
+ }\r
+\r
if (HttpInstance->Tcp4ChildHandle != NULL) {\r
gBS->CloseProtocol (\r
HttpInstance->Tcp4ChildHandle,\r
&gEfiTcp4ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
HttpInstance->Service->ControllerHandle\r
);\r
\r
gBS->CloseProtocol (\r
HttpInstance->Tcp4ChildHandle,\r
&gEfiTcp4ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
HttpInstance->Handle\r
);\r
\r
NetLibDestroyServiceChild (\r
HttpInstance->Service->ControllerHandle,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
&gEfiTcp4ServiceBindingProtocolGuid,\r
HttpInstance->Tcp4ChildHandle\r
);\r
gBS->CloseProtocol (\r
HttpInstance->Service->Tcp4ChildHandle,\r
&gEfiTcp4ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip4DriverBindingHandle,\r
HttpInstance->Handle\r
);\r
} \r
gBS->CloseProtocol (\r
HttpInstance->Tcp6ChildHandle,\r
&gEfiTcp6ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
HttpInstance->Service->ControllerHandle\r
);\r
\r
gBS->CloseProtocol (\r
HttpInstance->Tcp6ChildHandle,\r
&gEfiTcp6ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
HttpInstance->Handle\r
);\r
\r
NetLibDestroyServiceChild (\r
HttpInstance->Service->ControllerHandle,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
&gEfiTcp6ServiceBindingProtocolGuid,\r
HttpInstance->Tcp6ChildHandle\r
);\r
gBS->CloseProtocol (\r
HttpInstance->Service->Tcp6ChildHandle,\r
&gEfiTcp6ProtocolGuid,\r
- HttpInstance->Service->ImageHandle,\r
+ HttpInstance->Service->Ip6DriverBindingHandle,\r
HttpInstance->Handle\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 = TLS_CONTENT_TYPE_APPLICATION_DATA;\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
if (!HttpInstance->LocalAddressIsIPv6) {\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
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
Tx6Token = &Wrap->TcpWrap.Tx6Token;\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
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
return Status;\r
}\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
// 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
\r
if (HttpInstance->LocalAddressIsIPv6) {\r
Rx6Token = &Wrap->TcpWrap.Rx6Token;\r
- Rx6Token ->Packet.RxData->DataLength = (UINT32) HttpMsg->BodyLength;\r
- Rx6Token ->Packet.RxData->FragmentTable[0].FragmentLength = (UINT32) HttpMsg->BodyLength;\r
+ Rx6Token ->Packet.RxData->DataLength = (UINT32) MIN (MAX_UINT32, HttpMsg->BodyLength);\r
+ Rx6Token ->Packet.RxData->FragmentTable[0].FragmentLength = (UINT32) MIN (MAX_UINT32, HttpMsg->BodyLength);\r
Rx6Token ->Packet.RxData->FragmentTable[0].FragmentBuffer = (VOID *) HttpMsg->Body;\r
Rx6Token->CompletionToken.Status = EFI_NOT_READY;\r
\r
}\r
} else {\r
Rx4Token = &Wrap->TcpWrap.Rx4Token;\r
- Rx4Token->Packet.RxData->DataLength = (UINT32) HttpMsg->BodyLength;\r
- Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength = (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
Rx4Token->CompletionToken.Status = EFI_NOT_READY;\r