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 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include "HttpDriver.h"
19 Returns the first occurrence of a Null-terminated ASCII sub-string in a Null-terminated
20 ASCII string and ignore case during the search process.
22 This function scans the contents of the ASCII string specified by String
23 and returns the first occurrence of SearchString and ignore case during the search process.
24 If SearchString is not found in String, then NULL is returned. If the length of SearchString
25 is zero, then String is returned.
27 If String is NULL, then ASSERT().
28 If SearchString is NULL, then ASSERT().
30 @param[in] String A pointer to a Null-terminated ASCII string.
31 @param[in] SearchString A pointer to a Null-terminated ASCII string to search for.
33 @retval NULL If the SearchString does not appear in String.
34 @retval others If there is a match return the first occurrence of SearchingString.
35 If the length of SearchString is zero,return String.
40 IN CONST CHAR8
*String
,
41 IN CONST CHAR8
*SearchString
44 CONST CHAR8
*FirstMatch
;
45 CONST CHAR8
*SearchStringTmp
;
51 // ASSERT both strings are less long than PcdMaximumAsciiStringLength
53 ASSERT (AsciiStrSize (String
) != 0);
54 ASSERT (AsciiStrSize (SearchString
) != 0);
56 if (*SearchString
== '\0') {
57 return (CHAR8
*) String
;
60 while (*String
!= '\0') {
61 SearchStringTmp
= SearchString
;
64 while ((*SearchStringTmp
!= '\0')
65 && (*String
!= '\0')) {
67 Dst
= *SearchStringTmp
;
69 if ((Src
>= 'A') && (Src
<= 'Z')) {
73 if ((Dst
>= 'A') && (Dst
<= 'Z')) {
85 if (*SearchStringTmp
== '\0') {
86 return (CHAR8
*) FirstMatch
;
89 String
= FirstMatch
+ 1;
96 The callback function to free the net buffer list.
98 @param[in] Arg The opaque parameter.
107 ASSERT (Arg
!= NULL
);
109 NetbufFreeList ((LIST_ENTRY
*) Arg
);
114 Check whether the Url is from Https.
116 @param[in] Url The pointer to a HTTP or HTTPS URL string.
118 @retval TRUE The Url is from HTTPS.
119 @retval FALSE The Url is from HTTP.
131 Tmp
= AsciiStrCaseStr (Url
, HTTPS_FLAG
);
132 if (Tmp
!= NULL
&& Tmp
== Url
) {
140 Creates a Tls child handle, open EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL.
142 @param[in] ImageHandle The firmware allocated handle for the UEFI image.
143 @param[out] TlsSb Pointer to the TLS SERVICE_BINDING_PROTOCOL.
144 @param[out] TlsProto Pointer to the EFI_TLS_PROTOCOL instance.
145 @param[out] TlsConfiguration Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
147 @return The child handle with opened EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL.
153 IN EFI_HANDLE ImageHandle
,
154 OUT EFI_SERVICE_BINDING_PROTOCOL
**TlsSb
,
155 OUT EFI_TLS_PROTOCOL
**TlsProto
,
156 OUT EFI_TLS_CONFIGURATION_PROTOCOL
**TlsConfiguration
160 EFI_HANDLE TlsChildHandle
;
165 // Locate TlsServiceBinding protocol.
167 gBS
->LocateProtocol (
168 &gEfiTlsServiceBindingProtocolGuid
,
172 if (*TlsSb
== NULL
) {
176 Status
= (*TlsSb
)->CreateChild (*TlsSb
, &TlsChildHandle
);
177 if (EFI_ERROR (Status
)) {
181 Status
= gBS
->OpenProtocol (
183 &gEfiTlsProtocolGuid
,
187 EFI_OPEN_PROTOCOL_GET_PROTOCOL
189 if (EFI_ERROR (Status
)) {
190 (*TlsSb
)->DestroyChild (*TlsSb
, TlsChildHandle
);
194 Status
= gBS
->OpenProtocol (
196 &gEfiTlsConfigurationProtocolGuid
,
197 (VOID
**) TlsConfiguration
,
200 EFI_OPEN_PROTOCOL_GET_PROTOCOL
202 if (EFI_ERROR (Status
)) {
203 (*TlsSb
)->DestroyChild (*TlsSb
, TlsChildHandle
);
207 return TlsChildHandle
;
211 Create event for the TLS receive and transmit tokens which are used to receive and
212 transmit TLS related messages.
214 @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
216 @retval EFI_SUCCESS The events are created successfully.
217 @retval others Other error as indicated.
223 IN OUT HTTP_PROTOCOL
*HttpInstance
228 if (!HttpInstance
->LocalAddressIsIPv6
) {
230 // For Tcp4TlsTxToken.
232 Status
= gBS
->CreateEvent (
236 &HttpInstance
->TlsIsTxDone
,
237 &HttpInstance
->Tcp4TlsTxToken
.CompletionToken
.Event
239 if (EFI_ERROR (Status
)) {
243 HttpInstance
->Tcp4TlsTxData
.Push
= TRUE
;
244 HttpInstance
->Tcp4TlsTxData
.Urgent
= FALSE
;
245 HttpInstance
->Tcp4TlsTxData
.DataLength
= 0;
246 HttpInstance
->Tcp4TlsTxData
.FragmentCount
= 1;
247 HttpInstance
->Tcp4TlsTxData
.FragmentTable
[0].FragmentLength
= HttpInstance
->Tcp4TlsTxData
.DataLength
;
248 HttpInstance
->Tcp4TlsTxData
.FragmentTable
[0].FragmentBuffer
= NULL
;
249 HttpInstance
->Tcp4TlsTxToken
.Packet
.TxData
= &HttpInstance
->Tcp4TlsTxData
;
250 HttpInstance
->Tcp4TlsTxToken
.CompletionToken
.Status
= EFI_NOT_READY
;
253 // For Tcp4TlsRxToken.
255 Status
= gBS
->CreateEvent (
259 &HttpInstance
->TlsIsRxDone
,
260 &HttpInstance
->Tcp4TlsRxToken
.CompletionToken
.Event
262 if (EFI_ERROR (Status
)) {
266 HttpInstance
->Tcp4TlsRxData
.DataLength
= 0;
267 HttpInstance
->Tcp4TlsRxData
.FragmentCount
= 1;
268 HttpInstance
->Tcp4TlsRxData
.FragmentTable
[0].FragmentLength
= HttpInstance
->Tcp4TlsRxData
.DataLength
;
269 HttpInstance
->Tcp4TlsRxData
.FragmentTable
[0].FragmentBuffer
= NULL
;
270 HttpInstance
->Tcp4TlsRxToken
.Packet
.RxData
= &HttpInstance
->Tcp4TlsRxData
;
271 HttpInstance
->Tcp4TlsRxToken
.CompletionToken
.Status
= EFI_NOT_READY
;
274 // For Tcp6TlsTxToken.
276 Status
= gBS
->CreateEvent (
280 &HttpInstance
->TlsIsTxDone
,
281 &HttpInstance
->Tcp6TlsTxToken
.CompletionToken
.Event
283 if (EFI_ERROR (Status
)) {
287 HttpInstance
->Tcp6TlsTxData
.Push
= TRUE
;
288 HttpInstance
->Tcp6TlsTxData
.Urgent
= FALSE
;
289 HttpInstance
->Tcp6TlsTxData
.DataLength
= 0;
290 HttpInstance
->Tcp6TlsTxData
.FragmentCount
= 1;
291 HttpInstance
->Tcp6TlsTxData
.FragmentTable
[0].FragmentLength
= HttpInstance
->Tcp6TlsTxData
.DataLength
;
292 HttpInstance
->Tcp6TlsTxData
.FragmentTable
[0].FragmentBuffer
= NULL
;
293 HttpInstance
->Tcp6TlsTxToken
.Packet
.TxData
= &HttpInstance
->Tcp6TlsTxData
;
294 HttpInstance
->Tcp6TlsTxToken
.CompletionToken
.Status
= EFI_NOT_READY
;
297 // For Tcp6TlsRxToken.
299 Status
= gBS
->CreateEvent (
303 &HttpInstance
->TlsIsRxDone
,
304 &HttpInstance
->Tcp6TlsRxToken
.CompletionToken
.Event
306 if (EFI_ERROR (Status
)) {
310 HttpInstance
->Tcp6TlsRxData
.DataLength
= 0;
311 HttpInstance
->Tcp6TlsRxData
.FragmentCount
= 1;
312 HttpInstance
->Tcp6TlsRxData
.FragmentTable
[0].FragmentLength
= HttpInstance
->Tcp6TlsRxData
.DataLength
;
313 HttpInstance
->Tcp6TlsRxData
.FragmentTable
[0].FragmentBuffer
= NULL
;
314 HttpInstance
->Tcp6TlsRxToken
.Packet
.RxData
= &HttpInstance
->Tcp6TlsRxData
;
315 HttpInstance
->Tcp6TlsRxToken
.CompletionToken
.Status
= EFI_NOT_READY
;
324 TlsCloseTxRxEvent (HttpInstance
);
330 Close events in the TlsTxToken and TlsRxToken.
332 @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
338 IN HTTP_PROTOCOL
*HttpInstance
341 ASSERT (HttpInstance
!= NULL
);
342 if (!HttpInstance
->LocalAddressIsIPv6
) {
343 if (NULL
!= HttpInstance
->Tcp4TlsTxToken
.CompletionToken
.Event
) {
344 gBS
->CloseEvent(HttpInstance
->Tcp4TlsTxToken
.CompletionToken
.Event
);
345 HttpInstance
->Tcp4TlsTxToken
.CompletionToken
.Event
= NULL
;
348 if (NULL
!= HttpInstance
->Tcp4TlsRxToken
.CompletionToken
.Event
) {
349 gBS
->CloseEvent (HttpInstance
->Tcp4TlsRxToken
.CompletionToken
.Event
);
350 HttpInstance
->Tcp4TlsRxToken
.CompletionToken
.Event
= NULL
;
353 if (NULL
!= HttpInstance
->Tcp6TlsTxToken
.CompletionToken
.Event
) {
354 gBS
->CloseEvent(HttpInstance
->Tcp6TlsTxToken
.CompletionToken
.Event
);
355 HttpInstance
->Tcp6TlsTxToken
.CompletionToken
.Event
= NULL
;
358 if (NULL
!= HttpInstance
->Tcp6TlsRxToken
.CompletionToken
.Event
) {
359 gBS
->CloseEvent (HttpInstance
->Tcp6TlsRxToken
.CompletionToken
.Event
);
360 HttpInstance
->Tcp6TlsRxToken
.CompletionToken
.Event
= NULL
;
366 Read the TlsCaCertificate variable and configure it.
368 @param[in, out] HttpInstance The HTTP instance private data.
370 @retval EFI_SUCCESS TlsCaCertificate is configured.
371 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
372 @retval EFI_NOT_FOUND Fail to get 'TlsCaCertificate' variable.
373 @retval Others Other error as indicated.
377 TlsConfigCertificate (
378 IN OUT HTTP_PROTOCOL
*HttpInstance
385 EFI_SIGNATURE_LIST
*CertList
;
386 EFI_SIGNATURE_DATA
*Cert
;
394 // Try to read the TlsCaCertificate variable.
396 Status
= gRT
->GetVariable (
397 EFI_TLS_CA_CERTIFICATE_VARIABLE
,
398 &gEfiTlsCaCertificateGuid
,
404 if (EFI_ERROR (Status
) && Status
!= EFI_BUFFER_TOO_SMALL
) {
409 // Allocate buffer and read the config variable.
411 CACert
= AllocatePool (CACertSize
);
412 if (CACert
== NULL
) {
413 return EFI_OUT_OF_RESOURCES
;
416 Status
= gRT
->GetVariable (
417 EFI_TLS_CA_CERTIFICATE_VARIABLE
,
418 &gEfiTlsCaCertificateGuid
,
423 if (EFI_ERROR (Status
)) {
425 // GetVariable still error or the variable is corrupted.
426 // Fall back to the default value.
430 return EFI_NOT_FOUND
;
433 ASSERT (CACert
!= NULL
);
436 // Enumerate all data and erasing the target item.
438 ItemDataSize
= (UINT32
) CACertSize
;
439 CertList
= (EFI_SIGNATURE_LIST
*) CACert
;
440 while ((ItemDataSize
> 0) && (ItemDataSize
>= CertList
->SignatureListSize
)) {
441 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) CertList
+ sizeof (EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
);
442 CertCount
= (CertList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - CertList
->SignatureHeaderSize
) / CertList
->SignatureSize
;
443 for (Index
= 0; Index
< CertCount
; Index
++) {
445 // EfiTlsConfigDataTypeCACertificate
447 Status
= HttpInstance
->TlsConfiguration
->SetData (
448 HttpInstance
->TlsConfiguration
,
449 EfiTlsConfigDataTypeCACertificate
,
451 CertList
->SignatureSize
- sizeof (Cert
->SignatureOwner
)
453 if (EFI_ERROR (Status
)) {
458 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) Cert
+ CertList
->SignatureSize
);
461 ItemDataSize
-= CertList
->SignatureListSize
;
462 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
470 Read the HttpTlsCipherList variable and configure it for HTTPS session.
472 @param[in, out] HttpInstance The HTTP instance private data.
474 @retval EFI_SUCCESS The prefered HTTP TLS CipherList is configured.
475 @retval EFI_NOT_FOUND Fail to get 'HttpTlsCipherList' variable.
476 @retval EFI_INVALID_PARAMETER The contents of variable are invalid.
477 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
479 @retval Others Other error as indicated.
483 TlsConfigCipherList (
484 IN OUT HTTP_PROTOCOL
*HttpInstance
489 UINTN CipherListSize
;
495 // Try to read the HttpTlsCipherList variable.
497 Status
= gRT
->GetVariable (
498 EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE
,
499 &gEdkiiHttpTlsCipherListGuid
,
504 ASSERT (EFI_ERROR (Status
));
505 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
509 if (CipherListSize
% sizeof (EFI_TLS_CIPHER
) != 0) {
510 return EFI_INVALID_PARAMETER
;
514 // Allocate buffer and read the config variable.
516 CipherList
= AllocatePool (CipherListSize
);
517 if (CipherList
== NULL
) {
518 return EFI_OUT_OF_RESOURCES
;
521 Status
= gRT
->GetVariable (
522 EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE
,
523 &gEdkiiHttpTlsCipherListGuid
,
528 if (EFI_ERROR (Status
)) {
530 // GetVariable still error or the variable is corrupted.
535 ASSERT (CipherList
!= NULL
);
537 Status
= HttpInstance
->Tls
->SetSessionData (
545 FreePool (CipherList
);
551 Configure TLS session data.
553 @param[in, out] HttpInstance The HTTP instance private data.
555 @retval EFI_SUCCESS TLS session data is configured.
556 @retval Others Other error as indicated.
561 TlsConfigureSession (
562 IN OUT HTTP_PROTOCOL
*HttpInstance
568 // TlsConfigData initialization
570 HttpInstance
->TlsConfigData
.ConnectionEnd
= EfiTlsClient
;
571 HttpInstance
->TlsConfigData
.VerifyMethod
= EFI_TLS_VERIFY_PEER
;
572 HttpInstance
->TlsConfigData
.SessionState
= EfiTlsSessionNotStarted
;
575 // EfiTlsConnectionEnd,
576 // EfiTlsVerifyMethod
577 // EfiTlsSessionState
579 Status
= HttpInstance
->Tls
->SetSessionData (
582 &(HttpInstance
->TlsConfigData
.ConnectionEnd
),
583 sizeof (EFI_TLS_CONNECTION_END
)
585 if (EFI_ERROR (Status
)) {
589 Status
= HttpInstance
->Tls
->SetSessionData (
592 &HttpInstance
->TlsConfigData
.VerifyMethod
,
593 sizeof (EFI_TLS_VERIFY
)
595 if (EFI_ERROR (Status
)) {
599 Status
= HttpInstance
->Tls
->SetSessionData (
602 &(HttpInstance
->TlsConfigData
.SessionState
),
603 sizeof (EFI_TLS_SESSION_STATE
)
605 if (EFI_ERROR (Status
)) {
612 Status
= TlsConfigCipherList (HttpInstance
);
613 if (EFI_ERROR (Status
) && Status
!= EFI_NOT_FOUND
) {
614 DEBUG ((EFI_D_ERROR
, "TlsConfigCipherList: return %r error.\n", Status
));
619 // Tls Config Certificate
621 Status
= TlsConfigCertificate (HttpInstance
);
622 if (EFI_ERROR (Status
)) {
623 DEBUG ((EFI_D_ERROR
, "TLS Certificate Config Error!\n"));
628 // TlsCreateTxRxEvent
630 Status
= TlsCreateTxRxEvent (HttpInstance
);
631 if (EFI_ERROR (Status
)) {
638 TlsCloseTxRxEvent (HttpInstance
);
644 Transmit the Packet by processing the associated HTTPS token.
646 @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
647 @param[in] Packet The packet to transmit.
649 @retval EFI_SUCCESS The packet is transmitted.
650 @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
651 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
652 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
653 @retval Others Other errors as indicated.
659 IN OUT HTTP_PROTOCOL
*HttpInstance
,
667 if ((HttpInstance
== NULL
) || (Packet
== NULL
)) {
668 return EFI_INVALID_PARAMETER
;
671 if (!HttpInstance
->LocalAddressIsIPv6
) {
672 Size
= sizeof (EFI_TCP4_TRANSMIT_DATA
) +
673 (Packet
->BlockOpNum
- 1) * sizeof (EFI_TCP4_FRAGMENT_DATA
);
675 Size
= sizeof (EFI_TCP6_TRANSMIT_DATA
) +
676 (Packet
->BlockOpNum
- 1) * sizeof (EFI_TCP6_FRAGMENT_DATA
);
679 Data
= AllocatePool (Size
);
681 return EFI_OUT_OF_RESOURCES
;
684 if (!HttpInstance
->LocalAddressIsIPv6
) {
685 ((EFI_TCP4_TRANSMIT_DATA
*) Data
)->Push
= TRUE
;
686 ((EFI_TCP4_TRANSMIT_DATA
*) Data
)->Urgent
= FALSE
;
687 ((EFI_TCP4_TRANSMIT_DATA
*) Data
)->DataLength
= Packet
->TotalSize
;
690 // Build the fragment table.
692 ((EFI_TCP4_TRANSMIT_DATA
*) Data
)->FragmentCount
= Packet
->BlockOpNum
;
696 (NET_FRAGMENT
*) &((EFI_TCP4_TRANSMIT_DATA
*) Data
)->FragmentTable
[0],
697 &((EFI_TCP4_TRANSMIT_DATA
*) Data
)->FragmentCount
700 HttpInstance
->Tcp4TlsTxToken
.Packet
.TxData
= (EFI_TCP4_TRANSMIT_DATA
*) Data
;
702 Status
= EFI_DEVICE_ERROR
;
705 // Transmit the packet.
707 Status
= HttpInstance
->Tcp4
->Transmit (HttpInstance
->Tcp4
, &HttpInstance
->Tcp4TlsTxToken
);
708 if (EFI_ERROR (Status
)) {
712 while (!HttpInstance
->TlsIsTxDone
) {
713 HttpInstance
->Tcp4
->Poll (HttpInstance
->Tcp4
);
716 HttpInstance
->TlsIsTxDone
= FALSE
;
717 Status
= HttpInstance
->Tcp4TlsTxToken
.CompletionToken
.Status
;
719 ((EFI_TCP6_TRANSMIT_DATA
*) Data
)->Push
= TRUE
;
720 ((EFI_TCP6_TRANSMIT_DATA
*) Data
)->Urgent
= FALSE
;
721 ((EFI_TCP6_TRANSMIT_DATA
*) Data
)->DataLength
= Packet
->TotalSize
;
724 // Build the fragment table.
726 ((EFI_TCP6_TRANSMIT_DATA
*) Data
)->FragmentCount
= Packet
->BlockOpNum
;
730 (NET_FRAGMENT
*) &((EFI_TCP6_TRANSMIT_DATA
*) Data
)->FragmentTable
[0],
731 &((EFI_TCP6_TRANSMIT_DATA
*) Data
)->FragmentCount
734 HttpInstance
->Tcp6TlsTxToken
.Packet
.TxData
= (EFI_TCP6_TRANSMIT_DATA
*) Data
;
736 Status
= EFI_DEVICE_ERROR
;
739 // Transmit the packet.
741 Status
= HttpInstance
->Tcp6
->Transmit (HttpInstance
->Tcp6
, &HttpInstance
->Tcp6TlsTxToken
);
742 if (EFI_ERROR (Status
)) {
746 while (!HttpInstance
->TlsIsTxDone
) {
747 HttpInstance
->Tcp6
->Poll (HttpInstance
->Tcp6
);
750 HttpInstance
->TlsIsTxDone
= FALSE
;
751 Status
= HttpInstance
->Tcp6TlsTxToken
.CompletionToken
.Status
;
761 Receive the Packet by processing the associated HTTPS token.
763 @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
764 @param[in] Packet The packet to transmit.
765 @param[in] Timeout The time to wait for connection done.
767 @retval EFI_SUCCESS The Packet is received.
768 @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
769 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
770 @retval EFI_TIMEOUT The operation is time out.
771 @retval Others Other error as indicated.
777 IN OUT HTTP_PROTOCOL
*HttpInstance
,
782 EFI_TCP4_RECEIVE_DATA
*Tcp4RxData
;
783 EFI_TCP6_RECEIVE_DATA
*Tcp6RxData
;
785 NET_FRAGMENT
*Fragment
;
786 UINT32 FragmentCount
;
787 UINT32 CurrentFragment
;
792 if ((HttpInstance
== NULL
) || (Packet
== NULL
)) {
793 return EFI_INVALID_PARAMETER
;
796 FragmentCount
= Packet
->BlockOpNum
;
797 Fragment
= AllocatePool (FragmentCount
* sizeof (NET_FRAGMENT
));
798 if (Fragment
== NULL
) {
799 Status
= EFI_OUT_OF_RESOURCES
;
804 // Build the fragment table.
806 NetbufBuildExt (Packet
, Fragment
, &FragmentCount
);
808 if (!HttpInstance
->LocalAddressIsIPv6
) {
809 Tcp4RxData
= HttpInstance
->Tcp4TlsRxToken
.Packet
.RxData
;
810 if (Tcp4RxData
== NULL
) {
811 return EFI_INVALID_PARAMETER
;
813 Tcp4RxData
->FragmentCount
= 1;
815 Tcp6RxData
= HttpInstance
->Tcp6TlsRxToken
.Packet
.RxData
;
816 if (Tcp6RxData
== NULL
) {
817 return EFI_INVALID_PARAMETER
;
819 Tcp6RxData
->FragmentCount
= 1;
823 Status
= EFI_SUCCESS
;
825 while (CurrentFragment
< FragmentCount
) {
826 if (!HttpInstance
->LocalAddressIsIPv6
) {
827 Tcp4RxData
->DataLength
= Fragment
[CurrentFragment
].Len
;
828 Tcp4RxData
->FragmentTable
[0].FragmentLength
= Fragment
[CurrentFragment
].Len
;
829 Tcp4RxData
->FragmentTable
[0].FragmentBuffer
= Fragment
[CurrentFragment
].Bulk
;
830 Status
= HttpInstance
->Tcp4
->Receive (HttpInstance
->Tcp4
, &HttpInstance
->Tcp4TlsRxToken
);
832 Tcp6RxData
->DataLength
= Fragment
[CurrentFragment
].Len
;
833 Tcp6RxData
->FragmentTable
[0].FragmentLength
= Fragment
[CurrentFragment
].Len
;
834 Tcp6RxData
->FragmentTable
[0].FragmentBuffer
= Fragment
[CurrentFragment
].Bulk
;
835 Status
= HttpInstance
->Tcp6
->Receive (HttpInstance
->Tcp6
, &HttpInstance
->Tcp6TlsRxToken
);
837 if (EFI_ERROR (Status
)) {
841 while (!HttpInstance
->TlsIsRxDone
&& ((Timeout
== NULL
) || EFI_ERROR (gBS
->CheckEvent (Timeout
)))) {
843 // Poll until some data is received or an error occurs.
845 if (!HttpInstance
->LocalAddressIsIPv6
) {
846 HttpInstance
->Tcp4
->Poll (HttpInstance
->Tcp4
);
848 HttpInstance
->Tcp6
->Poll (HttpInstance
->Tcp6
);
852 if (!HttpInstance
->TlsIsRxDone
) {
854 // Timeout occurs, cancel the receive request.
856 if (!HttpInstance
->LocalAddressIsIPv6
) {
857 HttpInstance
->Tcp4
->Cancel (HttpInstance
->Tcp4
, &HttpInstance
->Tcp4TlsRxToken
.CompletionToken
);
859 HttpInstance
->Tcp6
->Cancel (HttpInstance
->Tcp6
, &HttpInstance
->Tcp6TlsRxToken
.CompletionToken
);
862 Status
= EFI_TIMEOUT
;
865 HttpInstance
->TlsIsRxDone
= FALSE
;
868 if (!HttpInstance
->LocalAddressIsIPv6
) {
869 Status
= HttpInstance
->Tcp4TlsRxToken
.CompletionToken
.Status
;
870 if (EFI_ERROR (Status
)) {
874 Fragment
[CurrentFragment
].Len
-= Tcp4RxData
->FragmentTable
[0].FragmentLength
;
875 if (Fragment
[CurrentFragment
].Len
== 0) {
878 Fragment
[CurrentFragment
].Bulk
+= Tcp4RxData
->FragmentTable
[0].FragmentLength
;
881 Status
= HttpInstance
->Tcp6TlsRxToken
.CompletionToken
.Status
;
882 if (EFI_ERROR (Status
)) {
886 Fragment
[CurrentFragment
].Len
-= Tcp6RxData
->FragmentTable
[0].FragmentLength
;
887 if (Fragment
[CurrentFragment
].Len
== 0) {
890 Fragment
[CurrentFragment
].Bulk
+= Tcp6RxData
->FragmentTable
[0].FragmentLength
;
897 if (Fragment
!= NULL
) {
905 Receive one TLS PDU. An TLS PDU contains an TLS record header and it's
906 corresponding record data. These two parts will be put into two blocks of buffers in the
909 @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
910 @param[out] Pdu The received TLS PDU.
911 @param[in] Timeout The time to wait for connection done.
913 @retval EFI_SUCCESS An TLS PDU is received.
914 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
915 @retval EFI_PROTOCOL_ERROR An unexpected TLS packet was received.
916 @retval Others Other errors as indicated.
922 IN OUT HTTP_PROTOCOL
*HttpInstance
,
929 LIST_ENTRY
*NbufList
;
935 TLS_RECORD_HEADER RecordHeader
;
944 NbufList
= AllocatePool (sizeof (LIST_ENTRY
));
945 if (NbufList
== NULL
) {
946 return EFI_OUT_OF_RESOURCES
;
949 InitializeListHead (NbufList
);
952 // Allocate buffer to receive one TLS header.
954 Len
= sizeof (TLS_RECORD_HEADER
);
955 PduHdr
= NetbufAlloc (Len
);
956 if (PduHdr
== NULL
) {
957 Status
= EFI_OUT_OF_RESOURCES
;
961 Header
= NetbufAllocSpace (PduHdr
, Len
, NET_BUF_TAIL
);
962 if (Header
== NULL
) {
963 Status
= EFI_OUT_OF_RESOURCES
;
968 // First step, receive one TLS header.
970 Status
= TlsCommonReceive (HttpInstance
, PduHdr
, Timeout
);
971 if (EFI_ERROR (Status
)) {
975 RecordHeader
= *(TLS_RECORD_HEADER
*) Header
;
976 if ((RecordHeader
.ContentType
== TlsContentTypeHandshake
||
977 RecordHeader
.ContentType
== TlsContentTypeAlert
||
978 RecordHeader
.ContentType
== TlsContentTypeChangeCipherSpec
||
979 RecordHeader
.ContentType
== TlsContentTypeApplicationData
) &&
980 (RecordHeader
.Version
.Major
== 0x03) && /// Major versions are same.
981 (RecordHeader
.Version
.Minor
== TLS10_PROTOCOL_VERSION_MINOR
||
982 RecordHeader
.Version
.Minor
==TLS11_PROTOCOL_VERSION_MINOR
||
983 RecordHeader
.Version
.Minor
== TLS12_PROTOCOL_VERSION_MINOR
)
985 InsertTailList (NbufList
, &PduHdr
->List
);
987 Status
= EFI_PROTOCOL_ERROR
;
991 Len
= SwapBytes16(RecordHeader
.Length
);
1000 // Allocate buffer to receive one TLS payload.
1002 DataSeg
= NetbufAlloc (Len
);
1003 if (DataSeg
== NULL
) {
1004 Status
= EFI_OUT_OF_RESOURCES
;
1008 NetbufAllocSpace (DataSeg
, Len
, NET_BUF_TAIL
);
1011 // Second step, receive one TLS payload.
1013 Status
= TlsCommonReceive (HttpInstance
, DataSeg
, Timeout
);
1014 if (EFI_ERROR (Status
)) {
1018 InsertTailList (NbufList
, &DataSeg
->List
);
1022 // Form the PDU from a list of PDU.
1024 *Pdu
= NetbufFromBufList (NbufList
, 0, 0, FreeNbufList
, NbufList
);
1026 Status
= EFI_OUT_OF_RESOURCES
;
1031 if (EFI_ERROR (Status
)) {
1033 // Free the Nbufs in this NbufList and the NbufList itself.
1035 FreeNbufList (NbufList
);
1042 Connect one TLS session by finishing the TLS handshake process.
1044 @param[in] HttpInstance The HTTP instance private data.
1045 @param[in] Timeout The time to wait for connection done.
1047 @retval EFI_SUCCESS The TLS session is established.
1048 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
1049 @retval EFI_ABORTED TLS session state is incorrect.
1050 @retval Others Other error as indicated.
1056 IN HTTP_PROTOCOL
*HttpInstance
,
1057 IN EFI_EVENT Timeout
1062 UINTN BufferOutSize
;
1068 UINT8
*GetSessionDataBuffer
;
1069 UINTN GetSessionDataBufferSize
;
1078 // Initialize TLS state.
1080 HttpInstance
->TlsSessionState
= EfiTlsSessionNotStarted
;
1081 Status
= HttpInstance
->Tls
->SetSessionData (
1084 &(HttpInstance
->TlsSessionState
),
1085 sizeof (EFI_TLS_SESSION_STATE
)
1087 if (EFI_ERROR (Status
)) {
1092 // Create ClientHello
1094 BufferOutSize
= DEF_BUF_LEN
;
1095 BufferOut
= AllocateZeroPool (BufferOutSize
);
1096 if (BufferOut
== NULL
) {
1097 Status
= EFI_OUT_OF_RESOURCES
;
1101 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1108 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1109 FreePool (BufferOut
);
1110 BufferOut
= AllocateZeroPool (BufferOutSize
);
1111 if (BufferOut
== NULL
) {
1112 Status
= EFI_OUT_OF_RESOURCES
;
1116 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1124 if (EFI_ERROR (Status
)) {
1125 FreePool (BufferOut
);
1130 // Transmit ClientHello
1132 PacketOut
= NetbufAlloc ((UINT32
) BufferOutSize
);
1133 DataOut
= NetbufAllocSpace (PacketOut
, (UINT32
) BufferOutSize
, NET_BUF_TAIL
);
1134 if (DataOut
== NULL
) {
1135 FreePool (BufferOut
);
1136 return EFI_OUT_OF_RESOURCES
;
1139 CopyMem (DataOut
, BufferOut
, BufferOutSize
);
1140 Status
= TlsCommonTransmit (HttpInstance
, PacketOut
);
1142 FreePool (BufferOut
);
1143 NetbufFree (PacketOut
);
1145 if (EFI_ERROR (Status
)) {
1149 while(HttpInstance
->TlsSessionState
!= EfiTlsSessionDataTransferring
&& \
1150 ((Timeout
== NULL
) || EFI_ERROR (gBS
->CheckEvent (Timeout
)))) {
1152 // Receive one TLS record.
1154 Status
= TlsReceiveOnePdu (HttpInstance
, &Pdu
, Timeout
);
1155 if (EFI_ERROR (Status
)) {
1159 BufferInSize
= Pdu
->TotalSize
;
1160 BufferIn
= AllocateZeroPool (BufferInSize
);
1161 if (BufferIn
== NULL
) {
1163 Status
= EFI_OUT_OF_RESOURCES
;
1167 NetbufCopy (Pdu
, 0, (UINT32
)BufferInSize
, BufferIn
);
1172 // Handle Receive data.
1174 BufferOutSize
= DEF_BUF_LEN
;
1175 BufferOut
= AllocateZeroPool (BufferOutSize
);
1176 if (BufferOut
== NULL
) {
1177 Status
= EFI_OUT_OF_RESOURCES
;
1181 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1188 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1189 FreePool (BufferOut
);
1190 BufferOut
= AllocateZeroPool (BufferOutSize
);
1191 if (BufferOut
== NULL
) {
1192 FreePool (BufferIn
);
1193 Status
= EFI_OUT_OF_RESOURCES
;
1197 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1206 FreePool (BufferIn
);
1208 if (EFI_ERROR (Status
)) {
1209 FreePool (BufferOut
);
1213 if (BufferOutSize
!= 0) {
1215 // Transmit the response packet.
1217 PacketOut
= NetbufAlloc ((UINT32
) BufferOutSize
);
1218 DataOut
= NetbufAllocSpace (PacketOut
, (UINT32
) BufferOutSize
, NET_BUF_TAIL
);
1219 if (DataOut
== NULL
) {
1220 FreePool (BufferOut
);
1221 return EFI_OUT_OF_RESOURCES
;
1224 CopyMem (DataOut
, BufferOut
, BufferOutSize
);
1226 Status
= TlsCommonTransmit (HttpInstance
, PacketOut
);
1228 NetbufFree (PacketOut
);
1230 if (EFI_ERROR (Status
)) {
1231 FreePool (BufferOut
);
1236 FreePool (BufferOut
);
1239 // Get the session state, then decide whether need to continue handle received packet.
1241 GetSessionDataBufferSize
= DEF_BUF_LEN
;
1242 GetSessionDataBuffer
= AllocateZeroPool (GetSessionDataBufferSize
);
1243 if (GetSessionDataBuffer
== NULL
) {
1244 Status
= EFI_OUT_OF_RESOURCES
;
1248 Status
= HttpInstance
->Tls
->GetSessionData (
1251 GetSessionDataBuffer
,
1252 &GetSessionDataBufferSize
1254 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1255 FreePool (GetSessionDataBuffer
);
1256 GetSessionDataBuffer
= AllocateZeroPool (GetSessionDataBufferSize
);
1257 if (GetSessionDataBuffer
== NULL
) {
1258 Status
= EFI_OUT_OF_RESOURCES
;
1262 Status
= HttpInstance
->Tls
->GetSessionData (
1265 GetSessionDataBuffer
,
1266 &GetSessionDataBufferSize
1269 if (EFI_ERROR (Status
)) {
1270 FreePool(GetSessionDataBuffer
);
1274 ASSERT(GetSessionDataBufferSize
== sizeof (EFI_TLS_SESSION_STATE
));
1275 HttpInstance
->TlsSessionState
= *(EFI_TLS_SESSION_STATE
*) GetSessionDataBuffer
;
1277 FreePool (GetSessionDataBuffer
);
1279 if(HttpInstance
->TlsSessionState
== EfiTlsSessionError
) {
1284 if (HttpInstance
->TlsSessionState
!= EfiTlsSessionDataTransferring
) {
1285 Status
= EFI_ABORTED
;
1292 Close the TLS session and send out the close notification message.
1294 @param[in] HttpInstance The HTTP instance private data.
1296 @retval EFI_SUCCESS The TLS session is closed.
1297 @retval EFI_INVALID_PARAMETER HttpInstance is NULL.
1298 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
1299 @retval Others Other error as indicated.
1305 IN HTTP_PROTOCOL
*HttpInstance
1311 UINTN BufferOutSize
;
1316 Status
= EFI_SUCCESS
;
1321 if (HttpInstance
== NULL
) {
1322 return EFI_INVALID_PARAMETER
;
1325 HttpInstance
->TlsSessionState
= EfiTlsSessionClosing
;
1327 Status
= HttpInstance
->Tls
->SetSessionData (
1330 &(HttpInstance
->TlsSessionState
),
1331 sizeof (EFI_TLS_SESSION_STATE
)
1333 if (EFI_ERROR (Status
)) {
1337 BufferOutSize
= DEF_BUF_LEN
;
1338 BufferOut
= AllocateZeroPool (BufferOutSize
);
1339 if (BufferOut
== NULL
) {
1340 Status
= EFI_OUT_OF_RESOURCES
;
1344 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1351 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1352 FreePool (BufferOut
);
1353 BufferOut
= AllocateZeroPool (BufferOutSize
);
1354 if (BufferOut
== NULL
) {
1355 Status
= EFI_OUT_OF_RESOURCES
;
1359 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1368 if (EFI_ERROR (Status
)) {
1369 FreePool (BufferOut
);
1373 PacketOut
= NetbufAlloc ((UINT32
) BufferOutSize
);
1374 DataOut
= NetbufAllocSpace (PacketOut
, (UINT32
) BufferOutSize
, NET_BUF_TAIL
);
1375 if (DataOut
== NULL
) {
1376 FreePool (BufferOut
);
1377 return EFI_OUT_OF_RESOURCES
;
1380 CopyMem (DataOut
, BufferOut
, BufferOutSize
);
1382 Status
= TlsCommonTransmit (HttpInstance
, PacketOut
);
1384 FreePool (BufferOut
);
1385 NetbufFree (PacketOut
);
1391 Process one message according to the CryptMode.
1393 @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
1394 @param[in] Message Pointer to the message buffer needed to processed.
1395 @param[in] MessageSize Pointer to the message buffer size.
1396 @param[in] ProcessMode Process mode.
1397 @param[in, out] Fragment Only one Fragment returned after the Message is
1398 processed successfully.
1400 @retval EFI_SUCCESS Message is processed successfully.
1401 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
1402 @retval Others Other errors as indicated.
1408 IN HTTP_PROTOCOL
*HttpInstance
,
1410 IN UINTN MessageSize
,
1411 IN EFI_TLS_CRYPT_MODE ProcessMode
,
1412 IN OUT NET_FRAGMENT
*Fragment
1419 EFI_TLS_FRAGMENT_DATA
*FragmentTable
;
1420 UINT32 FragmentCount
;
1421 EFI_TLS_FRAGMENT_DATA
*OriginalFragmentTable
;
1424 Status
= EFI_SUCCESS
;
1428 FragmentTable
= NULL
;
1429 OriginalFragmentTable
= NULL
;
1432 // Rebuild fragment table from BufferIn.
1435 FragmentTable
= AllocateZeroPool (FragmentCount
* sizeof (EFI_TLS_FRAGMENT_DATA
));
1436 if (FragmentTable
== NULL
) {
1437 Status
= EFI_OUT_OF_RESOURCES
;
1441 FragmentTable
->FragmentLength
= (UINT32
) MessageSize
;
1442 FragmentTable
->FragmentBuffer
= Message
;
1445 // Record the original FragmentTable.
1447 OriginalFragmentTable
= FragmentTable
;
1450 // Process the Message.
1452 Status
= HttpInstance
->Tls
->ProcessPacket (
1458 if (EFI_ERROR (Status
)) {
1463 // Calculate the size according to FragmentTable.
1465 for (Index
= 0; Index
< FragmentCount
; Index
++) {
1466 BufferSize
+= FragmentTable
[Index
].FragmentLength
;
1470 // Allocate buffer for processed data.
1472 Buffer
= AllocateZeroPool (BufferSize
);
1473 if (Buffer
== NULL
) {
1474 Status
= EFI_OUT_OF_RESOURCES
;
1479 // Copy the new FragmentTable buffer into Buffer.
1481 for (Index
= 0; Index
< FragmentCount
; Index
++) {
1483 (Buffer
+ BytesCopied
),
1484 FragmentTable
[Index
].FragmentBuffer
,
1485 FragmentTable
[Index
].FragmentLength
1487 BytesCopied
+= FragmentTable
[Index
].FragmentLength
;
1490 // Free the FragmentBuffer since it has been copied.
1492 FreePool (FragmentTable
[Index
].FragmentBuffer
);
1495 Fragment
->Len
= BufferSize
;
1496 Fragment
->Bulk
= Buffer
;
1500 if (OriginalFragmentTable
!= NULL
) {
1501 FreePool (OriginalFragmentTable
);
1502 OriginalFragmentTable
= NULL
;
1506 // Caller has the responsibility to free the FragmentTable.
1508 if (FragmentTable
!= NULL
) {
1509 FreePool (FragmentTable
);
1510 FragmentTable
= NULL
;
1517 Receive one fragment decrypted from one TLS record.
1519 @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
1520 @param[in, out] Fragment The received Fragment.
1521 @param[in] Timeout The time to wait for connection done.
1523 @retval EFI_SUCCESS One fragment is received.
1524 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
1525 @retval EFI_ABORTED Something wrong decryption the message.
1526 @retval Others Other errors as indicated.
1532 IN HTTP_PROTOCOL
*HttpInstance
,
1533 IN OUT NET_FRAGMENT
*Fragment
,
1534 IN EFI_EVENT Timeout
1539 TLS_RECORD_HEADER RecordHeader
;
1542 NET_FRAGMENT TempFragment
;
1544 UINTN BufferOutSize
;
1547 UINT8
*GetSessionDataBuffer
;
1548 UINTN GetSessionDataBufferSize
;
1550 Status
= EFI_SUCCESS
;
1558 GetSessionDataBuffer
= NULL
;
1559 GetSessionDataBufferSize
= 0;
1562 // Receive only one TLS record
1564 Status
= TlsReceiveOnePdu (HttpInstance
, &Pdu
, Timeout
);
1565 if (EFI_ERROR (Status
)) {
1569 BufferInSize
= Pdu
->TotalSize
;
1570 BufferIn
= AllocateZeroPool (BufferInSize
);
1571 if (BufferIn
== NULL
) {
1572 Status
= EFI_OUT_OF_RESOURCES
;
1577 NetbufCopy (Pdu
, 0, (UINT32
) BufferInSize
, BufferIn
);
1582 // Handle Receive data.
1584 RecordHeader
= *(TLS_RECORD_HEADER
*) BufferIn
;
1586 if ((RecordHeader
.ContentType
== TlsContentTypeApplicationData
) &&
1587 (RecordHeader
.Version
.Major
== 0x03) &&
1588 (RecordHeader
.Version
.Minor
== TLS10_PROTOCOL_VERSION_MINOR
||
1589 RecordHeader
.Version
.Minor
== TLS11_PROTOCOL_VERSION_MINOR
||
1590 RecordHeader
.Version
.Minor
== TLS12_PROTOCOL_VERSION_MINOR
)
1595 Status
= TlsProcessMessage (
1603 FreePool (BufferIn
);
1605 if (EFI_ERROR (Status
)) {
1606 if (Status
== EFI_ABORTED
) {
1608 // Something wrong decryption the message.
1609 // BuildResponsePacket() will be called to generate Error Alert message and send it out.
1611 BufferOutSize
= DEF_BUF_LEN
;
1612 BufferOut
= AllocateZeroPool (BufferOutSize
);
1613 if (BufferOut
== NULL
) {
1614 Status
= EFI_OUT_OF_RESOURCES
;
1618 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1625 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1626 FreePool (BufferOut
);
1627 BufferOut
= AllocateZeroPool (BufferOutSize
);
1628 if (BufferOut
== NULL
) {
1629 Status
= EFI_OUT_OF_RESOURCES
;
1633 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1641 if (EFI_ERROR (Status
)) {
1642 FreePool(BufferOut
);
1646 if (BufferOutSize
!= 0) {
1647 PacketOut
= NetbufAlloc ((UINT32
)BufferOutSize
);
1648 DataOut
= NetbufAllocSpace (PacketOut
, (UINT32
) BufferOutSize
, NET_BUF_TAIL
);
1649 if (DataOut
== NULL
) {
1650 FreePool (BufferOut
);
1651 return EFI_OUT_OF_RESOURCES
;
1654 CopyMem (DataOut
, BufferOut
, BufferOutSize
);
1656 Status
= TlsCommonTransmit (HttpInstance
, PacketOut
);
1658 NetbufFree (PacketOut
);
1661 FreePool(BufferOut
);
1663 if (EFI_ERROR (Status
)) {
1676 ASSERT (((TLS_RECORD_HEADER
*) (TempFragment
.Bulk
))->ContentType
== TlsContentTypeApplicationData
);
1678 BufferInSize
= ((TLS_RECORD_HEADER
*) (TempFragment
.Bulk
))->Length
;
1679 BufferIn
= AllocateZeroPool (BufferInSize
);
1680 if (BufferIn
== NULL
) {
1681 Status
= EFI_OUT_OF_RESOURCES
;
1685 CopyMem (BufferIn
, TempFragment
.Bulk
+ sizeof (TLS_RECORD_HEADER
), BufferInSize
);
1688 // Free the buffer in TempFragment.
1690 FreePool (TempFragment
.Bulk
);
1692 } else if ((RecordHeader
.ContentType
== TlsContentTypeAlert
) &&
1693 (RecordHeader
.Version
.Major
== 0x03) &&
1694 (RecordHeader
.Version
.Minor
== TLS10_PROTOCOL_VERSION_MINOR
||
1695 RecordHeader
.Version
.Minor
== TLS11_PROTOCOL_VERSION_MINOR
||
1696 RecordHeader
.Version
.Minor
== TLS12_PROTOCOL_VERSION_MINOR
)
1698 BufferOutSize
= DEF_BUF_LEN
;
1699 BufferOut
= AllocateZeroPool (BufferOutSize
);
1700 if (BufferOut
== NULL
) {
1701 FreePool (BufferIn
);
1702 Status
= EFI_OUT_OF_RESOURCES
;
1706 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1713 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1714 FreePool (BufferOut
);
1715 BufferOut
= AllocateZeroPool (BufferOutSize
);
1716 if (BufferOut
== NULL
) {
1717 FreePool (BufferIn
);
1718 Status
= EFI_OUT_OF_RESOURCES
;
1722 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1731 FreePool (BufferIn
);
1733 if (EFI_ERROR (Status
)) {
1734 FreePool (BufferOut
);
1738 if (BufferOutSize
!= 0) {
1739 PacketOut
= NetbufAlloc ((UINT32
) BufferOutSize
);
1740 DataOut
= NetbufAllocSpace (PacketOut
, (UINT32
) BufferOutSize
, NET_BUF_TAIL
);
1741 if (DataOut
== NULL
) {
1742 FreePool (BufferOut
);
1743 return EFI_OUT_OF_RESOURCES
;
1746 CopyMem (DataOut
, BufferOut
, BufferOutSize
);
1748 Status
= TlsCommonTransmit (HttpInstance
, PacketOut
);
1750 NetbufFree (PacketOut
);
1753 FreePool (BufferOut
);
1756 // Get the session state.
1758 GetSessionDataBufferSize
= DEF_BUF_LEN
;
1759 GetSessionDataBuffer
= AllocateZeroPool (GetSessionDataBufferSize
);
1760 if (GetSessionDataBuffer
== NULL
) {
1761 Status
= EFI_OUT_OF_RESOURCES
;
1765 Status
= HttpInstance
->Tls
->GetSessionData (
1768 GetSessionDataBuffer
,
1769 &GetSessionDataBufferSize
1771 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1772 FreePool (GetSessionDataBuffer
);
1773 GetSessionDataBuffer
= AllocateZeroPool (GetSessionDataBufferSize
);
1774 if (GetSessionDataBuffer
== NULL
) {
1775 Status
= EFI_OUT_OF_RESOURCES
;
1779 Status
= HttpInstance
->Tls
->GetSessionData (
1782 GetSessionDataBuffer
,
1783 &GetSessionDataBufferSize
1786 if (EFI_ERROR (Status
)) {
1787 FreePool (GetSessionDataBuffer
);
1791 ASSERT(GetSessionDataBufferSize
== sizeof (EFI_TLS_SESSION_STATE
));
1792 HttpInstance
->TlsSessionState
= *(EFI_TLS_SESSION_STATE
*) GetSessionDataBuffer
;
1794 FreePool (GetSessionDataBuffer
);
1796 if(HttpInstance
->TlsSessionState
== EfiTlsSessionError
) {
1797 DEBUG ((EFI_D_ERROR
, "TLS Session State Error!\n"));
1805 Fragment
->Bulk
= BufferIn
;
1806 Fragment
->Len
= (UINT32
) BufferInSize
;