]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/HttpDxe/HttpsSupport.c
NetworkPkg/HttpDxe: Handle the large data request via HTTPS channel.
[mirror_edk2.git] / NetworkPkg / HttpDxe / HttpsSupport.c
CommitLineData
7618784b
HW
1/** @file\r
2 Miscellaneous routines specific to Https for HttpDxe driver.\r
3\r
7ff68b5e 4Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
7618784b
HW
5(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
6This program and the accompanying materials\r
7are licensed and made available under the terms and conditions of the BSD License\r
8which accompanies this distribution. The full text of the license may be found at\r
9http://opensource.org/licenses/bsd-license.php\r
10\r
11THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include "HttpDriver.h"\r
17\r
18/**\r
19 Returns the first occurrence of a Null-terminated ASCII sub-string in a Null-terminated\r
20 ASCII string and ignore case during the search process.\r
21\r
22 This function scans the contents of the ASCII string specified by String\r
23 and returns the first occurrence of SearchString and ignore case during the search process.\r
24 If SearchString is not found in String, then NULL is returned. If the length of SearchString\r
25 is zero, then String is returned.\r
26\r
27 If String is NULL, then ASSERT().\r
28 If SearchString is NULL, then ASSERT().\r
29\r
30 @param[in] String A pointer to a Null-terminated ASCII string.\r
31 @param[in] SearchString A pointer to a Null-terminated ASCII string to search for.\r
32\r
33 @retval NULL If the SearchString does not appear in String.\r
34 @retval others If there is a match return the first occurrence of SearchingString.\r
35 If the length of SearchString is zero,return String.\r
36\r
37**/\r
38CHAR8 *\r
39AsciiStrCaseStr (\r
40 IN CONST CHAR8 *String,\r
41 IN CONST CHAR8 *SearchString\r
42 )\r
43{\r
44 CONST CHAR8 *FirstMatch;\r
45 CONST CHAR8 *SearchStringTmp;\r
46\r
47 CHAR8 Src;\r
48 CHAR8 Dst;\r
49\r
50 //\r
51 // ASSERT both strings are less long than PcdMaximumAsciiStringLength\r
52 //\r
53 ASSERT (AsciiStrSize (String) != 0);\r
54 ASSERT (AsciiStrSize (SearchString) != 0);\r
55\r
56 if (*SearchString == '\0') {\r
57 return (CHAR8 *) String;\r
58 }\r
59\r
60 while (*String != '\0') {\r
61 SearchStringTmp = SearchString;\r
62 FirstMatch = String;\r
63\r
64 while ((*SearchStringTmp != '\0')\r
65 && (*String != '\0')) {\r
66 Src = *String;\r
67 Dst = *SearchStringTmp;\r
68\r
69 if ((Src >= 'A') && (Src <= 'Z')) {\r
1e4725e5 70 Src += ('a' - 'A');\r
7618784b
HW
71 }\r
72\r
73 if ((Dst >= 'A') && (Dst <= 'Z')) {\r
1e4725e5 74 Dst += ('a' - 'A');\r
7618784b
HW
75 }\r
76\r
77 if (Src != Dst) {\r
78 break;\r
79 }\r
80\r
81 String++;\r
82 SearchStringTmp++;\r
83 }\r
84\r
85 if (*SearchStringTmp == '\0') {\r
86 return (CHAR8 *) FirstMatch;\r
87 }\r
88\r
89 String = FirstMatch + 1;\r
90 }\r
91\r
92 return NULL;\r
93}\r
94\r
95/**\r
96 The callback function to free the net buffer list.\r
97\r
98 @param[in] Arg The opaque parameter.\r
99\r
100**/\r
101VOID\r
102EFIAPI\r
103FreeNbufList (\r
104 IN VOID *Arg\r
105 )\r
106{\r
107 ASSERT (Arg != NULL);\r
108\r
109 NetbufFreeList ((LIST_ENTRY *) Arg);\r
110 FreePool (Arg);\r
111}\r
112\r
113/**\r
114 Check whether the Url is from Https.\r
115\r
116 @param[in] Url The pointer to a HTTP or HTTPS URL string.\r
117\r
118 @retval TRUE The Url is from HTTPS.\r
119 @retval FALSE The Url is from HTTP.\r
120\r
121**/\r
122BOOLEAN\r
123IsHttpsUrl (\r
124 IN CHAR8 *Url\r
125 )\r
126{\r
127 CHAR8 *Tmp;\r
128\r
129 Tmp = NULL;\r
130\r
131 Tmp = AsciiStrCaseStr (Url, HTTPS_FLAG);\r
132 if (Tmp != NULL && Tmp == Url) {\r
133 return TRUE;\r
134 }\r
135\r
136 return FALSE;\r
137}\r
138\r
139/**\r
140 Creates a Tls child handle, open EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL.\r
141\r
142 @param[in] ImageHandle The firmware allocated handle for the UEFI image.\r
45ea8a0c 143 @param[out] TlsSb Pointer to the TLS SERVICE_BINDING_PROTOCOL.\r
7618784b
HW
144 @param[out] TlsProto Pointer to the EFI_TLS_PROTOCOL instance.\r
145 @param[out] TlsConfiguration Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.\r
146\r
147 @return The child handle with opened EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL.\r
148\r
149**/\r
150EFI_HANDLE\r
151EFIAPI\r
152TlsCreateChild (\r
153 IN EFI_HANDLE ImageHandle,\r
45ea8a0c 154 OUT EFI_SERVICE_BINDING_PROTOCOL **TlsSb,\r
7618784b
HW
155 OUT EFI_TLS_PROTOCOL **TlsProto,\r
156 OUT EFI_TLS_CONFIGURATION_PROTOCOL **TlsConfiguration\r
157 )\r
158{\r
159 EFI_STATUS Status;\r
7618784b
HW
160 EFI_HANDLE TlsChildHandle;\r
161\r
7618784b
HW
162 TlsChildHandle = 0;\r
163\r
164 //\r
165 // Locate TlsServiceBinding protocol.\r
166 //\r
167 gBS->LocateProtocol (\r
168 &gEfiTlsServiceBindingProtocolGuid,\r
169 NULL,\r
45ea8a0c 170 (VOID **) TlsSb\r
7618784b 171 );\r
45ea8a0c 172 if (*TlsSb == NULL) {\r
7618784b
HW
173 return NULL;\r
174 }\r
175\r
45ea8a0c 176 Status = (*TlsSb)->CreateChild (*TlsSb, &TlsChildHandle);\r
7618784b
HW
177 if (EFI_ERROR (Status)) {\r
178 return NULL;\r
179 }\r
180\r
181 Status = gBS->OpenProtocol (\r
182 TlsChildHandle,\r
183 &gEfiTlsProtocolGuid,\r
184 (VOID **) TlsProto,\r
185 ImageHandle,\r
186 TlsChildHandle,\r
187 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
188 );\r
189 if (EFI_ERROR (Status)) {\r
45ea8a0c 190 (*TlsSb)->DestroyChild (*TlsSb, TlsChildHandle);\r
7618784b
HW
191 return NULL;\r
192 }\r
193\r
194 Status = gBS->OpenProtocol (\r
195 TlsChildHandle,\r
196 &gEfiTlsConfigurationProtocolGuid,\r
197 (VOID **) TlsConfiguration,\r
198 ImageHandle,\r
199 TlsChildHandle,\r
200 EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
201 );\r
202 if (EFI_ERROR (Status)) {\r
45ea8a0c 203 (*TlsSb)->DestroyChild (*TlsSb, TlsChildHandle);\r
7618784b
HW
204 return NULL;\r
205 }\r
206\r
207 return TlsChildHandle;\r
208}\r
209\r
210/**\r
211 Create event for the TLS receive and transmit tokens which are used to receive and\r
212 transmit TLS related messages.\r
213\r
214 @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.\r
215\r
216 @retval EFI_SUCCESS The events are created successfully.\r
217 @retval others Other error as indicated.\r
218\r
219**/\r
220EFI_STATUS\r
221EFIAPI\r
222TlsCreateTxRxEvent (\r
223 IN OUT HTTP_PROTOCOL *HttpInstance\r
224 )\r
225{\r
226 EFI_STATUS Status;\r
227\r
228 if (!HttpInstance->LocalAddressIsIPv6) {\r
229 //\r
230 // For Tcp4TlsTxToken.\r
231 //\r
232 Status = gBS->CreateEvent (\r
233 EVT_NOTIFY_SIGNAL,\r
234 TPL_NOTIFY,\r
235 HttpCommonNotify,\r
236 &HttpInstance->TlsIsTxDone,\r
237 &HttpInstance->Tcp4TlsTxToken.CompletionToken.Event\r
238 );\r
239 if (EFI_ERROR (Status)) {\r
240 goto ERROR;\r
241 }\r
242\r
243 HttpInstance->Tcp4TlsTxData.Push = TRUE;\r
244 HttpInstance->Tcp4TlsTxData.Urgent = FALSE;\r
245 HttpInstance->Tcp4TlsTxData.DataLength = 0;\r
246 HttpInstance->Tcp4TlsTxData.FragmentCount = 1;\r
247 HttpInstance->Tcp4TlsTxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp4TlsTxData.DataLength;\r
248 HttpInstance->Tcp4TlsTxData.FragmentTable[0].FragmentBuffer = NULL;\r
249 HttpInstance->Tcp4TlsTxToken.Packet.TxData = &HttpInstance->Tcp4TlsTxData;\r
250 HttpInstance->Tcp4TlsTxToken.CompletionToken.Status = EFI_NOT_READY;\r
251\r
252 //\r
253 // For Tcp4TlsRxToken.\r
254 //\r
255 Status = gBS->CreateEvent (\r
256 EVT_NOTIFY_SIGNAL,\r
257 TPL_NOTIFY,\r
258 HttpCommonNotify,\r
259 &HttpInstance->TlsIsRxDone,\r
260 &HttpInstance->Tcp4TlsRxToken.CompletionToken.Event\r
261 );\r
262 if (EFI_ERROR (Status)) {\r
263 goto ERROR;\r
264 }\r
265\r
266 HttpInstance->Tcp4TlsRxData.DataLength = 0;\r
267 HttpInstance->Tcp4TlsRxData.FragmentCount = 1;\r
268 HttpInstance->Tcp4TlsRxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp4TlsRxData.DataLength ;\r
269 HttpInstance->Tcp4TlsRxData.FragmentTable[0].FragmentBuffer = NULL;\r
270 HttpInstance->Tcp4TlsRxToken.Packet.RxData = &HttpInstance->Tcp4TlsRxData;\r
271 HttpInstance->Tcp4TlsRxToken.CompletionToken.Status = EFI_NOT_READY;\r
272 } else {\r
273 //\r
274 // For Tcp6TlsTxToken.\r
275 //\r
276 Status = gBS->CreateEvent (\r
277 EVT_NOTIFY_SIGNAL,\r
278 TPL_NOTIFY,\r
279 HttpCommonNotify,\r
280 &HttpInstance->TlsIsTxDone,\r
281 &HttpInstance->Tcp6TlsTxToken.CompletionToken.Event\r
282 );\r
283 if (EFI_ERROR (Status)) {\r
284 goto ERROR;\r
285 }\r
286\r
287 HttpInstance->Tcp6TlsTxData.Push = TRUE;\r
288 HttpInstance->Tcp6TlsTxData.Urgent = FALSE;\r
289 HttpInstance->Tcp6TlsTxData.DataLength = 0;\r
290 HttpInstance->Tcp6TlsTxData.FragmentCount = 1;\r
291 HttpInstance->Tcp6TlsTxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp6TlsTxData.DataLength;\r
292 HttpInstance->Tcp6TlsTxData.FragmentTable[0].FragmentBuffer = NULL;\r
293 HttpInstance->Tcp6TlsTxToken.Packet.TxData = &HttpInstance->Tcp6TlsTxData;\r
294 HttpInstance->Tcp6TlsTxToken.CompletionToken.Status = EFI_NOT_READY;\r
295\r
296 //\r
297 // For Tcp6TlsRxToken.\r
298 //\r
299 Status = gBS->CreateEvent (\r
300 EVT_NOTIFY_SIGNAL,\r
301 TPL_NOTIFY,\r
302 HttpCommonNotify,\r
303 &HttpInstance->TlsIsRxDone,\r
304 &HttpInstance->Tcp6TlsRxToken.CompletionToken.Event\r
305 );\r
306 if (EFI_ERROR (Status)) {\r
307 goto ERROR;\r
308 }\r
309\r
310 HttpInstance->Tcp6TlsRxData.DataLength = 0;\r
311 HttpInstance->Tcp6TlsRxData.FragmentCount = 1;\r
312 HttpInstance->Tcp6TlsRxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp6TlsRxData.DataLength ;\r
313 HttpInstance->Tcp6TlsRxData.FragmentTable[0].FragmentBuffer = NULL;\r
314 HttpInstance->Tcp6TlsRxToken.Packet.RxData = &HttpInstance->Tcp6TlsRxData;\r
315 HttpInstance->Tcp6TlsRxToken.CompletionToken.Status = EFI_NOT_READY;\r
316 }\r
317\r
318 return Status;\r
319\r
320ERROR:\r
321 //\r
322 // Error handling\r
323 //\r
324 TlsCloseTxRxEvent (HttpInstance);\r
325\r
326 return Status;\r
327}\r
328\r
329/**\r
330 Close events in the TlsTxToken and TlsRxToken.\r
331\r
332 @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.\r
333\r
334**/\r
335VOID\r
336EFIAPI\r
337TlsCloseTxRxEvent (\r
338 IN HTTP_PROTOCOL *HttpInstance\r
339 )\r
340{\r
341 ASSERT (HttpInstance != NULL);\r
342 if (!HttpInstance->LocalAddressIsIPv6) {\r
343 if (NULL != HttpInstance->Tcp4TlsTxToken.CompletionToken.Event) {\r
344 gBS->CloseEvent(HttpInstance->Tcp4TlsTxToken.CompletionToken.Event);\r
345 HttpInstance->Tcp4TlsTxToken.CompletionToken.Event = NULL;\r
346 }\r
347\r
348 if (NULL != HttpInstance->Tcp4TlsRxToken.CompletionToken.Event) {\r
349 gBS->CloseEvent (HttpInstance->Tcp4TlsRxToken.CompletionToken.Event);\r
350 HttpInstance->Tcp4TlsRxToken.CompletionToken.Event = NULL;\r
351 }\r
352 } else {\r
353 if (NULL != HttpInstance->Tcp6TlsTxToken.CompletionToken.Event) {\r
354 gBS->CloseEvent(HttpInstance->Tcp6TlsTxToken.CompletionToken.Event);\r
355 HttpInstance->Tcp6TlsTxToken.CompletionToken.Event = NULL;\r
356 }\r
357\r
358 if (NULL != HttpInstance->Tcp6TlsRxToken.CompletionToken.Event) {\r
359 gBS->CloseEvent (HttpInstance->Tcp6TlsRxToken.CompletionToken.Event);\r
360 HttpInstance->Tcp6TlsRxToken.CompletionToken.Event = NULL;\r
361 }\r
362 }\r
363}\r
364\r
365/**\r
366 Read the TlsCaCertificate variable and configure it.\r
367\r
368 @param[in, out] HttpInstance The HTTP instance private data.\r
369\r
370 @retval EFI_SUCCESS TlsCaCertificate is configured.\r
371 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.\r
372 @retval EFI_NOT_FOUND Fail to get 'TlsCaCertificate' variable.\r
373 @retval Others Other error as indicated.\r
374\r
375**/\r
376EFI_STATUS\r
377TlsConfigCertificate (\r
378 IN OUT HTTP_PROTOCOL *HttpInstance\r
379 )\r
380{\r
381 EFI_STATUS Status;\r
382 UINT8 *CACert;\r
383 UINTN CACertSize;\r
384 UINT32 Index;\r
385 EFI_SIGNATURE_LIST *CertList;\r
386 EFI_SIGNATURE_DATA *Cert;\r
387 UINTN CertCount;\r
388 UINT32 ItemDataSize;\r
389\r
390 CACert = NULL;\r
391 CACertSize = 0;\r
392\r
393 //\r
394 // Try to read the TlsCaCertificate variable.\r
395 //\r
396 Status = gRT->GetVariable (\r
397 EFI_TLS_CA_CERTIFICATE_VARIABLE,\r
398 &gEfiTlsCaCertificateGuid,\r
399 NULL,\r
400 &CACertSize,\r
401 NULL\r
402 );\r
403\r
404 if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {\r
405 return Status;\r
406 }\r
407\r
408 //\r
409 // Allocate buffer and read the config variable.\r
410 //\r
411 CACert = AllocatePool (CACertSize);\r
412 if (CACert == NULL) {\r
413 return EFI_OUT_OF_RESOURCES;\r
414 }\r
415\r
416 Status = gRT->GetVariable (\r
417 EFI_TLS_CA_CERTIFICATE_VARIABLE,\r
418 &gEfiTlsCaCertificateGuid,\r
419 NULL,\r
420 &CACertSize,\r
421 CACert\r
422 );\r
423 if (EFI_ERROR (Status)) {\r
424 //\r
425 // GetVariable still error or the variable is corrupted.\r
426 // Fall back to the default value.\r
427 //\r
428 FreePool (CACert);\r
429\r
430 return EFI_NOT_FOUND;\r
431 }\r
432\r
433 ASSERT (CACert != NULL);\r
434\r
435 //\r
436 // Enumerate all data and erasing the target item.\r
437 //\r
438 ItemDataSize = (UINT32) CACertSize;\r
439 CertList = (EFI_SIGNATURE_LIST *) CACert;\r
440 while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {\r
441 Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);\r
442 CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;\r
443 for (Index = 0; Index < CertCount; Index++) {\r
444 //\r
445 // EfiTlsConfigDataTypeCACertificate\r
446 //\r
447 Status = HttpInstance->TlsConfiguration->SetData (\r
448 HttpInstance->TlsConfiguration,\r
449 EfiTlsConfigDataTypeCACertificate,\r
450 Cert->SignatureData,\r
451 CertList->SignatureSize - sizeof (Cert->SignatureOwner)\r
452 );\r
453 if (EFI_ERROR (Status)) {\r
454 FreePool (CACert);\r
455 return Status;\r
456 }\r
457\r
458 Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);\r
459 }\r
460\r
461 ItemDataSize -= CertList->SignatureListSize;\r
462 CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);\r
463 }\r
464\r
465 FreePool (CACert);\r
466 return Status;\r
467}\r
468\r
7ff68b5e
JW
469/**\r
470 Read the HttpTlsCipherList variable and configure it for HTTPS session.\r
471\r
472 @param[in, out] HttpInstance The HTTP instance private data.\r
473\r
474 @retval EFI_SUCCESS The prefered HTTP TLS CipherList is configured.\r
475 @retval EFI_NOT_FOUND Fail to get 'HttpTlsCipherList' variable.\r
476 @retval EFI_INVALID_PARAMETER The contents of variable are invalid.\r
477 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.\r
478\r
479 @retval Others Other error as indicated.\r
480\r
481**/\r
482EFI_STATUS\r
483TlsConfigCipherList (\r
484 IN OUT HTTP_PROTOCOL *HttpInstance\r
485 )\r
486{\r
487 EFI_STATUS Status;\r
488 UINT8 *CipherList;\r
489 UINTN CipherListSize;\r
490\r
491 CipherList = NULL;\r
492 CipherListSize = 0;\r
493\r
494 //\r
495 // Try to read the HttpTlsCipherList variable.\r
496 //\r
497 Status = gRT->GetVariable (\r
498 EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE,\r
499 &gEdkiiHttpTlsCipherListGuid,\r
500 NULL,\r
501 &CipherListSize,\r
502 NULL\r
503 );\r
504 ASSERT (EFI_ERROR (Status));\r
505 if (Status != EFI_BUFFER_TOO_SMALL) {\r
506 return Status;\r
507 }\r
508\r
509 if (CipherListSize % sizeof (EFI_TLS_CIPHER) != 0) {\r
510 return EFI_INVALID_PARAMETER;\r
511 }\r
512\r
513 //\r
514 // Allocate buffer and read the config variable.\r
515 //\r
516 CipherList = AllocatePool (CipherListSize);\r
517 if (CipherList == NULL) {\r
518 return EFI_OUT_OF_RESOURCES;\r
519 }\r
520\r
521 Status = gRT->GetVariable (\r
522 EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE,\r
523 &gEdkiiHttpTlsCipherListGuid,\r
524 NULL,\r
525 &CipherListSize,\r
526 CipherList\r
527 );\r
528 if (EFI_ERROR (Status)) {\r
529 //\r
530 // GetVariable still error or the variable is corrupted.\r
531 //\r
532 goto ON_EXIT;\r
533 }\r
534\r
535 ASSERT (CipherList != NULL);\r
536\r
537 Status = HttpInstance->Tls->SetSessionData (\r
538 HttpInstance->Tls,\r
539 EfiTlsCipherList,\r
540 CipherList,\r
541 CipherListSize\r
542 );\r
543\r
544ON_EXIT: \r
545 FreePool (CipherList);\r
546 \r
547 return Status;\r
548}\r
549\r
7618784b
HW
550/**\r
551 Configure TLS session data.\r
552\r
553 @param[in, out] HttpInstance The HTTP instance private data.\r
554\r
555 @retval EFI_SUCCESS TLS session data is configured.\r
556 @retval Others Other error as indicated.\r
557\r
558**/\r
559EFI_STATUS\r
560EFIAPI\r
561TlsConfigureSession (\r
562 IN OUT HTTP_PROTOCOL *HttpInstance\r
563 )\r
564{\r
565 EFI_STATUS Status;\r
566\r
567 //\r
568 // TlsConfigData initialization\r
569 //\r
570 HttpInstance->TlsConfigData.ConnectionEnd = EfiTlsClient;\r
571 HttpInstance->TlsConfigData.VerifyMethod = EFI_TLS_VERIFY_PEER;\r
572 HttpInstance->TlsConfigData.SessionState = EfiTlsSessionNotStarted;\r
573\r
574 //\r
575 // EfiTlsConnectionEnd,\r
576 // EfiTlsVerifyMethod\r
577 // EfiTlsSessionState\r
578 //\r
579 Status = HttpInstance->Tls->SetSessionData (\r
580 HttpInstance->Tls,\r
581 EfiTlsConnectionEnd,\r
582 &(HttpInstance->TlsConfigData.ConnectionEnd),\r
583 sizeof (EFI_TLS_CONNECTION_END)\r
584 );\r
585 if (EFI_ERROR (Status)) {\r
586 return Status;\r
587 }\r
588\r
589 Status = HttpInstance->Tls->SetSessionData (\r
590 HttpInstance->Tls,\r
591 EfiTlsVerifyMethod,\r
592 &HttpInstance->TlsConfigData.VerifyMethod,\r
593 sizeof (EFI_TLS_VERIFY)\r
594 );\r
595 if (EFI_ERROR (Status)) {\r
596 return Status;\r
597 }\r
598\r
599 Status = HttpInstance->Tls->SetSessionData (\r
600 HttpInstance->Tls,\r
601 EfiTlsSessionState,\r
602 &(HttpInstance->TlsConfigData.SessionState),\r
603 sizeof (EFI_TLS_SESSION_STATE)\r
604 );\r
605 if (EFI_ERROR (Status)) {\r
606 return Status;\r
607 }\r
608\r
7ff68b5e
JW
609 //\r
610 // Tls Cipher List\r
611 //\r
612 Status = TlsConfigCipherList (HttpInstance);\r
613 if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) {\r
614 DEBUG ((EFI_D_ERROR, "TlsConfigCipherList: return %r error.\n", Status));\r
615 return Status;\r
616 }\r
617\r
7618784b
HW
618 //\r
619 // Tls Config Certificate\r
620 //\r
621 Status = TlsConfigCertificate (HttpInstance);\r
622 if (EFI_ERROR (Status)) {\r
623 DEBUG ((EFI_D_ERROR, "TLS Certificate Config Error!\n"));\r
624 return Status;\r
625 }\r
626\r
627 //\r
628 // TlsCreateTxRxEvent\r
629 //\r
630 Status = TlsCreateTxRxEvent (HttpInstance);\r
631 if (EFI_ERROR (Status)) {\r
632 goto ERROR;\r
633 }\r
634\r
635 return Status;\r
636\r
637ERROR:\r
638 TlsCloseTxRxEvent (HttpInstance);\r
639\r
640 return Status;\r
641}\r
642\r
643/**\r
644 Transmit the Packet by processing the associated HTTPS token.\r
645\r
646 @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.\r
647 @param[in] Packet The packet to transmit.\r
648\r
649 @retval EFI_SUCCESS The packet is transmitted.\r
650 @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.\r
651 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.\r
652 @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.\r
653 @retval Others Other errors as indicated.\r
654\r
655**/\r
656EFI_STATUS\r
657EFIAPI\r
658TlsCommonTransmit (\r
659 IN OUT HTTP_PROTOCOL *HttpInstance,\r
660 IN NET_BUF *Packet\r
661 )\r
662{\r
663 EFI_STATUS Status;\r
664 VOID *Data;\r
665 UINTN Size;\r
666\r
667 if ((HttpInstance == NULL) || (Packet == NULL)) {\r
668 return EFI_INVALID_PARAMETER;\r
669 }\r
670\r
671 if (!HttpInstance->LocalAddressIsIPv6) {\r
672 Size = sizeof (EFI_TCP4_TRANSMIT_DATA) +\r
673 (Packet->BlockOpNum - 1) * sizeof (EFI_TCP4_FRAGMENT_DATA);\r
674 } else {\r
675 Size = sizeof (EFI_TCP6_TRANSMIT_DATA) +\r
676 (Packet->BlockOpNum - 1) * sizeof (EFI_TCP6_FRAGMENT_DATA);\r
677 }\r
678\r
679 Data = AllocatePool (Size);\r
680 if (Data == NULL) {\r
681 return EFI_OUT_OF_RESOURCES;\r
682 }\r
683\r
684 if (!HttpInstance->LocalAddressIsIPv6) {\r
685 ((EFI_TCP4_TRANSMIT_DATA *) Data)->Push = TRUE;\r
686 ((EFI_TCP4_TRANSMIT_DATA *) Data)->Urgent = FALSE;\r
687 ((EFI_TCP4_TRANSMIT_DATA *) Data)->DataLength = Packet->TotalSize;\r
688\r
689 //\r
690 // Build the fragment table.\r
691 //\r
692 ((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentCount = Packet->BlockOpNum;\r
693\r
694 NetbufBuildExt (\r
695 Packet,\r
696 (NET_FRAGMENT *) &((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentTable[0],\r
697 &((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentCount\r
698 );\r
699\r
700 HttpInstance->Tcp4TlsTxToken.Packet.TxData = (EFI_TCP4_TRANSMIT_DATA *) Data;\r
701\r
702 Status = EFI_DEVICE_ERROR;\r
703\r
704 //\r
705 // Transmit the packet.\r
706 //\r
707 Status = HttpInstance->Tcp4->Transmit (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsTxToken);\r
708 if (EFI_ERROR (Status)) {\r
709 goto ON_EXIT;\r
710 }\r
711\r
712 while (!HttpInstance->TlsIsTxDone) {\r
713 HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);\r
714 }\r
715\r
716 HttpInstance->TlsIsTxDone = FALSE;\r
717 Status = HttpInstance->Tcp4TlsTxToken.CompletionToken.Status;\r
718 } else {\r
719 ((EFI_TCP6_TRANSMIT_DATA *) Data)->Push = TRUE;\r
720 ((EFI_TCP6_TRANSMIT_DATA *) Data)->Urgent = FALSE;\r
721 ((EFI_TCP6_TRANSMIT_DATA *) Data)->DataLength = Packet->TotalSize;\r
722\r
723 //\r
724 // Build the fragment table.\r
725 //\r
726 ((EFI_TCP6_TRANSMIT_DATA *) Data)->FragmentCount = Packet->BlockOpNum;\r
727\r
728 NetbufBuildExt (\r
729 Packet,\r
730 (NET_FRAGMENT *) &((EFI_TCP6_TRANSMIT_DATA *) Data)->FragmentTable[0],\r
731 &((EFI_TCP6_TRANSMIT_DATA *) Data)->FragmentCount\r
732 );\r
733\r
734 HttpInstance->Tcp6TlsTxToken.Packet.TxData = (EFI_TCP6_TRANSMIT_DATA *) Data;\r
735\r
736 Status = EFI_DEVICE_ERROR;\r
737\r
738 //\r
739 // Transmit the packet.\r
740 //\r
741 Status = HttpInstance->Tcp6->Transmit (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsTxToken);\r
742 if (EFI_ERROR (Status)) {\r
743 goto ON_EXIT;\r
744 }\r
745\r
746 while (!HttpInstance->TlsIsTxDone) {\r
747 HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);\r
748 }\r
749\r
750 HttpInstance->TlsIsTxDone = FALSE;\r
751 Status = HttpInstance->Tcp6TlsTxToken.CompletionToken.Status;\r
752 }\r
753\r
754ON_EXIT:\r
755 FreePool (Data);\r
756\r
757 return Status;\r
758}\r
759\r
760/**\r
761 Receive the Packet by processing the associated HTTPS token.\r
762\r
763 @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.\r
764 @param[in] Packet The packet to transmit.\r
765 @param[in] Timeout The time to wait for connection done.\r
766\r
767 @retval EFI_SUCCESS The Packet is received.\r
768 @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.\r
769 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.\r
770 @retval EFI_TIMEOUT The operation is time out.\r
771 @retval Others Other error as indicated.\r
772\r
773**/\r
774EFI_STATUS\r
775EFIAPI\r
776TlsCommonReceive (\r
777 IN OUT HTTP_PROTOCOL *HttpInstance,\r
778 IN NET_BUF *Packet,\r
779 IN EFI_EVENT Timeout\r
780 )\r
781{\r
782 EFI_TCP4_RECEIVE_DATA *Tcp4RxData;\r
783 EFI_TCP6_RECEIVE_DATA *Tcp6RxData;\r
784 EFI_STATUS Status;\r
785 NET_FRAGMENT *Fragment;\r
786 UINT32 FragmentCount;\r
787 UINT32 CurrentFragment;\r
788\r
789 Tcp4RxData = NULL;\r
790 Tcp6RxData = NULL;\r
791\r
792 if ((HttpInstance == NULL) || (Packet == NULL)) {\r
793 return EFI_INVALID_PARAMETER;\r
794 }\r
795\r
796 FragmentCount = Packet->BlockOpNum;\r
797 Fragment = AllocatePool (FragmentCount * sizeof (NET_FRAGMENT));\r
798 if (Fragment == NULL) {\r
799 Status = EFI_OUT_OF_RESOURCES;\r
800 goto ON_EXIT;\r
801 }\r
802\r
803 //\r
804 // Build the fragment table.\r
805 //\r
806 NetbufBuildExt (Packet, Fragment, &FragmentCount);\r
807\r
808 if (!HttpInstance->LocalAddressIsIPv6) {\r
809 Tcp4RxData = HttpInstance->Tcp4TlsRxToken.Packet.RxData;\r
810 if (Tcp4RxData == NULL) {\r
811 return EFI_INVALID_PARAMETER;\r
812 }\r
813 Tcp4RxData->FragmentCount = 1;\r
814 } else {\r
815 Tcp6RxData = HttpInstance->Tcp6TlsRxToken.Packet.RxData;\r
816 if (Tcp6RxData == NULL) {\r
817 return EFI_INVALID_PARAMETER;\r
818 }\r
819 Tcp6RxData->FragmentCount = 1;\r
820 }\r
821\r
822 CurrentFragment = 0;\r
823 Status = EFI_SUCCESS;\r
824\r
825 while (CurrentFragment < FragmentCount) {\r
826 if (!HttpInstance->LocalAddressIsIPv6) {\r
827 Tcp4RxData->DataLength = Fragment[CurrentFragment].Len;\r
828 Tcp4RxData->FragmentTable[0].FragmentLength = Fragment[CurrentFragment].Len;\r
829 Tcp4RxData->FragmentTable[0].FragmentBuffer = Fragment[CurrentFragment].Bulk;\r
830 Status = HttpInstance->Tcp4->Receive (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsRxToken);\r
831 } else {\r
832 Tcp6RxData->DataLength = Fragment[CurrentFragment].Len;\r
833 Tcp6RxData->FragmentTable[0].FragmentLength = Fragment[CurrentFragment].Len;\r
834 Tcp6RxData->FragmentTable[0].FragmentBuffer = Fragment[CurrentFragment].Bulk;\r
835 Status = HttpInstance->Tcp6->Receive (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsRxToken);\r
836 }\r
837 if (EFI_ERROR (Status)) {\r
838 goto ON_EXIT;\r
839 }\r
840\r
841 while (!HttpInstance->TlsIsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {\r
842 //\r
843 // Poll until some data is received or an error occurs.\r
844 //\r
845 if (!HttpInstance->LocalAddressIsIPv6) {\r
846 HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);\r
847 } else {\r
848 HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);\r
849 }\r
850 }\r
851\r
852 if (!HttpInstance->TlsIsRxDone) {\r
853 //\r
854 // Timeout occurs, cancel the receive request.\r
855 //\r
856 if (!HttpInstance->LocalAddressIsIPv6) {\r
857 HttpInstance->Tcp4->Cancel (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsRxToken.CompletionToken);\r
858 } else {\r
859 HttpInstance->Tcp6->Cancel (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsRxToken.CompletionToken);\r
860 }\r
861\r
862 Status = EFI_TIMEOUT;\r
863 goto ON_EXIT;\r
864 } else {\r
865 HttpInstance->TlsIsRxDone = FALSE;\r
866 }\r
867\r
868 if (!HttpInstance->LocalAddressIsIPv6) {\r
869 Status = HttpInstance->Tcp4TlsRxToken.CompletionToken.Status;\r
870 if (EFI_ERROR (Status)) {\r
871 goto ON_EXIT;\r
872 }\r
873\r
874 Fragment[CurrentFragment].Len -= Tcp4RxData->FragmentTable[0].FragmentLength;\r
875 if (Fragment[CurrentFragment].Len == 0) {\r
876 CurrentFragment++;\r
877 } else {\r
878 Fragment[CurrentFragment].Bulk += Tcp4RxData->FragmentTable[0].FragmentLength;\r
879 }\r
880 } else {\r
881 Status = HttpInstance->Tcp6TlsRxToken.CompletionToken.Status;\r
882 if (EFI_ERROR (Status)) {\r
883 goto ON_EXIT;\r
884 }\r
885\r
886 Fragment[CurrentFragment].Len -= Tcp6RxData->FragmentTable[0].FragmentLength;\r
887 if (Fragment[CurrentFragment].Len == 0) {\r
888 CurrentFragment++;\r
889 } else {\r
890 Fragment[CurrentFragment].Bulk += Tcp6RxData->FragmentTable[0].FragmentLength;\r
891 }\r
892 }\r
893 }\r
894\r
895ON_EXIT:\r
896\r
897 if (Fragment != NULL) {\r
898 FreePool (Fragment);\r
899 }\r
900\r
901 return Status;\r
902}\r
903\r
904/**\r
905 Receive one TLS PDU. An TLS PDU contains an TLS record header and it's\r
906 corresponding record data. These two parts will be put into two blocks of buffers in the\r
907 net buffer.\r
908\r
909 @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.\r
910 @param[out] Pdu The received TLS PDU.\r
911 @param[in] Timeout The time to wait for connection done.\r
912\r
913 @retval EFI_SUCCESS An TLS PDU is received.\r
914 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.\r
915 @retval EFI_PROTOCOL_ERROR An unexpected TLS packet was received.\r
916 @retval Others Other errors as indicated.\r
917\r
918**/\r
919EFI_STATUS\r
920EFIAPI\r
921TlsReceiveOnePdu (\r
922 IN OUT HTTP_PROTOCOL *HttpInstance,\r
923 OUT NET_BUF **Pdu,\r
924 IN EFI_EVENT Timeout\r
925 )\r
926{\r
927 EFI_STATUS Status;\r
928\r
929 LIST_ENTRY *NbufList;\r
930\r
931 UINT32 Len;\r
932\r
933 NET_BUF *PduHdr;\r
934 UINT8 *Header;\r
935 TLS_RECORD_HEADER RecordHeader;\r
936\r
937 NET_BUF *DataSeg;\r
938\r
939 NbufList = NULL;\r
940 PduHdr = NULL;\r
941 Header = NULL;\r
942 DataSeg = NULL;\r
943\r
944 NbufList = AllocatePool (sizeof (LIST_ENTRY));\r
945 if (NbufList == NULL) {\r
946 return EFI_OUT_OF_RESOURCES;\r
947 }\r
948\r
949 InitializeListHead (NbufList);\r
950\r
951 //\r
952 // Allocate buffer to receive one TLS header.\r
953 //\r
07bd82d4 954 Len = TLS_RECORD_HEADER_LENGTH;\r
7618784b
HW
955 PduHdr = NetbufAlloc (Len);\r
956 if (PduHdr == NULL) {\r
957 Status = EFI_OUT_OF_RESOURCES;\r
958 goto ON_EXIT;\r
959 }\r
960\r
961 Header = NetbufAllocSpace (PduHdr, Len, NET_BUF_TAIL);\r
962 if (Header == NULL) {\r
963 Status = EFI_OUT_OF_RESOURCES;\r
964 goto ON_EXIT;\r
965 }\r
966\r
967 //\r
968 // First step, receive one TLS header.\r
969 //\r
970 Status = TlsCommonReceive (HttpInstance, PduHdr, Timeout);\r
971 if (EFI_ERROR (Status)) {\r
972 goto ON_EXIT;\r
973 }\r
974\r
975 RecordHeader = *(TLS_RECORD_HEADER *) Header;\r
976 if ((RecordHeader.ContentType == TlsContentTypeHandshake ||\r
977 RecordHeader.ContentType == TlsContentTypeAlert ||\r
978 RecordHeader.ContentType == TlsContentTypeChangeCipherSpec ||\r
979 RecordHeader.ContentType == TlsContentTypeApplicationData) &&\r
980 (RecordHeader.Version.Major == 0x03) && /// Major versions are same.\r
981 (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR ||\r
982 RecordHeader.Version.Minor ==TLS11_PROTOCOL_VERSION_MINOR ||\r
983 RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR)\r
984 ) {\r
985 InsertTailList (NbufList, &PduHdr->List);\r
986 } else {\r
987 Status = EFI_PROTOCOL_ERROR;\r
988 goto ON_EXIT;\r
989 }\r
990\r
991 Len = SwapBytes16(RecordHeader.Length);\r
992 if (Len == 0) {\r
993 //\r
994 // No TLS payload.\r
995 //\r
996 goto FORM_PDU;\r
997 }\r
998\r
999 //\r
1000 // Allocate buffer to receive one TLS payload.\r
1001 //\r
1002 DataSeg = NetbufAlloc (Len);\r
1003 if (DataSeg == NULL) {\r
1004 Status = EFI_OUT_OF_RESOURCES;\r
1005 goto ON_EXIT;\r
1006 }\r
1007\r
1008 NetbufAllocSpace (DataSeg, Len, NET_BUF_TAIL);\r
1009\r
1010 //\r
1011 // Second step, receive one TLS payload.\r
1012 //\r
1013 Status = TlsCommonReceive (HttpInstance, DataSeg, Timeout);\r
1014 if (EFI_ERROR (Status)) {\r
1015 goto ON_EXIT;\r
1016 }\r
1017\r
1018 InsertTailList (NbufList, &DataSeg->List);\r
1019\r
1020FORM_PDU:\r
1021 //\r
1022 // Form the PDU from a list of PDU.\r
1023 //\r
1024 *Pdu = NetbufFromBufList (NbufList, 0, 0, FreeNbufList, NbufList);\r
1025 if (*Pdu == NULL) {\r
1026 Status = EFI_OUT_OF_RESOURCES;\r
1027 }\r
1028\r
1029ON_EXIT:\r
1030\r
1031 if (EFI_ERROR (Status)) {\r
1032 //\r
1033 // Free the Nbufs in this NbufList and the NbufList itself.\r
1034 //\r
1035 FreeNbufList (NbufList);\r
1036 }\r
1037\r
1038 return Status;\r
1039}\r
1040\r
1041/**\r
1042 Connect one TLS session by finishing the TLS handshake process.\r
1043\r
1044 @param[in] HttpInstance The HTTP instance private data.\r
1045 @param[in] Timeout The time to wait for connection done.\r
1046\r
1047 @retval EFI_SUCCESS The TLS session is established.\r
1048 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.\r
1049 @retval EFI_ABORTED TLS session state is incorrect.\r
1050 @retval Others Other error as indicated.\r
1051\r
1052**/\r
1053EFI_STATUS\r
1054EFIAPI\r
1055TlsConnectSession (\r
1056 IN HTTP_PROTOCOL *HttpInstance,\r
1057 IN EFI_EVENT Timeout\r
1058 )\r
1059{\r
1060 EFI_STATUS Status;\r
1061 UINT8 *BufferOut;\r
1062 UINTN BufferOutSize;\r
1063 NET_BUF *PacketOut;\r
1064 UINT8 *DataOut;\r
1065 NET_BUF *Pdu;\r
1066 UINT8 *BufferIn;\r
1067 UINTN BufferInSize;\r
1068 UINT8 *GetSessionDataBuffer;\r
1069 UINTN GetSessionDataBufferSize;\r
1070\r
1071 BufferOut = NULL;\r
1072 PacketOut = NULL;\r
1073 DataOut = NULL;\r
1074 Pdu = NULL;\r
1075 BufferIn = NULL;\r
1076\r
1077 //\r
1078 // Initialize TLS state.\r
1079 //\r
1080 HttpInstance->TlsSessionState = EfiTlsSessionNotStarted;\r
1081 Status = HttpInstance->Tls->SetSessionData (\r
1082 HttpInstance->Tls,\r
1083 EfiTlsSessionState,\r
1084 &(HttpInstance->TlsSessionState),\r
1085 sizeof (EFI_TLS_SESSION_STATE)\r
1086 );\r
1087 if (EFI_ERROR (Status)) {\r
1088 return Status;\r
1089 }\r
1090\r
1091 //\r
1092 // Create ClientHello\r
1093 //\r
1094 BufferOutSize = DEF_BUF_LEN;\r
1095 BufferOut = AllocateZeroPool (BufferOutSize);\r
1096 if (BufferOut == NULL) {\r
1097 Status = EFI_OUT_OF_RESOURCES;\r
1098 return Status;\r
1099 }\r
1100\r
1101 Status = HttpInstance->Tls->BuildResponsePacket (\r
1102 HttpInstance->Tls,\r
1103 NULL,\r
1104 0,\r
1105 BufferOut,\r
1106 &BufferOutSize\r
1107 );\r
1108 if (Status == EFI_BUFFER_TOO_SMALL) {\r
1109 FreePool (BufferOut);\r
1110 BufferOut = AllocateZeroPool (BufferOutSize);\r
1111 if (BufferOut == NULL) {\r
1112 Status = EFI_OUT_OF_RESOURCES;\r
1113 return Status;\r
1114 }\r
1115\r
1116 Status = HttpInstance->Tls->BuildResponsePacket (\r
1117 HttpInstance->Tls,\r
1118 NULL,\r
1119 0,\r
1120 BufferOut,\r
1121 &BufferOutSize\r
1122 );\r
1123 }\r
1124 if (EFI_ERROR (Status)) {\r
1125 FreePool (BufferOut);\r
1126 return Status;\r
1127 }\r
1128\r
1129 //\r
1130 // Transmit ClientHello\r
1131 //\r
1132 PacketOut = NetbufAlloc ((UINT32) BufferOutSize);\r
1133 DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL);\r
1134 if (DataOut == NULL) {\r
1135 FreePool (BufferOut);\r
1136 return EFI_OUT_OF_RESOURCES;\r
1137 }\r
1138\r
1139 CopyMem (DataOut, BufferOut, BufferOutSize);\r
1140 Status = TlsCommonTransmit (HttpInstance, PacketOut);\r
1141\r
1142 FreePool (BufferOut);\r
1143 NetbufFree (PacketOut);\r
1144\r
1145 if (EFI_ERROR (Status)) {\r
1146 return Status;\r
1147 }\r
1148\r
1149 while(HttpInstance->TlsSessionState != EfiTlsSessionDataTransferring && \\r
1150 ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {\r
1151 //\r
1152 // Receive one TLS record.\r
1153 //\r
1154 Status = TlsReceiveOnePdu (HttpInstance, &Pdu, Timeout);\r
1155 if (EFI_ERROR (Status)) {\r
1156 return Status;\r
1157 }\r
1158\r
1159 BufferInSize = Pdu->TotalSize;\r
1160 BufferIn = AllocateZeroPool (BufferInSize);\r
1161 if (BufferIn == NULL) {\r
1162 NetbufFree (Pdu);\r
1163 Status = EFI_OUT_OF_RESOURCES;\r
1164 return Status;\r
1165 }\r
1166\r
1167 NetbufCopy (Pdu, 0, (UINT32)BufferInSize, BufferIn);\r
1168\r
1169 NetbufFree (Pdu);\r
1170\r
1171 //\r
1172 // Handle Receive data.\r
1173 //\r
1174 BufferOutSize = DEF_BUF_LEN;\r
1175 BufferOut = AllocateZeroPool (BufferOutSize);\r
1176 if (BufferOut == NULL) {\r
1177 Status = EFI_OUT_OF_RESOURCES;\r
1178 return Status;\r
1179 }\r
1180\r
1181 Status = HttpInstance->Tls->BuildResponsePacket (\r
1182 HttpInstance->Tls,\r
1183 BufferIn,\r
1184 BufferInSize,\r
1185 BufferOut,\r
1186 &BufferOutSize\r
1187 );\r
1188 if (Status == EFI_BUFFER_TOO_SMALL) {\r
1189 FreePool (BufferOut);\r
1190 BufferOut = AllocateZeroPool (BufferOutSize);\r
1191 if (BufferOut == NULL) {\r
1192 FreePool (BufferIn);\r
1193 Status = EFI_OUT_OF_RESOURCES;\r
1194 return Status;\r
1195 }\r
1196\r
1197 Status = HttpInstance->Tls->BuildResponsePacket (\r
1198 HttpInstance->Tls,\r
1199 BufferIn,\r
1200 BufferInSize,\r
1201 BufferOut,\r
1202 &BufferOutSize\r
1203 );\r
1204 }\r
1205\r
1206 FreePool (BufferIn);\r
1207\r
1208 if (EFI_ERROR (Status)) {\r
1209 FreePool (BufferOut);\r
1210 return Status;\r
1211 }\r
1212\r
1213 if (BufferOutSize != 0) {\r
1214 //\r
1215 // Transmit the response packet.\r
1216 //\r
1217 PacketOut = NetbufAlloc ((UINT32) BufferOutSize);\r
1218 DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL);\r
1219 if (DataOut == NULL) {\r
1220 FreePool (BufferOut);\r
1221 return EFI_OUT_OF_RESOURCES;\r
1222 }\r
1223\r
1224 CopyMem (DataOut, BufferOut, BufferOutSize);\r
1225\r
1226 Status = TlsCommonTransmit (HttpInstance, PacketOut);\r
1227\r
1228 NetbufFree (PacketOut);\r
1229\r
1230 if (EFI_ERROR (Status)) {\r
1231 FreePool (BufferOut);\r
1232 return Status;\r
1233 }\r
1234 }\r
1235\r
1236 FreePool (BufferOut);\r
1237\r
1238 //\r
1239 // Get the session state, then decide whether need to continue handle received packet.\r
1240 //\r
1241 GetSessionDataBufferSize = DEF_BUF_LEN;\r
1242 GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);\r
1243 if (GetSessionDataBuffer == NULL) {\r
1244 Status = EFI_OUT_OF_RESOURCES;\r
1245 return Status;\r
1246 }\r
1247\r
1248 Status = HttpInstance->Tls->GetSessionData (\r
1249 HttpInstance->Tls,\r
1250 EfiTlsSessionState,\r
1251 GetSessionDataBuffer,\r
1252 &GetSessionDataBufferSize\r
1253 );\r
1254 if (Status == EFI_BUFFER_TOO_SMALL) {\r
1255 FreePool (GetSessionDataBuffer);\r
1256 GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);\r
1257 if (GetSessionDataBuffer == NULL) {\r
1258 Status = EFI_OUT_OF_RESOURCES;\r
1259 return Status;\r
1260 }\r
1261\r
1262 Status = HttpInstance->Tls->GetSessionData (\r
1263 HttpInstance->Tls,\r
1264 EfiTlsSessionState,\r
1265 GetSessionDataBuffer,\r
1266 &GetSessionDataBufferSize\r
1267 );\r
1268 }\r
1269 if (EFI_ERROR (Status)) {\r
1270 FreePool(GetSessionDataBuffer);\r
1271 return Status;\r
1272 }\r
1273\r
1274 ASSERT(GetSessionDataBufferSize == sizeof (EFI_TLS_SESSION_STATE));\r
1275 HttpInstance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) GetSessionDataBuffer;\r
1276\r
1277 FreePool (GetSessionDataBuffer);\r
1278\r
1279 if(HttpInstance->TlsSessionState == EfiTlsSessionError) {\r
1280 return EFI_ABORTED;\r
1281 }\r
1282 }\r
1283\r
1284 if (HttpInstance->TlsSessionState != EfiTlsSessionDataTransferring) {\r
1285 Status = EFI_ABORTED;\r
1286 }\r
1287\r
1288 return Status;\r
1289}\r
1290\r
1291/**\r
1292 Close the TLS session and send out the close notification message.\r
1293\r
1294 @param[in] HttpInstance The HTTP instance private data.\r
1295\r
1296 @retval EFI_SUCCESS The TLS session is closed.\r
1297 @retval EFI_INVALID_PARAMETER HttpInstance is NULL.\r
1298 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.\r
1299 @retval Others Other error as indicated.\r
1300\r
1301**/\r
1302EFI_STATUS\r
1303EFIAPI\r
1304TlsCloseSession (\r
1305 IN HTTP_PROTOCOL *HttpInstance\r
1306 )\r
1307{\r
1308 EFI_STATUS Status;\r
1309\r
1310 UINT8 *BufferOut;\r
1311 UINTN BufferOutSize;\r
1312\r
1313 NET_BUF *PacketOut;\r
1314 UINT8 *DataOut;\r
1315\r
1316 Status = EFI_SUCCESS;\r
1317 BufferOut = NULL;\r
1318 PacketOut = NULL;\r
1319 DataOut = NULL;\r
1320\r
1321 if (HttpInstance == NULL) {\r
1322 return EFI_INVALID_PARAMETER;\r
1323 }\r
1324\r
1325 HttpInstance->TlsSessionState = EfiTlsSessionClosing;\r
1326\r
1327 Status = HttpInstance->Tls->SetSessionData (\r
1328 HttpInstance->Tls,\r
1329 EfiTlsSessionState,\r
1330 &(HttpInstance->TlsSessionState),\r
1331 sizeof (EFI_TLS_SESSION_STATE)\r
1332 );\r
1333 if (EFI_ERROR (Status)) {\r
1334 return Status;\r
1335 }\r
1336\r
1337 BufferOutSize = DEF_BUF_LEN;\r
1338 BufferOut = AllocateZeroPool (BufferOutSize);\r
1339 if (BufferOut == NULL) {\r
1340 Status = EFI_OUT_OF_RESOURCES;\r
1341 return Status;\r
1342 }\r
1343\r
1344 Status = HttpInstance->Tls->BuildResponsePacket (\r
1345 HttpInstance->Tls,\r
1346 NULL,\r
1347 0,\r
1348 BufferOut,\r
1349 &BufferOutSize\r
1350 );\r
1351 if (Status == EFI_BUFFER_TOO_SMALL) {\r
1352 FreePool (BufferOut);\r
1353 BufferOut = AllocateZeroPool (BufferOutSize);\r
1354 if (BufferOut == NULL) {\r
1355 Status = EFI_OUT_OF_RESOURCES;\r
1356 return Status;\r
1357 }\r
1358\r
1359 Status = HttpInstance->Tls->BuildResponsePacket (\r
1360 HttpInstance->Tls,\r
1361 NULL,\r
1362 0,\r
1363 BufferOut,\r
1364 &BufferOutSize\r
1365 );\r
1366 }\r
1367\r
1368 if (EFI_ERROR (Status)) {\r
1369 FreePool (BufferOut);\r
1370 return Status;\r
1371 }\r
1372\r
1373 PacketOut = NetbufAlloc ((UINT32) BufferOutSize);\r
1374 DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL);\r
1375 if (DataOut == NULL) {\r
1376 FreePool (BufferOut);\r
1377 return EFI_OUT_OF_RESOURCES;\r
1378 }\r
1379\r
1380 CopyMem (DataOut, BufferOut, BufferOutSize);\r
1381\r
1382 Status = TlsCommonTransmit (HttpInstance, PacketOut);\r
1383\r
1384 FreePool (BufferOut);\r
1385 NetbufFree (PacketOut);\r
1386\r
1387 return Status;\r
1388}\r
1389\r
1390/**\r
1391 Process one message according to the CryptMode.\r
1392\r
1393 @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.\r
07bd82d4
JW
1394 @param[in] Message Pointer to the message buffer needed to processed. \r
1395 If ProcessMode is EfiTlsEncrypt, the message contain the TLS\r
1396 header and plain text TLS APP payload.\r
1397 If ProcessMode is EfiTlsDecrypt, the message contain the TLS \r
1398 header and cipher text TLS APP payload.\r
7618784b
HW
1399 @param[in] MessageSize Pointer to the message buffer size.\r
1400 @param[in] ProcessMode Process mode.\r
1401 @param[in, out] Fragment Only one Fragment returned after the Message is\r
1402 processed successfully.\r
07bd82d4
JW
1403 If ProcessMode is EfiTlsEncrypt, the fragment contain the TLS \r
1404 header and cipher text TLS APP payload.\r
1405 If ProcessMode is EfiTlsDecrypt, the fragment contain the TLS \r
1406 header and plain text TLS APP payload.\r
7618784b
HW
1407\r
1408 @retval EFI_SUCCESS Message is processed successfully.\r
1409 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.\r
1410 @retval Others Other errors as indicated.\r
1411\r
1412**/\r
1413EFI_STATUS\r
1414EFIAPI\r
1415TlsProcessMessage (\r
1416 IN HTTP_PROTOCOL *HttpInstance,\r
1417 IN UINT8 *Message,\r
1418 IN UINTN MessageSize,\r
1419 IN EFI_TLS_CRYPT_MODE ProcessMode,\r
1420 IN OUT NET_FRAGMENT *Fragment\r
1421 )\r
1422{\r
1423 EFI_STATUS Status;\r
1424 UINT8 *Buffer;\r
1425 UINT32 BufferSize;\r
1426 UINT32 BytesCopied;\r
1427 EFI_TLS_FRAGMENT_DATA *FragmentTable;\r
1428 UINT32 FragmentCount;\r
1429 EFI_TLS_FRAGMENT_DATA *OriginalFragmentTable;\r
1430 UINTN Index;\r
1431\r
1432 Status = EFI_SUCCESS;\r
1433 Buffer = NULL;\r
1434 BufferSize = 0;\r
1435 BytesCopied = 0;\r
1436 FragmentTable = NULL;\r
1437 OriginalFragmentTable = NULL;\r
1438\r
1439 //\r
1440 // Rebuild fragment table from BufferIn.\r
1441 //\r
1442 FragmentCount = 1;\r
1443 FragmentTable = AllocateZeroPool (FragmentCount * sizeof (EFI_TLS_FRAGMENT_DATA));\r
1444 if (FragmentTable == NULL) {\r
1445 Status = EFI_OUT_OF_RESOURCES;\r
1446 goto ON_EXIT;\r
1447 }\r
1448\r
1449 FragmentTable->FragmentLength = (UINT32) MessageSize;\r
1450 FragmentTable->FragmentBuffer = Message;\r
1451\r
1452 //\r
1453 // Record the original FragmentTable.\r
1454 //\r
1455 OriginalFragmentTable = FragmentTable;\r
1456\r
1457 //\r
1458 // Process the Message.\r
1459 //\r
1460 Status = HttpInstance->Tls->ProcessPacket (\r
1461 HttpInstance->Tls,\r
1462 &FragmentTable,\r
1463 &FragmentCount,\r
1464 ProcessMode\r
1465 );\r
1466 if (EFI_ERROR (Status)) {\r
1467 goto ON_EXIT;\r
1468 }\r
1469\r
1470 //\r
1471 // Calculate the size according to FragmentTable.\r
1472 //\r
1473 for (Index = 0; Index < FragmentCount; Index++) {\r
1474 BufferSize += FragmentTable[Index].FragmentLength;\r
1475 }\r
1476\r
1477 //\r
1478 // Allocate buffer for processed data.\r
1479 //\r
1480 Buffer = AllocateZeroPool (BufferSize);\r
1481 if (Buffer == NULL) {\r
1482 Status = EFI_OUT_OF_RESOURCES;\r
1483 goto ON_EXIT;\r
1484 }\r
1485\r
1486 //\r
1487 // Copy the new FragmentTable buffer into Buffer.\r
1488 //\r
1489 for (Index = 0; Index < FragmentCount; Index++) {\r
1490 CopyMem (\r
1491 (Buffer + BytesCopied),\r
1492 FragmentTable[Index].FragmentBuffer,\r
1493 FragmentTable[Index].FragmentLength\r
1494 );\r
1495 BytesCopied += FragmentTable[Index].FragmentLength;\r
1496\r
1497 //\r
1498 // Free the FragmentBuffer since it has been copied.\r
1499 //\r
1500 FreePool (FragmentTable[Index].FragmentBuffer);\r
1501 }\r
1502\r
1503 Fragment->Len = BufferSize;\r
1504 Fragment->Bulk = Buffer;\r
1505\r
1506ON_EXIT:\r
1507\r
1508 if (OriginalFragmentTable != NULL) {\r
07bd82d4
JW
1509 if( FragmentTable == OriginalFragmentTable) {\r
1510 FragmentTable = NULL;\r
1511 }\r
7618784b
HW
1512 FreePool (OriginalFragmentTable);\r
1513 OriginalFragmentTable = NULL;\r
1514 }\r
1515\r
1516 //\r
1517 // Caller has the responsibility to free the FragmentTable.\r
1518 //\r
1519 if (FragmentTable != NULL) {\r
1520 FreePool (FragmentTable);\r
1521 FragmentTable = NULL;\r
1522 }\r
1523\r
1524 return Status;\r
1525}\r
1526\r
1527/**\r
1528 Receive one fragment decrypted from one TLS record.\r
1529\r
1530 @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.\r
1531 @param[in, out] Fragment The received Fragment.\r
1532 @param[in] Timeout The time to wait for connection done.\r
1533\r
1534 @retval EFI_SUCCESS One fragment is received.\r
1535 @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.\r
1536 @retval EFI_ABORTED Something wrong decryption the message.\r
1537 @retval Others Other errors as indicated.\r
1538\r
1539**/\r
1540EFI_STATUS\r
1541EFIAPI\r
1542HttpsReceive (\r
1543 IN HTTP_PROTOCOL *HttpInstance,\r
1544 IN OUT NET_FRAGMENT *Fragment,\r
1545 IN EFI_EVENT Timeout\r
1546 )\r
1547{\r
1548 EFI_STATUS Status;\r
1549 NET_BUF *Pdu;\r
1550 TLS_RECORD_HEADER RecordHeader;\r
1551 UINT8 *BufferIn;\r
1552 UINTN BufferInSize;\r
1553 NET_FRAGMENT TempFragment;\r
1554 UINT8 *BufferOut;\r
1555 UINTN BufferOutSize;\r
1556 NET_BUF *PacketOut;\r
1557 UINT8 *DataOut;\r
1558 UINT8 *GetSessionDataBuffer;\r
1559 UINTN GetSessionDataBufferSize;\r
1560\r
1561 Status = EFI_SUCCESS;\r
1562 Pdu = NULL;\r
1563 BufferIn = NULL;\r
1564 BufferInSize = 0;\r
1565 BufferOut = NULL;\r
1566 BufferOutSize = 0;\r
1567 PacketOut = NULL;\r
1568 DataOut = NULL;\r
1569 GetSessionDataBuffer = NULL;\r
1570 GetSessionDataBufferSize = 0;\r
1571\r
1572 //\r
1573 // Receive only one TLS record\r
1574 //\r
1575 Status = TlsReceiveOnePdu (HttpInstance, &Pdu, Timeout);\r
1576 if (EFI_ERROR (Status)) {\r
1577 return Status;\r
1578 }\r
1579\r
1580 BufferInSize = Pdu->TotalSize;\r
1581 BufferIn = AllocateZeroPool (BufferInSize);\r
1582 if (BufferIn == NULL) {\r
1583 Status = EFI_OUT_OF_RESOURCES;\r
1584 NetbufFree (Pdu);\r
1585 return Status;\r
1586 }\r
1587\r
1588 NetbufCopy (Pdu, 0, (UINT32) BufferInSize, BufferIn);\r
1589\r
1590 NetbufFree (Pdu);\r
1591\r
1592 //\r
1593 // Handle Receive data.\r
1594 //\r
1595 RecordHeader = *(TLS_RECORD_HEADER *) BufferIn;\r
1596\r
1597 if ((RecordHeader.ContentType == TlsContentTypeApplicationData) &&\r
1598 (RecordHeader.Version.Major == 0x03) &&\r
1599 (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR ||\r
1600 RecordHeader.Version.Minor == TLS11_PROTOCOL_VERSION_MINOR ||\r
1601 RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR)\r
1602 ) {\r
1603 //\r
1604 // Decrypt Packet.\r
1605 //\r
1606 Status = TlsProcessMessage (\r
1607 HttpInstance,\r
1608 BufferIn,\r
1609 BufferInSize,\r
1610 EfiTlsDecrypt,\r
1611 &TempFragment\r
1612 );\r
1613\r
1614 FreePool (BufferIn);\r
1615\r
1616 if (EFI_ERROR (Status)) {\r
1617 if (Status == EFI_ABORTED) {\r
1618 //\r
1619 // Something wrong decryption the message.\r
1620 // BuildResponsePacket() will be called to generate Error Alert message and send it out.\r
1621 //\r
1622 BufferOutSize = DEF_BUF_LEN;\r
1623 BufferOut = AllocateZeroPool (BufferOutSize);\r
1624 if (BufferOut == NULL) {\r
1625 Status = EFI_OUT_OF_RESOURCES;\r
1626 return Status;\r
1627 }\r
1628\r
1629 Status = HttpInstance->Tls->BuildResponsePacket (\r
1630 HttpInstance->Tls,\r
1631 NULL,\r
1632 0,\r
1633 BufferOut,\r
1634 &BufferOutSize\r
1635 );\r
1636 if (Status == EFI_BUFFER_TOO_SMALL) {\r
1637 FreePool (BufferOut);\r
1638 BufferOut = AllocateZeroPool (BufferOutSize);\r
1639 if (BufferOut == NULL) {\r
1640 Status = EFI_OUT_OF_RESOURCES;\r
1641 return Status;\r
1642 }\r
1643\r
1644 Status = HttpInstance->Tls->BuildResponsePacket (\r
1645 HttpInstance->Tls,\r
1646 NULL,\r
1647 0,\r
1648 BufferOut,\r
1649 &BufferOutSize\r
1650 );\r
1651 }\r
1652 if (EFI_ERROR (Status)) {\r
1653 FreePool(BufferOut);\r
1654 return Status;\r
1655 }\r
1656\r
1657 if (BufferOutSize != 0) {\r
1658 PacketOut = NetbufAlloc ((UINT32)BufferOutSize);\r
1659 DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL);\r
1660 if (DataOut == NULL) {\r
1661 FreePool (BufferOut);\r
1662 return EFI_OUT_OF_RESOURCES;\r
1663 }\r
1664\r
1665 CopyMem (DataOut, BufferOut, BufferOutSize);\r
1666\r
1667 Status = TlsCommonTransmit (HttpInstance, PacketOut);\r
1668\r
1669 NetbufFree (PacketOut);\r
1670 }\r
1671\r
1672 FreePool(BufferOut);\r
1673\r
1674 if (EFI_ERROR (Status)) {\r
1675 return Status;\r
1676 }\r
1677\r
1678 return EFI_ABORTED;\r
1679 }\r
1680\r
1681 return Status;\r
1682 }\r
1683\r
1684 //\r
1685 // Parsing buffer.\r
1686 //\r
1687 ASSERT (((TLS_RECORD_HEADER *) (TempFragment.Bulk))->ContentType == TlsContentTypeApplicationData);\r
1688\r
1689 BufferInSize = ((TLS_RECORD_HEADER *) (TempFragment.Bulk))->Length;\r
1690 BufferIn = AllocateZeroPool (BufferInSize);\r
1691 if (BufferIn == NULL) {\r
1692 Status = EFI_OUT_OF_RESOURCES;\r
1693 return Status;\r
1694 }\r
1695\r
07bd82d4 1696 CopyMem (BufferIn, TempFragment.Bulk + TLS_RECORD_HEADER_LENGTH, BufferInSize);\r
7618784b
HW
1697\r
1698 //\r
1699 // Free the buffer in TempFragment.\r
1700 //\r
1701 FreePool (TempFragment.Bulk);\r
1702\r
1703 } else if ((RecordHeader.ContentType == TlsContentTypeAlert) &&\r
1704 (RecordHeader.Version.Major == 0x03) &&\r
1705 (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR ||\r
1706 RecordHeader.Version.Minor == TLS11_PROTOCOL_VERSION_MINOR ||\r
1707 RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR)\r
1708 ) {\r
1709 BufferOutSize = DEF_BUF_LEN;\r
1710 BufferOut = AllocateZeroPool (BufferOutSize);\r
1711 if (BufferOut == NULL) {\r
1712 FreePool (BufferIn);\r
1713 Status = EFI_OUT_OF_RESOURCES;\r
1714 return Status;\r
1715 }\r
1716\r
1717 Status = HttpInstance->Tls->BuildResponsePacket (\r
1718 HttpInstance->Tls,\r
1719 BufferIn,\r
1720 BufferInSize,\r
1721 BufferOut,\r
1722 &BufferOutSize\r
1723 );\r
1724 if (Status == EFI_BUFFER_TOO_SMALL) {\r
1725 FreePool (BufferOut);\r
1726 BufferOut = AllocateZeroPool (BufferOutSize);\r
1727 if (BufferOut == NULL) {\r
1728 FreePool (BufferIn);\r
1729 Status = EFI_OUT_OF_RESOURCES;\r
1730 return Status;\r
1731 }\r
1732\r
1733 Status = HttpInstance->Tls->BuildResponsePacket (\r
1734 HttpInstance->Tls,\r
1735 BufferIn,\r
1736 BufferInSize,\r
1737 BufferOut,\r
1738 &BufferOutSize\r
1739 );\r
1740 }\r
1741\r
1742 FreePool (BufferIn);\r
1743\r
1744 if (EFI_ERROR (Status)) {\r
1745 FreePool (BufferOut);\r
1746 return Status;\r
1747 }\r
1748\r
1749 if (BufferOutSize != 0) {\r
1750 PacketOut = NetbufAlloc ((UINT32) BufferOutSize);\r
1751 DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL);\r
1752 if (DataOut == NULL) {\r
1753 FreePool (BufferOut);\r
1754 return EFI_OUT_OF_RESOURCES;\r
1755 }\r
1756\r
1757 CopyMem (DataOut, BufferOut, BufferOutSize);\r
1758\r
1759 Status = TlsCommonTransmit (HttpInstance, PacketOut);\r
1760\r
1761 NetbufFree (PacketOut);\r
1762 }\r
1763\r
1764 FreePool (BufferOut);\r
1765\r
1766 //\r
1767 // Get the session state.\r
1768 //\r
1769 GetSessionDataBufferSize = DEF_BUF_LEN;\r
1770 GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);\r
1771 if (GetSessionDataBuffer == NULL) {\r
1772 Status = EFI_OUT_OF_RESOURCES;\r
1773 return Status;\r
1774 }\r
1775\r
1776 Status = HttpInstance->Tls->GetSessionData (\r
1777 HttpInstance->Tls,\r
1778 EfiTlsSessionState,\r
1779 GetSessionDataBuffer,\r
1780 &GetSessionDataBufferSize\r
1781 );\r
1782 if (Status == EFI_BUFFER_TOO_SMALL) {\r
1783 FreePool (GetSessionDataBuffer);\r
1784 GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);\r
1785 if (GetSessionDataBuffer == NULL) {\r
1786 Status = EFI_OUT_OF_RESOURCES;\r
1787 return Status;\r
1788 }\r
1789\r
1790 Status = HttpInstance->Tls->GetSessionData (\r
1791 HttpInstance->Tls,\r
1792 EfiTlsSessionState,\r
1793 GetSessionDataBuffer,\r
1794 &GetSessionDataBufferSize\r
1795 );\r
1796 }\r
1797 if (EFI_ERROR (Status)) {\r
1798 FreePool (GetSessionDataBuffer);\r
1799 return Status;\r
1800 }\r
1801\r
1802 ASSERT(GetSessionDataBufferSize == sizeof (EFI_TLS_SESSION_STATE));\r
1803 HttpInstance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) GetSessionDataBuffer;\r
1804\r
1805 FreePool (GetSessionDataBuffer);\r
1806\r
1807 if(HttpInstance->TlsSessionState == EfiTlsSessionError) {\r
1808 DEBUG ((EFI_D_ERROR, "TLS Session State Error!\n"));\r
1809 return EFI_ABORTED;\r
1810 }\r
1811\r
1812 BufferIn = NULL;\r
1813 BufferInSize = 0;\r
1814 }\r
1815\r
1816 Fragment->Bulk = BufferIn;\r
1817 Fragment->Len = (UINT32) BufferInSize;\r
1818\r
1819 return Status;\r
1820}\r
1821\r