2 Miscellaneous routines specific to Https for HttpDxe driver.
4 Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include "HttpDriver.h"
13 Returns the first occurrence of a Null-terminated ASCII sub-string in a Null-terminated
14 ASCII string and ignore case during the search process.
16 This function scans the contents of the ASCII string specified by String
17 and returns the first occurrence of SearchString and ignore case during the search process.
18 If SearchString is not found in String, then NULL is returned. If the length of SearchString
19 is zero, then String is returned.
21 If String is NULL, then ASSERT().
22 If SearchString is NULL, then ASSERT().
24 @param[in] String A pointer to a Null-terminated ASCII string.
25 @param[in] SearchString A pointer to a Null-terminated ASCII string to search for.
27 @retval NULL If the SearchString does not appear in String.
28 @retval others If there is a match return the first occurrence of SearchingString.
29 If the length of SearchString is zero,return String.
34 IN CONST CHAR8
*String
,
35 IN CONST CHAR8
*SearchString
38 CONST CHAR8
*FirstMatch
;
39 CONST CHAR8
*SearchStringTmp
;
45 // ASSERT both strings are less long than PcdMaximumAsciiStringLength
47 ASSERT (AsciiStrSize (String
) != 0);
48 ASSERT (AsciiStrSize (SearchString
) != 0);
50 if (*SearchString
== '\0') {
51 return (CHAR8
*)String
;
54 while (*String
!= '\0') {
55 SearchStringTmp
= SearchString
;
58 while ( (*SearchStringTmp
!= '\0')
62 Dst
= *SearchStringTmp
;
64 if ((Src
>= 'A') && (Src
<= 'Z')) {
68 if ((Dst
>= 'A') && (Dst
<= 'Z')) {
80 if (*SearchStringTmp
== '\0') {
81 return (CHAR8
*)FirstMatch
;
84 String
= FirstMatch
+ 1;
91 The callback function to free the net buffer list.
93 @param[in] Arg The opaque parameter.
102 ASSERT (Arg
!= NULL
);
104 NetbufFreeList ((LIST_ENTRY
*)Arg
);
109 Check whether the Url is from Https.
111 @param[in] Url The pointer to a HTTP or HTTPS URL string.
113 @retval TRUE The Url is from HTTPS.
114 @retval FALSE The Url is from HTTP.
126 Tmp
= AsciiStrCaseStr (Url
, HTTPS_FLAG
);
127 if ((Tmp
!= NULL
) && (Tmp
== Url
)) {
135 Creates a Tls child handle, open EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL.
137 @param[in] ImageHandle The firmware allocated handle for the UEFI image.
138 @param[out] TlsSb Pointer to the TLS SERVICE_BINDING_PROTOCOL.
139 @param[out] TlsProto Pointer to the EFI_TLS_PROTOCOL instance.
140 @param[out] TlsConfiguration Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
142 @return The child handle with opened EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL.
148 IN EFI_HANDLE ImageHandle
,
149 OUT EFI_SERVICE_BINDING_PROTOCOL
**TlsSb
,
150 OUT EFI_TLS_PROTOCOL
**TlsProto
,
151 OUT EFI_TLS_CONFIGURATION_PROTOCOL
**TlsConfiguration
155 EFI_HANDLE TlsChildHandle
;
160 // Locate TlsServiceBinding protocol.
162 gBS
->LocateProtocol (
163 &gEfiTlsServiceBindingProtocolGuid
,
167 if (*TlsSb
== NULL
) {
171 Status
= (*TlsSb
)->CreateChild (*TlsSb
, &TlsChildHandle
);
172 if (EFI_ERROR (Status
)) {
176 Status
= gBS
->OpenProtocol (
178 &gEfiTlsProtocolGuid
,
182 EFI_OPEN_PROTOCOL_GET_PROTOCOL
184 if (EFI_ERROR (Status
)) {
185 (*TlsSb
)->DestroyChild (*TlsSb
, TlsChildHandle
);
189 Status
= gBS
->OpenProtocol (
191 &gEfiTlsConfigurationProtocolGuid
,
192 (VOID
**)TlsConfiguration
,
195 EFI_OPEN_PROTOCOL_GET_PROTOCOL
197 if (EFI_ERROR (Status
)) {
198 (*TlsSb
)->DestroyChild (*TlsSb
, TlsChildHandle
);
202 return TlsChildHandle
;
206 Create event for the TLS receive and transmit tokens which are used to receive and
207 transmit TLS related messages.
209 @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
211 @retval EFI_SUCCESS The events are created successfully.
212 @retval others Other error as indicated.
218 IN OUT HTTP_PROTOCOL
*HttpInstance
223 if (!HttpInstance
->LocalAddressIsIPv6
) {
225 // For Tcp4TlsTxToken.
227 Status
= gBS
->CreateEvent (
231 &HttpInstance
->TlsIsTxDone
,
232 &HttpInstance
->Tcp4TlsTxToken
.CompletionToken
.Event
234 if (EFI_ERROR (Status
)) {
238 HttpInstance
->Tcp4TlsTxData
.Push
= TRUE
;
239 HttpInstance
->Tcp4TlsTxData
.Urgent
= FALSE
;
240 HttpInstance
->Tcp4TlsTxData
.DataLength
= 0;
241 HttpInstance
->Tcp4TlsTxData
.FragmentCount
= 1;
242 HttpInstance
->Tcp4TlsTxData
.FragmentTable
[0].FragmentLength
= HttpInstance
->Tcp4TlsTxData
.DataLength
;
243 HttpInstance
->Tcp4TlsTxData
.FragmentTable
[0].FragmentBuffer
= NULL
;
244 HttpInstance
->Tcp4TlsTxToken
.Packet
.TxData
= &HttpInstance
->Tcp4TlsTxData
;
245 HttpInstance
->Tcp4TlsTxToken
.CompletionToken
.Status
= EFI_NOT_READY
;
248 // For Tcp4TlsRxToken.
250 Status
= gBS
->CreateEvent (
254 &HttpInstance
->TlsIsRxDone
,
255 &HttpInstance
->Tcp4TlsRxToken
.CompletionToken
.Event
257 if (EFI_ERROR (Status
)) {
261 HttpInstance
->Tcp4TlsRxData
.DataLength
= 0;
262 HttpInstance
->Tcp4TlsRxData
.FragmentCount
= 1;
263 HttpInstance
->Tcp4TlsRxData
.FragmentTable
[0].FragmentLength
= HttpInstance
->Tcp4TlsRxData
.DataLength
;
264 HttpInstance
->Tcp4TlsRxData
.FragmentTable
[0].FragmentBuffer
= NULL
;
265 HttpInstance
->Tcp4TlsRxToken
.Packet
.RxData
= &HttpInstance
->Tcp4TlsRxData
;
266 HttpInstance
->Tcp4TlsRxToken
.CompletionToken
.Status
= EFI_NOT_READY
;
269 // For Tcp6TlsTxToken.
271 Status
= gBS
->CreateEvent (
275 &HttpInstance
->TlsIsTxDone
,
276 &HttpInstance
->Tcp6TlsTxToken
.CompletionToken
.Event
278 if (EFI_ERROR (Status
)) {
282 HttpInstance
->Tcp6TlsTxData
.Push
= TRUE
;
283 HttpInstance
->Tcp6TlsTxData
.Urgent
= FALSE
;
284 HttpInstance
->Tcp6TlsTxData
.DataLength
= 0;
285 HttpInstance
->Tcp6TlsTxData
.FragmentCount
= 1;
286 HttpInstance
->Tcp6TlsTxData
.FragmentTable
[0].FragmentLength
= HttpInstance
->Tcp6TlsTxData
.DataLength
;
287 HttpInstance
->Tcp6TlsTxData
.FragmentTable
[0].FragmentBuffer
= NULL
;
288 HttpInstance
->Tcp6TlsTxToken
.Packet
.TxData
= &HttpInstance
->Tcp6TlsTxData
;
289 HttpInstance
->Tcp6TlsTxToken
.CompletionToken
.Status
= EFI_NOT_READY
;
292 // For Tcp6TlsRxToken.
294 Status
= gBS
->CreateEvent (
298 &HttpInstance
->TlsIsRxDone
,
299 &HttpInstance
->Tcp6TlsRxToken
.CompletionToken
.Event
301 if (EFI_ERROR (Status
)) {
305 HttpInstance
->Tcp6TlsRxData
.DataLength
= 0;
306 HttpInstance
->Tcp6TlsRxData
.FragmentCount
= 1;
307 HttpInstance
->Tcp6TlsRxData
.FragmentTable
[0].FragmentLength
= HttpInstance
->Tcp6TlsRxData
.DataLength
;
308 HttpInstance
->Tcp6TlsRxData
.FragmentTable
[0].FragmentBuffer
= NULL
;
309 HttpInstance
->Tcp6TlsRxToken
.Packet
.RxData
= &HttpInstance
->Tcp6TlsRxData
;
310 HttpInstance
->Tcp6TlsRxToken
.CompletionToken
.Status
= EFI_NOT_READY
;
319 TlsCloseTxRxEvent (HttpInstance
);
325 Close events in the TlsTxToken and TlsRxToken.
327 @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
333 IN HTTP_PROTOCOL
*HttpInstance
336 ASSERT (HttpInstance
!= NULL
);
337 if (!HttpInstance
->LocalAddressIsIPv6
) {
338 if (NULL
!= HttpInstance
->Tcp4TlsTxToken
.CompletionToken
.Event
) {
339 gBS
->CloseEvent (HttpInstance
->Tcp4TlsTxToken
.CompletionToken
.Event
);
340 HttpInstance
->Tcp4TlsTxToken
.CompletionToken
.Event
= NULL
;
343 if (NULL
!= HttpInstance
->Tcp4TlsRxToken
.CompletionToken
.Event
) {
344 gBS
->CloseEvent (HttpInstance
->Tcp4TlsRxToken
.CompletionToken
.Event
);
345 HttpInstance
->Tcp4TlsRxToken
.CompletionToken
.Event
= NULL
;
348 if (NULL
!= HttpInstance
->Tcp6TlsTxToken
.CompletionToken
.Event
) {
349 gBS
->CloseEvent (HttpInstance
->Tcp6TlsTxToken
.CompletionToken
.Event
);
350 HttpInstance
->Tcp6TlsTxToken
.CompletionToken
.Event
= NULL
;
353 if (NULL
!= HttpInstance
->Tcp6TlsRxToken
.CompletionToken
.Event
) {
354 gBS
->CloseEvent (HttpInstance
->Tcp6TlsRxToken
.CompletionToken
.Event
);
355 HttpInstance
->Tcp6TlsRxToken
.CompletionToken
.Event
= NULL
;
361 Read the TlsCaCertificate variable and configure it.
363 @param[in, out] HttpInstance The HTTP instance private data.
365 @retval EFI_SUCCESS TlsCaCertificate is configured.
366 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
367 @retval EFI_NOT_FOUND Fail to get 'TlsCaCertificate' variable.
368 @retval Others Other error as indicated.
372 TlsConfigCertificate (
373 IN OUT HTTP_PROTOCOL
*HttpInstance
380 EFI_SIGNATURE_LIST
*CertList
;
381 EFI_SIGNATURE_DATA
*Cert
;
382 UINTN CertArraySizeInBytes
;
390 // Try to read the TlsCaCertificate variable.
392 Status
= gRT
->GetVariable (
393 EFI_TLS_CA_CERTIFICATE_VARIABLE
,
394 &gEfiTlsCaCertificateGuid
,
400 if (EFI_ERROR (Status
) && (Status
!= EFI_BUFFER_TOO_SMALL
)) {
405 // Allocate buffer and read the config variable.
407 CACert
= AllocatePool (CACertSize
);
408 if (CACert
== NULL
) {
409 return EFI_OUT_OF_RESOURCES
;
412 Status
= gRT
->GetVariable (
413 EFI_TLS_CA_CERTIFICATE_VARIABLE
,
414 &gEfiTlsCaCertificateGuid
,
419 if (EFI_ERROR (Status
)) {
421 // GetVariable still error or the variable is corrupted.
426 ASSERT (CACert
!= NULL
);
431 Status
= EFI_INVALID_PARAMETER
;
433 ItemDataSize
= (UINT32
)CACertSize
;
434 while (ItemDataSize
> 0) {
435 if (ItemDataSize
< sizeof (EFI_SIGNATURE_LIST
)) {
438 "%a: truncated EFI_SIGNATURE_LIST header\n",
444 CertList
= (EFI_SIGNATURE_LIST
*)(CACert
+ (CACertSize
- ItemDataSize
));
446 if (CertList
->SignatureListSize
< sizeof (EFI_SIGNATURE_LIST
)) {
449 "%a: SignatureListSize too small for EFI_SIGNATURE_LIST\n",
455 if (CertList
->SignatureListSize
> ItemDataSize
) {
458 "%a: truncated EFI_SIGNATURE_LIST body\n",
464 if (!CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Guid
)) {
467 "%a: only X509 certificates are supported\n",
470 Status
= EFI_UNSUPPORTED
;
474 if (CertList
->SignatureHeaderSize
!= 0) {
477 "%a: SignatureHeaderSize must be 0 for X509\n",
483 if (CertList
->SignatureSize
< sizeof (EFI_SIGNATURE_DATA
)) {
486 "%a: SignatureSize too small for EFI_SIGNATURE_DATA\n",
492 CertArraySizeInBytes
= (CertList
->SignatureListSize
-
493 sizeof (EFI_SIGNATURE_LIST
));
494 if (CertArraySizeInBytes
% CertList
->SignatureSize
!= 0) {
497 "%a: EFI_SIGNATURE_DATA array not a multiple of SignatureSize\n",
503 CertCount
+= CertArraySizeInBytes
/ CertList
->SignatureSize
;
504 ItemDataSize
-= CertList
->SignatureListSize
;
507 if (CertCount
== 0) {
508 DEBUG ((DEBUG_ERROR
, "%a: no X509 certificates provided\n", __FUNCTION__
));
513 // Enumerate all data and erasing the target item.
515 ItemDataSize
= (UINT32
)CACertSize
;
516 CertList
= (EFI_SIGNATURE_LIST
*)CACert
;
517 while ((ItemDataSize
> 0) && (ItemDataSize
>= CertList
->SignatureListSize
)) {
518 Cert
= (EFI_SIGNATURE_DATA
*)((UINT8
*)CertList
+ sizeof (EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
);
519 CertCount
= (CertList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - CertList
->SignatureHeaderSize
) / CertList
->SignatureSize
;
520 for (Index
= 0; Index
< CertCount
; Index
++) {
522 // EfiTlsConfigDataTypeCACertificate
524 Status
= HttpInstance
->TlsConfiguration
->SetData (
525 HttpInstance
->TlsConfiguration
,
526 EfiTlsConfigDataTypeCACertificate
,
528 CertList
->SignatureSize
- sizeof (Cert
->SignatureOwner
)
530 if (EFI_ERROR (Status
)) {
534 Cert
= (EFI_SIGNATURE_DATA
*)((UINT8
*)Cert
+ CertList
->SignatureSize
);
537 ItemDataSize
-= CertList
->SignatureListSize
;
538 CertList
= (EFI_SIGNATURE_LIST
*)((UINT8
*)CertList
+ CertList
->SignatureListSize
);
547 Read the HttpTlsCipherList variable and configure it for HTTPS session.
549 @param[in, out] HttpInstance The HTTP instance private data.
551 @retval EFI_SUCCESS The prefered HTTP TLS CipherList is configured.
552 @retval EFI_NOT_FOUND Fail to get 'HttpTlsCipherList' variable.
553 @retval EFI_INVALID_PARAMETER The contents of variable are invalid.
554 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
556 @retval Others Other error as indicated.
560 TlsConfigCipherList (
561 IN OUT HTTP_PROTOCOL
*HttpInstance
566 UINTN CipherListSize
;
572 // Try to read the HttpTlsCipherList variable.
574 Status
= gRT
->GetVariable (
575 EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE
,
576 &gEdkiiHttpTlsCipherListGuid
,
581 ASSERT (EFI_ERROR (Status
));
582 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
586 if (CipherListSize
% sizeof (EFI_TLS_CIPHER
) != 0) {
587 return EFI_INVALID_PARAMETER
;
591 // Allocate buffer and read the config variable.
593 CipherList
= AllocatePool (CipherListSize
);
594 if (CipherList
== NULL
) {
595 return EFI_OUT_OF_RESOURCES
;
598 Status
= gRT
->GetVariable (
599 EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE
,
600 &gEdkiiHttpTlsCipherListGuid
,
605 if (EFI_ERROR (Status
)) {
607 // GetVariable still error or the variable is corrupted.
612 ASSERT (CipherList
!= NULL
);
614 Status
= HttpInstance
->Tls
->SetSessionData (
622 FreePool (CipherList
);
628 Configure TLS session data.
630 @param[in, out] HttpInstance The HTTP instance private data.
632 @retval EFI_SUCCESS TLS session data is configured.
633 @retval Others Other error as indicated.
638 TlsConfigureSession (
639 IN OUT HTTP_PROTOCOL
*HttpInstance
645 // TlsConfigData initialization
647 HttpInstance
->TlsConfigData
.ConnectionEnd
= EfiTlsClient
;
648 HttpInstance
->TlsConfigData
.VerifyMethod
= EFI_TLS_VERIFY_PEER
;
649 HttpInstance
->TlsConfigData
.VerifyHost
.Flags
= EFI_TLS_VERIFY_FLAG_NONE
;
650 HttpInstance
->TlsConfigData
.VerifyHost
.HostName
= HttpInstance
->RemoteHost
;
651 HttpInstance
->TlsConfigData
.SessionState
= EfiTlsSessionNotStarted
;
654 // EfiTlsConnectionEnd,
655 // EfiTlsVerifyMethod,
657 // EfiTlsSessionState
659 Status
= HttpInstance
->Tls
->SetSessionData (
662 &(HttpInstance
->TlsConfigData
.ConnectionEnd
),
663 sizeof (EFI_TLS_CONNECTION_END
)
665 if (EFI_ERROR (Status
)) {
669 Status
= HttpInstance
->Tls
->SetSessionData (
672 &HttpInstance
->TlsConfigData
.VerifyMethod
,
673 sizeof (EFI_TLS_VERIFY
)
675 if (EFI_ERROR (Status
)) {
679 Status
= HttpInstance
->Tls
->SetSessionData (
682 &HttpInstance
->TlsConfigData
.VerifyHost
,
683 sizeof (EFI_TLS_VERIFY_HOST
)
685 if (EFI_ERROR (Status
)) {
689 Status
= HttpInstance
->Tls
->SetSessionData (
692 &(HttpInstance
->TlsConfigData
.SessionState
),
693 sizeof (EFI_TLS_SESSION_STATE
)
695 if (EFI_ERROR (Status
)) {
702 Status
= TlsConfigCipherList (HttpInstance
);
703 if (EFI_ERROR (Status
) && (Status
!= EFI_NOT_FOUND
)) {
704 DEBUG ((DEBUG_ERROR
, "TlsConfigCipherList: return %r error.\n", Status
));
709 // Tls Config Certificate
711 Status
= TlsConfigCertificate (HttpInstance
);
712 if (EFI_ERROR (Status
)) {
713 DEBUG ((DEBUG_ERROR
, "TLS Certificate Config Error!\n"));
718 // TlsCreateTxRxEvent
720 Status
= TlsCreateTxRxEvent (HttpInstance
);
721 if (EFI_ERROR (Status
)) {
728 TlsCloseTxRxEvent (HttpInstance
);
734 Transmit the Packet by processing the associated HTTPS token.
736 @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
737 @param[in] Packet The packet to transmit.
739 @retval EFI_SUCCESS The packet is transmitted.
740 @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
741 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
742 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
743 @retval Others Other errors as indicated.
749 IN OUT HTTP_PROTOCOL
*HttpInstance
,
757 if ((HttpInstance
== NULL
) || (Packet
== NULL
)) {
758 return EFI_INVALID_PARAMETER
;
761 if (!HttpInstance
->LocalAddressIsIPv6
) {
762 Size
= sizeof (EFI_TCP4_TRANSMIT_DATA
) +
763 (Packet
->BlockOpNum
- 1) * sizeof (EFI_TCP4_FRAGMENT_DATA
);
765 Size
= sizeof (EFI_TCP6_TRANSMIT_DATA
) +
766 (Packet
->BlockOpNum
- 1) * sizeof (EFI_TCP6_FRAGMENT_DATA
);
769 Data
= AllocatePool (Size
);
771 return EFI_OUT_OF_RESOURCES
;
774 if (!HttpInstance
->LocalAddressIsIPv6
) {
775 ((EFI_TCP4_TRANSMIT_DATA
*)Data
)->Push
= TRUE
;
776 ((EFI_TCP4_TRANSMIT_DATA
*)Data
)->Urgent
= FALSE
;
777 ((EFI_TCP4_TRANSMIT_DATA
*)Data
)->DataLength
= Packet
->TotalSize
;
780 // Build the fragment table.
782 ((EFI_TCP4_TRANSMIT_DATA
*)Data
)->FragmentCount
= Packet
->BlockOpNum
;
786 (NET_FRAGMENT
*)&((EFI_TCP4_TRANSMIT_DATA
*)Data
)->FragmentTable
[0],
787 &((EFI_TCP4_TRANSMIT_DATA
*)Data
)->FragmentCount
790 HttpInstance
->Tcp4TlsTxToken
.Packet
.TxData
= (EFI_TCP4_TRANSMIT_DATA
*)Data
;
792 Status
= EFI_DEVICE_ERROR
;
795 // Transmit the packet.
797 Status
= HttpInstance
->Tcp4
->Transmit (HttpInstance
->Tcp4
, &HttpInstance
->Tcp4TlsTxToken
);
798 if (EFI_ERROR (Status
)) {
802 while (!HttpInstance
->TlsIsTxDone
) {
803 HttpInstance
->Tcp4
->Poll (HttpInstance
->Tcp4
);
806 HttpInstance
->TlsIsTxDone
= FALSE
;
807 Status
= HttpInstance
->Tcp4TlsTxToken
.CompletionToken
.Status
;
809 ((EFI_TCP6_TRANSMIT_DATA
*)Data
)->Push
= TRUE
;
810 ((EFI_TCP6_TRANSMIT_DATA
*)Data
)->Urgent
= FALSE
;
811 ((EFI_TCP6_TRANSMIT_DATA
*)Data
)->DataLength
= Packet
->TotalSize
;
814 // Build the fragment table.
816 ((EFI_TCP6_TRANSMIT_DATA
*)Data
)->FragmentCount
= Packet
->BlockOpNum
;
820 (NET_FRAGMENT
*)&((EFI_TCP6_TRANSMIT_DATA
*)Data
)->FragmentTable
[0],
821 &((EFI_TCP6_TRANSMIT_DATA
*)Data
)->FragmentCount
824 HttpInstance
->Tcp6TlsTxToken
.Packet
.TxData
= (EFI_TCP6_TRANSMIT_DATA
*)Data
;
826 Status
= EFI_DEVICE_ERROR
;
829 // Transmit the packet.
831 Status
= HttpInstance
->Tcp6
->Transmit (HttpInstance
->Tcp6
, &HttpInstance
->Tcp6TlsTxToken
);
832 if (EFI_ERROR (Status
)) {
836 while (!HttpInstance
->TlsIsTxDone
) {
837 HttpInstance
->Tcp6
->Poll (HttpInstance
->Tcp6
);
840 HttpInstance
->TlsIsTxDone
= FALSE
;
841 Status
= HttpInstance
->Tcp6TlsTxToken
.CompletionToken
.Status
;
851 Receive the Packet by processing the associated HTTPS token.
853 @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
854 @param[in] Packet The packet to transmit.
855 @param[in] Timeout The time to wait for connection done.
857 @retval EFI_SUCCESS The Packet is received.
858 @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
859 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
860 @retval EFI_TIMEOUT The operation is time out.
861 @retval Others Other error as indicated.
867 IN OUT HTTP_PROTOCOL
*HttpInstance
,
872 EFI_TCP4_RECEIVE_DATA
*Tcp4RxData
;
873 EFI_TCP6_RECEIVE_DATA
*Tcp6RxData
;
875 NET_FRAGMENT
*Fragment
;
876 UINT32 FragmentCount
;
877 UINT32 CurrentFragment
;
882 if ((HttpInstance
== NULL
) || (Packet
== NULL
)) {
883 return EFI_INVALID_PARAMETER
;
886 FragmentCount
= Packet
->BlockOpNum
;
887 Fragment
= AllocatePool (FragmentCount
* sizeof (NET_FRAGMENT
));
888 if (Fragment
== NULL
) {
889 Status
= EFI_OUT_OF_RESOURCES
;
894 // Build the fragment table.
896 NetbufBuildExt (Packet
, Fragment
, &FragmentCount
);
898 if (!HttpInstance
->LocalAddressIsIPv6
) {
899 Tcp4RxData
= HttpInstance
->Tcp4TlsRxToken
.Packet
.RxData
;
900 if (Tcp4RxData
== NULL
) {
901 return EFI_INVALID_PARAMETER
;
904 Tcp4RxData
->FragmentCount
= 1;
906 Tcp6RxData
= HttpInstance
->Tcp6TlsRxToken
.Packet
.RxData
;
907 if (Tcp6RxData
== NULL
) {
908 return EFI_INVALID_PARAMETER
;
911 Tcp6RxData
->FragmentCount
= 1;
915 Status
= EFI_SUCCESS
;
917 while (CurrentFragment
< FragmentCount
) {
918 if (!HttpInstance
->LocalAddressIsIPv6
) {
919 Tcp4RxData
->DataLength
= Fragment
[CurrentFragment
].Len
;
920 Tcp4RxData
->FragmentTable
[0].FragmentLength
= Fragment
[CurrentFragment
].Len
;
921 Tcp4RxData
->FragmentTable
[0].FragmentBuffer
= Fragment
[CurrentFragment
].Bulk
;
922 Status
= HttpInstance
->Tcp4
->Receive (HttpInstance
->Tcp4
, &HttpInstance
->Tcp4TlsRxToken
);
924 Tcp6RxData
->DataLength
= Fragment
[CurrentFragment
].Len
;
925 Tcp6RxData
->FragmentTable
[0].FragmentLength
= Fragment
[CurrentFragment
].Len
;
926 Tcp6RxData
->FragmentTable
[0].FragmentBuffer
= Fragment
[CurrentFragment
].Bulk
;
927 Status
= HttpInstance
->Tcp6
->Receive (HttpInstance
->Tcp6
, &HttpInstance
->Tcp6TlsRxToken
);
930 if (EFI_ERROR (Status
)) {
934 while (!HttpInstance
->TlsIsRxDone
&& ((Timeout
== NULL
) || EFI_ERROR (gBS
->CheckEvent (Timeout
)))) {
936 // Poll until some data is received or an error occurs.
938 if (!HttpInstance
->LocalAddressIsIPv6
) {
939 HttpInstance
->Tcp4
->Poll (HttpInstance
->Tcp4
);
941 HttpInstance
->Tcp6
->Poll (HttpInstance
->Tcp6
);
945 if (!HttpInstance
->TlsIsRxDone
) {
947 // Timeout occurs, cancel the receive request.
949 if (!HttpInstance
->LocalAddressIsIPv6
) {
950 HttpInstance
->Tcp4
->Cancel (HttpInstance
->Tcp4
, &HttpInstance
->Tcp4TlsRxToken
.CompletionToken
);
952 HttpInstance
->Tcp6
->Cancel (HttpInstance
->Tcp6
, &HttpInstance
->Tcp6TlsRxToken
.CompletionToken
);
955 Status
= EFI_TIMEOUT
;
958 HttpInstance
->TlsIsRxDone
= FALSE
;
961 if (!HttpInstance
->LocalAddressIsIPv6
) {
962 Status
= HttpInstance
->Tcp4TlsRxToken
.CompletionToken
.Status
;
963 if (EFI_ERROR (Status
)) {
967 Fragment
[CurrentFragment
].Len
-= Tcp4RxData
->FragmentTable
[0].FragmentLength
;
968 if (Fragment
[CurrentFragment
].Len
== 0) {
971 Fragment
[CurrentFragment
].Bulk
+= Tcp4RxData
->FragmentTable
[0].FragmentLength
;
974 Status
= HttpInstance
->Tcp6TlsRxToken
.CompletionToken
.Status
;
975 if (EFI_ERROR (Status
)) {
979 Fragment
[CurrentFragment
].Len
-= Tcp6RxData
->FragmentTable
[0].FragmentLength
;
980 if (Fragment
[CurrentFragment
].Len
== 0) {
983 Fragment
[CurrentFragment
].Bulk
+= Tcp6RxData
->FragmentTable
[0].FragmentLength
;
990 if (Fragment
!= NULL
) {
998 Receive one TLS PDU. An TLS PDU contains an TLS record header and its
999 corresponding record data. These two parts will be put into two blocks of buffers in the
1002 @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
1003 @param[out] Pdu The received TLS PDU.
1004 @param[in] Timeout The time to wait for connection done.
1006 @retval EFI_SUCCESS An TLS PDU is received.
1007 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
1008 @retval EFI_PROTOCOL_ERROR An unexpected TLS packet was received.
1009 @retval Others Other errors as indicated.
1015 IN OUT HTTP_PROTOCOL
*HttpInstance
,
1017 IN EFI_EVENT Timeout
1022 LIST_ENTRY
*NbufList
;
1028 TLS_RECORD_HEADER RecordHeader
;
1037 NbufList
= AllocatePool (sizeof (LIST_ENTRY
));
1038 if (NbufList
== NULL
) {
1039 return EFI_OUT_OF_RESOURCES
;
1042 InitializeListHead (NbufList
);
1045 // Allocate buffer to receive one TLS header.
1047 Len
= TLS_RECORD_HEADER_LENGTH
;
1048 PduHdr
= NetbufAlloc (Len
);
1049 if (PduHdr
== NULL
) {
1050 Status
= EFI_OUT_OF_RESOURCES
;
1054 Header
= NetbufAllocSpace (PduHdr
, Len
, NET_BUF_TAIL
);
1055 if (Header
== NULL
) {
1056 Status
= EFI_OUT_OF_RESOURCES
;
1061 // First step, receive one TLS header.
1063 Status
= TlsCommonReceive (HttpInstance
, PduHdr
, Timeout
);
1064 if (EFI_ERROR (Status
)) {
1068 RecordHeader
= *(TLS_RECORD_HEADER
*)Header
;
1069 if (((RecordHeader
.ContentType
== TlsContentTypeHandshake
) ||
1070 (RecordHeader
.ContentType
== TlsContentTypeAlert
) ||
1071 (RecordHeader
.ContentType
== TlsContentTypeChangeCipherSpec
) ||
1072 (RecordHeader
.ContentType
== TlsContentTypeApplicationData
)) &&
1073 (RecordHeader
.Version
.Major
== 0x03) && /// Major versions are same.
1074 ((RecordHeader
.Version
.Minor
== TLS10_PROTOCOL_VERSION_MINOR
) ||
1075 (RecordHeader
.Version
.Minor
== TLS11_PROTOCOL_VERSION_MINOR
) ||
1076 (RecordHeader
.Version
.Minor
== TLS12_PROTOCOL_VERSION_MINOR
))
1079 InsertTailList (NbufList
, &PduHdr
->List
);
1081 Status
= EFI_PROTOCOL_ERROR
;
1085 Len
= SwapBytes16 (RecordHeader
.Length
);
1094 // Allocate buffer to receive one TLS payload.
1096 DataSeg
= NetbufAlloc (Len
);
1097 if (DataSeg
== NULL
) {
1098 Status
= EFI_OUT_OF_RESOURCES
;
1102 NetbufAllocSpace (DataSeg
, Len
, NET_BUF_TAIL
);
1105 // Second step, receive one TLS payload.
1107 Status
= TlsCommonReceive (HttpInstance
, DataSeg
, Timeout
);
1108 if (EFI_ERROR (Status
)) {
1112 InsertTailList (NbufList
, &DataSeg
->List
);
1116 // Form the PDU from a list of PDU.
1118 *Pdu
= NetbufFromBufList (NbufList
, 0, 0, FreeNbufList
, NbufList
);
1120 Status
= EFI_OUT_OF_RESOURCES
;
1125 if (EFI_ERROR (Status
)) {
1127 // Free the Nbufs in this NbufList and the NbufList itself.
1129 FreeNbufList (NbufList
);
1136 Connect one TLS session by finishing the TLS handshake process.
1138 @param[in] HttpInstance The HTTP instance private data.
1139 @param[in] Timeout The time to wait for connection done.
1141 @retval EFI_SUCCESS The TLS session is established.
1142 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
1143 @retval EFI_ABORTED TLS session state is incorrect.
1144 @retval Others Other error as indicated.
1150 IN HTTP_PROTOCOL
*HttpInstance
,
1151 IN EFI_EVENT Timeout
1156 UINTN BufferOutSize
;
1162 UINT8
*GetSessionDataBuffer
;
1163 UINTN GetSessionDataBufferSize
;
1172 // Initialize TLS state.
1174 HttpInstance
->TlsSessionState
= EfiTlsSessionNotStarted
;
1175 Status
= HttpInstance
->Tls
->SetSessionData (
1178 &(HttpInstance
->TlsSessionState
),
1179 sizeof (EFI_TLS_SESSION_STATE
)
1181 if (EFI_ERROR (Status
)) {
1186 // Create ClientHello
1188 BufferOutSize
= DEF_BUF_LEN
;
1189 BufferOut
= AllocateZeroPool (BufferOutSize
);
1190 if (BufferOut
== NULL
) {
1191 Status
= EFI_OUT_OF_RESOURCES
;
1195 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1202 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1203 FreePool (BufferOut
);
1204 BufferOut
= AllocateZeroPool (BufferOutSize
);
1205 if (BufferOut
== NULL
) {
1206 Status
= EFI_OUT_OF_RESOURCES
;
1210 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1219 if (EFI_ERROR (Status
)) {
1220 FreePool (BufferOut
);
1225 // Transmit ClientHello
1227 PacketOut
= NetbufAlloc ((UINT32
)BufferOutSize
);
1228 DataOut
= NetbufAllocSpace (PacketOut
, (UINT32
)BufferOutSize
, NET_BUF_TAIL
);
1229 if (DataOut
== NULL
) {
1230 FreePool (BufferOut
);
1231 return EFI_OUT_OF_RESOURCES
;
1234 CopyMem (DataOut
, BufferOut
, BufferOutSize
);
1235 Status
= TlsCommonTransmit (HttpInstance
, PacketOut
);
1237 FreePool (BufferOut
);
1238 NetbufFree (PacketOut
);
1240 if (EFI_ERROR (Status
)) {
1244 while (HttpInstance
->TlsSessionState
!= EfiTlsSessionDataTransferring
&& \
1245 ((Timeout
== NULL
) || EFI_ERROR (gBS
->CheckEvent (Timeout
))))
1248 // Receive one TLS record.
1250 Status
= TlsReceiveOnePdu (HttpInstance
, &Pdu
, Timeout
);
1251 if (EFI_ERROR (Status
)) {
1255 BufferInSize
= Pdu
->TotalSize
;
1256 BufferIn
= AllocateZeroPool (BufferInSize
);
1257 if (BufferIn
== NULL
) {
1259 Status
= EFI_OUT_OF_RESOURCES
;
1263 NetbufCopy (Pdu
, 0, (UINT32
)BufferInSize
, BufferIn
);
1268 // Handle Receive data.
1270 BufferOutSize
= DEF_BUF_LEN
;
1271 BufferOut
= AllocateZeroPool (BufferOutSize
);
1272 if (BufferOut
== NULL
) {
1273 Status
= EFI_OUT_OF_RESOURCES
;
1277 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1284 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1285 FreePool (BufferOut
);
1286 BufferOut
= AllocateZeroPool (BufferOutSize
);
1287 if (BufferOut
== NULL
) {
1288 FreePool (BufferIn
);
1289 Status
= EFI_OUT_OF_RESOURCES
;
1293 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1302 FreePool (BufferIn
);
1304 if (EFI_ERROR (Status
)) {
1305 FreePool (BufferOut
);
1309 if (BufferOutSize
!= 0) {
1311 // Transmit the response packet.
1313 PacketOut
= NetbufAlloc ((UINT32
)BufferOutSize
);
1314 DataOut
= NetbufAllocSpace (PacketOut
, (UINT32
)BufferOutSize
, NET_BUF_TAIL
);
1315 if (DataOut
== NULL
) {
1316 FreePool (BufferOut
);
1317 return EFI_OUT_OF_RESOURCES
;
1320 CopyMem (DataOut
, BufferOut
, BufferOutSize
);
1322 Status
= TlsCommonTransmit (HttpInstance
, PacketOut
);
1324 NetbufFree (PacketOut
);
1326 if (EFI_ERROR (Status
)) {
1327 FreePool (BufferOut
);
1332 FreePool (BufferOut
);
1335 // Get the session state, then decide whether need to continue handle received packet.
1337 GetSessionDataBufferSize
= DEF_BUF_LEN
;
1338 GetSessionDataBuffer
= AllocateZeroPool (GetSessionDataBufferSize
);
1339 if (GetSessionDataBuffer
== NULL
) {
1340 Status
= EFI_OUT_OF_RESOURCES
;
1344 Status
= HttpInstance
->Tls
->GetSessionData (
1347 GetSessionDataBuffer
,
1348 &GetSessionDataBufferSize
1350 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1351 FreePool (GetSessionDataBuffer
);
1352 GetSessionDataBuffer
= AllocateZeroPool (GetSessionDataBufferSize
);
1353 if (GetSessionDataBuffer
== NULL
) {
1354 Status
= EFI_OUT_OF_RESOURCES
;
1358 Status
= HttpInstance
->Tls
->GetSessionData (
1361 GetSessionDataBuffer
,
1362 &GetSessionDataBufferSize
1366 if (EFI_ERROR (Status
)) {
1367 FreePool (GetSessionDataBuffer
);
1371 ASSERT (GetSessionDataBufferSize
== sizeof (EFI_TLS_SESSION_STATE
));
1372 HttpInstance
->TlsSessionState
= *(EFI_TLS_SESSION_STATE
*)GetSessionDataBuffer
;
1374 FreePool (GetSessionDataBuffer
);
1376 if (HttpInstance
->TlsSessionState
== EfiTlsSessionError
) {
1381 if (HttpInstance
->TlsSessionState
!= EfiTlsSessionDataTransferring
) {
1382 Status
= EFI_ABORTED
;
1389 Close the TLS session and send out the close notification message.
1391 @param[in] HttpInstance The HTTP instance private data.
1393 @retval EFI_SUCCESS The TLS session is closed.
1394 @retval EFI_INVALID_PARAMETER HttpInstance is NULL.
1395 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
1396 @retval Others Other error as indicated.
1402 IN HTTP_PROTOCOL
*HttpInstance
1408 UINTN BufferOutSize
;
1413 Status
= EFI_SUCCESS
;
1418 if (HttpInstance
== NULL
) {
1419 return EFI_INVALID_PARAMETER
;
1422 HttpInstance
->TlsSessionState
= EfiTlsSessionClosing
;
1424 Status
= HttpInstance
->Tls
->SetSessionData (
1427 &(HttpInstance
->TlsSessionState
),
1428 sizeof (EFI_TLS_SESSION_STATE
)
1430 if (EFI_ERROR (Status
)) {
1434 BufferOutSize
= DEF_BUF_LEN
;
1435 BufferOut
= AllocateZeroPool (BufferOutSize
);
1436 if (BufferOut
== NULL
) {
1437 Status
= EFI_OUT_OF_RESOURCES
;
1441 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1448 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1449 FreePool (BufferOut
);
1450 BufferOut
= AllocateZeroPool (BufferOutSize
);
1451 if (BufferOut
== NULL
) {
1452 Status
= EFI_OUT_OF_RESOURCES
;
1456 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1465 if (EFI_ERROR (Status
)) {
1466 FreePool (BufferOut
);
1470 PacketOut
= NetbufAlloc ((UINT32
)BufferOutSize
);
1471 DataOut
= NetbufAllocSpace (PacketOut
, (UINT32
)BufferOutSize
, NET_BUF_TAIL
);
1472 if (DataOut
== NULL
) {
1473 FreePool (BufferOut
);
1474 return EFI_OUT_OF_RESOURCES
;
1477 CopyMem (DataOut
, BufferOut
, BufferOutSize
);
1479 Status
= TlsCommonTransmit (HttpInstance
, PacketOut
);
1481 FreePool (BufferOut
);
1482 NetbufFree (PacketOut
);
1488 Process one message according to the CryptMode.
1490 @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
1491 @param[in] Message Pointer to the message buffer needed to processed.
1492 If ProcessMode is EfiTlsEncrypt, the message contain the TLS
1493 header and plain text TLS APP payload.
1494 If ProcessMode is EfiTlsDecrypt, the message contain the TLS
1495 header and cipher text TLS APP payload.
1496 @param[in] MessageSize Pointer to the message buffer size.
1497 @param[in] ProcessMode Process mode.
1498 @param[in, out] Fragment Only one Fragment returned after the Message is
1499 processed successfully.
1500 If ProcessMode is EfiTlsEncrypt, the fragment contain the TLS
1501 header and cipher text TLS APP payload.
1502 If ProcessMode is EfiTlsDecrypt, the fragment contain the TLS
1503 header and plain text TLS APP payload.
1505 @retval EFI_SUCCESS Message is processed successfully.
1506 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
1507 @retval Others Other errors as indicated.
1513 IN HTTP_PROTOCOL
*HttpInstance
,
1515 IN UINTN MessageSize
,
1516 IN EFI_TLS_CRYPT_MODE ProcessMode
,
1517 IN OUT NET_FRAGMENT
*Fragment
1524 EFI_TLS_FRAGMENT_DATA
*FragmentTable
;
1525 UINT32 FragmentCount
;
1526 EFI_TLS_FRAGMENT_DATA
*OriginalFragmentTable
;
1529 Status
= EFI_SUCCESS
;
1533 FragmentTable
= NULL
;
1534 OriginalFragmentTable
= NULL
;
1537 // Rebuild fragment table from BufferIn.
1540 FragmentTable
= AllocateZeroPool (FragmentCount
* sizeof (EFI_TLS_FRAGMENT_DATA
));
1541 if (FragmentTable
== NULL
) {
1542 Status
= EFI_OUT_OF_RESOURCES
;
1546 FragmentTable
->FragmentLength
= (UINT32
)MessageSize
;
1547 FragmentTable
->FragmentBuffer
= Message
;
1550 // Record the original FragmentTable.
1552 OriginalFragmentTable
= FragmentTable
;
1555 // Process the Message.
1557 Status
= HttpInstance
->Tls
->ProcessPacket (
1563 if (EFI_ERROR (Status
)) {
1568 // Calculate the size according to FragmentTable.
1570 for (Index
= 0; Index
< FragmentCount
; Index
++) {
1571 BufferSize
+= FragmentTable
[Index
].FragmentLength
;
1575 // Allocate buffer for processed data.
1577 Buffer
= AllocateZeroPool (BufferSize
);
1578 if (Buffer
== NULL
) {
1579 Status
= EFI_OUT_OF_RESOURCES
;
1584 // Copy the new FragmentTable buffer into Buffer.
1586 for (Index
= 0; Index
< FragmentCount
; Index
++) {
1588 (Buffer
+ BytesCopied
),
1589 FragmentTable
[Index
].FragmentBuffer
,
1590 FragmentTable
[Index
].FragmentLength
1592 BytesCopied
+= FragmentTable
[Index
].FragmentLength
;
1595 // Free the FragmentBuffer since it has been copied.
1597 FreePool (FragmentTable
[Index
].FragmentBuffer
);
1600 Fragment
->Len
= BufferSize
;
1601 Fragment
->Bulk
= Buffer
;
1605 if (OriginalFragmentTable
!= NULL
) {
1606 if ( FragmentTable
== OriginalFragmentTable
) {
1607 FragmentTable
= NULL
;
1610 FreePool (OriginalFragmentTable
);
1611 OriginalFragmentTable
= NULL
;
1615 // Caller has the responsibility to free the FragmentTable.
1617 if (FragmentTable
!= NULL
) {
1618 FreePool (FragmentTable
);
1619 FragmentTable
= NULL
;
1626 Receive one fragment decrypted from one TLS record.
1628 @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
1629 @param[in, out] Fragment The received Fragment.
1630 @param[in] Timeout The time to wait for connection done.
1632 @retval EFI_SUCCESS One fragment is received.
1633 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
1634 @retval EFI_ABORTED Something wrong decryption the message.
1635 @retval Others Other errors as indicated.
1641 IN HTTP_PROTOCOL
*HttpInstance
,
1642 IN OUT NET_FRAGMENT
*Fragment
,
1643 IN EFI_EVENT Timeout
1648 TLS_RECORD_HEADER RecordHeader
;
1651 NET_FRAGMENT TempFragment
;
1653 UINTN BufferOutSize
;
1656 UINT8
*GetSessionDataBuffer
;
1657 UINTN GetSessionDataBufferSize
;
1659 Status
= EFI_SUCCESS
;
1667 GetSessionDataBuffer
= NULL
;
1668 GetSessionDataBufferSize
= 0;
1671 // Receive only one TLS record
1673 Status
= TlsReceiveOnePdu (HttpInstance
, &Pdu
, Timeout
);
1674 if (EFI_ERROR (Status
)) {
1678 BufferInSize
= Pdu
->TotalSize
;
1679 BufferIn
= AllocateZeroPool (BufferInSize
);
1680 if (BufferIn
== NULL
) {
1681 Status
= EFI_OUT_OF_RESOURCES
;
1686 NetbufCopy (Pdu
, 0, (UINT32
)BufferInSize
, BufferIn
);
1691 // Handle Receive data.
1693 RecordHeader
= *(TLS_RECORD_HEADER
*)BufferIn
;
1695 if ((RecordHeader
.ContentType
== TlsContentTypeApplicationData
) &&
1696 (RecordHeader
.Version
.Major
== 0x03) &&
1697 ((RecordHeader
.Version
.Minor
== TLS10_PROTOCOL_VERSION_MINOR
) ||
1698 (RecordHeader
.Version
.Minor
== TLS11_PROTOCOL_VERSION_MINOR
) ||
1699 (RecordHeader
.Version
.Minor
== TLS12_PROTOCOL_VERSION_MINOR
))
1705 Status
= TlsProcessMessage (
1713 FreePool (BufferIn
);
1715 if (EFI_ERROR (Status
)) {
1716 if (Status
== EFI_ABORTED
) {
1718 // Something wrong decryption the message.
1719 // BuildResponsePacket() will be called to generate Error Alert message and send it out.
1721 BufferOutSize
= DEF_BUF_LEN
;
1722 BufferOut
= AllocateZeroPool (BufferOutSize
);
1723 if (BufferOut
== NULL
) {
1724 Status
= EFI_OUT_OF_RESOURCES
;
1728 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1735 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1736 FreePool (BufferOut
);
1737 BufferOut
= AllocateZeroPool (BufferOutSize
);
1738 if (BufferOut
== NULL
) {
1739 Status
= EFI_OUT_OF_RESOURCES
;
1743 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1752 if (EFI_ERROR (Status
)) {
1753 FreePool (BufferOut
);
1757 if (BufferOutSize
!= 0) {
1758 PacketOut
= NetbufAlloc ((UINT32
)BufferOutSize
);
1759 DataOut
= NetbufAllocSpace (PacketOut
, (UINT32
)BufferOutSize
, NET_BUF_TAIL
);
1760 if (DataOut
== NULL
) {
1761 FreePool (BufferOut
);
1762 return EFI_OUT_OF_RESOURCES
;
1765 CopyMem (DataOut
, BufferOut
, BufferOutSize
);
1767 Status
= TlsCommonTransmit (HttpInstance
, PacketOut
);
1769 NetbufFree (PacketOut
);
1772 FreePool (BufferOut
);
1774 if (EFI_ERROR (Status
)) {
1787 ASSERT (((TLS_RECORD_HEADER
*)(TempFragment
.Bulk
))->ContentType
== TlsContentTypeApplicationData
);
1789 BufferInSize
= ((TLS_RECORD_HEADER
*)(TempFragment
.Bulk
))->Length
;
1790 BufferIn
= AllocateZeroPool (BufferInSize
);
1791 if (BufferIn
== NULL
) {
1792 Status
= EFI_OUT_OF_RESOURCES
;
1796 CopyMem (BufferIn
, TempFragment
.Bulk
+ TLS_RECORD_HEADER_LENGTH
, BufferInSize
);
1799 // Free the buffer in TempFragment.
1801 FreePool (TempFragment
.Bulk
);
1802 } else if ((RecordHeader
.ContentType
== TlsContentTypeAlert
) &&
1803 (RecordHeader
.Version
.Major
== 0x03) &&
1804 ((RecordHeader
.Version
.Minor
== TLS10_PROTOCOL_VERSION_MINOR
) ||
1805 (RecordHeader
.Version
.Minor
== TLS11_PROTOCOL_VERSION_MINOR
) ||
1806 (RecordHeader
.Version
.Minor
== TLS12_PROTOCOL_VERSION_MINOR
))
1809 BufferOutSize
= DEF_BUF_LEN
;
1810 BufferOut
= AllocateZeroPool (BufferOutSize
);
1811 if (BufferOut
== NULL
) {
1812 FreePool (BufferIn
);
1813 Status
= EFI_OUT_OF_RESOURCES
;
1817 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1824 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1825 FreePool (BufferOut
);
1826 BufferOut
= AllocateZeroPool (BufferOutSize
);
1827 if (BufferOut
== NULL
) {
1828 FreePool (BufferIn
);
1829 Status
= EFI_OUT_OF_RESOURCES
;
1833 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1842 FreePool (BufferIn
);
1844 if (EFI_ERROR (Status
)) {
1845 FreePool (BufferOut
);
1849 if (BufferOutSize
!= 0) {
1850 PacketOut
= NetbufAlloc ((UINT32
)BufferOutSize
);
1851 DataOut
= NetbufAllocSpace (PacketOut
, (UINT32
)BufferOutSize
, NET_BUF_TAIL
);
1852 if (DataOut
== NULL
) {
1853 FreePool (BufferOut
);
1854 return EFI_OUT_OF_RESOURCES
;
1857 CopyMem (DataOut
, BufferOut
, BufferOutSize
);
1859 Status
= TlsCommonTransmit (HttpInstance
, PacketOut
);
1861 NetbufFree (PacketOut
);
1864 FreePool (BufferOut
);
1867 // Get the session state.
1869 GetSessionDataBufferSize
= DEF_BUF_LEN
;
1870 GetSessionDataBuffer
= AllocateZeroPool (GetSessionDataBufferSize
);
1871 if (GetSessionDataBuffer
== NULL
) {
1872 Status
= EFI_OUT_OF_RESOURCES
;
1876 Status
= HttpInstance
->Tls
->GetSessionData (
1879 GetSessionDataBuffer
,
1880 &GetSessionDataBufferSize
1882 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1883 FreePool (GetSessionDataBuffer
);
1884 GetSessionDataBuffer
= AllocateZeroPool (GetSessionDataBufferSize
);
1885 if (GetSessionDataBuffer
== NULL
) {
1886 Status
= EFI_OUT_OF_RESOURCES
;
1890 Status
= HttpInstance
->Tls
->GetSessionData (
1893 GetSessionDataBuffer
,
1894 &GetSessionDataBufferSize
1898 if (EFI_ERROR (Status
)) {
1899 FreePool (GetSessionDataBuffer
);
1903 ASSERT (GetSessionDataBufferSize
== sizeof (EFI_TLS_SESSION_STATE
));
1904 HttpInstance
->TlsSessionState
= *(EFI_TLS_SESSION_STATE
*)GetSessionDataBuffer
;
1906 FreePool (GetSessionDataBuffer
);
1908 if (HttpInstance
->TlsSessionState
== EfiTlsSessionError
) {
1909 DEBUG ((DEBUG_ERROR
, "TLS Session State Error!\n"));
1917 Fragment
->Bulk
= BufferIn
;
1918 Fragment
->Len
= (UINT32
)BufferInSize
;