summaryrefslogtreecommitdiff
path: root/Codec/Encryption/OpenPGP/ASCIIArmor/Decode.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Codec/Encryption/OpenPGP/ASCIIArmor/Decode.hs')
-rw-r--r--Codec/Encryption/OpenPGP/ASCIIArmor/Decode.hs39
1 files changed, 18 insertions, 21 deletions
diff --git a/Codec/Encryption/OpenPGP/ASCIIArmor/Decode.hs b/Codec/Encryption/OpenPGP/ASCIIArmor/Decode.hs
index b1cc5c0..98934a0 100644
--- a/Codec/Encryption/OpenPGP/ASCIIArmor/Decode.hs
+++ b/Codec/Encryption/OpenPGP/ASCIIArmor/Decode.hs
@@ -17,7 +17,6 @@ import Data.Attoparsec.ByteString (Parser, many1, string, inClass, notInClass, s
17import qualified Data.Attoparsec.ByteString as AS 17import qualified Data.Attoparsec.ByteString as AS
18import qualified Data.Attoparsec.ByteString.Lazy as AL 18import qualified Data.Attoparsec.ByteString.Lazy as AL
19import Data.Attoparsec.ByteString.Char8 (isDigit_w8, anyChar) 19import Data.Attoparsec.ByteString.Char8 (isDigit_w8, anyChar)
20import Data.Attoparsec.Combinator (manyTill)
21import Data.Bits (shiftL) 20import Data.Bits (shiftL)
22import Data.ByteString (ByteString) 21import Data.ByteString (ByteString)
23import qualified Data.ByteString as B 22import qualified Data.ByteString as B
@@ -25,23 +24,21 @@ import qualified Data.ByteString.Lazy as BL
25import qualified Data.ByteString.Char8 as BC8 24import qualified Data.ByteString.Char8 as BC8
26import qualified Data.ByteString.Base64 as Base64 25import qualified Data.ByteString.Base64 as Base64
27import Data.Digest.CRC24 (crc24) 26import Data.Digest.CRC24 (crc24)
28import Data.Serialize (get)
29import Data.Serialize.Get (Get, runGet, getWord8) 27import Data.Serialize.Get (Get, runGet, getWord8)
30import Data.Serialize.Put (runPut, putWord32be)
31import Data.String (IsString, fromString) 28import Data.String (IsString, fromString)
32import Data.Word (Word32) 29import Data.Word (Word32)
33 30
34decode :: IsString e => ByteString -> Either e [Armor] 31decode :: IsString e => ByteString -> Either e [Armor]
35decode bs = go (AS.parse parseArmors bs) 32decode bs = go (AS.parse parseArmors bs)
36 where 33 where
37 go (AS.Fail t c e) = Left (fromString e) 34 go (AS.Fail _ _ e) = Left (fromString e)
38 go (AS.Partial cont) = go (cont B.empty) 35 go (AS.Partial cont) = go (cont B.empty)
39 go (AS.Done _ r) = Right r 36 go (AS.Done _ r) = Right r
40 37
41decodeLazy :: IsString e => BL.ByteString -> Either e [Armor] 38decodeLazy :: IsString e => BL.ByteString -> Either e [Armor]
42decodeLazy bs = go (AL.parse parseArmors bs) 39decodeLazy bs = go (AL.parse parseArmors bs)
43 where 40 where
44 go (AL.Fail t c e) = Left (fromString e) 41 go (AL.Fail _ _ e) = Left (fromString e)
45 go (AL.Done _ r) = Right r 42 go (AL.Done _ r) = Right r
46 43
47parseArmors :: Parser [Armor] 44parseArmors :: Parser [Armor]
@@ -52,10 +49,10 @@ parseArmor = prefixed (clearsigned <|> armor) <?> "armor"
52 49
53clearsigned :: Parser Armor 50clearsigned :: Parser Armor
54clearsigned = do 51clearsigned = do
55 string "-----BEGIN PGP SIGNED MESSAGE-----" <?> "clearsign header" 52 _ <- string "-----BEGIN PGP SIGNED MESSAGE-----" <?> "clearsign header"
56 lineEnding <?> "line ending" 53 _ <- lineEnding <?> "line ending"
57 headers <- armorHeaders <?> "clearsign headers" 54 headers <- armorHeaders <?> "clearsign headers"
58 blankishLine <?> "blank line" 55 _ <- blankishLine <?> "blank line"
59 cleartext <- dashEscapedCleartext 56 cleartext <- dashEscapedCleartext
60 sig <- armor 57 sig <- armor
61 return $ ClearSigned headers (BL.fromChunks [cleartext]) sig 58 return $ ClearSigned headers (BL.fromChunks [cleartext]) sig
@@ -64,18 +61,18 @@ armor :: Parser Armor
64armor = do 61armor = do
65 atype <- beginLine <?> "begin line" 62 atype <- beginLine <?> "begin line"
66 headers <- armorHeaders <?> "headers" 63 headers <- armorHeaders <?> "headers"
67 blankishLine <?> "blank line" 64 _ <- blankishLine <?> "blank line"
68 payload <- base64Data <?> "base64 data" 65 payload <- base64Data <?> "base64 data"
69 endLine atype <?> "end line" 66 _ <- endLine atype <?> "end line"
70 return $ Armor atype headers (BL.fromChunks [payload]) 67 return $ Armor atype headers (BL.fromChunks [payload])
71 68
72beginLine :: Parser ArmorType 69beginLine :: Parser ArmorType
73beginLine = do 70beginLine = do
74 string "-----BEGIN PGP " <?> "leading minus-hyphens" 71 _ <- string "-----BEGIN PGP " <?> "leading minus-hyphens"
75 atype <- pubkey <|> privkey <|> parts <|> message <|> signature 72 atype <- pubkey <|> privkey <|> parts <|> message <|> signature
76 string "-----" <?> "trailing minus-hyphens" 73 _ <- string "-----" <?> "trailing minus-hyphens"
77 many (satisfy (inClass " \t")) <?> "whitespace" 74 _ <- many (satisfy (inClass " \t")) <?> "whitespace"
78 lineEnding <?> "line ending" 75 _ <- lineEnding <?> "line ending"
79 return atype 76 return atype
80 where 77 where
81 message = string "MESSAGE" *> return ArmorMessage 78 message = string "MESSAGE" *> return ArmorMessage
@@ -85,7 +82,7 @@ beginLine = do
85 parts = string "MESSAGE, PART " *> (partsdef <|> partsindef) 82 parts = string "MESSAGE, PART " *> (partsdef <|> partsindef)
86 partsdef = do 83 partsdef = do
87 firstnum <- num 84 firstnum <- num
88 word8 (fromIntegral . fromEnum $ '/') 85 _ <- word8 (fromIntegral . fromEnum $ '/')
89 secondnum <- num 86 secondnum <- num
90 return $ ArmorSplitMessage (BL.pack firstnum) (BL.pack secondnum) 87 return $ ArmorSplitMessage (BL.pack firstnum) (BL.pack secondnum)
91 partsindef = ArmorSplitMessageIndefinite . BL.pack <$> num 88 partsindef = ArmorSplitMessageIndefinite . BL.pack <$> num
@@ -100,9 +97,9 @@ armorHeaders = many armorHeader
100armorHeader :: Parser (String, String) 97armorHeader :: Parser (String, String)
101armorHeader = do 98armorHeader = do
102 key <- many1 (satisfy (inClass "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")) 99 key <- many1 (satisfy (inClass "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"))
103 string ": " 100 _ <- string ": "
104 val <- many1 (satisfy (notInClass "\n\r")) 101 val <- many1 (satisfy (notInClass "\n\r"))
105 lineEnding 102 _ <- lineEnding
106 return (w8sToString key, w8sToString val) 103 return (w8sToString key, w8sToString val)
107 where 104 where
108 w8sToString = BC8.unpack . B.pack 105 w8sToString = BC8.unpack . B.pack
@@ -112,7 +109,7 @@ blankishLine = many (satisfy (inClass " \t")) *> lineEnding
112 109
113endLine :: ArmorType -> Parser ByteString 110endLine :: ArmorType -> Parser ByteString
114endLine atype = do 111endLine atype = do
115 string $ "-----END PGP " `B.append` aType atype `B.append` "-----" 112 _ <- string $ "-----END PGP " `B.append` aType atype `B.append` "-----"
116 lineEnding 113 lineEnding
117 114
118aType :: ArmorType -> ByteString 115aType :: ArmorType -> ByteString
@@ -140,16 +137,16 @@ base64Data = do
140 base64Line = do 137 base64Line = do
141 b64 <- many1 (satisfy (inClass "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")) 138 b64 <- many1 (satisfy (inClass "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"))
142 pad <- many (word8 (fromIntegral . fromEnum $ '=')) 139 pad <- many (word8 (fromIntegral . fromEnum $ '='))
143 lineEnding 140 _ <- lineEnding
144 let line = B.pack b64 `B.append` B.pack pad 141 let line = B.pack b64 `B.append` B.pack pad
145 case Base64.decode line of 142 case Base64.decode line of
146 Left err -> fail err 143 Left err -> fail err
147 Right bs -> return bs 144 Right bs -> return bs
148 checksumLine :: Parser ByteString 145 checksumLine :: Parser ByteString
149 checksumLine = do 146 checksumLine = do
150 word8 (fromIntegral . fromEnum $ '=') 147 _ <- word8 (fromIntegral . fromEnum $ '=')
151 b64 <- many1 (satisfy (inClass "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/")) 148 b64 <- many1 (satisfy (inClass "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"))
152 lineEnding 149 _ <- lineEnding
153 let line = B.pack b64 150 let line = B.pack b64
154 case Base64.decode line of 151 case Base64.decode line of
155 Left err -> fail err 152 Left err -> fail err