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