summaryrefslogtreecommitdiff
path: root/Codec/Encryption/OpenPGP/ASCIIArmor/Encode.hs
diff options
context:
space:
mode:
Diffstat (limited to 'Codec/Encryption/OpenPGP/ASCIIArmor/Encode.hs')
-rw-r--r--Codec/Encryption/OpenPGP/ASCIIArmor/Encode.hs58
1 files changed, 58 insertions, 0 deletions
diff --git a/Codec/Encryption/OpenPGP/ASCIIArmor/Encode.hs b/Codec/Encryption/OpenPGP/ASCIIArmor/Encode.hs
new file mode 100644
index 0000000..d08c3c1
--- /dev/null
+++ b/Codec/Encryption/OpenPGP/ASCIIArmor/Encode.hs
@@ -0,0 +1,58 @@
1-- ASCIIArmor/Encode.hs: OpenPGP (RFC4880) ASCII armor implementation
2-- Copyright Ⓒ 2012 Clint Adams
3-- This software is released under the terms of the Expat (MIT) license.
4-- (See the LICENSE file).
5
6module Codec.Encryption.OpenPGP.ASCIIArmor.Encode (
7 armor
8) where
9
10import Codec.Encryption.OpenPGP.Serialize (putPackets)
11import Codec.Encryption.OpenPGP.Types
12import Data.ByteString (ByteString)
13import qualified Data.ByteString as B
14import qualified Data.ByteString.Char8 as BC8
15import qualified Data.ByteString.Base64 as Base64
16import Data.Digest.CRC24 (crc24)
17import Data.Serialize.Put (runPut, putWord32be)
18import Data.String (IsString, fromString)
19
20armor :: (Integral a, Show a) => Armor a -> ByteString
21armor (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
22
23blankLine :: ByteString
24blankLine = BC8.singleton '\n'
25
26beginLine :: (Integral a, Show a) => ArmorType a -> ByteString
27beginLine atype = BC8.pack "-----BEGIN PGP " `B.append` aType atype `B.append` BC8.pack "-----\n"
28
29endLine :: (Integral a, Show a) => ArmorType a -> ByteString
30endLine atype = BC8.pack "-----END PGP " `B.append` aType atype `B.append` BC8.pack "-----\n"
31
32aType :: (Integral a, Show a) => ArmorType a -> ByteString
33aType (ArmorMessage) = BC8.pack "MESSAGE"
34aType (ArmorPublicKeyBlock) = BC8.pack "PUBLIC KEY BLOCK"
35aType (ArmorPrivateKeyBlock) = BC8.pack "PRIVATE KEY BLOCK"
36aType (ArmorSplitMessage x y) = BC8.pack $ "MESSAGE, PART " ++ show x ++ "/" ++ show y
37aType (ArmorSplitMessageIndefinite x) = BC8.pack $ "MESSAGE, PART " ++ show x
38aType (ArmorSignature) = BC8.pack "SIGNATURE"
39
40armorHeaders :: [ArmorHeader] -> ByteString
41armorHeaders ahs = BC8.unlines . map armorHeader $ ahs
42 where
43 armorHeader :: ArmorHeader -> ByteString
44 armorHeader (k, v) = k `B.append` BC8.pack ": " `B.append` v
45
46opgpStream :: [Packet] -> ByteString
47opgpStream = runPut . putPackets
48
49armorData :: ByteString -> ByteString
50armorData = BC8.unlines . wrap76 . Base64.encode
51
52wrap76 :: ByteString -> [ByteString]
53wrap76 bs
54 | B.null bs = []
55 | otherwise = B.take 76 bs : wrap76 (B.drop 76 bs)
56
57armorChecksum :: ByteString -> ByteString
58armorChecksum = BC8.cons '=' . armorData . B.tail . runPut . putWord32be . crc24