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