]> git.proxmox.com Git - mirror_edk2.git/commitdiff
NetworkPkg/HttpDxe: Handle the large data request via HTTPS channel.
authorJiaxin Wu <jiaxin.wu@intel.com>
Thu, 15 Mar 2018 10:38:58 +0000 (18:38 +0800)
committerJiaxin Wu <jiaxin.wu@intel.com>
Thu, 22 Mar 2018 00:25:02 +0000 (08:25 +0800)
Cc: Karunakar P <karunakarp@amiindia.co.in>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Ye Ting <ting.ye@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
Reviewed-by: Karunakar p <karunakarp@amiindia.co.in>
Reviewed-by: Fu Siyuan <siyuan.fu@intel.com>
NetworkPkg/HttpDxe/HttpProto.c
NetworkPkg/HttpDxe/HttpsSupport.c
NetworkPkg/HttpDxe/HttpsSupport.h

index d7fe271168fe29b41eb9dbb154fdf2719371b510..35c4a166c445a47ae785e02f23f6fdc904006056 100644 (file)
@@ -1,7 +1,7 @@
 /** @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
@@ -1476,50 +1476,87 @@ HttpTransmitTcp (
   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
   if (!HttpInstance->LocalAddressIsIPv6) {\r
@@ -1527,9 +1564,9 @@ HttpTransmitTcp (
     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
@@ -1542,7 +1579,7 @@ HttpTransmitTcp (
     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
@@ -1550,9 +1587,9 @@ HttpTransmitTcp (
     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
@@ -1565,10 +1602,26 @@ HttpTransmitTcp (
     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
index f5e5911b8656310047d14ef53b478dec9f415f5b..5105a2014c25147a209d8d2f326f250ec81e1740 100644 (file)
@@ -951,7 +951,7 @@ TlsReceiveOnePdu (
   //\r
   // Allocate buffer to receive one TLS header.\r
   //\r
-  Len     = sizeof (TLS_RECORD_HEADER);\r
+  Len     = TLS_RECORD_HEADER_LENGTH;\r
   PduHdr  = NetbufAlloc (Len);\r
   if (PduHdr == NULL) {\r
     Status = EFI_OUT_OF_RESOURCES;\r
@@ -1391,11 +1391,19 @@ TlsCloseSession (
   Process one message according to the CryptMode.\r
 \r
   @param[in]           HttpInstance    Pointer to HTTP_PROTOCOL structure.\r
-  @param[in]           Message         Pointer to the message buffer needed to processed.\r
+  @param[in]           Message         Pointer to the message buffer needed to processed. \r
+                                       If ProcessMode is EfiTlsEncrypt, the message contain the TLS\r
+                                       header and plain text TLS APP payload.\r
+                                       If ProcessMode is EfiTlsDecrypt, the message contain the TLS \r
+                                       header and cipher text TLS APP payload.\r
   @param[in]           MessageSize     Pointer to the message buffer size.\r
   @param[in]           ProcessMode     Process mode.\r
   @param[in, out]      Fragment        Only one Fragment returned after the Message is\r
                                        processed successfully.\r
+                                       If ProcessMode is EfiTlsEncrypt, the fragment contain the TLS \r
+                                       header and cipher text TLS APP payload.\r
+                                       If ProcessMode is EfiTlsDecrypt, the fragment contain the TLS \r
+                                       header and plain text TLS APP payload.\r
 \r
   @retval EFI_SUCCESS          Message is processed successfully.\r
   @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resources.\r
@@ -1498,6 +1506,9 @@ TlsProcessMessage (
 ON_EXIT:\r
 \r
   if (OriginalFragmentTable != NULL) {\r
+    if( FragmentTable == OriginalFragmentTable) {\r
+      FragmentTable = NULL;\r
+    }\r
     FreePool (OriginalFragmentTable);\r
     OriginalFragmentTable = NULL;\r
   }\r
@@ -1682,7 +1693,7 @@ HttpsReceive (
       return Status;\r
     }\r
 \r
-    CopyMem (BufferIn, TempFragment.Bulk + sizeof (TLS_RECORD_HEADER), BufferInSize);\r
+    CopyMem (BufferIn, TempFragment.Bulk + TLS_RECORD_HEADER_LENGTH, BufferInSize);\r
 \r
     //\r
     // Free the buffer in TempFragment.\r
index f7a2d303e6aed3a2f13a2b26c6cb4682ebcad019..5d4ca011088542b1a962135d61517bd2098df99f 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   The header files of miscellaneous routines specific to Https for HttpDxe driver.\r
 \r
-Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<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
@@ -217,11 +217,19 @@ TlsCloseSession (
   Process one message according to the CryptMode.\r
 \r
   @param[in]           HttpInstance    Pointer to HTTP_PROTOCOL structure.\r
-  @param[in]           Message         Pointer to the message buffer needed to processed.\r
+  @param[in]           Message         Pointer to the message buffer needed to processed. \r
+                                       If ProcessMode is EfiTlsEncrypt, the message contain the TLS\r
+                                       header and plain text TLS APP payload.\r
+                                       If ProcessMode is EfiTlsDecrypt, the message contain the TLS \r
+                                       header and cipher text TLS APP payload.\r
   @param[in]           MessageSize     Pointer to the message buffer size.\r
   @param[in]           ProcessMode     Process mode.\r
   @param[in, out]      Fragment        Only one Fragment returned after the Message is\r
                                        processed successfully.\r
+                                       If ProcessMode is EfiTlsEncrypt, the fragment contain the TLS \r
+                                       header and cipher text TLS APP payload.\r
+                                       If ProcessMode is EfiTlsDecrypt, the fragment contain the TLS \r
+                                       header and plain text TLS APP payload.\r
 \r
   @retval EFI_SUCCESS          Message is processed successfully.\r
   @retval EFI_OUT_OF_RESOURCES   Can't allocate memory resources.\r