Fix PDF encryption for revision 5 and 6.

Several CPDFSecurityHandlerEmbedderTests try to save PDFs with revision
5 or 6 encryption, but then cannot re-open the saved PDFs. This is
because the saved PDFs had an outdated /Perms entry. To fix this, always
call AES256_SetPerms() in CPDF_SecurityHandler::OnCreateInternal().

Re-enable tests that were disabled due to this issue. Fix tests that
were using the wrong password, which also caused the tests to fail. Keep
tests disabled for MSAN, because there still remains an uninit memory
condition.

Bug: pdfium:1441
Change-Id: I27aafd19e5e9ce1dff7c803abc961e5678cd0370
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/63931
Reviewed-by: Tom Sepez <tsepez@chromium.org>
Commit-Queue: Lei Zhang <thestig@chromium.org>
diff --git a/core/fpdfapi/parser/cpdf_security_handler.cpp b/core/fpdfapi/parser/cpdf_security_handler.cpp
index d00fd60..0c8eadd 100644
--- a/core/fpdfapi/parser/cpdf_security_handler.cpp
+++ b/core/fpdfapi/parser/cpdf_security_handler.cpp
@@ -559,12 +559,11 @@
     CRYPT_SHA256Update(&sha, (uint8_t*)"there", 5);
     CRYPT_SHA256Finish(&sha, m_EncryptKey);
     AES256_SetPassword(pEncryptDict, user_password, false, m_EncryptKey);
-    if (bDefault) {
+    if (bDefault)
       AES256_SetPassword(pEncryptDict, owner_password_copy, true, m_EncryptKey);
-      AES256_SetPerms(pEncryptDict, m_Permissions,
-                      pEncryptDict->GetBooleanFor("EncryptMetadata", true),
-                      m_EncryptKey);
-    }
+    AES256_SetPerms(pEncryptDict, m_Permissions,
+                    pEncryptDict->GetBooleanFor("EncryptMetadata", true),
+                    m_EncryptKey);
     return;
   }
   if (bDefault) {
diff --git a/core/fpdfapi/parser/cpdf_security_handler_embeddertest.cpp b/core/fpdfapi/parser/cpdf_security_handler_embeddertest.cpp
index acb2ec3..a9698a0 100644
--- a/core/fpdfapi/parser/cpdf_security_handler_embeddertest.cpp
+++ b/core/fpdfapi/parser/cpdf_security_handler_embeddertest.cpp
@@ -279,12 +279,17 @@
   VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
   VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
 
-#if 0
+#if !defined(MEMORY_SANITIZER)
   // TODO(crbug.com/1032090): This triggers an MSAN error.
   // Fix and enable this code.
   ClearString();
   RemoveTrailerIdFromDocument();
   EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
+  // With revision 5 and 6, the existing implementation regenerates the user
+  // password with the provided password, and the original owner password entry
+  // is no longer valid. Thus only check the owner password, which is now the
+  // user password.
+  // TODO(thestig): Check and see if this regeneration is necessary.
   VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
   VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
 #endif
@@ -301,11 +306,9 @@
   VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
   VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
 
-#if 0
+#if !defined(MEMORY_SANITIZER)
   // TODO(crbug.com/1032090): This triggers an MSAN error.
   // Fix and enable this code.
-  // TODO(crbug.com/pdfium/1441): Output encryption dictionary may be bad.
-  // Fix and enable this code.
   ClearString();
   RemoveTrailerIdFromDocument();
   EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
@@ -325,7 +328,7 @@
   VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
   VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
 
-#if 0
+#if !defined(MEMORY_SANITIZER)
   // TODO(crbug.com/1032090): This triggers an MSAN error.
   // Fix and enable this code.
   ClearString();
@@ -347,11 +350,9 @@
   VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
   VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
 
-#if 0
+#if !defined(MEMORY_SANITIZER)
   // TODO(crbug.com/1032090): This triggers an MSAN error.
   // Fix and enable this code.
-  // TODO(crbug.com/pdfium/1441): Output encryption dictionary may be bad.
-  // Fix and enable this code.
   ClearString();
   RemoveTrailerIdFromDocument();
   EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
@@ -456,14 +457,18 @@
   VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
   VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
 
-#if 0
+#if !defined(MEMORY_SANITIZER)
   // TODO(crbug.com/1032090): This triggers an MSAN error.
   // Fix and enable this code.
   ClearString();
   RemoveTrailerIdFromDocument();
   EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
-  VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
-  VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
+  // With revision 5 and 6, the existing implementation regenerates the user
+  // password with the provided password, and the original owner password entry
+  // is no longer valid. Thus only check the user password.
+  // TODO(thestig): Check and see if this regeneration is necessary.
+  VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
+  VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
 #endif
 }
 
@@ -478,16 +483,14 @@
   VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
   VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
 
-#if 0
+#if !defined(MEMORY_SANITIZER)
   // TODO(crbug.com/1032090): This triggers an MSAN error.
   // Fix and enable this code.
-  // TODO(crbug.com/pdfium/1441): Output encryption dictionary may be bad.
-  // Fix and enable this code.
   ClearString();
   RemoveTrailerIdFromDocument();
   EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
-  VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
-  VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
+  VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
+  VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
 #endif
 }
 
@@ -502,14 +505,14 @@
   VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
   VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
 
-#if 0
+#if !defined(MEMORY_SANITIZER)
   // TODO(crbug.com/1032090): This triggers an MSAN error.
   // Fix and enable this code.
   ClearString();
   RemoveTrailerIdFromDocument();
   EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
-  VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
-  VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
+  VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
+  VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
 #endif
 }
 
@@ -524,15 +527,13 @@
   VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
   VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
 
-#if 0
+#if !defined(MEMORY_SANITIZER)
   // TODO(crbug.com/1032090): This triggers an MSAN error.
   // Fix and enable this code.
-  // TODO(crbug.com/pdfium/1441): Output encryption dictionary may be bad.
-  // Fix and enable this code.
   ClearString();
   RemoveTrailerIdFromDocument();
   EXPECT_TRUE(FPDF_SaveAsCopy(document(), this, 0));
-  VerifySavedHelloWorldDocumentWithPassword(kAgeLatin1);
-  VerifySavedHelloWorldDocumentWithPassword(kAgeUTF8);
+  VerifySavedHelloWorldDocumentWithPassword(kHotelLatin1);
+  VerifySavedHelloWorldDocumentWithPassword(kHotelUTF8);
 #endif
 }