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.hs46
1 files changed, 25 insertions, 21 deletions
diff --git a/Codec/Encryption/OpenPGP/ASCIIArmor/Decode.hs b/Codec/Encryption/OpenPGP/ASCIIArmor/Decode.hs
index e69087c..0376abc 100644
--- a/Codec/Encryption/OpenPGP/ASCIIArmor/Decode.hs
+++ b/Codec/Encryption/OpenPGP/ASCIIArmor/Decode.hs
@@ -26,17 +26,17 @@ import Data.Serialize.Put (runPut, putWord32be)
26import Data.String (IsString, fromString) 26import Data.String (IsString, fromString)
27import Data.Word (Word32) 27import Data.Word (Word32)
28 28
29decode :: (Integral a, Read a, Show a, IsString e) => ByteString -> Either e ([Armor a]) 29decode :: IsString e => ByteString -> Either e [Armor]
30decode bs = go (parse parseArmors bs) 30decode bs = go (parse parseArmors bs)
31 where 31 where
32 go (Fail t c e) = Left (fromString e) 32 go (Fail t c e) = Left (fromString e)
33 go (Partial cont) = go (cont B.empty) 33 go (Partial cont) = go (cont B.empty)
34 go (Done _ r) = Right r 34 go (Done _ r) = Right r
35 35
36parseArmors :: (Integral a, Read a, Show a) => Parser ([Armor a]) 36parseArmors :: Parser [Armor]
37parseArmors = many parseArmor 37parseArmors = many parseArmor
38 38
39parseArmor :: (Integral a, Read a, Show a) => Parser (Armor a) 39parseArmor :: Parser Armor
40parseArmor = do 40parseArmor = do
41 atype <- prefixed beginLine <?> "begin line" 41 atype <- prefixed beginLine <?> "begin line"
42 headers <- armorHeaders <?> "headers" 42 headers <- armorHeaders <?> "headers"
@@ -45,23 +45,27 @@ parseArmor = do
45 endLine atype <?> "end line" 45 endLine atype <?> "end line"
46 return $ Armor atype headers payload 46 return $ Armor atype headers payload
47 47
48beginLine :: (Integral a, Read a, Show a) => Parser (ArmorType a) 48beginLine :: Parser ArmorType
49beginLine = do 49beginLine = do
50 string "-----BEGIN PGP " 50 string "-----BEGIN PGP " <?> "leading minus-hyphens"
51 atype <- message <|> pubkey <|> privkey<|> parts <|> signature 51 atype <- pubkey <|> privkey <|> parts <|> message <|> signature
52 string "-----" 52 string "-----" <?> "trailing minus-hyphens"
53 many (satisfy (inClass " \t")) 53 many (satisfy (inClass " \t")) <?> "whitespace"
54 lineEnding 54 lineEnding <?> "line ending"
55 return atype 55 return atype
56 where 56 where
57 message = string "MESSAGE" >> return ArmorMessage 57 message = string "MESSAGE" *> return ArmorMessage
58 pubkey = string "PUBLIC KEY BLOCK" >> return ArmorPublicKeyBlock 58 pubkey = string "PUBLIC KEY BLOCK" *> return ArmorPublicKeyBlock
59 privkey = string "PRIVATE KEY BLOCK" >> return ArmorPrivateKeyBlock 59 privkey = string "PRIVATE KEY BLOCK" *> return ArmorPrivateKeyBlock
60 signature = string "SIGNATURE" >> return ArmorSignature 60 signature = string "SIGNATURE" *> return ArmorSignature
61 parts = do 61 parts = string "MESSAGE, PART " *> (partsdef <|> partsindef)
62 string "MESSAGE, PART " 62 partsdef = do
63 firstnum <- read . BC8.unpack . B.pack <$> many1 (satisfy isDigit_w8) 63 firstnum <- num
64 return $ ArmorSplitMessageIndefinite firstnum 64 word8 (fromIntegral . fromEnum $ '/')
65 secondnum <- num
66 return $ ArmorSplitMessage (B.pack firstnum) (B.pack secondnum)
67 partsindef = ArmorSplitMessageIndefinite . B.pack <$> num
68 num = many1 (satisfy isDigit_w8) <?> "number"
65 69
66lineEnding :: Parser ByteString 70lineEnding :: Parser ByteString
67lineEnding = string "\n" <|> string "\r\n" 71lineEnding = string "\n" <|> string "\r\n"
@@ -82,17 +86,17 @@ armorHeader = do
82blankishLine :: Parser ByteString 86blankishLine :: Parser ByteString
83blankishLine = many (satisfy (inClass " \t")) >> lineEnding 87blankishLine = many (satisfy (inClass " \t")) >> lineEnding
84 88
85endLine :: (Integral a, Read a, Show a) => ArmorType a -> Parser ByteString 89endLine :: ArmorType -> Parser ByteString
86endLine atype = do 90endLine atype = do
87 string $ "-----END PGP " `B.append` aType atype `B.append` "-----" 91 string $ "-----END PGP " `B.append` aType atype `B.append` "-----"
88 lineEnding 92 lineEnding
89 93
90aType :: (Integral a, Read a, Show a) => ArmorType a -> ByteString 94aType :: ArmorType -> ByteString
91aType (ArmorMessage) = BC8.pack "MESSAGE" 95aType (ArmorMessage) = BC8.pack "MESSAGE"
92aType (ArmorPublicKeyBlock) = BC8.pack "PUBLIC KEY BLOCK" 96aType (ArmorPublicKeyBlock) = BC8.pack "PUBLIC KEY BLOCK"
93aType (ArmorPrivateKeyBlock) = BC8.pack "PRIVATE KEY BLOCK" 97aType (ArmorPrivateKeyBlock) = BC8.pack "PRIVATE KEY BLOCK"
94aType (ArmorSplitMessage x y) = BC8.pack $ "MESSAGE, PART " ++ show x ++ "/" ++ show y 98aType (ArmorSplitMessage x y) = BC8.pack "MESSAGE, PART " `B.append` x `B.append` BC8.singleton '/' `B.append` y
95aType (ArmorSplitMessageIndefinite x) = BC8.pack $ "MESSAGE, PART " ++ show x 99aType (ArmorSplitMessageIndefinite x) = BC8.pack "MESSAGE, PART " `B.append` x
96aType (ArmorSignature) = BC8.pack "SIGNATURE" 100aType (ArmorSignature) = BC8.pack "SIGNATURE"
97 101
98base64Data :: Parser ByteString 102base64Data :: Parser ByteString