hOpenPGP 3.6 → 3.6.1
raw patch · 6 files changed
+57/−34 lines, 6 files
Files
- Codec/Encryption/OpenPGP/Encrypt.hs +6/−2
- Codec/Encryption/OpenPGP/Internal.hs +13/−15
- Codec/Encryption/OpenPGP/Types/Internal/Base.hs +3/−3
- hOpenPGP.cabal +2/−2
- tests/Tests/Encryption.hs +3/−3
- tests/Tests/Serialization.hs +30/−9
Codec/Encryption/OpenPGP/Encrypt.hs view
@@ -2078,7 +2078,9 @@ ECDSAPubKey (ECDSA_PublicKey recipientPub) -> do (ephemeralPub, ephemeralPriv) <- ECCGen.generate (ECDSA.public_curve recipientPub)- case point2MBS (ECDSA.public_q ephemeralPub) of+ case point2MBS+ (ECDSA.public_curve ephemeralPub)+ (ECDSA.public_q ephemeralPub) of Nothing -> pure ( Left@@ -2164,7 +2166,9 @@ ECDSAPubKey (ECDSA_PublicKey recipientPub) -> do (ephemeralPub, ephemeralPriv) <- ECCGen.generate (ECDSA.public_curve recipientPub)- case point2MBS (ECDSA.public_q ephemeralPub) of+ case point2MBS+ (ECDSA.public_curve ephemeralPub)+ (ECDSA.public_q ephemeralPub) of Nothing -> pure ( Left
Codec/Encryption/OpenPGP/Internal.hs view
@@ -190,14 +190,14 @@ pubkeyToMPIs (ElGamalPubKey p g y) = [MPI p, MPI g, MPI y] pubkeyToMPIs ( ECDHPubKey- (ECDSAPubKey (ECDSA_PublicKey (ECDSA.PublicKey _ q)))+ (ECDSAPubKey (ECDSA_PublicKey (ECDSA.PublicKey curve q))) _ _ ) =- [MPI (os2ip (pointToBSOrError q))]+ [MPI (os2ip (pointToBSOrError curve q))] pubkeyToMPIs (ECDHPubKey (EdDSAPubKey _ ep) _ _) = [MPI (edPointInteger ep)]-pubkeyToMPIs (ECDSAPubKey ((ECDSA_PublicKey (ECDSA.PublicKey _ q)))) =- [MPI (os2ip (pointToBSOrError q))]+pubkeyToMPIs (ECDSAPubKey ((ECDSA_PublicKey (ECDSA.PublicKey curve q)))) =+ [MPI (os2ip (pointToBSOrError curve q))] pubkeyToMPIs (EdDSAPubKey _ ep) = [MPI (edPointInteger ep)] edPointInteger :: EdPoint -> Integer@@ -240,22 +240,20 @@ [0x2B, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01] curveToCurveoidBS Curve448 = Right $ B.pack [0x2B, 0x65, 0x6F] -point2MBS :: ECCT.PublicPoint -> Maybe B.ByteString-point2MBS (ECCT.Point x y)- | B.null xb || B.null yb = Nothing- | B.length xb /= B.length yb = Nothing- | otherwise = Just (B.concat [B.singleton 0x04, xb, yb])+point2MBS :: ECCT.Curve -> ECCT.PublicPoint -> Maybe B.ByteString+point2MBS curve (ECCT.Point x y) = Just $ B.concat [B.singleton 0x04, pad x, pad y] where- xb = i2osp x- yb = i2osp y-point2MBS ECCT.PointO = Nothing+ pad n = leftPadTo coordBytes (i2osp n)+ coordBytes = (ECCT.curveSizeBits curve + 7) `div` 8+point2MBS _ ECCT.PointO = Nothing -pointToBSOrError :: ECCT.PublicPoint -> B.ByteString-pointToBSOrError point =+pointToBSOrError+ :: ECCT.Curve -> ECCT.PublicPoint -> B.ByteString+pointToBSOrError curve point = case point of ECCT.PointO -> error "OpenPGP forbids serializing the point at infinity" _ ->- case point2MBS point of+ case point2MBS curve point of Just bs -> bs Nothing -> error
Codec/Encryption/OpenPGP/Types/Internal/Base.hs view
@@ -2224,7 +2224,7 @@ = NISTP256 | NISTP384 | NISTP521- | Curve25519+ | Curve25519 -- FIXME: rename this to Curve25519 legacy | Curve448 deriving (Data, Eq, Generic, Ord, Show, Typeable) @@ -2232,8 +2232,8 @@ pretty NISTP256 = pretty "NIST P-256" pretty NISTP384 = pretty "NIST P-384" pretty NISTP521 = pretty "NIST P-521"- pretty Curve25519 = pretty "Curve25519"- pretty Curve448 = pretty "Curve448"+ pretty Curve25519 = pretty "Curve25519 (legacy)"+ pretty Curve448 = pretty "Curve448 (legacy)" instance Hashable ECCCurve
hOpenPGP.cabal view
@@ -1,6 +1,6 @@ Cabal-version: 3.4 Name: hOpenPGP-Version: 3.6+Version: 3.6.1 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+ tag: v3.6.1
tests/Tests/Encryption.hs view
@@ -4720,7 +4720,7 @@ maybe (error "failed to encode ephemeral point") id- (point2MBS (ECDSA.public_q ephPub))+ (point2MBS (ECDSA.public_curve ephPub) (ECDSA.public_q ephPub)) pkesk = PKESKPkt ( PKESKPayloadV3Packet@@ -4830,7 +4830,7 @@ maybe (error "failed to encode ephemeral point") id- (point2MBS (ECDSA.public_q ephPub))+ (point2MBS (ECDSA.public_curve ephPub) (ECDSA.public_q ephPub)) truncatedEphemeral = B.take (B.length ephPointBytes - 1) ephPointBytes pkesk = PKESKPkt@@ -6255,7 +6255,7 @@ maybe (error "failed to encode ephemeral point") id- (point2MBS (ECDSA.public_q ephPub))+ (point2MBS (ECDSA.public_curve ephPub) (ECDSA.public_q ephPub)) pkesk = PKESKPkt ( PKESKPayloadV3Packet
tests/Tests/Serialization.hs view
@@ -10,7 +10,7 @@ import Control.Lens ((^.)) import Control.Monad (forM_) import qualified Crypto.Error as CE-import Crypto.Number.Serialize (os2ip)+import Crypto.Number.Serialize (i2osp, os2ip) import qualified Crypto.PubKey.ECC.ECDSA as ECDSA import qualified Crypto.PubKey.ECC.Types as ECCT import qualified Crypto.PubKey.Ed25519 as Ed25519@@ -51,6 +51,7 @@ import Codec.Encryption.OpenPGP.Internal ( PktStreamContext (..) , emptyPSC+ , leftPadTo , point2MBS ) import Codec.Encryption.OpenPGP.KeyringParser@@ -353,8 +354,11 @@ "should not serialize point at infinity" testPointAtInfinitySerialization , testCase- "should reject mismatched EC coordinate widths"- testPointSerializationRejectsMismatchedCoordinateWidths+ "should pad EC coordinates to fixed width per RFC 9580 §13.2"+ testPointSerializationPadsCoordinatesToFixedWidth+ , testCase+ "should pad P-521 EC coordinates to 66-byte field width"+ testPointSerializationP521PadsTo66Bytes ] , testGroup "TKUnknown Serialization group"@@ -653,15 +657,32 @@ assertEqual "point at infinity should not serialize" Nothing- (point2MBS ECCT.PointO)+ (point2MBS (ECCT.getCurveByName ECCT.SEC_p256r1) ECCT.PointO) -testPointSerializationRejectsMismatchedCoordinateWidths+testPointSerializationPadsCoordinatesToFixedWidth :: Assertion-testPointSerializationRejectsMismatchedCoordinateWidths =+testPointSerializationPadsCoordinatesToFixedWidth = assertEqual- "point serialization should reject mismatched coordinate widths"- Nothing- (point2MBS (ECCT.Point 1 256))+ "point serialization should pad coordinates to the fixed field width (RFC 9580 §13.2)"+ ( Just+ (B.cons 0x04 (leftPadTo 32 (i2osp 1) <> leftPadTo 32 (i2osp 1)))+ )+ (point2MBS (ECCT.getCurveByName ECCT.SEC_p256r1) (ECCT.Point 1 1))++{- | Regression test: P-521 has a 521-bit prime, so coordinates+can be 1..66 bytes long when minimally encoded. Per RFC 9580+section 13.2 the wire form must use the fixed field width+@B = ceil(521/8) = 66@ bytes per coordinate regardless.+-}+testPointSerializationP521PadsTo66Bytes+ :: Assertion+testPointSerializationP521PadsTo66Bytes =+ assertEqual+ "P-521 EC point serialization should always produce 1 + 2*66 = 133 bytes"+ (Just 133)+ ( B.length+ <$> point2MBS (ECCT.getCurveByName ECCT.SEC_p521r1) (ECCT.Point 1 1)+ ) testSEIPDv2PacketRoundTrip :: Assertion testSEIPDv2PacketRoundTrip = do