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.
430 ASSERT (CACert
!= NULL
);
433 // Enumerate all data and erasing the target item.
435 ItemDataSize
= (UINT32
) CACertSize
;
436 CertList
= (EFI_SIGNATURE_LIST
*) CACert
;
437 while ((ItemDataSize
> 0) && (ItemDataSize
>= CertList
->SignatureListSize
)) {
438 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) CertList
+ sizeof (EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
);
439 CertCount
= (CertList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - CertList
->SignatureHeaderSize
) / CertList
->SignatureSize
;
440 for (Index
= 0; Index
< CertCount
; Index
++) {
442 // EfiTlsConfigDataTypeCACertificate
444 Status
= HttpInstance
->TlsConfiguration
->SetData (
445 HttpInstance
->TlsConfiguration
,
446 EfiTlsConfigDataTypeCACertificate
,
448 CertList
->SignatureSize
- sizeof (Cert
->SignatureOwner
)
450 if (EFI_ERROR (Status
)) {
454 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) Cert
+ CertList
->SignatureSize
);
457 ItemDataSize
-= CertList
->SignatureListSize
;
458 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
467 Read the HttpTlsCipherList variable and configure it for HTTPS session.
469 @param[in, out] HttpInstance The HTTP instance private data.
471 @retval EFI_SUCCESS The prefered HTTP TLS CipherList is configured.
472 @retval EFI_NOT_FOUND Fail to get 'HttpTlsCipherList' variable.
473 @retval EFI_INVALID_PARAMETER The contents of variable are invalid.
474 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
476 @retval Others Other error as indicated.
480 TlsConfigCipherList (
481 IN OUT HTTP_PROTOCOL
*HttpInstance
486 UINTN CipherListSize
;
492 // Try to read the HttpTlsCipherList variable.
494 Status
= gRT
->GetVariable (
495 EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE
,
496 &gEdkiiHttpTlsCipherListGuid
,
501 ASSERT (EFI_ERROR (Status
));
502 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
506 if (CipherListSize
% sizeof (EFI_TLS_CIPHER
) != 0) {
507 return EFI_INVALID_PARAMETER
;
511 // Allocate buffer and read the config variable.
513 CipherList
= AllocatePool (CipherListSize
);
514 if (CipherList
== NULL
) {
515 return EFI_OUT_OF_RESOURCES
;
518 Status
= gRT
->GetVariable (
519 EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE
,
520 &gEdkiiHttpTlsCipherListGuid
,
525 if (EFI_ERROR (Status
)) {
527 // GetVariable still error or the variable is corrupted.
532 ASSERT (CipherList
!= NULL
);
534 Status
= HttpInstance
->Tls
->SetSessionData (
542 FreePool (CipherList
);
548 Configure TLS session data.
550 @param[in, out] HttpInstance The HTTP instance private data.
552 @retval EFI_SUCCESS TLS session data is configured.
553 @retval Others Other error as indicated.
558 TlsConfigureSession (
559 IN OUT HTTP_PROTOCOL
*HttpInstance
565 // TlsConfigData initialization
567 HttpInstance
->TlsConfigData
.ConnectionEnd
= EfiTlsClient
;
568 HttpInstance
->TlsConfigData
.VerifyMethod
= EFI_TLS_VERIFY_PEER
;
569 HttpInstance
->TlsConfigData
.SessionState
= EfiTlsSessionNotStarted
;
572 // EfiTlsConnectionEnd,
573 // EfiTlsVerifyMethod
574 // EfiTlsSessionState
576 Status
= HttpInstance
->Tls
->SetSessionData (
579 &(HttpInstance
->TlsConfigData
.ConnectionEnd
),
580 sizeof (EFI_TLS_CONNECTION_END
)
582 if (EFI_ERROR (Status
)) {
586 Status
= HttpInstance
->Tls
->SetSessionData (
589 &HttpInstance
->TlsConfigData
.VerifyMethod
,
590 sizeof (EFI_TLS_VERIFY
)
592 if (EFI_ERROR (Status
)) {
596 Status
= HttpInstance
->Tls
->SetSessionData (
599 &(HttpInstance
->TlsConfigData
.SessionState
),
600 sizeof (EFI_TLS_SESSION_STATE
)
602 if (EFI_ERROR (Status
)) {
609 Status
= TlsConfigCipherList (HttpInstance
);
610 if (EFI_ERROR (Status
) && Status
!= EFI_NOT_FOUND
) {
611 DEBUG ((EFI_D_ERROR
, "TlsConfigCipherList: return %r error.\n", Status
));
616 // Tls Config Certificate
618 Status
= TlsConfigCertificate (HttpInstance
);
619 if (EFI_ERROR (Status
)) {
620 DEBUG ((EFI_D_ERROR
, "TLS Certificate Config Error!\n"));
625 // TlsCreateTxRxEvent
627 Status
= TlsCreateTxRxEvent (HttpInstance
);
628 if (EFI_ERROR (Status
)) {
635 TlsCloseTxRxEvent (HttpInstance
);
641 Transmit the Packet by processing the associated HTTPS token.
643 @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
644 @param[in] Packet The packet to transmit.
646 @retval EFI_SUCCESS The packet is transmitted.
647 @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
648 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
649 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
650 @retval Others Other errors as indicated.
656 IN OUT HTTP_PROTOCOL
*HttpInstance
,
664 if ((HttpInstance
== NULL
) || (Packet
== NULL
)) {
665 return EFI_INVALID_PARAMETER
;
668 if (!HttpInstance
->LocalAddressIsIPv6
) {
669 Size
= sizeof (EFI_TCP4_TRANSMIT_DATA
) +
670 (Packet
->BlockOpNum
- 1) * sizeof (EFI_TCP4_FRAGMENT_DATA
);
672 Size
= sizeof (EFI_TCP6_TRANSMIT_DATA
) +
673 (Packet
->BlockOpNum
- 1) * sizeof (EFI_TCP6_FRAGMENT_DATA
);
676 Data
= AllocatePool (Size
);
678 return EFI_OUT_OF_RESOURCES
;
681 if (!HttpInstance
->LocalAddressIsIPv6
) {
682 ((EFI_TCP4_TRANSMIT_DATA
*) Data
)->Push
= TRUE
;
683 ((EFI_TCP4_TRANSMIT_DATA
*) Data
)->Urgent
= FALSE
;
684 ((EFI_TCP4_TRANSMIT_DATA
*) Data
)->DataLength
= Packet
->TotalSize
;
687 // Build the fragment table.
689 ((EFI_TCP4_TRANSMIT_DATA
*) Data
)->FragmentCount
= Packet
->BlockOpNum
;
693 (NET_FRAGMENT
*) &((EFI_TCP4_TRANSMIT_DATA
*) Data
)->FragmentTable
[0],
694 &((EFI_TCP4_TRANSMIT_DATA
*) Data
)->FragmentCount
697 HttpInstance
->Tcp4TlsTxToken
.Packet
.TxData
= (EFI_TCP4_TRANSMIT_DATA
*) Data
;
699 Status
= EFI_DEVICE_ERROR
;
702 // Transmit the packet.
704 Status
= HttpInstance
->Tcp4
->Transmit (HttpInstance
->Tcp4
, &HttpInstance
->Tcp4TlsTxToken
);
705 if (EFI_ERROR (Status
)) {
709 while (!HttpInstance
->TlsIsTxDone
) {
710 HttpInstance
->Tcp4
->Poll (HttpInstance
->Tcp4
);
713 HttpInstance
->TlsIsTxDone
= FALSE
;
714 Status
= HttpInstance
->Tcp4TlsTxToken
.CompletionToken
.Status
;
716 ((EFI_TCP6_TRANSMIT_DATA
*) Data
)->Push
= TRUE
;
717 ((EFI_TCP6_TRANSMIT_DATA
*) Data
)->Urgent
= FALSE
;
718 ((EFI_TCP6_TRANSMIT_DATA
*) Data
)->DataLength
= Packet
->TotalSize
;
721 // Build the fragment table.
723 ((EFI_TCP6_TRANSMIT_DATA
*) Data
)->FragmentCount
= Packet
->BlockOpNum
;
727 (NET_FRAGMENT
*) &((EFI_TCP6_TRANSMIT_DATA
*) Data
)->FragmentTable
[0],
728 &((EFI_TCP6_TRANSMIT_DATA
*) Data
)->FragmentCount
731 HttpInstance
->Tcp6TlsTxToken
.Packet
.TxData
= (EFI_TCP6_TRANSMIT_DATA
*) Data
;
733 Status
= EFI_DEVICE_ERROR
;
736 // Transmit the packet.
738 Status
= HttpInstance
->Tcp6
->Transmit (HttpInstance
->Tcp6
, &HttpInstance
->Tcp6TlsTxToken
);
739 if (EFI_ERROR (Status
)) {
743 while (!HttpInstance
->TlsIsTxDone
) {
744 HttpInstance
->Tcp6
->Poll (HttpInstance
->Tcp6
);
747 HttpInstance
->TlsIsTxDone
= FALSE
;
748 Status
= HttpInstance
->Tcp6TlsTxToken
.CompletionToken
.Status
;
758 Receive the Packet by processing the associated HTTPS token.
760 @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
761 @param[in] Packet The packet to transmit.
762 @param[in] Timeout The time to wait for connection done.
764 @retval EFI_SUCCESS The Packet is received.
765 @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
766 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
767 @retval EFI_TIMEOUT The operation is time out.
768 @retval Others Other error as indicated.
774 IN OUT HTTP_PROTOCOL
*HttpInstance
,
779 EFI_TCP4_RECEIVE_DATA
*Tcp4RxData
;
780 EFI_TCP6_RECEIVE_DATA
*Tcp6RxData
;
782 NET_FRAGMENT
*Fragment
;
783 UINT32 FragmentCount
;
784 UINT32 CurrentFragment
;
789 if ((HttpInstance
== NULL
) || (Packet
== NULL
)) {
790 return EFI_INVALID_PARAMETER
;
793 FragmentCount
= Packet
->BlockOpNum
;
794 Fragment
= AllocatePool (FragmentCount
* sizeof (NET_FRAGMENT
));
795 if (Fragment
== NULL
) {
796 Status
= EFI_OUT_OF_RESOURCES
;
801 // Build the fragment table.
803 NetbufBuildExt (Packet
, Fragment
, &FragmentCount
);
805 if (!HttpInstance
->LocalAddressIsIPv6
) {
806 Tcp4RxData
= HttpInstance
->Tcp4TlsRxToken
.Packet
.RxData
;
807 if (Tcp4RxData
== NULL
) {
808 return EFI_INVALID_PARAMETER
;
810 Tcp4RxData
->FragmentCount
= 1;
812 Tcp6RxData
= HttpInstance
->Tcp6TlsRxToken
.Packet
.RxData
;
813 if (Tcp6RxData
== NULL
) {
814 return EFI_INVALID_PARAMETER
;
816 Tcp6RxData
->FragmentCount
= 1;
820 Status
= EFI_SUCCESS
;
822 while (CurrentFragment
< FragmentCount
) {
823 if (!HttpInstance
->LocalAddressIsIPv6
) {
824 Tcp4RxData
->DataLength
= Fragment
[CurrentFragment
].Len
;
825 Tcp4RxData
->FragmentTable
[0].FragmentLength
= Fragment
[CurrentFragment
].Len
;
826 Tcp4RxData
->FragmentTable
[0].FragmentBuffer
= Fragment
[CurrentFragment
].Bulk
;
827 Status
= HttpInstance
->Tcp4
->Receive (HttpInstance
->Tcp4
, &HttpInstance
->Tcp4TlsRxToken
);
829 Tcp6RxData
->DataLength
= Fragment
[CurrentFragment
].Len
;
830 Tcp6RxData
->FragmentTable
[0].FragmentLength
= Fragment
[CurrentFragment
].Len
;
831 Tcp6RxData
->FragmentTable
[0].FragmentBuffer
= Fragment
[CurrentFragment
].Bulk
;
832 Status
= HttpInstance
->Tcp6
->Receive (HttpInstance
->Tcp6
, &HttpInstance
->Tcp6TlsRxToken
);
834 if (EFI_ERROR (Status
)) {
838 while (!HttpInstance
->TlsIsRxDone
&& ((Timeout
== NULL
) || EFI_ERROR (gBS
->CheckEvent (Timeout
)))) {
840 // Poll until some data is received or an error occurs.
842 if (!HttpInstance
->LocalAddressIsIPv6
) {
843 HttpInstance
->Tcp4
->Poll (HttpInstance
->Tcp4
);
845 HttpInstance
->Tcp6
->Poll (HttpInstance
->Tcp6
);
849 if (!HttpInstance
->TlsIsRxDone
) {
851 // Timeout occurs, cancel the receive request.
853 if (!HttpInstance
->LocalAddressIsIPv6
) {
854 HttpInstance
->Tcp4
->Cancel (HttpInstance
->Tcp4
, &HttpInstance
->Tcp4TlsRxToken
.CompletionToken
);
856 HttpInstance
->Tcp6
->Cancel (HttpInstance
->Tcp6
, &HttpInstance
->Tcp6TlsRxToken
.CompletionToken
);
859 Status
= EFI_TIMEOUT
;
862 HttpInstance
->TlsIsRxDone
= FALSE
;
865 if (!HttpInstance
->LocalAddressIsIPv6
) {
866 Status
= HttpInstance
->Tcp4TlsRxToken
.CompletionToken
.Status
;
867 if (EFI_ERROR (Status
)) {
871 Fragment
[CurrentFragment
].Len
-= Tcp4RxData
->FragmentTable
[0].FragmentLength
;
872 if (Fragment
[CurrentFragment
].Len
== 0) {
875 Fragment
[CurrentFragment
].Bulk
+= Tcp4RxData
->FragmentTable
[0].FragmentLength
;
878 Status
= HttpInstance
->Tcp6TlsRxToken
.CompletionToken
.Status
;
879 if (EFI_ERROR (Status
)) {
883 Fragment
[CurrentFragment
].Len
-= Tcp6RxData
->FragmentTable
[0].FragmentLength
;
884 if (Fragment
[CurrentFragment
].Len
== 0) {
887 Fragment
[CurrentFragment
].Bulk
+= Tcp6RxData
->FragmentTable
[0].FragmentLength
;
894 if (Fragment
!= NULL
) {
902 Receive one TLS PDU. An TLS PDU contains an TLS record header and it's
903 corresponding record data. These two parts will be put into two blocks of buffers in the
906 @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
907 @param[out] Pdu The received TLS PDU.
908 @param[in] Timeout The time to wait for connection done.
910 @retval EFI_SUCCESS An TLS PDU is received.
911 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
912 @retval EFI_PROTOCOL_ERROR An unexpected TLS packet was received.
913 @retval Others Other errors as indicated.
919 IN OUT HTTP_PROTOCOL
*HttpInstance
,
926 LIST_ENTRY
*NbufList
;
932 TLS_RECORD_HEADER RecordHeader
;
941 NbufList
= AllocatePool (sizeof (LIST_ENTRY
));
942 if (NbufList
== NULL
) {
943 return EFI_OUT_OF_RESOURCES
;
946 InitializeListHead (NbufList
);
949 // Allocate buffer to receive one TLS header.
951 Len
= TLS_RECORD_HEADER_LENGTH
;
952 PduHdr
= NetbufAlloc (Len
);
953 if (PduHdr
== NULL
) {
954 Status
= EFI_OUT_OF_RESOURCES
;
958 Header
= NetbufAllocSpace (PduHdr
, Len
, NET_BUF_TAIL
);
959 if (Header
== NULL
) {
960 Status
= EFI_OUT_OF_RESOURCES
;
965 // First step, receive one TLS header.
967 Status
= TlsCommonReceive (HttpInstance
, PduHdr
, Timeout
);
968 if (EFI_ERROR (Status
)) {
972 RecordHeader
= *(TLS_RECORD_HEADER
*) Header
;
973 if ((RecordHeader
.ContentType
== TlsContentTypeHandshake
||
974 RecordHeader
.ContentType
== TlsContentTypeAlert
||
975 RecordHeader
.ContentType
== TlsContentTypeChangeCipherSpec
||
976 RecordHeader
.ContentType
== TlsContentTypeApplicationData
) &&
977 (RecordHeader
.Version
.Major
== 0x03) && /// Major versions are same.
978 (RecordHeader
.Version
.Minor
== TLS10_PROTOCOL_VERSION_MINOR
||
979 RecordHeader
.Version
.Minor
==TLS11_PROTOCOL_VERSION_MINOR
||
980 RecordHeader
.Version
.Minor
== TLS12_PROTOCOL_VERSION_MINOR
)
982 InsertTailList (NbufList
, &PduHdr
->List
);
984 Status
= EFI_PROTOCOL_ERROR
;
988 Len
= SwapBytes16(RecordHeader
.Length
);
997 // Allocate buffer to receive one TLS payload.
999 DataSeg
= NetbufAlloc (Len
);
1000 if (DataSeg
== NULL
) {
1001 Status
= EFI_OUT_OF_RESOURCES
;
1005 NetbufAllocSpace (DataSeg
, Len
, NET_BUF_TAIL
);
1008 // Second step, receive one TLS payload.
1010 Status
= TlsCommonReceive (HttpInstance
, DataSeg
, Timeout
);
1011 if (EFI_ERROR (Status
)) {
1015 InsertTailList (NbufList
, &DataSeg
->List
);
1019 // Form the PDU from a list of PDU.
1021 *Pdu
= NetbufFromBufList (NbufList
, 0, 0, FreeNbufList
, NbufList
);
1023 Status
= EFI_OUT_OF_RESOURCES
;
1028 if (EFI_ERROR (Status
)) {
1030 // Free the Nbufs in this NbufList and the NbufList itself.
1032 FreeNbufList (NbufList
);
1039 Connect one TLS session by finishing the TLS handshake process.
1041 @param[in] HttpInstance The HTTP instance private data.
1042 @param[in] Timeout The time to wait for connection done.
1044 @retval EFI_SUCCESS The TLS session is established.
1045 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
1046 @retval EFI_ABORTED TLS session state is incorrect.
1047 @retval Others Other error as indicated.
1053 IN HTTP_PROTOCOL
*HttpInstance
,
1054 IN EFI_EVENT Timeout
1059 UINTN BufferOutSize
;
1065 UINT8
*GetSessionDataBuffer
;
1066 UINTN GetSessionDataBufferSize
;
1075 // Initialize TLS state.
1077 HttpInstance
->TlsSessionState
= EfiTlsSessionNotStarted
;
1078 Status
= HttpInstance
->Tls
->SetSessionData (
1081 &(HttpInstance
->TlsSessionState
),
1082 sizeof (EFI_TLS_SESSION_STATE
)
1084 if (EFI_ERROR (Status
)) {
1089 // Create ClientHello
1091 BufferOutSize
= DEF_BUF_LEN
;
1092 BufferOut
= AllocateZeroPool (BufferOutSize
);
1093 if (BufferOut
== NULL
) {
1094 Status
= EFI_OUT_OF_RESOURCES
;
1098 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1105 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1106 FreePool (BufferOut
);
1107 BufferOut
= AllocateZeroPool (BufferOutSize
);
1108 if (BufferOut
== NULL
) {
1109 Status
= EFI_OUT_OF_RESOURCES
;
1113 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1121 if (EFI_ERROR (Status
)) {
1122 FreePool (BufferOut
);
1127 // Transmit ClientHello
1129 PacketOut
= NetbufAlloc ((UINT32
) BufferOutSize
);
1130 DataOut
= NetbufAllocSpace (PacketOut
, (UINT32
) BufferOutSize
, NET_BUF_TAIL
);
1131 if (DataOut
== NULL
) {
1132 FreePool (BufferOut
);
1133 return EFI_OUT_OF_RESOURCES
;
1136 CopyMem (DataOut
, BufferOut
, BufferOutSize
);
1137 Status
= TlsCommonTransmit (HttpInstance
, PacketOut
);
1139 FreePool (BufferOut
);
1140 NetbufFree (PacketOut
);
1142 if (EFI_ERROR (Status
)) {
1146 while(HttpInstance
->TlsSessionState
!= EfiTlsSessionDataTransferring
&& \
1147 ((Timeout
== NULL
) || EFI_ERROR (gBS
->CheckEvent (Timeout
)))) {
1149 // Receive one TLS record.
1151 Status
= TlsReceiveOnePdu (HttpInstance
, &Pdu
, Timeout
);
1152 if (EFI_ERROR (Status
)) {
1156 BufferInSize
= Pdu
->TotalSize
;
1157 BufferIn
= AllocateZeroPool (BufferInSize
);
1158 if (BufferIn
== NULL
) {
1160 Status
= EFI_OUT_OF_RESOURCES
;
1164 NetbufCopy (Pdu
, 0, (UINT32
)BufferInSize
, BufferIn
);
1169 // Handle Receive data.
1171 BufferOutSize
= DEF_BUF_LEN
;
1172 BufferOut
= AllocateZeroPool (BufferOutSize
);
1173 if (BufferOut
== NULL
) {
1174 Status
= EFI_OUT_OF_RESOURCES
;
1178 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1185 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1186 FreePool (BufferOut
);
1187 BufferOut
= AllocateZeroPool (BufferOutSize
);
1188 if (BufferOut
== NULL
) {
1189 FreePool (BufferIn
);
1190 Status
= EFI_OUT_OF_RESOURCES
;
1194 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1203 FreePool (BufferIn
);
1205 if (EFI_ERROR (Status
)) {
1206 FreePool (BufferOut
);
1210 if (BufferOutSize
!= 0) {
1212 // Transmit the response packet.
1214 PacketOut
= NetbufAlloc ((UINT32
) BufferOutSize
);
1215 DataOut
= NetbufAllocSpace (PacketOut
, (UINT32
) BufferOutSize
, NET_BUF_TAIL
);
1216 if (DataOut
== NULL
) {
1217 FreePool (BufferOut
);
1218 return EFI_OUT_OF_RESOURCES
;
1221 CopyMem (DataOut
, BufferOut
, BufferOutSize
);
1223 Status
= TlsCommonTransmit (HttpInstance
, PacketOut
);
1225 NetbufFree (PacketOut
);
1227 if (EFI_ERROR (Status
)) {
1228 FreePool (BufferOut
);
1233 FreePool (BufferOut
);
1236 // Get the session state, then decide whether need to continue handle received packet.
1238 GetSessionDataBufferSize
= DEF_BUF_LEN
;
1239 GetSessionDataBuffer
= AllocateZeroPool (GetSessionDataBufferSize
);
1240 if (GetSessionDataBuffer
== NULL
) {
1241 Status
= EFI_OUT_OF_RESOURCES
;
1245 Status
= HttpInstance
->Tls
->GetSessionData (
1248 GetSessionDataBuffer
,
1249 &GetSessionDataBufferSize
1251 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1252 FreePool (GetSessionDataBuffer
);
1253 GetSessionDataBuffer
= AllocateZeroPool (GetSessionDataBufferSize
);
1254 if (GetSessionDataBuffer
== NULL
) {
1255 Status
= EFI_OUT_OF_RESOURCES
;
1259 Status
= HttpInstance
->Tls
->GetSessionData (
1262 GetSessionDataBuffer
,
1263 &GetSessionDataBufferSize
1266 if (EFI_ERROR (Status
)) {
1267 FreePool(GetSessionDataBuffer
);
1271 ASSERT(GetSessionDataBufferSize
== sizeof (EFI_TLS_SESSION_STATE
));
1272 HttpInstance
->TlsSessionState
= *(EFI_TLS_SESSION_STATE
*) GetSessionDataBuffer
;
1274 FreePool (GetSessionDataBuffer
);
1276 if(HttpInstance
->TlsSessionState
== EfiTlsSessionError
) {
1281 if (HttpInstance
->TlsSessionState
!= EfiTlsSessionDataTransferring
) {
1282 Status
= EFI_ABORTED
;
1289 Close the TLS session and send out the close notification message.
1291 @param[in] HttpInstance The HTTP instance private data.
1293 @retval EFI_SUCCESS The TLS session is closed.
1294 @retval EFI_INVALID_PARAMETER HttpInstance is NULL.
1295 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
1296 @retval Others Other error as indicated.
1302 IN HTTP_PROTOCOL
*HttpInstance
1308 UINTN BufferOutSize
;
1313 Status
= EFI_SUCCESS
;
1318 if (HttpInstance
== NULL
) {
1319 return EFI_INVALID_PARAMETER
;
1322 HttpInstance
->TlsSessionState
= EfiTlsSessionClosing
;
1324 Status
= HttpInstance
->Tls
->SetSessionData (
1327 &(HttpInstance
->TlsSessionState
),
1328 sizeof (EFI_TLS_SESSION_STATE
)
1330 if (EFI_ERROR (Status
)) {
1334 BufferOutSize
= DEF_BUF_LEN
;
1335 BufferOut
= AllocateZeroPool (BufferOutSize
);
1336 if (BufferOut
== NULL
) {
1337 Status
= EFI_OUT_OF_RESOURCES
;
1341 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1348 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1349 FreePool (BufferOut
);
1350 BufferOut
= AllocateZeroPool (BufferOutSize
);
1351 if (BufferOut
== NULL
) {
1352 Status
= EFI_OUT_OF_RESOURCES
;
1356 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1365 if (EFI_ERROR (Status
)) {
1366 FreePool (BufferOut
);
1370 PacketOut
= NetbufAlloc ((UINT32
) BufferOutSize
);
1371 DataOut
= NetbufAllocSpace (PacketOut
, (UINT32
) BufferOutSize
, NET_BUF_TAIL
);
1372 if (DataOut
== NULL
) {
1373 FreePool (BufferOut
);
1374 return EFI_OUT_OF_RESOURCES
;
1377 CopyMem (DataOut
, BufferOut
, BufferOutSize
);
1379 Status
= TlsCommonTransmit (HttpInstance
, PacketOut
);
1381 FreePool (BufferOut
);
1382 NetbufFree (PacketOut
);
1388 Process one message according to the CryptMode.
1390 @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
1391 @param[in] Message Pointer to the message buffer needed to processed.
1392 If ProcessMode is EfiTlsEncrypt, the message contain the TLS
1393 header and plain text TLS APP payload.
1394 If ProcessMode is EfiTlsDecrypt, the message contain the TLS
1395 header and cipher text TLS APP payload.
1396 @param[in] MessageSize Pointer to the message buffer size.
1397 @param[in] ProcessMode Process mode.
1398 @param[in, out] Fragment Only one Fragment returned after the Message is
1399 processed successfully.
1400 If ProcessMode is EfiTlsEncrypt, the fragment contain the TLS
1401 header and cipher text TLS APP payload.
1402 If ProcessMode is EfiTlsDecrypt, the fragment contain the TLS
1403 header and plain text TLS APP payload.
1405 @retval EFI_SUCCESS Message is processed successfully.
1406 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
1407 @retval Others Other errors as indicated.
1413 IN HTTP_PROTOCOL
*HttpInstance
,
1415 IN UINTN MessageSize
,
1416 IN EFI_TLS_CRYPT_MODE ProcessMode
,
1417 IN OUT NET_FRAGMENT
*Fragment
1424 EFI_TLS_FRAGMENT_DATA
*FragmentTable
;
1425 UINT32 FragmentCount
;
1426 EFI_TLS_FRAGMENT_DATA
*OriginalFragmentTable
;
1429 Status
= EFI_SUCCESS
;
1433 FragmentTable
= NULL
;
1434 OriginalFragmentTable
= NULL
;
1437 // Rebuild fragment table from BufferIn.
1440 FragmentTable
= AllocateZeroPool (FragmentCount
* sizeof (EFI_TLS_FRAGMENT_DATA
));
1441 if (FragmentTable
== NULL
) {
1442 Status
= EFI_OUT_OF_RESOURCES
;
1446 FragmentTable
->FragmentLength
= (UINT32
) MessageSize
;
1447 FragmentTable
->FragmentBuffer
= Message
;
1450 // Record the original FragmentTable.
1452 OriginalFragmentTable
= FragmentTable
;
1455 // Process the Message.
1457 Status
= HttpInstance
->Tls
->ProcessPacket (
1463 if (EFI_ERROR (Status
)) {
1468 // Calculate the size according to FragmentTable.
1470 for (Index
= 0; Index
< FragmentCount
; Index
++) {
1471 BufferSize
+= FragmentTable
[Index
].FragmentLength
;
1475 // Allocate buffer for processed data.
1477 Buffer
= AllocateZeroPool (BufferSize
);
1478 if (Buffer
== NULL
) {
1479 Status
= EFI_OUT_OF_RESOURCES
;
1484 // Copy the new FragmentTable buffer into Buffer.
1486 for (Index
= 0; Index
< FragmentCount
; Index
++) {
1488 (Buffer
+ BytesCopied
),
1489 FragmentTable
[Index
].FragmentBuffer
,
1490 FragmentTable
[Index
].FragmentLength
1492 BytesCopied
+= FragmentTable
[Index
].FragmentLength
;
1495 // Free the FragmentBuffer since it has been copied.
1497 FreePool (FragmentTable
[Index
].FragmentBuffer
);
1500 Fragment
->Len
= BufferSize
;
1501 Fragment
->Bulk
= Buffer
;
1505 if (OriginalFragmentTable
!= NULL
) {
1506 if( FragmentTable
== OriginalFragmentTable
) {
1507 FragmentTable
= NULL
;
1509 FreePool (OriginalFragmentTable
);
1510 OriginalFragmentTable
= NULL
;
1514 // Caller has the responsibility to free the FragmentTable.
1516 if (FragmentTable
!= NULL
) {
1517 FreePool (FragmentTable
);
1518 FragmentTable
= NULL
;
1525 Receive one fragment decrypted from one TLS record.
1527 @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
1528 @param[in, out] Fragment The received Fragment.
1529 @param[in] Timeout The time to wait for connection done.
1531 @retval EFI_SUCCESS One fragment is received.
1532 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
1533 @retval EFI_ABORTED Something wrong decryption the message.
1534 @retval Others Other errors as indicated.
1540 IN HTTP_PROTOCOL
*HttpInstance
,
1541 IN OUT NET_FRAGMENT
*Fragment
,
1542 IN EFI_EVENT Timeout
1547 TLS_RECORD_HEADER RecordHeader
;
1550 NET_FRAGMENT TempFragment
;
1552 UINTN BufferOutSize
;
1555 UINT8
*GetSessionDataBuffer
;
1556 UINTN GetSessionDataBufferSize
;
1558 Status
= EFI_SUCCESS
;
1566 GetSessionDataBuffer
= NULL
;
1567 GetSessionDataBufferSize
= 0;
1570 // Receive only one TLS record
1572 Status
= TlsReceiveOnePdu (HttpInstance
, &Pdu
, Timeout
);
1573 if (EFI_ERROR (Status
)) {
1577 BufferInSize
= Pdu
->TotalSize
;
1578 BufferIn
= AllocateZeroPool (BufferInSize
);
1579 if (BufferIn
== NULL
) {
1580 Status
= EFI_OUT_OF_RESOURCES
;
1585 NetbufCopy (Pdu
, 0, (UINT32
) BufferInSize
, BufferIn
);
1590 // Handle Receive data.
1592 RecordHeader
= *(TLS_RECORD_HEADER
*) BufferIn
;
1594 if ((RecordHeader
.ContentType
== TlsContentTypeApplicationData
) &&
1595 (RecordHeader
.Version
.Major
== 0x03) &&
1596 (RecordHeader
.Version
.Minor
== TLS10_PROTOCOL_VERSION_MINOR
||
1597 RecordHeader
.Version
.Minor
== TLS11_PROTOCOL_VERSION_MINOR
||
1598 RecordHeader
.Version
.Minor
== TLS12_PROTOCOL_VERSION_MINOR
)
1603 Status
= TlsProcessMessage (
1611 FreePool (BufferIn
);
1613 if (EFI_ERROR (Status
)) {
1614 if (Status
== EFI_ABORTED
) {
1616 // Something wrong decryption the message.
1617 // BuildResponsePacket() will be called to generate Error Alert message and send it out.
1619 BufferOutSize
= DEF_BUF_LEN
;
1620 BufferOut
= AllocateZeroPool (BufferOutSize
);
1621 if (BufferOut
== NULL
) {
1622 Status
= EFI_OUT_OF_RESOURCES
;
1626 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1633 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1634 FreePool (BufferOut
);
1635 BufferOut
= AllocateZeroPool (BufferOutSize
);
1636 if (BufferOut
== NULL
) {
1637 Status
= EFI_OUT_OF_RESOURCES
;
1641 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1649 if (EFI_ERROR (Status
)) {
1650 FreePool(BufferOut
);
1654 if (BufferOutSize
!= 0) {
1655 PacketOut
= NetbufAlloc ((UINT32
)BufferOutSize
);
1656 DataOut
= NetbufAllocSpace (PacketOut
, (UINT32
) BufferOutSize
, NET_BUF_TAIL
);
1657 if (DataOut
== NULL
) {
1658 FreePool (BufferOut
);
1659 return EFI_OUT_OF_RESOURCES
;
1662 CopyMem (DataOut
, BufferOut
, BufferOutSize
);
1664 Status
= TlsCommonTransmit (HttpInstance
, PacketOut
);
1666 NetbufFree (PacketOut
);
1669 FreePool(BufferOut
);
1671 if (EFI_ERROR (Status
)) {
1684 ASSERT (((TLS_RECORD_HEADER
*) (TempFragment
.Bulk
))->ContentType
== TlsContentTypeApplicationData
);
1686 BufferInSize
= ((TLS_RECORD_HEADER
*) (TempFragment
.Bulk
))->Length
;
1687 BufferIn
= AllocateZeroPool (BufferInSize
);
1688 if (BufferIn
== NULL
) {
1689 Status
= EFI_OUT_OF_RESOURCES
;
1693 CopyMem (BufferIn
, TempFragment
.Bulk
+ TLS_RECORD_HEADER_LENGTH
, BufferInSize
);
1696 // Free the buffer in TempFragment.
1698 FreePool (TempFragment
.Bulk
);
1700 } else if ((RecordHeader
.ContentType
== TlsContentTypeAlert
) &&
1701 (RecordHeader
.Version
.Major
== 0x03) &&
1702 (RecordHeader
.Version
.Minor
== TLS10_PROTOCOL_VERSION_MINOR
||
1703 RecordHeader
.Version
.Minor
== TLS11_PROTOCOL_VERSION_MINOR
||
1704 RecordHeader
.Version
.Minor
== TLS12_PROTOCOL_VERSION_MINOR
)
1706 BufferOutSize
= DEF_BUF_LEN
;
1707 BufferOut
= AllocateZeroPool (BufferOutSize
);
1708 if (BufferOut
== NULL
) {
1709 FreePool (BufferIn
);
1710 Status
= EFI_OUT_OF_RESOURCES
;
1714 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1721 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1722 FreePool (BufferOut
);
1723 BufferOut
= AllocateZeroPool (BufferOutSize
);
1724 if (BufferOut
== NULL
) {
1725 FreePool (BufferIn
);
1726 Status
= EFI_OUT_OF_RESOURCES
;
1730 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1739 FreePool (BufferIn
);
1741 if (EFI_ERROR (Status
)) {
1742 FreePool (BufferOut
);
1746 if (BufferOutSize
!= 0) {
1747 PacketOut
= NetbufAlloc ((UINT32
) BufferOutSize
);
1748 DataOut
= NetbufAllocSpace (PacketOut
, (UINT32
) BufferOutSize
, NET_BUF_TAIL
);
1749 if (DataOut
== NULL
) {
1750 FreePool (BufferOut
);
1751 return EFI_OUT_OF_RESOURCES
;
1754 CopyMem (DataOut
, BufferOut
, BufferOutSize
);
1756 Status
= TlsCommonTransmit (HttpInstance
, PacketOut
);
1758 NetbufFree (PacketOut
);
1761 FreePool (BufferOut
);
1764 // Get the session state.
1766 GetSessionDataBufferSize
= DEF_BUF_LEN
;
1767 GetSessionDataBuffer
= AllocateZeroPool (GetSessionDataBufferSize
);
1768 if (GetSessionDataBuffer
== NULL
) {
1769 Status
= EFI_OUT_OF_RESOURCES
;
1773 Status
= HttpInstance
->Tls
->GetSessionData (
1776 GetSessionDataBuffer
,
1777 &GetSessionDataBufferSize
1779 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1780 FreePool (GetSessionDataBuffer
);
1781 GetSessionDataBuffer
= AllocateZeroPool (GetSessionDataBufferSize
);
1782 if (GetSessionDataBuffer
== NULL
) {
1783 Status
= EFI_OUT_OF_RESOURCES
;
1787 Status
= HttpInstance
->Tls
->GetSessionData (
1790 GetSessionDataBuffer
,
1791 &GetSessionDataBufferSize
1794 if (EFI_ERROR (Status
)) {
1795 FreePool (GetSessionDataBuffer
);
1799 ASSERT(GetSessionDataBufferSize
== sizeof (EFI_TLS_SESSION_STATE
));
1800 HttpInstance
->TlsSessionState
= *(EFI_TLS_SESSION_STATE
*) GetSessionDataBuffer
;
1802 FreePool (GetSessionDataBuffer
);
1804 if(HttpInstance
->TlsSessionState
== EfiTlsSessionError
) {
1805 DEBUG ((EFI_D_ERROR
, "TLS Session State Error!\n"));
1813 Fragment
->Bulk
= BufferIn
;
1814 Fragment
->Len
= (UINT32
) BufferInSize
;