Skip to content

Commit

Permalink
Support decrypting V4/R4 files with AESV2 and no Length property
Browse files Browse the repository at this point in the history
  • Loading branch information
Arnaud TAMAILLON authored and BobLd committed Oct 17, 2024
1 parent 8cee4f4 commit ea95a7a
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,15 @@ public void CanReadDocumentWithEmptyStringEncryptedWithAESEncryptionAndOnlyIV()
}
}

[Fact]
public void CanReadDocumentWithNoKeyLengthAndRevision4()
{
using (var document = PdfDocument.Open(IntegrationHelpers.GetSpecificTestDocumentPath("r4_aesv2_no_length")))
{
Assert.Empty(document.Information.Producer);
}
}

private static string GetPath() => IntegrationHelpers.GetSpecificTestDocumentPath(FileName);
}
}
Binary file not shown.
17 changes: 14 additions & 3 deletions src/UglyToad.PdfPig/Encryption/EncryptionHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ public EncryptionHandler(EncryptionDictionary encryptionDictionary, TrailerDicti

cryptHandler = cryptHandlerLocal;

useAes = cryptHandlerLocal?.StreamDictionary?.Name == CryptDictionary.Method.AesV2
|| cryptHandlerLocal?.StreamDictionary?.Name == CryptDictionary.Method.AesV3;
useAes = cryptHandlerLocal.StreamDictionary.Name == CryptDictionary.Method.AesV2
|| cryptHandlerLocal.StreamDictionary.Name == CryptDictionary.Method.AesV3;
}

var charset = OtherEncodings.Iso88591;
Expand All @@ -96,7 +96,18 @@ public EncryptionHandler(EncryptionDictionary encryptionDictionary, TrailerDicti

var length = encryptionDictionary.EncryptionAlgorithmCode == EncryptionAlgorithmCode.Rc4OrAes40BitKey
? 5
: encryptionDictionary.KeyLength.GetValueOrDefault() / 8;
: encryptionDictionary.KeyLength switch
{
// this is as per the PDF specification, (PDF_ISO_32000-2, 7.6.2 Application of encryption, table 20, indicating Length default value is 40)
null when encryptionDictionary.EncryptionAlgorithmCode == EncryptionAlgorithmCode.Rc4OrAesGreaterThan40BitKey => 40,
null when encryptionDictionary.EncryptionAlgorithmCode == EncryptionAlgorithmCode.UnpublishedAlgorithm40To128BitKey => 40,
// this is based on a specific use case encountered and tested, in link with the pdf specification (PDF_ISO_32000-2, 7.6.5.3 Public-key encryption algorithms, table 25, CFM comments)
null when cryptHandler?.StreamDictionary.Name == CryptDictionary.Method.AesV2 => 128,
// this is speculation, in link with the pdf spec, in link with the pdf specification (PDF_ISO_32000-2, 7.6.5.3 Public-key encryption algorithms, table 25, CFM comments)
null when cryptHandler?.StreamDictionary.Name == CryptDictionary.Method.AesV3 => 256,
// other use cases
_ => encryptionDictionary.KeyLength.GetValueOrDefault()
} / 8;

var foundPassword = false;

Expand Down

0 comments on commit ea95a7a

Please sign in to comment.