]> git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c
NetworkPkg: Convert files to CRLF line ending
[mirror_edk2.git] / NetworkPkg / TlsAuthConfigDxe / TlsAuthConfigImpl.c
1 /** @file
2 The Miscellaneous Routines for TlsAuthConfigDxe driver.
3
4 Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>
5
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 "TlsAuthConfigImpl.h"
17
18 VOID *mStartOpCodeHandle = NULL;
19 VOID *mEndOpCodeHandle = NULL;
20 EFI_IFR_GUID_LABEL *mStartLabel = NULL;
21 EFI_IFR_GUID_LABEL *mEndLabel = NULL;
22
23
24 CHAR16 mTlsAuthConfigStorageName[] = L"TLS_AUTH_CONFIG_IFR_NVDATA";
25
26 TLS_AUTH_CONFIG_PRIVATE_DATA *mTlsAuthPrivateData = NULL;
27
28 HII_VENDOR_DEVICE_PATH mTlsAuthConfigHiiVendorDevicePath = {
29 {
30 {
31 HARDWARE_DEVICE_PATH,
32 HW_VENDOR_DP,
33 {
34 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
35 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
36 }
37 },
38 TLS_AUTH_CONFIG_GUID
39 },
40 {
41 END_DEVICE_PATH_TYPE,
42 END_ENTIRE_DEVICE_PATH_SUBTYPE,
43 {
44 (UINT8) (END_DEVICE_PATH_LENGTH),
45 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
46 }
47 }
48 };
49
50 //
51 // Possible DER-encoded certificate file suffixes, end with NULL pointer.
52 //
53 CHAR16* mDerPemEncodedSuffix[] = {
54 L".cer",
55 L".der",
56 L".crt",
57 L".pem",
58 NULL
59 };
60
61 /**
62 This code checks if the FileSuffix is one of the possible DER/PEM-encoded certificate suffix.
63
64 @param[in] FileSuffix The suffix of the input certificate file
65
66 @retval TRUE It's a DER/PEM-encoded certificate.
67 @retval FALSE It's NOT a DER/PEM-encoded certificate.
68
69 **/
70 BOOLEAN
71 IsDerPemEncodeCertificate (
72 IN CONST CHAR16 *FileSuffix
73 )
74 {
75 UINTN Index;
76 for (Index = 0; mDerPemEncodedSuffix[Index] != NULL; Index++) {
77 if (StrCmp (FileSuffix, mDerPemEncodedSuffix[Index]) == 0) {
78 return TRUE;
79 }
80 }
81 return FALSE;
82 }
83
84 /**
85 Worker function that prints an EFI_GUID into specified Buffer.
86
87 @param[in] Guid Pointer to GUID to print.
88 @param[in] Buffer Buffer to print Guid into.
89 @param[in] BufferSize Size of Buffer.
90
91 @retval Number of characters printed.
92
93 **/
94 UINTN
95 GuidToString (
96 IN EFI_GUID *Guid,
97 IN CHAR16 *Buffer,
98 IN UINTN BufferSize
99 )
100 {
101 return UnicodeSPrint (
102 Buffer,
103 BufferSize,
104 L"%g",
105 Guid
106 );
107 }
108
109 /**
110 List all cert in specified database by GUID in the page
111 for user to select and delete as needed.
112
113 @param[in] PrivateData Module's private data.
114 @param[in] VariableName The variable name of the vendor's signature database.
115 @param[in] VendorGuid A unique identifier for the vendor.
116 @param[in] LabelNumber Label number to insert opcodes.
117 @param[in] FormId Form ID of current page.
118 @param[in] QuestionIdBase Base question id of the signature list.
119
120 @retval EFI_SUCCESS Success to update the signature list page
121 @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
122
123 **/
124 EFI_STATUS
125 UpdateDeletePage (
126 IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,
127 IN CHAR16 *VariableName,
128 IN EFI_GUID *VendorGuid,
129 IN UINT16 LabelNumber,
130 IN EFI_FORM_ID FormId,
131 IN EFI_QUESTION_ID QuestionIdBase
132 )
133 {
134 EFI_STATUS Status;
135 UINT32 Index;
136 UINTN CertCount;
137 UINTN GuidIndex;
138 VOID *StartOpCodeHandle;
139 VOID *EndOpCodeHandle;
140 EFI_IFR_GUID_LABEL *StartLabel;
141 EFI_IFR_GUID_LABEL *EndLabel;
142 UINTN DataSize;
143 UINT8 *Data;
144 EFI_SIGNATURE_LIST *CertList;
145 EFI_SIGNATURE_DATA *Cert;
146 UINT32 ItemDataSize;
147 CHAR16 *GuidStr;
148 EFI_STRING_ID GuidID;
149 EFI_STRING_ID Help;
150
151 Data = NULL;
152 CertList = NULL;
153 Cert = NULL;
154 GuidStr = NULL;
155 StartOpCodeHandle = NULL;
156 EndOpCodeHandle = NULL;
157
158 //
159 // Initialize the container for dynamic opcodes.
160 //
161 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
162 if (StartOpCodeHandle == NULL) {
163 Status = EFI_OUT_OF_RESOURCES;
164 goto ON_EXIT;
165 }
166
167 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
168 if (EndOpCodeHandle == NULL) {
169 Status = EFI_OUT_OF_RESOURCES;
170 goto ON_EXIT;
171 }
172
173 //
174 // Create Hii Extend Label OpCode.
175 //
176 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
177 StartOpCodeHandle,
178 &gEfiIfrTianoGuid,
179 NULL,
180 sizeof (EFI_IFR_GUID_LABEL)
181 );
182 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
183 StartLabel->Number = LabelNumber;
184
185 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
186 EndOpCodeHandle,
187 &gEfiIfrTianoGuid,
188 NULL,
189 sizeof (EFI_IFR_GUID_LABEL)
190 );
191 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
192 EndLabel->Number = LABEL_END;
193
194 //
195 // Read Variable.
196 //
197 DataSize = 0;
198 Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, Data);
199 if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
200 goto ON_EXIT;
201 }
202
203 Data = (UINT8 *) AllocateZeroPool (DataSize);
204 if (Data == NULL) {
205 Status = EFI_OUT_OF_RESOURCES;
206 goto ON_EXIT;
207 }
208
209 Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, Data);
210 if (EFI_ERROR (Status)) {
211 goto ON_EXIT;
212 }
213
214 GuidStr = AllocateZeroPool (100);
215 if (GuidStr == NULL) {
216 Status = EFI_OUT_OF_RESOURCES;
217 goto ON_EXIT;
218 }
219
220 //
221 // Enumerate all data.
222 //
223 ItemDataSize = (UINT32) DataSize;
224 CertList = (EFI_SIGNATURE_LIST *) Data;
225 GuidIndex = 0;
226
227 while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
228
229 if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
230 Help = STRING_TOKEN (STR_CERT_TYPE_PCKS_GUID);
231 } else {
232 //
233 // The signature type is not supported in current implementation.
234 //
235 ItemDataSize -= CertList->SignatureListSize;
236 CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
237 continue;
238 }
239
240 CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
241 for (Index = 0; Index < CertCount; Index++) {
242 Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList
243 + sizeof (EFI_SIGNATURE_LIST)
244 + CertList->SignatureHeaderSize
245 + Index * CertList->SignatureSize);
246 //
247 // Display GUID and help
248 //
249 GuidToString (&Cert->SignatureOwner, GuidStr, 100);
250 GuidID = HiiSetString (Private->RegisteredHandle, 0, GuidStr, NULL);
251 HiiCreateCheckBoxOpCode (
252 StartOpCodeHandle,
253 (EFI_QUESTION_ID) (QuestionIdBase + GuidIndex++),
254 0,
255 0,
256 GuidID,
257 Help,
258 EFI_IFR_FLAG_CALLBACK,
259 0,
260 NULL
261 );
262 }
263
264 ItemDataSize -= CertList->SignatureListSize;
265 CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
266 }
267
268 ON_EXIT:
269 HiiUpdateForm (
270 Private->RegisteredHandle,
271 &gTlsAuthConfigGuid,
272 FormId,
273 StartOpCodeHandle,
274 EndOpCodeHandle
275 );
276
277 if (StartOpCodeHandle != NULL) {
278 HiiFreeOpCodeHandle (StartOpCodeHandle);
279 }
280
281 if (EndOpCodeHandle != NULL) {
282 HiiFreeOpCodeHandle (EndOpCodeHandle);
283 }
284
285 if (Data != NULL) {
286 FreePool (Data);
287 }
288
289 if (GuidStr != NULL) {
290 FreePool (GuidStr);
291 }
292
293 return EFI_SUCCESS;
294 }
295
296 /**
297 Delete one entry from cert database.
298
299 @param[in] PrivateData Module's private data.
300 @param[in] VariableName The variable name of the database.
301 @param[in] VendorGuid A unique identifier for the vendor.
302 @param[in] LabelNumber Label number to insert opcodes.
303 @param[in] FormId Form ID of current page.
304 @param[in] QuestionIdBase Base question id of the cert list.
305 @param[in] DeleteIndex Cert index to delete.
306
307 @retval EFI_SUCCESS Delete siganture successfully.
308 @retval EFI_NOT_FOUND Can't find the signature item,
309 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
310 **/
311 EFI_STATUS
312 DeleteCert (
313 IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,
314 IN CHAR16 *VariableName,
315 IN EFI_GUID *VendorGuid,
316 IN UINT16 LabelNumber,
317 IN EFI_FORM_ID FormId,
318 IN EFI_QUESTION_ID QuestionIdBase,
319 IN UINTN DeleteIndex
320 )
321 {
322 EFI_STATUS Status;
323 UINTN DataSize;
324 UINT8 *Data;
325 UINT8 *OldData;
326 UINT32 Attr;
327 UINT32 Index;
328 EFI_SIGNATURE_LIST *CertList;
329 EFI_SIGNATURE_LIST *NewCertList;
330 EFI_SIGNATURE_DATA *Cert;
331 UINTN CertCount;
332 UINT32 Offset;
333 BOOLEAN IsItemFound;
334 UINT32 ItemDataSize;
335 UINTN GuidIndex;
336
337 Data = NULL;
338 OldData = NULL;
339 CertList = NULL;
340 Cert = NULL;
341 Attr = 0;
342
343 //
344 // Get original signature list data.
345 //
346 DataSize = 0;
347 Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, NULL);
348 if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
349 goto ON_EXIT;
350 }
351
352 OldData = (UINT8 *) AllocateZeroPool (DataSize);
353 if (OldData == NULL) {
354 Status = EFI_OUT_OF_RESOURCES;
355 goto ON_EXIT;
356 }
357
358 Status = gRT->GetVariable (VariableName, VendorGuid, &Attr, &DataSize, OldData);
359 if (EFI_ERROR(Status)) {
360 goto ON_EXIT;
361 }
362
363 //
364 // Allocate space for new variable.
365 //
366 Data = (UINT8*) AllocateZeroPool (DataSize);
367 if (Data == NULL) {
368 Status = EFI_OUT_OF_RESOURCES;
369 goto ON_EXIT;
370 }
371
372 //
373 // Enumerate all data and erasing the target item.
374 //
375 IsItemFound = FALSE;
376 ItemDataSize = (UINT32) DataSize;
377 CertList = (EFI_SIGNATURE_LIST *) OldData;
378 Offset = 0;
379 GuidIndex = 0;
380 while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
381 if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
382 //
383 // Copy EFI_SIGNATURE_LIST header then calculate the signature count in this list.
384 //
385 CopyMem (Data + Offset, CertList, (sizeof(EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize));
386 NewCertList = (EFI_SIGNATURE_LIST*) (Data + Offset);
387 Offset += (sizeof(EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
388 Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
389 CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
390 for (Index = 0; Index < CertCount; Index++) {
391 if (GuidIndex == DeleteIndex) {
392 //
393 // Find it! Skip it!
394 //
395 NewCertList->SignatureListSize -= CertList->SignatureSize;
396 IsItemFound = TRUE;
397 } else {
398 //
399 // This item doesn't match. Copy it to the Data buffer.
400 //
401 CopyMem (Data + Offset, (UINT8*)(Cert), CertList->SignatureSize);
402 Offset += CertList->SignatureSize;
403 }
404 GuidIndex++;
405 Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);
406 }
407 } else {
408 //
409 // This List doesn't match. Just copy it to the Data buffer.
410 //
411 CopyMem (Data + Offset, (UINT8*)(CertList), CertList->SignatureListSize);
412 Offset += CertList->SignatureListSize;
413 }
414
415 ItemDataSize -= CertList->SignatureListSize;
416 CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
417 }
418
419 if (!IsItemFound) {
420 //
421 // Doesn't find the signature Item!
422 //
423 Status = EFI_NOT_FOUND;
424 goto ON_EXIT;
425 }
426
427 //
428 // Delete the EFI_SIGNATURE_LIST header if there is no signature in the list.
429 //
430 ItemDataSize = Offset;
431 CertList = (EFI_SIGNATURE_LIST *) Data;
432 Offset = 0;
433 ZeroMem (OldData, ItemDataSize);
434 while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
435 CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
436 DEBUG ((DEBUG_INFO, " CertCount = %x\n", CertCount));
437 if (CertCount != 0) {
438 CopyMem (OldData + Offset, (UINT8*)(CertList), CertList->SignatureListSize);
439 Offset += CertList->SignatureListSize;
440 }
441 ItemDataSize -= CertList->SignatureListSize;
442 CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
443 }
444
445 DataSize = Offset;
446
447 Status = gRT->SetVariable(
448 VariableName,
449 VendorGuid,
450 Attr,
451 DataSize,
452 OldData
453 );
454 if (EFI_ERROR (Status)) {
455 DEBUG ((DEBUG_ERROR, "Failed to set variable, Status = %r\n", Status));
456 goto ON_EXIT;
457 }
458
459 ON_EXIT:
460 if (Data != NULL) {
461 FreePool(Data);
462 }
463
464 if (OldData != NULL) {
465 FreePool(OldData);
466 }
467
468 return UpdateDeletePage (
469 Private,
470 VariableName,
471 VendorGuid,
472 LabelNumber,
473 FormId,
474 QuestionIdBase
475 );
476 }
477
478
479 /**
480 Close an open file handle.
481
482 @param[in] FileHandle The file handle to close.
483
484 **/
485 VOID
486 CloseFile (
487 IN EFI_FILE_HANDLE FileHandle
488 )
489 {
490 if (FileHandle != NULL) {
491 FileHandle->Close (FileHandle);
492 }
493 }
494
495 /**
496 Read file content into BufferPtr, the size of the allocate buffer
497 is *FileSize plus AddtionAllocateSize.
498
499 @param[in] FileHandle The file to be read.
500 @param[in, out] BufferPtr Pointers to the pointer of allocated buffer.
501 @param[out] FileSize Size of input file
502 @param[in] AddtionAllocateSize Addtion size the buffer need to be allocated.
503 In case the buffer need to contain others besides the file content.
504
505 @retval EFI_SUCCESS The file was read into the buffer.
506 @retval EFI_INVALID_PARAMETER A parameter was invalid.
507 @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
508 @retval others Unexpected error.
509
510 **/
511 EFI_STATUS
512 ReadFileContent (
513 IN EFI_FILE_HANDLE FileHandle,
514 IN OUT VOID **BufferPtr,
515 OUT UINTN *FileSize,
516 IN UINTN AddtionAllocateSize
517 )
518
519 {
520 UINTN BufferSize;
521 UINT64 SourceFileSize;
522 VOID *Buffer;
523 EFI_STATUS Status;
524
525 if ((FileHandle == NULL) || (FileSize == NULL)) {
526 return EFI_INVALID_PARAMETER;
527 }
528
529 Buffer = NULL;
530
531 //
532 // Get the file size
533 //
534 Status = FileHandle->SetPosition (FileHandle, (UINT64) -1);
535 if (EFI_ERROR (Status)) {
536 goto ON_EXIT;
537 }
538
539 Status = FileHandle->GetPosition (FileHandle, &SourceFileSize);
540 if (EFI_ERROR (Status)) {
541 goto ON_EXIT;
542 }
543
544 Status = FileHandle->SetPosition (FileHandle, 0);
545 if (EFI_ERROR (Status)) {
546 goto ON_EXIT;
547 }
548
549 BufferSize = (UINTN) SourceFileSize + AddtionAllocateSize;
550 Buffer = AllocateZeroPool(BufferSize);
551 if (Buffer == NULL) {
552 return EFI_OUT_OF_RESOURCES;
553 }
554
555 BufferSize = (UINTN) SourceFileSize;
556 *FileSize = BufferSize;
557
558 Status = FileHandle->Read (FileHandle, &BufferSize, Buffer);
559 if (EFI_ERROR (Status) || BufferSize != *FileSize) {
560 FreePool (Buffer);
561 Buffer = NULL;
562 Status = EFI_BAD_BUFFER_SIZE;
563 goto ON_EXIT;
564 }
565
566 ON_EXIT:
567
568 *BufferPtr = Buffer;
569 return Status;
570 }
571
572 /**
573 This function will open a file or directory referenced by DevicePath.
574
575 This function opens a file with the open mode according to the file path. The
576 Attributes is valid only for EFI_FILE_MODE_CREATE.
577
578 @param[in, out] FilePath On input, the device path to the file.
579 On output, the remaining device path.
580 @param[out] FileHandle Pointer to the file handle.
581 @param[in] OpenMode The mode to open the file with.
582 @param[in] Attributes The file's file attributes.
583
584 @retval EFI_SUCCESS The information was set.
585 @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
586 @retval EFI_UNSUPPORTED Could not open the file path.
587 @retval EFI_NOT_FOUND The specified file could not be found on the
588 device or the file system could not be found on
589 the device.
590 @retval EFI_NO_MEDIA The device has no medium.
591 @retval EFI_MEDIA_CHANGED The device has a different medium in it or the
592 medium is no longer supported.
593 @retval EFI_DEVICE_ERROR The device reported an error.
594 @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
595 @retval EFI_WRITE_PROTECTED The file or medium is write protected.
596 @retval EFI_ACCESS_DENIED The file was opened read only.
597 @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the
598 file.
599 @retval EFI_VOLUME_FULL The volume is full.
600 **/
601 EFI_STATUS
602 EFIAPI
603 OpenFileByDevicePath (
604 IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath,
605 OUT EFI_FILE_HANDLE *FileHandle,
606 IN UINT64 OpenMode,
607 IN UINT64 Attributes
608 )
609 {
610 EFI_STATUS Status;
611 EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *EfiSimpleFileSystemProtocol;
612 EFI_FILE_PROTOCOL *Handle1;
613 EFI_FILE_PROTOCOL *Handle2;
614 EFI_HANDLE DeviceHandle;
615
616 if ((FilePath == NULL || FileHandle == NULL)) {
617 return EFI_INVALID_PARAMETER;
618 }
619
620 Status = gBS->LocateDevicePath (
621 &gEfiSimpleFileSystemProtocolGuid,
622 FilePath,
623 &DeviceHandle
624 );
625 if (EFI_ERROR (Status)) {
626 return Status;
627 }
628
629 Status = gBS->OpenProtocol(
630 DeviceHandle,
631 &gEfiSimpleFileSystemProtocolGuid,
632 (VOID**)&EfiSimpleFileSystemProtocol,
633 gImageHandle,
634 NULL,
635 EFI_OPEN_PROTOCOL_GET_PROTOCOL
636 );
637 if (EFI_ERROR (Status)) {
638 return Status;
639 }
640
641 Status = EfiSimpleFileSystemProtocol->OpenVolume(EfiSimpleFileSystemProtocol, &Handle1);
642 if (EFI_ERROR (Status)) {
643 FileHandle = NULL;
644 return Status;
645 }
646
647 //
648 // go down directories one node at a time.
649 //
650 while (!IsDevicePathEnd (*FilePath)) {
651 //
652 // For file system access each node should be a file path component
653 //
654 if (DevicePathType (*FilePath) != MEDIA_DEVICE_PATH ||
655 DevicePathSubType (*FilePath) != MEDIA_FILEPATH_DP
656 ) {
657 FileHandle = NULL;
658 return (EFI_INVALID_PARAMETER);
659 }
660 //
661 // Open this file path node
662 //
663 Handle2 = Handle1;
664 Handle1 = NULL;
665
666 //
667 // Try to test opening an existing file
668 //
669 Status = Handle2->Open (
670 Handle2,
671 &Handle1,
672 ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,
673 OpenMode &~EFI_FILE_MODE_CREATE,
674 0
675 );
676
677 //
678 // see if the error was that it needs to be created
679 //
680 if ((EFI_ERROR (Status)) && (OpenMode != (OpenMode &~EFI_FILE_MODE_CREATE))) {
681 Status = Handle2->Open (
682 Handle2,
683 &Handle1,
684 ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,
685 OpenMode,
686 Attributes
687 );
688 }
689 //
690 // Close the last node
691 //
692 Handle2->Close (Handle2);
693
694 if (EFI_ERROR(Status)) {
695 return (Status);
696 }
697
698 //
699 // Get the next node
700 //
701 *FilePath = NextDevicePathNode (*FilePath);
702 }
703
704 //
705 // This is a weak spot since if the undefined SHELL_FILE_HANDLE format changes this must change also!
706 //
707 *FileHandle = (VOID*)Handle1;
708 return EFI_SUCCESS;
709 }
710
711 /**
712 This function converts an input device structure to a Unicode string.
713
714 @param[in] DevPath A pointer to the device path structure.
715
716 @return A new allocated Unicode string that represents the device path.
717
718 **/
719 CHAR16 *
720 EFIAPI
721 DevicePathToStr (
722 IN EFI_DEVICE_PATH_PROTOCOL *DevPath
723 )
724 {
725 return ConvertDevicePathToText (
726 DevPath,
727 FALSE,
728 TRUE
729 );
730 }
731
732
733 /**
734 Extract filename from device path. The returned buffer is allocated using AllocateCopyPool.
735 The caller is responsible for freeing the allocated buffer using FreePool(). If return NULL
736 means not enough memory resource.
737
738 @param DevicePath Device path.
739
740 @retval NULL Not enough memory resourece for AllocateCopyPool.
741 @retval Other A new allocated string that represents the file name.
742
743 **/
744 CHAR16 *
745 ExtractFileNameFromDevicePath (
746 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
747 )
748 {
749 CHAR16 *String;
750 CHAR16 *MatchString;
751 CHAR16 *LastMatch;
752 CHAR16 *FileName;
753 UINTN Length;
754
755 ASSERT(DevicePath != NULL);
756
757 String = DevicePathToStr(DevicePath);
758 MatchString = String;
759 LastMatch = String;
760 FileName = NULL;
761
762 while(MatchString != NULL){
763 LastMatch = MatchString + 1;
764 MatchString = StrStr(LastMatch,L"\\");
765 }
766
767 Length = StrLen(LastMatch);
768 FileName = AllocateCopyPool ((Length + 1) * sizeof(CHAR16), LastMatch);
769 if (FileName != NULL) {
770 *(FileName + Length) = 0;
771 }
772
773 FreePool(String);
774
775 return FileName;
776 }
777
778 /**
779 Enroll a new X509 certificate into Variable.
780
781 @param[in] PrivateData The module's private data.
782 @param[in] VariableName Variable name of CA database.
783
784 @retval EFI_SUCCESS New X509 is enrolled successfully.
785 @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
786
787 **/
788 EFI_STATUS
789 EnrollX509toVariable (
790 IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,
791 IN CHAR16 *VariableName
792 )
793 {
794 EFI_STATUS Status;
795 UINTN X509DataSize;
796 VOID *X509Data;
797 EFI_SIGNATURE_LIST *CACert;
798 EFI_SIGNATURE_DATA *CACertData;
799 VOID *Data;
800 UINTN DataSize;
801 UINTN SigDataSize;
802 UINT32 Attr;
803
804 X509DataSize = 0;
805 SigDataSize = 0;
806 DataSize = 0;
807 X509Data = NULL;
808 CACert = NULL;
809 CACertData = NULL;
810 Data = NULL;
811
812 Status = ReadFileContent (
813 Private->FileContext->FHandle,
814 &X509Data,
815 &X509DataSize,
816 0
817 );
818 if (EFI_ERROR (Status)) {
819 goto ON_EXIT;
820 }
821 ASSERT (X509Data != NULL);
822
823 SigDataSize = sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_SIGNATURE_DATA) - 1 + X509DataSize;
824
825 Data = AllocateZeroPool (SigDataSize);
826 if (Data == NULL) {
827 Status = EFI_OUT_OF_RESOURCES;
828 goto ON_EXIT;
829 }
830
831 //
832 // Fill Certificate Database parameters.
833 //
834 CACert = (EFI_SIGNATURE_LIST*) Data;
835 CACert->SignatureListSize = (UINT32) SigDataSize;
836 CACert->SignatureHeaderSize = 0;
837 CACert->SignatureSize = (UINT32) (sizeof(EFI_SIGNATURE_DATA) - 1 + X509DataSize);
838 CopyGuid (&CACert->SignatureType, &gEfiCertX509Guid);
839
840 CACertData = (EFI_SIGNATURE_DATA*) ((UINT8* ) CACert + sizeof (EFI_SIGNATURE_LIST));
841 CopyGuid (&CACertData->SignatureOwner, Private->CertGuid);
842 CopyMem ((UINT8* ) (CACertData->SignatureData), X509Data, X509DataSize);
843
844 //
845 // Check if signature database entry has been already existed.
846 // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
847 // new signature data to original variable
848 //
849 Attr = TLS_AUTH_CONFIG_VAR_BASE_ATTR;
850
851 Status = gRT->GetVariable(
852 VariableName,
853 &gEfiTlsCaCertificateGuid,
854 NULL,
855 &DataSize,
856 NULL
857 );
858 if (Status == EFI_BUFFER_TOO_SMALL) {
859 Attr |= EFI_VARIABLE_APPEND_WRITE;
860 } else if (Status != EFI_NOT_FOUND) {
861 goto ON_EXIT;
862 }
863
864 Status = gRT->SetVariable(
865 VariableName,
866 &gEfiTlsCaCertificateGuid,
867 Attr,
868 SigDataSize,
869 Data
870 );
871 if (EFI_ERROR (Status)) {
872 goto ON_EXIT;
873 }
874
875 ON_EXIT:
876
877 CloseFile (Private->FileContext->FHandle);
878 if (Private->FileContext->FileName != NULL) {
879 FreePool(Private->FileContext->FileName);
880 Private->FileContext->FileName = NULL;
881 }
882
883 Private->FileContext->FHandle = NULL;
884
885 if (Private->CertGuid != NULL) {
886 FreePool (Private->CertGuid);
887 Private->CertGuid = NULL;
888 }
889
890 if (Data != NULL) {
891 FreePool (Data);
892 }
893
894 if (X509Data != NULL) {
895 FreePool (X509Data);
896 }
897
898 return Status;
899 }
900
901 /**
902 Enroll Cert into TlsCaCertificate. The GUID will be Private->CertGuid.
903
904 @param[in] PrivateData The module's private data.
905 @param[in] VariableName Variable name of signature database.
906
907 @retval EFI_SUCCESS New Cert enrolled successfully.
908 @retval EFI_INVALID_PARAMETER The parameter is invalid.
909 @retval EFI_UNSUPPORTED The Cert file is unsupported type.
910 @retval others Fail to enroll Cert data.
911
912 **/
913 EFI_STATUS
914 EnrollCertDatabase (
915 IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,
916 IN CHAR16 *VariableName
917 )
918 {
919 UINT16* FilePostFix;
920 UINTN NameLength;
921
922 if ((Private->FileContext->FileName == NULL) || (Private->FileContext->FHandle == NULL) || (Private->CertGuid == NULL)) {
923 return EFI_INVALID_PARAMETER;
924 }
925
926 //
927 // Parse the file's postfix.
928 //
929 NameLength = StrLen (Private->FileContext->FileName);
930 if (NameLength <= 4) {
931 return EFI_INVALID_PARAMETER;
932 }
933 FilePostFix = Private->FileContext->FileName + NameLength - 4;
934
935 if (IsDerPemEncodeCertificate (FilePostFix)) {
936 //
937 // Supports DER-encoded X509 certificate.
938 //
939 return EnrollX509toVariable (Private, VariableName);
940 }
941
942 return EFI_UNSUPPORTED;
943 }
944
945 /**
946 Refresh the global UpdateData structure.
947
948 **/
949 VOID
950 RefreshUpdateData (
951 VOID
952 )
953 {
954 //
955 // Free current updated date
956 //
957 if (mStartOpCodeHandle != NULL) {
958 HiiFreeOpCodeHandle (mStartOpCodeHandle);
959 }
960
961 //
962 // Create new OpCode Handle
963 //
964 mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
965
966 //
967 // Create Hii Extend Label OpCode as the start opcode
968 //
969 mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
970 mStartOpCodeHandle,
971 &gEfiIfrTianoGuid,
972 NULL,
973 sizeof (EFI_IFR_GUID_LABEL)
974 );
975 mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
976 }
977
978 /**
979 Clean up the dynamic opcode at label and form specified by both LabelId.
980
981 @param[in] LabelId It is both the Form ID and Label ID for opcode deletion.
982 @param[in] PrivateData Module private data.
983
984 **/
985 VOID
986 CleanUpPage (
987 IN UINT16 LabelId,
988 IN TLS_AUTH_CONFIG_PRIVATE_DATA *PrivateData
989 )
990 {
991 RefreshUpdateData ();
992
993 //
994 // Remove all op-codes from dynamic page
995 //
996 mStartLabel->Number = LabelId;
997 HiiUpdateForm (
998 PrivateData->RegisteredHandle,
999 &gTlsAuthConfigGuid,
1000 LabelId,
1001 mStartOpCodeHandle, // Label LabelId
1002 mEndOpCodeHandle // LABEL_END
1003 );
1004 }
1005
1006 /**
1007 Update the form base on the selected file.
1008
1009 @param FilePath Point to the file path.
1010 @param FormId The form need to display.
1011
1012 @retval TRUE Exit caller function.
1013 @retval FALSE Not exit caller function.
1014
1015 **/
1016 BOOLEAN
1017 UpdatePage(
1018 IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
1019 IN EFI_FORM_ID FormId
1020 )
1021 {
1022 CHAR16 *FileName;
1023 EFI_STRING_ID StringToken;
1024
1025 FileName = NULL;
1026
1027 if (FilePath != NULL) {
1028 FileName = ExtractFileNameFromDevicePath(FilePath);
1029 }
1030 if (FileName == NULL) {
1031 //
1032 // FileName = NULL has two case:
1033 // 1. FilePath == NULL, not select file.
1034 // 2. FilePath != NULL, but ExtractFileNameFromDevicePath return NULL not enough memory resource.
1035 // In these two case, no need to update the form, and exit the caller function.
1036 //
1037 return TRUE;
1038 }
1039 StringToken = HiiSetString (mTlsAuthPrivateData->RegisteredHandle, 0, FileName, NULL);
1040
1041 mTlsAuthPrivateData->FileContext->FileName = FileName;
1042
1043 OpenFileByDevicePath (
1044 &FilePath,
1045 &mTlsAuthPrivateData->FileContext->FHandle,
1046 EFI_FILE_MODE_READ,
1047 0
1048 );
1049 //
1050 // Create Subtitle op-code for the display string of the option.
1051 //
1052 RefreshUpdateData ();
1053 mStartLabel->Number = FormId;
1054
1055 HiiCreateSubTitleOpCode (
1056 mStartOpCodeHandle,
1057 StringToken,
1058 0,
1059 0,
1060 0
1061 );
1062
1063 HiiUpdateForm (
1064 mTlsAuthPrivateData->RegisteredHandle,
1065 &gTlsAuthConfigGuid,
1066 FormId,
1067 mStartOpCodeHandle, /// Label FormId
1068 mEndOpCodeHandle /// LABEL_END
1069 );
1070
1071 return TRUE;
1072 }
1073
1074 /**
1075 Update the form base on the input file path info.
1076
1077 @param FilePath Point to the file path.
1078
1079 @retval TRUE Exit caller function.
1080 @retval FALSE Not exit caller function.
1081 **/
1082 BOOLEAN
1083 EFIAPI
1084 UpdateCAFromFile (
1085 IN EFI_DEVICE_PATH_PROTOCOL *FilePath
1086 )
1087 {
1088 return UpdatePage(FilePath, TLS_AUTH_CONFIG_FORMID4_FORM);
1089 }
1090
1091 /**
1092 Unload the configuration form, this includes: delete all the configuration
1093 entries, uninstall the form callback protocol, and free the resources used.
1094
1095 @param[in] Private Pointer to the driver private data.
1096
1097 @retval EFI_SUCCESS The configuration form is unloaded.
1098 @retval Others Failed to unload the form.
1099
1100 **/
1101 EFI_STATUS
1102 TlsAuthConfigFormUnload (
1103 IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private
1104 )
1105 {
1106 if (Private->DriverHandle != NULL) {
1107 //
1108 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
1109 //
1110 gBS->UninstallMultipleProtocolInterfaces (
1111 Private->DriverHandle,
1112 &gEfiDevicePathProtocolGuid,
1113 &mTlsAuthConfigHiiVendorDevicePath,
1114 &gEfiHiiConfigAccessProtocolGuid,
1115 &Private->ConfigAccess,
1116 NULL
1117 );
1118 Private->DriverHandle = NULL;
1119 }
1120
1121 if (Private->RegisteredHandle != NULL) {
1122 //
1123 // Remove HII package list
1124 //
1125 HiiRemovePackages (Private->RegisteredHandle);
1126 Private->RegisteredHandle = NULL;
1127 }
1128
1129 if (Private->CertGuid != NULL) {
1130 FreePool (Private->CertGuid);
1131 }
1132
1133 if (Private->FileContext != NULL) {
1134 FreePool (Private->FileContext);
1135 }
1136
1137 FreePool (Private);
1138
1139 if (mStartOpCodeHandle != NULL) {
1140 HiiFreeOpCodeHandle (mStartOpCodeHandle);
1141 }
1142
1143 if (mEndOpCodeHandle != NULL) {
1144 HiiFreeOpCodeHandle (mEndOpCodeHandle);
1145 }
1146
1147 return EFI_SUCCESS;
1148 }
1149
1150
1151 /**
1152 Initialize the configuration form.
1153
1154 @param[in] Private Pointer to the driver private data.
1155
1156 @retval EFI_SUCCESS The configuration form is initialized.
1157 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
1158
1159 **/
1160 EFI_STATUS
1161 TlsAuthConfigFormInit (
1162 IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private
1163 )
1164 {
1165 EFI_STATUS Status;
1166
1167 Private->Signature = TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE;
1168
1169 Private->ConfigAccess.ExtractConfig = TlsAuthConfigAccessExtractConfig;
1170 Private->ConfigAccess.RouteConfig = TlsAuthConfigAccessRouteConfig;
1171 Private->ConfigAccess.Callback = TlsAuthConfigAccessCallback;
1172
1173 //
1174 // Install Device Path Protocol and Config Access protocol to driver handle.
1175 //
1176 Status = gBS->InstallMultipleProtocolInterfaces (
1177 &Private->DriverHandle,
1178 &gEfiDevicePathProtocolGuid,
1179 &mTlsAuthConfigHiiVendorDevicePath,
1180 &gEfiHiiConfigAccessProtocolGuid,
1181 &Private->ConfigAccess,
1182 NULL
1183 );
1184 if (EFI_ERROR (Status)) {
1185 return Status;
1186 }
1187
1188 //
1189 // Publish our HII data.
1190 //
1191 Private->RegisteredHandle = HiiAddPackages (
1192 &gTlsAuthConfigGuid,
1193 Private->DriverHandle,
1194 TlsAuthConfigDxeStrings,
1195 TlsAuthConfigVfrBin,
1196 NULL
1197 );
1198 if (Private->RegisteredHandle == NULL) {
1199 Status = EFI_OUT_OF_RESOURCES;
1200 goto Error;
1201 }
1202
1203 Private->FileContext = AllocateZeroPool (sizeof (TLS_AUTH_CONFIG_FILE_CONTEXT));
1204 if (Private->FileContext == NULL) {
1205 Status = EFI_OUT_OF_RESOURCES;
1206 goto Error;
1207 }
1208
1209 //
1210 // Init OpCode Handle and Allocate space for creation of Buffer
1211 //
1212 mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
1213 if (mStartOpCodeHandle == NULL) {
1214 Status = EFI_OUT_OF_RESOURCES;
1215 goto Error;
1216 }
1217
1218 mEndOpCodeHandle = HiiAllocateOpCodeHandle ();
1219 if (mEndOpCodeHandle == NULL) {
1220 Status = EFI_OUT_OF_RESOURCES;
1221 goto Error;
1222 }
1223
1224 //
1225 // Create Hii Extend Label OpCode as the start opcode
1226 //
1227 mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
1228 mStartOpCodeHandle,
1229 &gEfiIfrTianoGuid,
1230 NULL,
1231 sizeof (EFI_IFR_GUID_LABEL)
1232 );
1233 mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1234
1235 //
1236 // Create Hii Extend Label OpCode as the end opcode
1237 //
1238 mEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
1239 mEndOpCodeHandle,
1240 &gEfiIfrTianoGuid,
1241 NULL,
1242 sizeof (EFI_IFR_GUID_LABEL)
1243 );
1244 mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1245 mEndLabel->Number = LABEL_END;
1246
1247 return EFI_SUCCESS;
1248
1249 Error:
1250 TlsAuthConfigFormUnload (Private);
1251 return Status;
1252 }
1253
1254 /**
1255
1256 This function allows the caller to request the current
1257 configuration for one or more named elements. The resulting
1258 string is in <ConfigAltResp> format. Any and all alternative
1259 configuration strings shall also be appended to the end of the
1260 current configuration string. If they are, they must appear
1261 after the current configuration. They must contain the same
1262 routing (GUID, NAME, PATH) as the current configuration string.
1263 They must have an additional description indicating the type of
1264 alternative configuration the string represents,
1265 "ALTCFG=<StringToken>". That <StringToken> (when
1266 converted from Hex UNICODE to binary) is a reference to a
1267 string in the associated string pack.
1268
1269 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1270
1271 @param Request A null-terminated Unicode string in
1272 <ConfigRequest> format. Note that this
1273 includes the routing information as well as
1274 the configurable name / value pairs. It is
1275 invalid for this string to be in
1276 <MultiConfigRequest> format.
1277 If a NULL is passed in for the Request field,
1278 all of the settings being abstracted by this function
1279 will be returned in the Results field. In addition,
1280 if a ConfigHdr is passed in with no request elements,
1281 all of the settings being abstracted for that particular
1282 ConfigHdr reference will be returned in the Results Field.
1283
1284 @param Progress On return, points to a character in the
1285 Request string. Points to the string's null
1286 terminator if request was successful. Points
1287 to the most recent "&" before the first
1288 failing name / value pair (or the beginning
1289 of the string if the failure is in the first
1290 name / value pair) if the request was not
1291 successful.
1292
1293 @param Results A null-terminated Unicode string in
1294 <MultiConfigAltResp> format which has all values
1295 filled in for the names in the Request string.
1296 String to be allocated by the called function.
1297
1298 @retval EFI_SUCCESS The Results string is filled with the
1299 values corresponding to all requested
1300 names.
1301
1302 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
1303 parts of the results that must be
1304 stored awaiting possible future
1305 protocols.
1306
1307 @retval EFI_NOT_FOUND Routing data doesn't match any
1308 known driver. Progress set to the
1309 first character in the routing header.
1310 Note: There is no requirement that the
1311 driver validate the routing data. It
1312 must skip the <ConfigHdr> in order to
1313 process the names.
1314
1315 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
1316 to most recent "&" before the
1317 error or the beginning of the
1318 string.
1319
1320 @retval EFI_INVALID_PARAMETER Unknown name. Progress points
1321 to the & before the name in
1322 question.
1323
1324 **/
1325 EFI_STATUS
1326 EFIAPI
1327 TlsAuthConfigAccessExtractConfig (
1328 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1329 IN CONST EFI_STRING Request,
1330 OUT EFI_STRING *Progress,
1331 OUT EFI_STRING *Results
1332 )
1333 {
1334 EFI_STATUS Status;
1335 UINTN BufferSize;
1336 UINTN Size;
1337 EFI_STRING ConfigRequest;
1338 EFI_STRING ConfigRequestHdr;
1339 TLS_AUTH_CONFIG_PRIVATE_DATA *Private;
1340 BOOLEAN AllocatedRequest;
1341
1342 if (Progress == NULL || Results == NULL) {
1343 return EFI_INVALID_PARAMETER;
1344 }
1345
1346 AllocatedRequest = FALSE;
1347 ConfigRequestHdr = NULL;
1348 ConfigRequest = NULL;
1349 Size = 0;
1350
1351 Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);
1352
1353 BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
1354 ZeroMem (&Private->TlsAuthConfigNvData, BufferSize);
1355
1356 *Progress = Request;
1357
1358 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gTlsAuthConfigGuid, mTlsAuthConfigStorageName)) {
1359 return EFI_NOT_FOUND;
1360 }
1361
1362 ConfigRequest = Request;
1363 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
1364 //
1365 // Request is set to NULL or OFFSET is NULL, construct full request string.
1366 //
1367 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
1368 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
1369 //
1370 ConfigRequestHdr = HiiConstructConfigHdr (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, Private->DriverHandle);
1371 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
1372 ConfigRequest = AllocateZeroPool (Size);
1373 ASSERT (ConfigRequest != NULL);
1374 AllocatedRequest = TRUE;
1375 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
1376 FreePool (ConfigRequestHdr);
1377 ConfigRequestHdr = NULL;
1378 }
1379
1380 Status = gHiiConfigRouting->BlockToConfig (
1381 gHiiConfigRouting,
1382 ConfigRequest,
1383 (UINT8 *) &Private->TlsAuthConfigNvData,
1384 BufferSize,
1385 Results,
1386 Progress
1387 );
1388
1389 //
1390 // Free the allocated config request string.
1391 //
1392 if (AllocatedRequest) {
1393 FreePool (ConfigRequest);
1394 }
1395
1396 //
1397 // Set Progress string to the original request string.
1398 //
1399 if (Request == NULL) {
1400 *Progress = NULL;
1401 } else if (StrStr (Request, L"OFFSET") == NULL) {
1402 *Progress = Request + StrLen (Request);
1403 }
1404
1405 return Status;
1406 }
1407
1408 /**
1409
1410 This function applies changes in a driver's configuration.
1411 Input is a Configuration, which has the routing data for this
1412 driver followed by name / value configuration pairs. The driver
1413 must apply those pairs to its configurable storage. If the
1414 driver's configuration is stored in a linear block of data
1415 and the driver's name / value pairs are in <BlockConfig>
1416 format, it may use the ConfigToBlock helper function (above) to
1417 simplify the job.
1418
1419 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1420
1421 @param Configuration A null-terminated Unicode string in
1422 <ConfigString> format.
1423
1424 @param Progress A pointer to a string filled in with the
1425 offset of the most recent '&' before the
1426 first failing name / value pair (or the
1427 beginn ing of the string if the failure
1428 is in the first name / value pair) or
1429 the terminating NULL if all was
1430 successful.
1431
1432 @retval EFI_SUCCESS The results have been distributed or are
1433 awaiting distribution.
1434
1435 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
1436 parts of the results that must be
1437 stored awaiting possible future
1438 protocols.
1439
1440 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
1441 Results parameter would result
1442 in this type of error.
1443
1444 @retval EFI_NOT_FOUND Target for the specified routing data
1445 was not found
1446
1447 **/
1448 EFI_STATUS
1449 EFIAPI
1450 TlsAuthConfigAccessRouteConfig (
1451 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1452 IN CONST EFI_STRING Configuration,
1453 OUT EFI_STRING *Progress
1454 )
1455 {
1456 EFI_STATUS Status;
1457 UINTN BufferSize;
1458 TLS_AUTH_CONFIG_PRIVATE_DATA *Private;
1459
1460 if (Progress == NULL) {
1461 return EFI_INVALID_PARAMETER;
1462 }
1463 *Progress = Configuration;
1464
1465 if (Configuration == NULL) {
1466 return EFI_INVALID_PARAMETER;
1467 }
1468
1469 //
1470 // Check routing data in <ConfigHdr>.
1471 // Note: there is no name for Name/Value storage, only GUID will be checked
1472 //
1473 if (!HiiIsConfigHdrMatch (Configuration, &gTlsAuthConfigGuid, mTlsAuthConfigStorageName)) {
1474 return EFI_NOT_FOUND;
1475 }
1476
1477 Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);
1478
1479 BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
1480 ZeroMem (&Private->TlsAuthConfigNvData, BufferSize);
1481
1482 Status = gHiiConfigRouting->ConfigToBlock (
1483 gHiiConfigRouting,
1484 Configuration,
1485 (UINT8 *) &Private->TlsAuthConfigNvData,
1486 &BufferSize,
1487 Progress
1488 );
1489 if (EFI_ERROR (Status)) {
1490 return Status;
1491 }
1492
1493 return Status;
1494 }
1495
1496 /**
1497
1498 This function is called to provide results data to the driver.
1499 This data consists of a unique key that is used to identify
1500 which data is either being passed back or being asked for.
1501
1502 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1503 @param Action Specifies the type of action taken by the browser.
1504 @param QuestionId A unique value which is sent to the original
1505 exporting driver so that it can identify the type
1506 of data to expect. The format of the data tends to
1507 vary based on the opcode that generated the callback.
1508 @param Type The type of value for the question.
1509 @param Value A pointer to the data being sent to the original
1510 exporting driver.
1511 @param ActionRequest On return, points to the action requested by the
1512 callback function.
1513
1514 @retval EFI_SUCCESS The callback successfully handled the action.
1515 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1516 variable and its data.
1517 @retval EFI_DEVICE_ERROR The variable could not be saved.
1518 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1519 callback.
1520 **/
1521 EFI_STATUS
1522 EFIAPI
1523 TlsAuthConfigAccessCallback (
1524 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1525 IN EFI_BROWSER_ACTION Action,
1526 IN EFI_QUESTION_ID QuestionId,
1527 IN UINT8 Type,
1528 IN OUT EFI_IFR_TYPE_VALUE *Value,
1529 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
1530 )
1531 {
1532 EFI_INPUT_KEY Key;
1533 EFI_STATUS Status;
1534 RETURN_STATUS RStatus;
1535 TLS_AUTH_CONFIG_PRIVATE_DATA *Private;
1536 UINTN BufferSize;
1537 TLS_AUTH_CONFIG_IFR_NVDATA *IfrNvData;
1538 UINT16 LabelId;
1539 EFI_DEVICE_PATH_PROTOCOL *File;
1540
1541 Status = EFI_SUCCESS;
1542 File = NULL;
1543
1544 if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {
1545 return EFI_INVALID_PARAMETER;
1546 }
1547
1548 Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);
1549
1550 mTlsAuthPrivateData = Private;
1551
1552 //
1553 // Retrieve uncommitted data from Browser
1554 //
1555 BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
1556 IfrNvData = AllocateZeroPool (BufferSize);
1557 if (IfrNvData == NULL) {
1558 return EFI_OUT_OF_RESOURCES;
1559 }
1560
1561 HiiGetBrowserData (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, BufferSize, (UINT8 *) IfrNvData);
1562
1563 if ((Action != EFI_BROWSER_ACTION_CHANGED) &&
1564 (Action != EFI_BROWSER_ACTION_CHANGING)) {
1565 Status = EFI_UNSUPPORTED;
1566 goto EXIT;
1567 }
1568
1569 if (Action == EFI_BROWSER_ACTION_CHANGING) {
1570 switch (QuestionId) {
1571 case KEY_TLS_AUTH_CONFIG_CLIENT_CERT:
1572 case KEY_TLS_AUTH_CONFIG_SERVER_CA:
1573 //
1574 // Clear Cert GUID.
1575 //
1576 ZeroMem (IfrNvData->CertGuid, sizeof (IfrNvData->CertGuid));
1577 if (Private->CertGuid == NULL) {
1578 Private->CertGuid = (EFI_GUID *) AllocateZeroPool (sizeof (EFI_GUID));
1579 if (Private->CertGuid == NULL) {
1580 return EFI_OUT_OF_RESOURCES;
1581 }
1582 }
1583 if (QuestionId == KEY_TLS_AUTH_CONFIG_CLIENT_CERT) {
1584 LabelId = TLS_AUTH_CONFIG_FORMID3_FORM;
1585 } else {
1586 LabelId = TLS_AUTH_CONFIG_FORMID4_FORM;
1587 }
1588
1589 //
1590 // Refresh selected file.
1591 //
1592 CleanUpPage (LabelId, Private);
1593 break;
1594 case KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE:
1595 ChooseFile( NULL, NULL, UpdateCAFromFile, &File);
1596 break;
1597
1598 case KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT:
1599 Status = EnrollCertDatabase (Private, EFI_TLS_CA_CERTIFICATE_VARIABLE);
1600 if (EFI_ERROR (Status)) {
1601 CreatePopUp (
1602 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1603 &Key,
1604 L"ERROR: Enroll Cert Failure!",
1605 NULL
1606 );
1607 }
1608 break;
1609
1610 case KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT:
1611 if (Private->FileContext->FHandle != NULL) {
1612 CloseFile (Private->FileContext->FHandle);
1613 Private->FileContext->FHandle = NULL;
1614 if (Private->FileContext->FileName!= NULL){
1615 FreePool(Private->FileContext->FileName);
1616 Private->FileContext->FileName = NULL;
1617 }
1618 }
1619
1620 if (Private->CertGuid!= NULL) {
1621 FreePool (Private->CertGuid);
1622 Private->CertGuid = NULL;
1623 }
1624 break;
1625
1626 case KEY_TLS_AUTH_CONFIG_DELETE_CERT:
1627 UpdateDeletePage (
1628 Private,
1629 EFI_TLS_CA_CERTIFICATE_VARIABLE,
1630 &gEfiTlsCaCertificateGuid,
1631 LABEL_CA_DELETE,
1632 TLS_AUTH_CONFIG_FORMID5_FORM,
1633 OPTION_DEL_CA_ESTION_ID
1634 );
1635 break;
1636
1637 default:
1638 if ((QuestionId >= OPTION_DEL_CA_ESTION_ID) &&
1639 (QuestionId < (OPTION_DEL_CA_ESTION_ID + OPTION_CONFIG_RANGE))) {
1640 DeleteCert (
1641 Private,
1642 EFI_TLS_CA_CERTIFICATE_VARIABLE,
1643 &gEfiTlsCaCertificateGuid,
1644 LABEL_CA_DELETE,
1645 TLS_AUTH_CONFIG_FORMID5_FORM,
1646 OPTION_DEL_CA_ESTION_ID,
1647 QuestionId - OPTION_DEL_CA_ESTION_ID
1648 );
1649 }
1650 break;
1651 }
1652 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
1653 switch (QuestionId) {
1654 case KEY_TLS_AUTH_CONFIG_CERT_GUID:
1655 ASSERT (Private->CertGuid != NULL);
1656 RStatus = StrToGuid (
1657 IfrNvData->CertGuid,
1658 Private->CertGuid
1659 );
1660 if (RETURN_ERROR (RStatus) || (IfrNvData->CertGuid[GUID_STRING_LENGTH] != L'\0')) {
1661 Status = EFI_INVALID_PARAMETER;
1662 break;
1663 }
1664
1665 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
1666 break;
1667 default:
1668 break;
1669 }
1670 }
1671
1672 EXIT:
1673
1674 if (!EFI_ERROR (Status)) {
1675 BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
1676 HiiSetBrowserData (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, BufferSize, (UINT8*) IfrNvData, NULL);
1677 }
1678
1679 FreePool (IfrNvData);
1680
1681 if (File != NULL){
1682 FreePool(File);
1683 File = NULL;
1684 }
1685
1686 return EFI_SUCCESS;
1687
1688 }
1689