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
;
387 UINTN CertArraySizeInBytes
;
395 // Try to read the TlsCaCertificate variable.
397 Status
= gRT
->GetVariable (
398 EFI_TLS_CA_CERTIFICATE_VARIABLE
,
399 &gEfiTlsCaCertificateGuid
,
405 if (EFI_ERROR (Status
) && Status
!= EFI_BUFFER_TOO_SMALL
) {
410 // Allocate buffer and read the config variable.
412 CACert
= AllocatePool (CACertSize
);
413 if (CACert
== NULL
) {
414 return EFI_OUT_OF_RESOURCES
;
417 Status
= gRT
->GetVariable (
418 EFI_TLS_CA_CERTIFICATE_VARIABLE
,
419 &gEfiTlsCaCertificateGuid
,
424 if (EFI_ERROR (Status
)) {
426 // GetVariable still error or the variable is corrupted.
431 ASSERT (CACert
!= NULL
);
436 Status
= EFI_INVALID_PARAMETER
;
438 ItemDataSize
= (UINT32
) CACertSize
;
439 while (ItemDataSize
> 0) {
440 if (ItemDataSize
< sizeof (EFI_SIGNATURE_LIST
)) {
441 DEBUG ((DEBUG_ERROR
, "%a: truncated EFI_SIGNATURE_LIST header\n",
446 CertList
= (EFI_SIGNATURE_LIST
*) (CACert
+ (CACertSize
- ItemDataSize
));
448 if (CertList
->SignatureListSize
< sizeof (EFI_SIGNATURE_LIST
)) {
450 "%a: SignatureListSize too small for EFI_SIGNATURE_LIST\n",
455 if (CertList
->SignatureListSize
> ItemDataSize
) {
456 DEBUG ((DEBUG_ERROR
, "%a: truncated EFI_SIGNATURE_LIST body\n",
461 if (!CompareGuid (&CertList
->SignatureType
, &gEfiCertX509Guid
)) {
462 DEBUG ((DEBUG_ERROR
, "%a: only X509 certificates are supported\n",
464 Status
= EFI_UNSUPPORTED
;
468 if (CertList
->SignatureHeaderSize
!= 0) {
469 DEBUG ((DEBUG_ERROR
, "%a: SignatureHeaderSize must be 0 for X509\n",
474 if (CertList
->SignatureSize
< sizeof (EFI_SIGNATURE_DATA
)) {
476 "%a: SignatureSize too small for EFI_SIGNATURE_DATA\n", __FUNCTION__
));
480 CertArraySizeInBytes
= (CertList
->SignatureListSize
-
481 sizeof (EFI_SIGNATURE_LIST
));
482 if (CertArraySizeInBytes
% CertList
->SignatureSize
!= 0) {
484 "%a: EFI_SIGNATURE_DATA array not a multiple of SignatureSize\n",
489 CertCount
+= CertArraySizeInBytes
/ CertList
->SignatureSize
;
490 ItemDataSize
-= CertList
->SignatureListSize
;
492 if (CertCount
== 0) {
493 DEBUG ((DEBUG_ERROR
, "%a: no X509 certificates provided\n", __FUNCTION__
));
498 // Enumerate all data and erasing the target item.
500 ItemDataSize
= (UINT32
) CACertSize
;
501 CertList
= (EFI_SIGNATURE_LIST
*) CACert
;
502 while ((ItemDataSize
> 0) && (ItemDataSize
>= CertList
->SignatureListSize
)) {
503 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) CertList
+ sizeof (EFI_SIGNATURE_LIST
) + CertList
->SignatureHeaderSize
);
504 CertCount
= (CertList
->SignatureListSize
- sizeof (EFI_SIGNATURE_LIST
) - CertList
->SignatureHeaderSize
) / CertList
->SignatureSize
;
505 for (Index
= 0; Index
< CertCount
; Index
++) {
507 // EfiTlsConfigDataTypeCACertificate
509 Status
= HttpInstance
->TlsConfiguration
->SetData (
510 HttpInstance
->TlsConfiguration
,
511 EfiTlsConfigDataTypeCACertificate
,
513 CertList
->SignatureSize
- sizeof (Cert
->SignatureOwner
)
515 if (EFI_ERROR (Status
)) {
519 Cert
= (EFI_SIGNATURE_DATA
*) ((UINT8
*) Cert
+ CertList
->SignatureSize
);
522 ItemDataSize
-= CertList
->SignatureListSize
;
523 CertList
= (EFI_SIGNATURE_LIST
*) ((UINT8
*) CertList
+ CertList
->SignatureListSize
);
532 Read the HttpTlsCipherList variable and configure it for HTTPS session.
534 @param[in, out] HttpInstance The HTTP instance private data.
536 @retval EFI_SUCCESS The prefered HTTP TLS CipherList is configured.
537 @retval EFI_NOT_FOUND Fail to get 'HttpTlsCipherList' variable.
538 @retval EFI_INVALID_PARAMETER The contents of variable are invalid.
539 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
541 @retval Others Other error as indicated.
545 TlsConfigCipherList (
546 IN OUT HTTP_PROTOCOL
*HttpInstance
551 UINTN CipherListSize
;
557 // Try to read the HttpTlsCipherList variable.
559 Status
= gRT
->GetVariable (
560 EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE
,
561 &gEdkiiHttpTlsCipherListGuid
,
566 ASSERT (EFI_ERROR (Status
));
567 if (Status
!= EFI_BUFFER_TOO_SMALL
) {
571 if (CipherListSize
% sizeof (EFI_TLS_CIPHER
) != 0) {
572 return EFI_INVALID_PARAMETER
;
576 // Allocate buffer and read the config variable.
578 CipherList
= AllocatePool (CipherListSize
);
579 if (CipherList
== NULL
) {
580 return EFI_OUT_OF_RESOURCES
;
583 Status
= gRT
->GetVariable (
584 EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE
,
585 &gEdkiiHttpTlsCipherListGuid
,
590 if (EFI_ERROR (Status
)) {
592 // GetVariable still error or the variable is corrupted.
597 ASSERT (CipherList
!= NULL
);
599 Status
= HttpInstance
->Tls
->SetSessionData (
607 FreePool (CipherList
);
613 Configure TLS session data.
615 @param[in, out] HttpInstance The HTTP instance private data.
617 @retval EFI_SUCCESS TLS session data is configured.
618 @retval Others Other error as indicated.
623 TlsConfigureSession (
624 IN OUT HTTP_PROTOCOL
*HttpInstance
630 // TlsConfigData initialization
632 HttpInstance
->TlsConfigData
.ConnectionEnd
= EfiTlsClient
;
633 HttpInstance
->TlsConfigData
.VerifyMethod
= EFI_TLS_VERIFY_PEER
;
634 HttpInstance
->TlsConfigData
.SessionState
= EfiTlsSessionNotStarted
;
637 // EfiTlsConnectionEnd,
638 // EfiTlsVerifyMethod
639 // EfiTlsSessionState
641 Status
= HttpInstance
->Tls
->SetSessionData (
644 &(HttpInstance
->TlsConfigData
.ConnectionEnd
),
645 sizeof (EFI_TLS_CONNECTION_END
)
647 if (EFI_ERROR (Status
)) {
651 Status
= HttpInstance
->Tls
->SetSessionData (
654 &HttpInstance
->TlsConfigData
.VerifyMethod
,
655 sizeof (EFI_TLS_VERIFY
)
657 if (EFI_ERROR (Status
)) {
661 Status
= HttpInstance
->Tls
->SetSessionData (
664 &(HttpInstance
->TlsConfigData
.SessionState
),
665 sizeof (EFI_TLS_SESSION_STATE
)
667 if (EFI_ERROR (Status
)) {
674 Status
= TlsConfigCipherList (HttpInstance
);
675 if (EFI_ERROR (Status
) && Status
!= EFI_NOT_FOUND
) {
676 DEBUG ((EFI_D_ERROR
, "TlsConfigCipherList: return %r error.\n", Status
));
681 // Tls Config Certificate
683 Status
= TlsConfigCertificate (HttpInstance
);
684 if (EFI_ERROR (Status
)) {
685 DEBUG ((EFI_D_ERROR
, "TLS Certificate Config Error!\n"));
690 // TlsCreateTxRxEvent
692 Status
= TlsCreateTxRxEvent (HttpInstance
);
693 if (EFI_ERROR (Status
)) {
700 TlsCloseTxRxEvent (HttpInstance
);
706 Transmit the Packet by processing the associated HTTPS token.
708 @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
709 @param[in] Packet The packet to transmit.
711 @retval EFI_SUCCESS The packet is transmitted.
712 @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
713 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
714 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
715 @retval Others Other errors as indicated.
721 IN OUT HTTP_PROTOCOL
*HttpInstance
,
729 if ((HttpInstance
== NULL
) || (Packet
== NULL
)) {
730 return EFI_INVALID_PARAMETER
;
733 if (!HttpInstance
->LocalAddressIsIPv6
) {
734 Size
= sizeof (EFI_TCP4_TRANSMIT_DATA
) +
735 (Packet
->BlockOpNum
- 1) * sizeof (EFI_TCP4_FRAGMENT_DATA
);
737 Size
= sizeof (EFI_TCP6_TRANSMIT_DATA
) +
738 (Packet
->BlockOpNum
- 1) * sizeof (EFI_TCP6_FRAGMENT_DATA
);
741 Data
= AllocatePool (Size
);
743 return EFI_OUT_OF_RESOURCES
;
746 if (!HttpInstance
->LocalAddressIsIPv6
) {
747 ((EFI_TCP4_TRANSMIT_DATA
*) Data
)->Push
= TRUE
;
748 ((EFI_TCP4_TRANSMIT_DATA
*) Data
)->Urgent
= FALSE
;
749 ((EFI_TCP4_TRANSMIT_DATA
*) Data
)->DataLength
= Packet
->TotalSize
;
752 // Build the fragment table.
754 ((EFI_TCP4_TRANSMIT_DATA
*) Data
)->FragmentCount
= Packet
->BlockOpNum
;
758 (NET_FRAGMENT
*) &((EFI_TCP4_TRANSMIT_DATA
*) Data
)->FragmentTable
[0],
759 &((EFI_TCP4_TRANSMIT_DATA
*) Data
)->FragmentCount
762 HttpInstance
->Tcp4TlsTxToken
.Packet
.TxData
= (EFI_TCP4_TRANSMIT_DATA
*) Data
;
764 Status
= EFI_DEVICE_ERROR
;
767 // Transmit the packet.
769 Status
= HttpInstance
->Tcp4
->Transmit (HttpInstance
->Tcp4
, &HttpInstance
->Tcp4TlsTxToken
);
770 if (EFI_ERROR (Status
)) {
774 while (!HttpInstance
->TlsIsTxDone
) {
775 HttpInstance
->Tcp4
->Poll (HttpInstance
->Tcp4
);
778 HttpInstance
->TlsIsTxDone
= FALSE
;
779 Status
= HttpInstance
->Tcp4TlsTxToken
.CompletionToken
.Status
;
781 ((EFI_TCP6_TRANSMIT_DATA
*) Data
)->Push
= TRUE
;
782 ((EFI_TCP6_TRANSMIT_DATA
*) Data
)->Urgent
= FALSE
;
783 ((EFI_TCP6_TRANSMIT_DATA
*) Data
)->DataLength
= Packet
->TotalSize
;
786 // Build the fragment table.
788 ((EFI_TCP6_TRANSMIT_DATA
*) Data
)->FragmentCount
= Packet
->BlockOpNum
;
792 (NET_FRAGMENT
*) &((EFI_TCP6_TRANSMIT_DATA
*) Data
)->FragmentTable
[0],
793 &((EFI_TCP6_TRANSMIT_DATA
*) Data
)->FragmentCount
796 HttpInstance
->Tcp6TlsTxToken
.Packet
.TxData
= (EFI_TCP6_TRANSMIT_DATA
*) Data
;
798 Status
= EFI_DEVICE_ERROR
;
801 // Transmit the packet.
803 Status
= HttpInstance
->Tcp6
->Transmit (HttpInstance
->Tcp6
, &HttpInstance
->Tcp6TlsTxToken
);
804 if (EFI_ERROR (Status
)) {
808 while (!HttpInstance
->TlsIsTxDone
) {
809 HttpInstance
->Tcp6
->Poll (HttpInstance
->Tcp6
);
812 HttpInstance
->TlsIsTxDone
= FALSE
;
813 Status
= HttpInstance
->Tcp6TlsTxToken
.CompletionToken
.Status
;
823 Receive the Packet by processing the associated HTTPS token.
825 @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
826 @param[in] Packet The packet to transmit.
827 @param[in] Timeout The time to wait for connection done.
829 @retval EFI_SUCCESS The Packet is received.
830 @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
831 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
832 @retval EFI_TIMEOUT The operation is time out.
833 @retval Others Other error as indicated.
839 IN OUT HTTP_PROTOCOL
*HttpInstance
,
844 EFI_TCP4_RECEIVE_DATA
*Tcp4RxData
;
845 EFI_TCP6_RECEIVE_DATA
*Tcp6RxData
;
847 NET_FRAGMENT
*Fragment
;
848 UINT32 FragmentCount
;
849 UINT32 CurrentFragment
;
854 if ((HttpInstance
== NULL
) || (Packet
== NULL
)) {
855 return EFI_INVALID_PARAMETER
;
858 FragmentCount
= Packet
->BlockOpNum
;
859 Fragment
= AllocatePool (FragmentCount
* sizeof (NET_FRAGMENT
));
860 if (Fragment
== NULL
) {
861 Status
= EFI_OUT_OF_RESOURCES
;
866 // Build the fragment table.
868 NetbufBuildExt (Packet
, Fragment
, &FragmentCount
);
870 if (!HttpInstance
->LocalAddressIsIPv6
) {
871 Tcp4RxData
= HttpInstance
->Tcp4TlsRxToken
.Packet
.RxData
;
872 if (Tcp4RxData
== NULL
) {
873 return EFI_INVALID_PARAMETER
;
875 Tcp4RxData
->FragmentCount
= 1;
877 Tcp6RxData
= HttpInstance
->Tcp6TlsRxToken
.Packet
.RxData
;
878 if (Tcp6RxData
== NULL
) {
879 return EFI_INVALID_PARAMETER
;
881 Tcp6RxData
->FragmentCount
= 1;
885 Status
= EFI_SUCCESS
;
887 while (CurrentFragment
< FragmentCount
) {
888 if (!HttpInstance
->LocalAddressIsIPv6
) {
889 Tcp4RxData
->DataLength
= Fragment
[CurrentFragment
].Len
;
890 Tcp4RxData
->FragmentTable
[0].FragmentLength
= Fragment
[CurrentFragment
].Len
;
891 Tcp4RxData
->FragmentTable
[0].FragmentBuffer
= Fragment
[CurrentFragment
].Bulk
;
892 Status
= HttpInstance
->Tcp4
->Receive (HttpInstance
->Tcp4
, &HttpInstance
->Tcp4TlsRxToken
);
894 Tcp6RxData
->DataLength
= Fragment
[CurrentFragment
].Len
;
895 Tcp6RxData
->FragmentTable
[0].FragmentLength
= Fragment
[CurrentFragment
].Len
;
896 Tcp6RxData
->FragmentTable
[0].FragmentBuffer
= Fragment
[CurrentFragment
].Bulk
;
897 Status
= HttpInstance
->Tcp6
->Receive (HttpInstance
->Tcp6
, &HttpInstance
->Tcp6TlsRxToken
);
899 if (EFI_ERROR (Status
)) {
903 while (!HttpInstance
->TlsIsRxDone
&& ((Timeout
== NULL
) || EFI_ERROR (gBS
->CheckEvent (Timeout
)))) {
905 // Poll until some data is received or an error occurs.
907 if (!HttpInstance
->LocalAddressIsIPv6
) {
908 HttpInstance
->Tcp4
->Poll (HttpInstance
->Tcp4
);
910 HttpInstance
->Tcp6
->Poll (HttpInstance
->Tcp6
);
914 if (!HttpInstance
->TlsIsRxDone
) {
916 // Timeout occurs, cancel the receive request.
918 if (!HttpInstance
->LocalAddressIsIPv6
) {
919 HttpInstance
->Tcp4
->Cancel (HttpInstance
->Tcp4
, &HttpInstance
->Tcp4TlsRxToken
.CompletionToken
);
921 HttpInstance
->Tcp6
->Cancel (HttpInstance
->Tcp6
, &HttpInstance
->Tcp6TlsRxToken
.CompletionToken
);
924 Status
= EFI_TIMEOUT
;
927 HttpInstance
->TlsIsRxDone
= FALSE
;
930 if (!HttpInstance
->LocalAddressIsIPv6
) {
931 Status
= HttpInstance
->Tcp4TlsRxToken
.CompletionToken
.Status
;
932 if (EFI_ERROR (Status
)) {
936 Fragment
[CurrentFragment
].Len
-= Tcp4RxData
->FragmentTable
[0].FragmentLength
;
937 if (Fragment
[CurrentFragment
].Len
== 0) {
940 Fragment
[CurrentFragment
].Bulk
+= Tcp4RxData
->FragmentTable
[0].FragmentLength
;
943 Status
= HttpInstance
->Tcp6TlsRxToken
.CompletionToken
.Status
;
944 if (EFI_ERROR (Status
)) {
948 Fragment
[CurrentFragment
].Len
-= Tcp6RxData
->FragmentTable
[0].FragmentLength
;
949 if (Fragment
[CurrentFragment
].Len
== 0) {
952 Fragment
[CurrentFragment
].Bulk
+= Tcp6RxData
->FragmentTable
[0].FragmentLength
;
959 if (Fragment
!= NULL
) {
967 Receive one TLS PDU. An TLS PDU contains an TLS record header and it's
968 corresponding record data. These two parts will be put into two blocks of buffers in the
971 @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
972 @param[out] Pdu The received TLS PDU.
973 @param[in] Timeout The time to wait for connection done.
975 @retval EFI_SUCCESS An TLS PDU is received.
976 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
977 @retval EFI_PROTOCOL_ERROR An unexpected TLS packet was received.
978 @retval Others Other errors as indicated.
984 IN OUT HTTP_PROTOCOL
*HttpInstance
,
991 LIST_ENTRY
*NbufList
;
997 TLS_RECORD_HEADER RecordHeader
;
1006 NbufList
= AllocatePool (sizeof (LIST_ENTRY
));
1007 if (NbufList
== NULL
) {
1008 return EFI_OUT_OF_RESOURCES
;
1011 InitializeListHead (NbufList
);
1014 // Allocate buffer to receive one TLS header.
1016 Len
= TLS_RECORD_HEADER_LENGTH
;
1017 PduHdr
= NetbufAlloc (Len
);
1018 if (PduHdr
== NULL
) {
1019 Status
= EFI_OUT_OF_RESOURCES
;
1023 Header
= NetbufAllocSpace (PduHdr
, Len
, NET_BUF_TAIL
);
1024 if (Header
== NULL
) {
1025 Status
= EFI_OUT_OF_RESOURCES
;
1030 // First step, receive one TLS header.
1032 Status
= TlsCommonReceive (HttpInstance
, PduHdr
, Timeout
);
1033 if (EFI_ERROR (Status
)) {
1037 RecordHeader
= *(TLS_RECORD_HEADER
*) Header
;
1038 if ((RecordHeader
.ContentType
== TlsContentTypeHandshake
||
1039 RecordHeader
.ContentType
== TlsContentTypeAlert
||
1040 RecordHeader
.ContentType
== TlsContentTypeChangeCipherSpec
||
1041 RecordHeader
.ContentType
== TlsContentTypeApplicationData
) &&
1042 (RecordHeader
.Version
.Major
== 0x03) && /// Major versions are same.
1043 (RecordHeader
.Version
.Minor
== TLS10_PROTOCOL_VERSION_MINOR
||
1044 RecordHeader
.Version
.Minor
==TLS11_PROTOCOL_VERSION_MINOR
||
1045 RecordHeader
.Version
.Minor
== TLS12_PROTOCOL_VERSION_MINOR
)
1047 InsertTailList (NbufList
, &PduHdr
->List
);
1049 Status
= EFI_PROTOCOL_ERROR
;
1053 Len
= SwapBytes16(RecordHeader
.Length
);
1062 // Allocate buffer to receive one TLS payload.
1064 DataSeg
= NetbufAlloc (Len
);
1065 if (DataSeg
== NULL
) {
1066 Status
= EFI_OUT_OF_RESOURCES
;
1070 NetbufAllocSpace (DataSeg
, Len
, NET_BUF_TAIL
);
1073 // Second step, receive one TLS payload.
1075 Status
= TlsCommonReceive (HttpInstance
, DataSeg
, Timeout
);
1076 if (EFI_ERROR (Status
)) {
1080 InsertTailList (NbufList
, &DataSeg
->List
);
1084 // Form the PDU from a list of PDU.
1086 *Pdu
= NetbufFromBufList (NbufList
, 0, 0, FreeNbufList
, NbufList
);
1088 Status
= EFI_OUT_OF_RESOURCES
;
1093 if (EFI_ERROR (Status
)) {
1095 // Free the Nbufs in this NbufList and the NbufList itself.
1097 FreeNbufList (NbufList
);
1104 Connect one TLS session by finishing the TLS handshake process.
1106 @param[in] HttpInstance The HTTP instance private data.
1107 @param[in] Timeout The time to wait for connection done.
1109 @retval EFI_SUCCESS The TLS session is established.
1110 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
1111 @retval EFI_ABORTED TLS session state is incorrect.
1112 @retval Others Other error as indicated.
1118 IN HTTP_PROTOCOL
*HttpInstance
,
1119 IN EFI_EVENT Timeout
1124 UINTN BufferOutSize
;
1130 UINT8
*GetSessionDataBuffer
;
1131 UINTN GetSessionDataBufferSize
;
1140 // Initialize TLS state.
1142 HttpInstance
->TlsSessionState
= EfiTlsSessionNotStarted
;
1143 Status
= HttpInstance
->Tls
->SetSessionData (
1146 &(HttpInstance
->TlsSessionState
),
1147 sizeof (EFI_TLS_SESSION_STATE
)
1149 if (EFI_ERROR (Status
)) {
1154 // Create ClientHello
1156 BufferOutSize
= DEF_BUF_LEN
;
1157 BufferOut
= AllocateZeroPool (BufferOutSize
);
1158 if (BufferOut
== NULL
) {
1159 Status
= EFI_OUT_OF_RESOURCES
;
1163 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1170 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1171 FreePool (BufferOut
);
1172 BufferOut
= AllocateZeroPool (BufferOutSize
);
1173 if (BufferOut
== NULL
) {
1174 Status
= EFI_OUT_OF_RESOURCES
;
1178 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1186 if (EFI_ERROR (Status
)) {
1187 FreePool (BufferOut
);
1192 // Transmit ClientHello
1194 PacketOut
= NetbufAlloc ((UINT32
) BufferOutSize
);
1195 DataOut
= NetbufAllocSpace (PacketOut
, (UINT32
) BufferOutSize
, NET_BUF_TAIL
);
1196 if (DataOut
== NULL
) {
1197 FreePool (BufferOut
);
1198 return EFI_OUT_OF_RESOURCES
;
1201 CopyMem (DataOut
, BufferOut
, BufferOutSize
);
1202 Status
= TlsCommonTransmit (HttpInstance
, PacketOut
);
1204 FreePool (BufferOut
);
1205 NetbufFree (PacketOut
);
1207 if (EFI_ERROR (Status
)) {
1211 while(HttpInstance
->TlsSessionState
!= EfiTlsSessionDataTransferring
&& \
1212 ((Timeout
== NULL
) || EFI_ERROR (gBS
->CheckEvent (Timeout
)))) {
1214 // Receive one TLS record.
1216 Status
= TlsReceiveOnePdu (HttpInstance
, &Pdu
, Timeout
);
1217 if (EFI_ERROR (Status
)) {
1221 BufferInSize
= Pdu
->TotalSize
;
1222 BufferIn
= AllocateZeroPool (BufferInSize
);
1223 if (BufferIn
== NULL
) {
1225 Status
= EFI_OUT_OF_RESOURCES
;
1229 NetbufCopy (Pdu
, 0, (UINT32
)BufferInSize
, BufferIn
);
1234 // Handle Receive data.
1236 BufferOutSize
= DEF_BUF_LEN
;
1237 BufferOut
= AllocateZeroPool (BufferOutSize
);
1238 if (BufferOut
== NULL
) {
1239 Status
= EFI_OUT_OF_RESOURCES
;
1243 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1250 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1251 FreePool (BufferOut
);
1252 BufferOut
= AllocateZeroPool (BufferOutSize
);
1253 if (BufferOut
== NULL
) {
1254 FreePool (BufferIn
);
1255 Status
= EFI_OUT_OF_RESOURCES
;
1259 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1268 FreePool (BufferIn
);
1270 if (EFI_ERROR (Status
)) {
1271 FreePool (BufferOut
);
1275 if (BufferOutSize
!= 0) {
1277 // Transmit the response packet.
1279 PacketOut
= NetbufAlloc ((UINT32
) BufferOutSize
);
1280 DataOut
= NetbufAllocSpace (PacketOut
, (UINT32
) BufferOutSize
, NET_BUF_TAIL
);
1281 if (DataOut
== NULL
) {
1282 FreePool (BufferOut
);
1283 return EFI_OUT_OF_RESOURCES
;
1286 CopyMem (DataOut
, BufferOut
, BufferOutSize
);
1288 Status
= TlsCommonTransmit (HttpInstance
, PacketOut
);
1290 NetbufFree (PacketOut
);
1292 if (EFI_ERROR (Status
)) {
1293 FreePool (BufferOut
);
1298 FreePool (BufferOut
);
1301 // Get the session state, then decide whether need to continue handle received packet.
1303 GetSessionDataBufferSize
= DEF_BUF_LEN
;
1304 GetSessionDataBuffer
= AllocateZeroPool (GetSessionDataBufferSize
);
1305 if (GetSessionDataBuffer
== NULL
) {
1306 Status
= EFI_OUT_OF_RESOURCES
;
1310 Status
= HttpInstance
->Tls
->GetSessionData (
1313 GetSessionDataBuffer
,
1314 &GetSessionDataBufferSize
1316 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1317 FreePool (GetSessionDataBuffer
);
1318 GetSessionDataBuffer
= AllocateZeroPool (GetSessionDataBufferSize
);
1319 if (GetSessionDataBuffer
== NULL
) {
1320 Status
= EFI_OUT_OF_RESOURCES
;
1324 Status
= HttpInstance
->Tls
->GetSessionData (
1327 GetSessionDataBuffer
,
1328 &GetSessionDataBufferSize
1331 if (EFI_ERROR (Status
)) {
1332 FreePool(GetSessionDataBuffer
);
1336 ASSERT(GetSessionDataBufferSize
== sizeof (EFI_TLS_SESSION_STATE
));
1337 HttpInstance
->TlsSessionState
= *(EFI_TLS_SESSION_STATE
*) GetSessionDataBuffer
;
1339 FreePool (GetSessionDataBuffer
);
1341 if(HttpInstance
->TlsSessionState
== EfiTlsSessionError
) {
1346 if (HttpInstance
->TlsSessionState
!= EfiTlsSessionDataTransferring
) {
1347 Status
= EFI_ABORTED
;
1354 Close the TLS session and send out the close notification message.
1356 @param[in] HttpInstance The HTTP instance private data.
1358 @retval EFI_SUCCESS The TLS session is closed.
1359 @retval EFI_INVALID_PARAMETER HttpInstance is NULL.
1360 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
1361 @retval Others Other error as indicated.
1367 IN HTTP_PROTOCOL
*HttpInstance
1373 UINTN BufferOutSize
;
1378 Status
= EFI_SUCCESS
;
1383 if (HttpInstance
== NULL
) {
1384 return EFI_INVALID_PARAMETER
;
1387 HttpInstance
->TlsSessionState
= EfiTlsSessionClosing
;
1389 Status
= HttpInstance
->Tls
->SetSessionData (
1392 &(HttpInstance
->TlsSessionState
),
1393 sizeof (EFI_TLS_SESSION_STATE
)
1395 if (EFI_ERROR (Status
)) {
1399 BufferOutSize
= DEF_BUF_LEN
;
1400 BufferOut
= AllocateZeroPool (BufferOutSize
);
1401 if (BufferOut
== NULL
) {
1402 Status
= EFI_OUT_OF_RESOURCES
;
1406 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1413 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1414 FreePool (BufferOut
);
1415 BufferOut
= AllocateZeroPool (BufferOutSize
);
1416 if (BufferOut
== NULL
) {
1417 Status
= EFI_OUT_OF_RESOURCES
;
1421 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1430 if (EFI_ERROR (Status
)) {
1431 FreePool (BufferOut
);
1435 PacketOut
= NetbufAlloc ((UINT32
) BufferOutSize
);
1436 DataOut
= NetbufAllocSpace (PacketOut
, (UINT32
) BufferOutSize
, NET_BUF_TAIL
);
1437 if (DataOut
== NULL
) {
1438 FreePool (BufferOut
);
1439 return EFI_OUT_OF_RESOURCES
;
1442 CopyMem (DataOut
, BufferOut
, BufferOutSize
);
1444 Status
= TlsCommonTransmit (HttpInstance
, PacketOut
);
1446 FreePool (BufferOut
);
1447 NetbufFree (PacketOut
);
1453 Process one message according to the CryptMode.
1455 @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
1456 @param[in] Message Pointer to the message buffer needed to processed.
1457 If ProcessMode is EfiTlsEncrypt, the message contain the TLS
1458 header and plain text TLS APP payload.
1459 If ProcessMode is EfiTlsDecrypt, the message contain the TLS
1460 header and cipher text TLS APP payload.
1461 @param[in] MessageSize Pointer to the message buffer size.
1462 @param[in] ProcessMode Process mode.
1463 @param[in, out] Fragment Only one Fragment returned after the Message is
1464 processed successfully.
1465 If ProcessMode is EfiTlsEncrypt, the fragment contain the TLS
1466 header and cipher text TLS APP payload.
1467 If ProcessMode is EfiTlsDecrypt, the fragment contain the TLS
1468 header and plain text TLS APP payload.
1470 @retval EFI_SUCCESS Message is processed successfully.
1471 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
1472 @retval Others Other errors as indicated.
1478 IN HTTP_PROTOCOL
*HttpInstance
,
1480 IN UINTN MessageSize
,
1481 IN EFI_TLS_CRYPT_MODE ProcessMode
,
1482 IN OUT NET_FRAGMENT
*Fragment
1489 EFI_TLS_FRAGMENT_DATA
*FragmentTable
;
1490 UINT32 FragmentCount
;
1491 EFI_TLS_FRAGMENT_DATA
*OriginalFragmentTable
;
1494 Status
= EFI_SUCCESS
;
1498 FragmentTable
= NULL
;
1499 OriginalFragmentTable
= NULL
;
1502 // Rebuild fragment table from BufferIn.
1505 FragmentTable
= AllocateZeroPool (FragmentCount
* sizeof (EFI_TLS_FRAGMENT_DATA
));
1506 if (FragmentTable
== NULL
) {
1507 Status
= EFI_OUT_OF_RESOURCES
;
1511 FragmentTable
->FragmentLength
= (UINT32
) MessageSize
;
1512 FragmentTable
->FragmentBuffer
= Message
;
1515 // Record the original FragmentTable.
1517 OriginalFragmentTable
= FragmentTable
;
1520 // Process the Message.
1522 Status
= HttpInstance
->Tls
->ProcessPacket (
1528 if (EFI_ERROR (Status
)) {
1533 // Calculate the size according to FragmentTable.
1535 for (Index
= 0; Index
< FragmentCount
; Index
++) {
1536 BufferSize
+= FragmentTable
[Index
].FragmentLength
;
1540 // Allocate buffer for processed data.
1542 Buffer
= AllocateZeroPool (BufferSize
);
1543 if (Buffer
== NULL
) {
1544 Status
= EFI_OUT_OF_RESOURCES
;
1549 // Copy the new FragmentTable buffer into Buffer.
1551 for (Index
= 0; Index
< FragmentCount
; Index
++) {
1553 (Buffer
+ BytesCopied
),
1554 FragmentTable
[Index
].FragmentBuffer
,
1555 FragmentTable
[Index
].FragmentLength
1557 BytesCopied
+= FragmentTable
[Index
].FragmentLength
;
1560 // Free the FragmentBuffer since it has been copied.
1562 FreePool (FragmentTable
[Index
].FragmentBuffer
);
1565 Fragment
->Len
= BufferSize
;
1566 Fragment
->Bulk
= Buffer
;
1570 if (OriginalFragmentTable
!= NULL
) {
1571 if( FragmentTable
== OriginalFragmentTable
) {
1572 FragmentTable
= NULL
;
1574 FreePool (OriginalFragmentTable
);
1575 OriginalFragmentTable
= NULL
;
1579 // Caller has the responsibility to free the FragmentTable.
1581 if (FragmentTable
!= NULL
) {
1582 FreePool (FragmentTable
);
1583 FragmentTable
= NULL
;
1590 Receive one fragment decrypted from one TLS record.
1592 @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
1593 @param[in, out] Fragment The received Fragment.
1594 @param[in] Timeout The time to wait for connection done.
1596 @retval EFI_SUCCESS One fragment is received.
1597 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
1598 @retval EFI_ABORTED Something wrong decryption the message.
1599 @retval Others Other errors as indicated.
1605 IN HTTP_PROTOCOL
*HttpInstance
,
1606 IN OUT NET_FRAGMENT
*Fragment
,
1607 IN EFI_EVENT Timeout
1612 TLS_RECORD_HEADER RecordHeader
;
1615 NET_FRAGMENT TempFragment
;
1617 UINTN BufferOutSize
;
1620 UINT8
*GetSessionDataBuffer
;
1621 UINTN GetSessionDataBufferSize
;
1623 Status
= EFI_SUCCESS
;
1631 GetSessionDataBuffer
= NULL
;
1632 GetSessionDataBufferSize
= 0;
1635 // Receive only one TLS record
1637 Status
= TlsReceiveOnePdu (HttpInstance
, &Pdu
, Timeout
);
1638 if (EFI_ERROR (Status
)) {
1642 BufferInSize
= Pdu
->TotalSize
;
1643 BufferIn
= AllocateZeroPool (BufferInSize
);
1644 if (BufferIn
== NULL
) {
1645 Status
= EFI_OUT_OF_RESOURCES
;
1650 NetbufCopy (Pdu
, 0, (UINT32
) BufferInSize
, BufferIn
);
1655 // Handle Receive data.
1657 RecordHeader
= *(TLS_RECORD_HEADER
*) BufferIn
;
1659 if ((RecordHeader
.ContentType
== TlsContentTypeApplicationData
) &&
1660 (RecordHeader
.Version
.Major
== 0x03) &&
1661 (RecordHeader
.Version
.Minor
== TLS10_PROTOCOL_VERSION_MINOR
||
1662 RecordHeader
.Version
.Minor
== TLS11_PROTOCOL_VERSION_MINOR
||
1663 RecordHeader
.Version
.Minor
== TLS12_PROTOCOL_VERSION_MINOR
)
1668 Status
= TlsProcessMessage (
1676 FreePool (BufferIn
);
1678 if (EFI_ERROR (Status
)) {
1679 if (Status
== EFI_ABORTED
) {
1681 // Something wrong decryption the message.
1682 // BuildResponsePacket() will be called to generate Error Alert message and send it out.
1684 BufferOutSize
= DEF_BUF_LEN
;
1685 BufferOut
= AllocateZeroPool (BufferOutSize
);
1686 if (BufferOut
== NULL
) {
1687 Status
= EFI_OUT_OF_RESOURCES
;
1691 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1698 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1699 FreePool (BufferOut
);
1700 BufferOut
= AllocateZeroPool (BufferOutSize
);
1701 if (BufferOut
== NULL
) {
1702 Status
= EFI_OUT_OF_RESOURCES
;
1706 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1714 if (EFI_ERROR (Status
)) {
1715 FreePool(BufferOut
);
1719 if (BufferOutSize
!= 0) {
1720 PacketOut
= NetbufAlloc ((UINT32
)BufferOutSize
);
1721 DataOut
= NetbufAllocSpace (PacketOut
, (UINT32
) BufferOutSize
, NET_BUF_TAIL
);
1722 if (DataOut
== NULL
) {
1723 FreePool (BufferOut
);
1724 return EFI_OUT_OF_RESOURCES
;
1727 CopyMem (DataOut
, BufferOut
, BufferOutSize
);
1729 Status
= TlsCommonTransmit (HttpInstance
, PacketOut
);
1731 NetbufFree (PacketOut
);
1734 FreePool(BufferOut
);
1736 if (EFI_ERROR (Status
)) {
1749 ASSERT (((TLS_RECORD_HEADER
*) (TempFragment
.Bulk
))->ContentType
== TlsContentTypeApplicationData
);
1751 BufferInSize
= ((TLS_RECORD_HEADER
*) (TempFragment
.Bulk
))->Length
;
1752 BufferIn
= AllocateZeroPool (BufferInSize
);
1753 if (BufferIn
== NULL
) {
1754 Status
= EFI_OUT_OF_RESOURCES
;
1758 CopyMem (BufferIn
, TempFragment
.Bulk
+ TLS_RECORD_HEADER_LENGTH
, BufferInSize
);
1761 // Free the buffer in TempFragment.
1763 FreePool (TempFragment
.Bulk
);
1765 } else if ((RecordHeader
.ContentType
== TlsContentTypeAlert
) &&
1766 (RecordHeader
.Version
.Major
== 0x03) &&
1767 (RecordHeader
.Version
.Minor
== TLS10_PROTOCOL_VERSION_MINOR
||
1768 RecordHeader
.Version
.Minor
== TLS11_PROTOCOL_VERSION_MINOR
||
1769 RecordHeader
.Version
.Minor
== TLS12_PROTOCOL_VERSION_MINOR
)
1771 BufferOutSize
= DEF_BUF_LEN
;
1772 BufferOut
= AllocateZeroPool (BufferOutSize
);
1773 if (BufferOut
== NULL
) {
1774 FreePool (BufferIn
);
1775 Status
= EFI_OUT_OF_RESOURCES
;
1779 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1786 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1787 FreePool (BufferOut
);
1788 BufferOut
= AllocateZeroPool (BufferOutSize
);
1789 if (BufferOut
== NULL
) {
1790 FreePool (BufferIn
);
1791 Status
= EFI_OUT_OF_RESOURCES
;
1795 Status
= HttpInstance
->Tls
->BuildResponsePacket (
1804 FreePool (BufferIn
);
1806 if (EFI_ERROR (Status
)) {
1807 FreePool (BufferOut
);
1811 if (BufferOutSize
!= 0) {
1812 PacketOut
= NetbufAlloc ((UINT32
) BufferOutSize
);
1813 DataOut
= NetbufAllocSpace (PacketOut
, (UINT32
) BufferOutSize
, NET_BUF_TAIL
);
1814 if (DataOut
== NULL
) {
1815 FreePool (BufferOut
);
1816 return EFI_OUT_OF_RESOURCES
;
1819 CopyMem (DataOut
, BufferOut
, BufferOutSize
);
1821 Status
= TlsCommonTransmit (HttpInstance
, PacketOut
);
1823 NetbufFree (PacketOut
);
1826 FreePool (BufferOut
);
1829 // Get the session state.
1831 GetSessionDataBufferSize
= DEF_BUF_LEN
;
1832 GetSessionDataBuffer
= AllocateZeroPool (GetSessionDataBufferSize
);
1833 if (GetSessionDataBuffer
== NULL
) {
1834 Status
= EFI_OUT_OF_RESOURCES
;
1838 Status
= HttpInstance
->Tls
->GetSessionData (
1841 GetSessionDataBuffer
,
1842 &GetSessionDataBufferSize
1844 if (Status
== EFI_BUFFER_TOO_SMALL
) {
1845 FreePool (GetSessionDataBuffer
);
1846 GetSessionDataBuffer
= AllocateZeroPool (GetSessionDataBufferSize
);
1847 if (GetSessionDataBuffer
== NULL
) {
1848 Status
= EFI_OUT_OF_RESOURCES
;
1852 Status
= HttpInstance
->Tls
->GetSessionData (
1855 GetSessionDataBuffer
,
1856 &GetSessionDataBufferSize
1859 if (EFI_ERROR (Status
)) {
1860 FreePool (GetSessionDataBuffer
);
1864 ASSERT(GetSessionDataBufferSize
== sizeof (EFI_TLS_SESSION_STATE
));
1865 HttpInstance
->TlsSessionState
= *(EFI_TLS_SESSION_STATE
*) GetSessionDataBuffer
;
1867 FreePool (GetSessionDataBuffer
);
1869 if(HttpInstance
->TlsSessionState
== EfiTlsSessionError
) {
1870 DEBUG ((EFI_D_ERROR
, "TLS Session State Error!\n"));
1878 Fragment
->Bulk
= BufferIn
;
1879 Fragment
->Len
= (UINT32
) BufferInSize
;