//\r
// Allow the delete operation of common authenticated variable at user physical presence.\r
//\r
- if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {\r
+ Status = AuthServiceInternalUpdateVariable (\r
+ VariableName,\r
+ VendorGuid,\r
+ NULL,\r
+ 0,\r
+ 0\r
+ );\r
+ if (!EFI_ERROR (Status) && ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0)) {\r
Status = DeleteCertsFromDb (VariableName, VendorGuid);\r
}\r
- if (!EFI_ERROR (Status)) {\r
- Status = AuthServiceInternalUpdateVariable (\r
- VariableName,\r
- VendorGuid,\r
- NULL,\r
- 0,\r
- 0\r
- );\r
- }\r
+\r
return Status;\r
}\r
\r
return Status;\r
}\r
\r
+/**\r
+ Clean up signer's certificates for common authenticated variable\r
+ by corresponding VariableName and VendorGuid from "certdb".\r
+ Sytem may break down during Timebased Variable update & certdb update,\r
+ make them inconsistent, this function is called in AuthVariable Init to ensure \r
+ consistency\r
+ \r
+ @retval EFI_NOT_FOUND Fail to find matching certs.\r
+ @retval EFI_SUCCESS Find matching certs and output parameters.\r
+\r
+**/\r
+EFI_STATUS\r
+CleanCertsFromDb (\r
+ VOID\r
+ ){\r
+ UINT32 Offset;\r
+ AUTH_CERT_DB_DATA *Ptr;\r
+ UINT32 NameSize;\r
+ UINT32 NodeSize;\r
+ CHAR16 *VariableName;\r
+ EFI_STATUS Status;\r
+ BOOLEAN CertCleaned;\r
+ UINT8 *Data;\r
+ UINTN DataSize;\r
+ UINT8 *AuthVarData;\r
+ UINTN AuthVarDataSize;\r
+ EFI_GUID AuthVarGuid;\r
+\r
+ Status = EFI_SUCCESS;\r
+\r
+ //\r
+ // Get corresponding certificates by VendorGuid and VariableName.\r
+ //\r
+ do {\r
+ CertCleaned = FALSE;\r
+\r
+ //\r
+ // Get latest variable "certdb"\r
+ //\r
+ Status = AuthServiceInternalFindVariable (\r
+ EFI_CERT_DB_NAME,\r
+ &gEfiCertDbGuid,\r
+ (VOID **) &Data,\r
+ &DataSize\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if ((DataSize == 0) || (Data == NULL)) {\r
+ ASSERT (FALSE);\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ Offset = sizeof (UINT32);\r
+\r
+ while (Offset < (UINT32) DataSize) {\r
+ Ptr = (AUTH_CERT_DB_DATA *) (Data + Offset);\r
+ //\r
+ // Check whether VendorGuid matches.\r
+ //\r
+ NodeSize = ReadUnaligned32 (&Ptr->CertNodeSize);\r
+ NameSize = ReadUnaligned32 (&Ptr->NameSize);\r
+\r
+ //\r
+ // Get VarName tailed with '\0'\r
+ //\r
+ VariableName = AllocateZeroPool((NameSize + 1) * sizeof(CHAR16));\r
+ if (VariableName == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ CopyMem (VariableName, (UINT8 *) Ptr + sizeof (AUTH_CERT_DB_DATA), NameSize * sizeof(CHAR16));\r
+ //\r
+ // Keep VarGuid aligned\r
+ //\r
+ CopyMem (&AuthVarGuid, &Ptr->VendorGuid, sizeof(EFI_GUID));\r
+\r
+ //\r
+ // Find corresponding time auth variable\r
+ //\r
+ Status = AuthServiceInternalFindVariable (\r
+ VariableName,\r
+ &AuthVarGuid,\r
+ (VOID **) &AuthVarData,\r
+ &AuthVarDataSize\r
+ );\r
+\r
+ if (EFI_ERROR(Status)) {\r
+ Status = DeleteCertsFromDb(VariableName, &AuthVarGuid);\r
+ CertCleaned = TRUE;\r
+ DEBUG((EFI_D_INFO, "Recovery!! Cert for Auth Variable %s Guid %g is removed for consistency\n", VariableName, &AuthVarGuid));\r
+ FreePool(VariableName);\r
+ break;\r
+ }\r
+\r
+ FreePool(VariableName);\r
+ Offset = Offset + NodeSize;\r
+ }\r
+ } while (CertCleaned);\r
+\r
+ return Status;\r
+}\r
+\r
/**\r
Process variable with EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS set\r
\r
goto Exit;\r
}\r
\r
- //\r
- // Delete signer's certificates when delete the common authenticated variable.\r
- //\r
- if ((PayloadSize == 0) && (OrgTimeStamp != NULL) && ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0)) {\r
- Status = DeleteCertsFromDb (VariableName, VendorGuid);\r
- if (EFI_ERROR (Status)) {\r
- VerifyStatus = FALSE;\r
- goto Exit;\r
- }\r
- } else if ((OrgTimeStamp == NULL) && (PayloadSize != 0)) {\r
+ if ((OrgTimeStamp == NULL) && (PayloadSize != 0)) {\r
//\r
// Insert signer's certificates when adding a new common authenticated variable.\r
//\r
UINTN PayloadSize;\r
EFI_VARIABLE_AUTHENTICATION_2 *CertData;\r
AUTH_VARIABLE_INFO OrgVariableInfo;\r
+ BOOLEAN IsDel;\r
\r
ZeroMem (&OrgVariableInfo, sizeof (OrgVariableInfo));\r
FindStatus = mAuthVarLibContextIn->FindVariable (\r
return Status;\r
}\r
\r
- if ((PayloadSize == 0) && (VarDel != NULL)) {\r
- *VarDel = TRUE;\r
+ if (!EFI_ERROR(FindStatus)\r
+ && (PayloadSize == 0)\r
+ && ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0)) {\r
+ IsDel = TRUE;\r
+ } else {\r
+ IsDel = FALSE;\r
}\r
\r
CertData = (EFI_VARIABLE_AUTHENTICATION_2 *) Data;\r
//\r
// Final step: Update/Append Variable if it pass Pkcs7Verify\r
//\r
- return AuthServiceInternalUpdateVariableWithTimeStamp (\r
- VariableName,\r
- VendorGuid,\r
- PayloadPtr,\r
- PayloadSize,\r
- Attributes,\r
- &CertData->TimeStamp\r
- );\r
+ Status = AuthServiceInternalUpdateVariableWithTimeStamp (\r
+ VariableName,\r
+ VendorGuid,\r
+ PayloadPtr,\r
+ PayloadSize,\r
+ Attributes,\r
+ &CertData->TimeStamp\r
+ );\r
+\r
+ //\r
+ // Delete signer's certificates when delete the common authenticated variable.\r
+ //\r
+ if (IsDel && AuthVarType == AuthVarTypePriv && !EFI_ERROR(Status) ) {\r
+ Status = DeleteCertsFromDb (VariableName, VendorGuid);\r
+ }\r
+\r
+ if (VarDel != NULL) {\r
+ if (IsDel && !EFI_ERROR(Status)) {\r
+ *VarDel = TRUE;\r
+ } else {\r
+ *VarDel = FALSE;\r
+ }\r
+ }\r
+\r
+ return Status;\r
}\r