]> git.proxmox.com Git - mirror_edk2.git/blobdiff - SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigImpl.c
SecurityPkg: Add constraints on PK strength
[mirror_edk2.git] / SecurityPkg / VariableAuthenticated / SecureBootConfigDxe / SecureBootConfigImpl.c
index 4f01a2ed677e8813b845ce3f054a9078cf293430..e82bfe77570de0960daa8fb2e0a226ac44cbf55a 100644 (file)
@@ -90,6 +90,22 @@ CHAR16* mDerEncodedSuffix[] = {
 };\r
 CHAR16* mSupportX509Suffix = L"*.cer/der/crt";\r
 \r
+//\r
+// Prompt strings during certificate enrollment.\r
+//\r
+CHAR16* mX509EnrollPromptTitle[] = {\r
+  L"",\r
+  L"ERROR: Unsupported file type!",\r
+  L"ERROR: Unsupported certificate!",\r
+  NULL\r
+};\r
+CHAR16* mX509EnrollPromptString[] = {\r
+  L"",\r
+  L"Only DER encoded certificate file (*.cer/der/crt) is supported.",\r
+  L"Public key length should be equal to or greater than 2048 bits.",\r
+  NULL\r
+};\r
+\r
 SECUREBOOT_CONFIG_PRIVATE_DATA  *gSecureBootPrivateData = NULL;\r
 \r
 /**\r
@@ -383,6 +399,102 @@ SetSecureBootMode (
                 );\r
 }\r
 \r
+/**\r
+  This code checks if the encode type and key strength of X.509\r
+  certificate is qualified.\r
+\r
+  @param[in]  X509FileContext     FileContext of X.509 certificate storing\r
+                                  file.\r
+  @param[out] Error               Error type checked in the certificate.\r
+\r
+  @return EFI_SUCCESS             The certificate checked successfully.\r
+  @return EFI_INVALID_PARAMETER   The parameter is invalid.\r
+  @return EFI_OUT_OF_RESOURCES    Memory allocation failed.\r
+\r
+**/\r
+EFI_STATUS\r
+CheckX509Certificate (\r
+  IN    SECUREBOOT_FILE_CONTEXT*    X509FileContext,\r
+  OUT   ENROLL_KEY_ERROR*           Error\r
+)\r
+{\r
+  EFI_STATUS     Status;\r
+  UINT16*        FilePostFix;\r
+  UINTN          NameLength;\r
+  UINT8*         X509Data;\r
+  UINTN          X509DataSize;\r
+  void*          X509PubKey;\r
+  UINTN          PubKeyModSize;\r
+\r
+  if (X509FileContext->FileName == NULL) {\r
+    *Error = Unsupported_Type;\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  X509Data       = NULL;\r
+  X509DataSize   = 0;\r
+  X509PubKey     = NULL;\r
+  PubKeyModSize  = 0;\r
+\r
+  //\r
+  // Parse the file's postfix. Only support DER encoded X.509 certificate files.\r
+  //\r
+  NameLength = StrLen (X509FileContext->FileName);\r
+  if (NameLength <= 4) {\r
+    DEBUG ((DEBUG_ERROR, "Wrong X509 NameLength\n"));\r
+    *Error = Unsupported_Type;\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  FilePostFix = X509FileContext->FileName + NameLength - 4;\r
+  if (!IsDerEncodeCertificate (FilePostFix)) {\r
+    DEBUG ((DEBUG_ERROR, "Unsupported file type, only DER encoded certificate (%s) is supported.\n", mSupportX509Suffix));\r
+    *Error = Unsupported_Type;\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+  DEBUG ((DEBUG_INFO, "FileName= %s\n", X509FileContext->FileName));\r
+  DEBUG ((DEBUG_INFO, "FilePostFix = %s\n", FilePostFix));\r
+\r
+  //\r
+  // Read the certificate file content\r
+  //\r
+  Status = ReadFileContent (X509FileContext->FHandle, (VOID**) &X509Data, &X509DataSize, 0);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((DEBUG_ERROR, "Error occured while reading the file.\n"));\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  //\r
+  // Parse the public key context.\r
+  //\r
+  if (RsaGetPublicKeyFromX509 (X509Data, X509DataSize, &X509PubKey) == FALSE) {\r
+    DEBUG ((DEBUG_ERROR, "Error occured while parsing the pubkey from certificate.\n"));\r
+    Status = EFI_INVALID_PARAMETER;\r
+    *Error = Unsupported_Type;\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  //\r
+  // Parse Module size of public key using interface provided by CryptoPkg, which is\r
+  // actually the size of public key.\r
+  //\r
+  if (X509PubKey != NULL) {\r
+    RsaGetKey (X509PubKey, RsaKeyN, NULL, &PubKeyModSize);\r
+    if (PubKeyModSize < CER_PUBKEY_MIN_SIZE) {\r
+      DEBUG ((DEBUG_ERROR, "Unqualified PK size, key size should be equal to or greater than 2048 bits.\n"));\r
+      Status = EFI_INVALID_PARAMETER;\r
+      *Error = Unqualified_Key;\r
+    }\r
+    RsaFree (X509PubKey);\r
+  }\r
+\r
+ ON_EXIT:\r
+  if (X509Data != NULL) {\r
+    FreePool (X509Data);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
 /**\r
   Generate the PK signature list from the X509 Certificate storing file (.cer)\r
 \r
@@ -477,12 +589,6 @@ EnrollPlatformKey (
   UINT32                          Attr;\r
   UINTN                           DataSize;\r
   EFI_SIGNATURE_LIST              *PkCert;\r
-  UINT16*                         FilePostFix;\r
-  UINTN                           NameLength;\r
-\r
-  if (Private->FileContext->FileName == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
 \r
   PkCert = NULL;\r
 \r
@@ -491,21 +597,6 @@ EnrollPlatformKey (
     return Status;\r
   }\r
 \r
-  //\r
-  // Parse the file's postfix. Only support DER encoded X.509 certificate files.\r
-  //\r
-  NameLength = StrLen (Private->FileContext->FileName);\r
-  if (NameLength <= 4) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  FilePostFix = Private->FileContext->FileName + NameLength - 4;\r
-  if (!IsDerEncodeCertificate(FilePostFix)) {\r
-    DEBUG ((EFI_D_ERROR, "Unsupported file type, only DER encoded certificate (%s) is supported.", mSupportX509Suffix));\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  DEBUG ((EFI_D_INFO, "FileName= %s\n", Private->FileContext->FileName));\r
-  DEBUG ((EFI_D_INFO, "FilePostFix = %s\n", FilePostFix));\r
-\r
   //\r
   // Prase the selected PK file and generate PK certificate list.\r
   //\r
@@ -4300,12 +4391,14 @@ SecureBootCallback (
   UINT16                          *FilePostFix;\r
   SECUREBOOT_CONFIG_PRIVATE_DATA  *PrivateData;\r
   BOOLEAN                         GetBrowserDataResult;\r
+  ENROLL_KEY_ERROR                EnrollKeyErrorCode;\r
 \r
-  Status           = EFI_SUCCESS;\r
-  SecureBootEnable = NULL;\r
-  SecureBootMode   = NULL;\r
-  SetupMode        = NULL;\r
-  File             = NULL;\r
+  Status             = EFI_SUCCESS;\r
+  SecureBootEnable   = NULL;\r
+  SecureBootMode     = NULL;\r
+  SetupMode          = NULL;\r
+  File               = NULL;\r
+  EnrollKeyErrorCode = None_Error;\r
 \r
   if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {\r
     return EFI_INVALID_PARAMETER;\r
@@ -4718,18 +4811,35 @@ SecureBootCallback (
       }\r
       break;\r
     case KEY_VALUE_SAVE_AND_EXIT_PK:\r
-      Status = EnrollPlatformKey (Private);\r
+      //\r
+      // Check the suffix, encode type and the key strength of PK certificate.\r
+      //\r
+      Status = CheckX509Certificate (Private->FileContext, &EnrollKeyErrorCode);\r
+      if (EFI_ERROR (Status)) {\r
+        if (EnrollKeyErrorCode != None_Error && EnrollKeyErrorCode < Enroll_Error_Max) {\r
+          CreatePopUp (\r
+            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
+            &Key,\r
+            mX509EnrollPromptTitle[EnrollKeyErrorCode],\r
+            mX509EnrollPromptString[EnrollKeyErrorCode],\r
+            NULL\r
+            );\r
+          break;\r
+        }\r
+      } else {\r
+        Status = EnrollPlatformKey (Private);\r
+      }\r
       if (EFI_ERROR (Status)) {\r
         UnicodeSPrint (\r
           PromptString,\r
           sizeof (PromptString),\r
-          L"Only DER encoded certificate file (%s) is supported.",\r
-          mSupportX509Suffix\r
+          L"Error status: %x.",\r
+          Status\r
           );\r
         CreatePopUp (\r
           EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
           &Key,\r
-          L"ERROR: Unsupported file type!",\r
+          L"ERROR: Enrollment failed!",\r
           PromptString,\r
           NULL\r
           );\r