hOpenPGP 3.6.1 → 3.6.2
raw patch · 3 files changed
+67/−34 lines, 3 files
Files
- Data/Conduit/OpenPGP/Decrypt.hs +0/−18
- hOpenPGP.cabal +2/−2
- tests/Tests/Encryption.hs +65/−14
Data/Conduit/OpenPGP/Decrypt.hs view
@@ -1679,21 +1679,7 @@ SEIPDv2AlignedPKESK :: PKESKPayloadV6 -> AlignedPendingESK 'SEIPDv2EncryptedPayloadVersion- {- | A version 3 PKESK that precedes a SEIPDv2 payload. - RFC 9580 §5.13 explicitly permits version 3 PKESKs before a version 2- SEIPD packet, as a backward-compatibility allowance for implementations- that cannot yet produce v6 key material. The v3 PKESK carries the- session key wrapped with legacy (v3) asymmetric key wrapping; the SEIPD- v2 payload itself is still authenticated with modern AEAD. This- constructor therefore counts as "aligned" for SEIPDv2 — it does not- indicate a mis-assembled message — even though the PKESK version does- not match the SEIPD version.- -}- SEIPDv2AlignedLegacyPKESK- :: PKESKPayloadV3- -> AlignedPendingESK 'SEIPDv2EncryptedPayloadVersion- alignedPrecedingESKs :: EncryptedPayloadFlavor v -> [PendingESK]@@ -1712,9 +1698,6 @@ case esk of PendingSKESK (SKESKPayloadV6Packet skesk6) -> Just (SEIPDv2AlignedSKESK skesk6) PendingPKESK (PKESKPayloadV6Packet pkesk6) -> Just (SEIPDv2AlignedPKESK pkesk6)- -- v3 PKESK before SEIPDv2 is explicitly allowed by RFC 9580 §5.13;- -- see 'SEIPDv2AlignedLegacyPKESK' for details.- PendingPKESK (PKESKPayloadV3Packet pkesk3) -> Just (SEIPDv2AlignedLegacyPKESK pkesk3) _ -> Nothing ) @@ -1727,7 +1710,6 @@ LegacyAlignedPKESK pkesk3 -> PendingPKESK (PKESKPayloadV3Packet pkesk3) SEIPDv2AlignedSKESK skesk6 -> PendingSKESK (SKESKPayloadV6Packet skesk6) SEIPDv2AlignedPKESK pkesk6 -> PendingPKESK (PKESKPayloadV6Packet pkesk6)- SEIPDv2AlignedLegacyPKESK pkesk3 -> PendingPKESK (PKESKPayloadV3Packet pkesk3) ) payloadExpectedSymmetricAlgorithm
hOpenPGP.cabal view
@@ -1,6 +1,6 @@ Cabal-version: 3.4 Name: hOpenPGP-Version: 3.6.1+Version: 3.6.2 Synopsis: native Haskell implementation of OpenPGP (RFC9580) Description: native Haskell implementation of OpenPGP (RFC9580), with some backwards compatibility Homepage: https://salsa.debian.org/clint/hOpenPGP@@ -346,4 +346,4 @@ source-repository this type: git location: https://salsa.debian.org/clint/hOpenPGP.git- tag: v3.6.1+ tag: v3.6.2
tests/Tests/Encryption.hs view
@@ -565,6 +565,9 @@ "strict policy rejects SEIPDv2 with only misaligned ESK versions" testRejectsMisalignedESKVersionForSEIPDv2 , testCase+ "strict policy rejects legacy v3 PKESK before SEIPDv2"+ testRejectsLegacyPKESKBeforeSEIPDv2+ , testCase "strict policy discards misaligned ESK when aligned ESK is present" testDiscardsMisalignedESKWhenAlignedCandidateExists , testCase@@ -1434,6 +1437,46 @@ assertFailure ("Expected DecryptMalformedStructure but got: " ++ show other) +testRejectsLegacyPKESKBeforeSEIPDv2 :: Assertion+testRejectsLegacyPKESKBeforeSEIPDv2 = do+ pt <- encryptedSEIPDv2Packets+ let malformed =+ case pt of+ (_ : rest) ->+ PKESKPkt+ ( PKESKPayloadV3Packet+ ( PKESKPayloadV3+ 3+ (EightOctetKeyId (B.replicate 8 0))+ RSA+ (MPI 0 :| [])+ )+ )+ : rest+ _ -> pt+ passphrase = B.pack (map (fromIntegral . fromEnum) ("test" :: String))+ cb = const (pure passphrase)+ result <-+ try+ ( DC.runConduitRes $+ CL.sourceList malformed+ DC..| fuseBoth (testDecryptChecked cb) CL.consume+ )+ :: IO (Either SomeException (DecryptOutcome, [Pkt]))+ case result of+ Left err ->+ assertFailure+ ( "Expected DecryptMalformedStructure but got exception: "+ ++ show err+ )+ Right+ ( DecryptMalformedStructure DecryptStructureESKSEIPDMismatch+ , _+ ) -> pure ()+ Right (other, _) ->+ assertFailure+ ("Expected DecryptMalformedStructure but got: " ++ show other)+ testDiscardsMisalignedESKWhenAlignedCandidateExists :: Assertion testDiscardsMisalignedESKWhenAlignedCandidateExists = do pt <- encryptedSEIPDv2Packets@@ -4611,7 +4654,6 @@ ) >> fail "expected RSA public key" let sessionKey = B.replicate 32 0x42- salt = Salt (B.pack [0x00 .. 0x1f]) payload = "pkesk rsa unwrap via sha1-cfb protected key loaded from file" literalBlock = Block@@ -4624,7 +4666,12 @@ passphraseCallback _ = pure B.empty keyContextCallback pkt = pure (selectRecipientKeyInfo pkt keyInfos) encryptedResult <-- ( P15.encrypt publicKey sessionKey+ ( P15.encrypt+ publicKey+ ( B.singleton (fromFVal AES256)+ <> sessionKey+ <> checksum16Bytes sessionKey+ ) :: IO (Either RSA.Error B.ByteString) ) encryptedSessionMaterial <-@@ -4633,19 +4680,23 @@ assertFailure ("RSA PKESK encryption failed: " ++ show err) >> pure mempty Right ct -> pure ct+ let iv = IV (B.pack [0x00 .. 0x0f])+ cleartext = BL.toStrict (runPut (put literalBlock))+ cleartextWithMDC = cleartext <> mdcTrailerForSEIPDv1 iv cleartext ciphertext <-- case encryptSEIPDv2Payload- AES256- OCB- 6- salt- (SessionKey sessionKey)- (BL.toStrict (runPut (put literalBlock))) of- Left err ->- assertFailure- ("encryptSEIPDv2Payload failed: " ++ renderSEIPDv2Failure err)+ either+ ( \e ->+ assertFailure ("encryptOpenPGPCfbRaw failed: " ++ show e) >> pure mempty- Right ct -> pure ct+ )+ pure+ ( encryptOpenPGPCfbRaw+ OpenPGPCFBNoResyncW+ AES256+ iv+ cleartextWithMDC+ sessionKey+ ) let pkesk = PKESKPkt ( PKESKPayloadV3Packet@@ -4661,7 +4712,7 @@ CL.sourceList [ pkesk , SymEncIntegrityProtectedDataPkt- (SEIPD2 AES256 OCB 6 salt (BL.fromStrict ciphertext))+ (SEIPD1 1 (BL.fromStrict ciphertext)) ] DC..| conduitDecryptWithPKESKContext keyContextCallback