diff options
Diffstat (limited to 'Codec/Encryption/OpenPGP/ASCIIArmor/Encode.hs')
-rw-r--r-- | Codec/Encryption/OpenPGP/ASCIIArmor/Encode.hs | 25 |
1 files changed, 11 insertions, 14 deletions
diff --git a/Codec/Encryption/OpenPGP/ASCIIArmor/Encode.hs b/Codec/Encryption/OpenPGP/ASCIIArmor/Encode.hs index c9c9641..8853be3 100644 --- a/Codec/Encryption/OpenPGP/ASCIIArmor/Encode.hs +++ b/Codec/Encryption/OpenPGP/ASCIIArmor/Encode.hs | |||
@@ -1,14 +1,13 @@ | |||
1 | -- ASCIIArmor/Encode.hs: OpenPGP (RFC4880) ASCII armor implementation | 1 | -- ASCIIArmor/Encode.hs: OpenPGP (RFC4880) ASCII armor implementation |
2 | -- Copyright Ⓒ 2012 Clint Adams | 2 | -- Copyright Ⓒ 2012 Clint Adams |
3 | -- This software is released under the terms of the Expat (MIT) license. | 3 | -- This software is released under the terms of the ISC license. |
4 | -- (See the LICENSE file). | 4 | -- (See the LICENSE file). |
5 | 5 | ||
6 | module Codec.Encryption.OpenPGP.ASCIIArmor.Encode ( | 6 | module Codec.Encryption.OpenPGP.ASCIIArmor.Encode ( |
7 | armor | 7 | armor |
8 | ) where | 8 | ) where |
9 | 9 | ||
10 | import Codec.Encryption.OpenPGP.Serialize () | 10 | import Codec.Encryption.OpenPGP.ASCIIArmor.Types |
11 | import Codec.Encryption.OpenPGP.Types | ||
12 | import Data.ByteString (ByteString) | 11 | import Data.ByteString (ByteString) |
13 | import qualified Data.ByteString as B | 12 | import qualified Data.ByteString as B |
14 | import qualified Data.ByteString.Char8 as BC8 | 13 | import qualified Data.ByteString.Char8 as BC8 |
@@ -19,7 +18,7 @@ import Data.Serialize.Put (runPut, putWord32be) | |||
19 | import Data.String (IsString, fromString) | 18 | import Data.String (IsString, fromString) |
20 | 19 | ||
21 | armor :: (Integral a, Show a) => Armor a -> ByteString | 20 | armor :: (Integral a, Show a) => Armor a -> ByteString |
22 | armor (Armor atype ahs ps) = beginLine atype `B.append` armorHeaders ahs `B.append` blankLine `B.append` armorData (opgpStream ps) `B.append` armorChecksum (opgpStream ps) `B.append` endLine atype | 21 | armor (Armor atype ahs bs) = beginLine atype `B.append` armorHeaders ahs `B.append` blankLine `B.append` armorData bs `B.append` armorChecksum bs `B.append` endLine atype |
23 | 22 | ||
24 | blankLine :: ByteString | 23 | blankLine :: ByteString |
25 | blankLine = BC8.singleton '\n' | 24 | blankLine = BC8.singleton '\n' |
@@ -38,22 +37,20 @@ aType (ArmorSplitMessage x y) = BC8.pack $ "MESSAGE, PART " ++ show x ++ "/" ++ | |||
38 | aType (ArmorSplitMessageIndefinite x) = BC8.pack $ "MESSAGE, PART " ++ show x | 37 | aType (ArmorSplitMessageIndefinite x) = BC8.pack $ "MESSAGE, PART " ++ show x |
39 | aType (ArmorSignature) = BC8.pack "SIGNATURE" | 38 | aType (ArmorSignature) = BC8.pack "SIGNATURE" |
40 | 39 | ||
41 | armorHeaders :: [ArmorHeader] -> ByteString | 40 | armorHeaders :: [(String, String)] -> ByteString |
42 | armorHeaders ahs = BC8.unlines . map armorHeader $ ahs | 41 | armorHeaders ahs = BC8.unlines . map armorHeader $ ahs |
43 | where | 42 | where |
44 | armorHeader :: ArmorHeader -> ByteString | 43 | armorHeader :: (String, String) -> ByteString |
45 | armorHeader (k, v) = k `B.append` BC8.pack ": " `B.append` v | 44 | armorHeader (k, v) = BC8.pack k `B.append` BC8.pack ": " `B.append` BC8.pack v |
46 | |||
47 | opgpStream :: [Packet] -> ByteString | ||
48 | opgpStream = runPut . put . Block | ||
49 | 45 | ||
50 | armorData :: ByteString -> ByteString | 46 | armorData :: ByteString -> ByteString |
51 | armorData = BC8.unlines . wrap76 . Base64.encode | 47 | armorData = BC8.unlines . wordWrap 64 . Base64.encode |
52 | 48 | ||
53 | wrap76 :: ByteString -> [ByteString] | 49 | wordWrap :: Int -> ByteString -> [ByteString] |
54 | wrap76 bs | 50 | wordWrap lw bs |
55 | | B.null bs = [] | 51 | | B.null bs = [] |
56 | | otherwise = B.take 76 bs : wrap76 (B.drop 76 bs) | 52 | | lw < 1 || lw > 76 = wordWrap 76 bs |
53 | | otherwise = B.take lw bs : wordWrap lw (B.drop lw bs) | ||
57 | 54 | ||
58 | armorChecksum :: ByteString -> ByteString | 55 | armorChecksum :: ByteString -> ByteString |
59 | armorChecksum = BC8.cons '=' . armorData . B.tail . runPut . putWord32be . crc24 | 56 | armorChecksum = BC8.cons '=' . armorData . B.tail . runPut . putWord32be . crc24 |