openpgp 0.1 → 0.2
raw patch · 4 files changed
+84/−15 lines, 4 files
Files
- Data/OpenPGP.hs +11/−2
- Data/OpenPGP/Crypto.hs +48/−1
- README +12/−6
- openpgp.cabal +13/−6
Data/OpenPGP.hs view
@@ -3,7 +3,7 @@ -- The recommended way to import this module is: -- -- > import qualified Data.OpenPGP as OpenPGP-module Data.OpenPGP (Message(..), Packet(..), SignatureSubpacket(..), HashAlgorithm(..), KeyAlgorithm(..), CompressionAlgorithm(..), MPI(..), fingerprint_material, signatures_and_data, signature_issuer) where+module Data.OpenPGP (Message(..), Packet(..), SignatureSubpacket(..), HashAlgorithm(..), KeyAlgorithm(..), CompressionAlgorithm(..), MPI(..), fingerprint_material, signatures_and_data, signature_issuer, calculate_signature_trailer) where import Control.Monad import Data.Bits@@ -403,6 +403,15 @@ ] where material = LZ.concat $ map (\f -> encode (key ! f)) (public_key_fields algorithm)+-- Proxy to make SecretKeyPacket work+fingerprint_material (SecretKeyPacket {version = 4,+ timestamp = timestamp,+ key_algorithm = algorithm,+ key = key}) =+ fingerprint_material PublicKeyPacket {version = 4,+ timestamp = timestamp,+ key_algorithm = algorithm,+ key = key} fingerprint_material p | version p `elem` [2, 3] = [n, e] where n = LZ.drop 2 (encode (key p ! 'n')) e = LZ.drop 2 (encode (key p ! 'e'))@@ -537,7 +546,7 @@ return len tag <- get :: Get Word8 -- This forces the whole packet to be consumed- packet <- getLazyByteString len+ packet <- getLazyByteString (len-1) return $ runGet (parse_signature_subpacket tag) packet -- | Find the keyid that issued a SignaturePacket
Data/OpenPGP/Crypto.hs view
@@ -4,13 +4,15 @@ -- The recommended way to import this module is: -- -- > import qualified Data.OpenPGP.Crypto as OpenPGP-module Data.OpenPGP.Crypto (verify, fingerprint) where+module Data.OpenPGP.Crypto (sign, verify, fingerprint) where import Data.Word+import Data.List (find) import Data.Map ((!)) import qualified Data.ByteString.Lazy as LZ import Data.Binary+import Codec.Utils (fromOctets) import qualified Codec.Encryption.RSA as RSA import qualified Data.Digest.MD5 as MD5 import qualified Data.Digest.SHA1 as SHA1@@ -91,3 +93,48 @@ sig = sigs !! sigidx (sigs, (OpenPGP.LiteralDataPacket {OpenPGP.content = dta}):_) = OpenPGP.signatures_and_data message++-- | Sign a message. Only supports RSA keys for now.+sign :: OpenPGP.Message -- ^ SecretKeys, one of which will be used+ -> OpenPGP.Message -- ^ Message containing LiteralData to sign+ -> OpenPGP.HashAlgorithm -- ^ HashAlgorithm to use is signature+ -> String -- ^ KeyID of key to choose or @[]@ for first+ -> Integer -- ^ Timestamp to put in signature+ -> OpenPGP.Message+sign keys message hsh keyid timestamp =+ OpenPGP.Message $ (sig' {+ OpenPGP.signature = OpenPGP.MPI $ toNum $ reverse final,+ OpenPGP.hash_head = toNum $ take 2 final+ }):m+ where+ -- toNum has explicit param so that it can remain polymorphic+ toNum l = fromOctets (256::Integer) l+ final = RSA.decrypt (n, d) encoded+ encoded = emsa_pkcs1_v1_5_encode dta (length n) hsh+ (n, d) = (keyfield_as_octets k 'n', keyfield_as_octets k 'd')+ dta = LZ.unpack $ LZ.append+ (OpenPGP.content dataP) (OpenPGP.trailer sig')+ sig' = sig {+ OpenPGP.trailer = OpenPGP.calculate_signature_trailer sig+ }+ sig = OpenPGP.SignaturePacket {+ OpenPGP.version = 4,+ OpenPGP.key_algorithm = OpenPGP.RSA,+ OpenPGP.hash_algorithm = hsh,+ OpenPGP.signature_type = stype,+ OpenPGP.hashed_subpackets = [+ OpenPGP.SignatureCreationTimePacket $ fromIntegral timestamp,+ OpenPGP.IssuerPacket keyid'+ ],+ OpenPGP.unhashed_subpackets = [],+ OpenPGP.signature = undefined,+ OpenPGP.trailer = undefined,+ OpenPGP.hash_head = undefined+ }+ keyid' = reverse $ take 16 $ reverse $ fingerprint k+ stype = if OpenPGP.format dataP == 'b' then 0x00 else 0x01+ Just k = find_key keys keyid+ Just dataP = find isLiteralData m+ OpenPGP.Message m = message+ isLiteralData (OpenPGP.LiteralDataPacket {}) = True+ isLiteralData _ = False
README view
@@ -1,12 +1,18 @@-OpenPGP-Haskell--This is an OpenPGP library inspired by my work on OpenPGP-PHP <http://github.com/bendiken/openpgp-php>.+This is an OpenPGP library inspired by my work on OpenPGP libraries in+Ruby <https://github.com/singpolyma/openpgp>,+PHP <http://github.com/singpolyma/openpgp-php>,+and Python <https://github.com/singpolyma/OpenPGP-Python>. -It defines types Message and Packet to represent OpenPGP messages as series of packets and then defines instances of Data.Binary for each to facilitate encoding/decoding.+It defines types to represent OpenPGP messages as a series of packets+and then defines instances of Data.Binary for each to facilitate+encoding/decoding. -There is also a wrapper around <http://hackage.haskell.org/package/Crypto> that currently does fingerprint generation and signature verification.+There is also a wrapper around <http://hackage.haskell.org/package/Crypto>+that currently does fingerprint generation, signature generation, and+signature verification (for RSA keys only). -It is intended that you use qualified imports with this library. If importing both modules, something like this will do:+It is intended that you use qualified imports with this library. If importing+both modules, something like this will do: > import qualified Data.OpenPGP as OpenPGP > import qualified Data.OpenPGP.Crypto as OpenPGP
openpgp.cabal view
@@ -1,5 +1,5 @@ name: openpgp-version: 0.1+version: 0.2 cabal-version: >= 1.8 license: OtherLicense license-file: COPYING@@ -13,15 +13,22 @@ homepage: http://github.com/singpolyma/OpenPGP-Haskell bug-reports: http://github.com/singpolyma/OpenPGP-Haskell/issues build-type: Simple-description: This is an OpenPGP library inspired by my work on OpenPGP-PHP <http://github.com/bendiken/openpgp-php>.- It defines types Message and Packet to represent OpenPGP messages as series- of packets and then defines instances of Data.Binary for each to facilitate+description:+ This is an OpenPGP library inspired by my work on OpenPGP libraries in+ Ruby <https://github.com/singpolyma/openpgp>,+ PHP <http://github.com/singpolyma/openpgp-php>,+ and Python <https://github.com/singpolyma/OpenPGP-Python>.+ .+ It defines types to represent OpenPGP messages as a series of packets+ and then defines instances of Data.Binary for each to facilitate encoding/decoding. . There is also a wrapper around <http://hackage.haskell.org/package/Crypto>- that currently does fingerprint generation and signature verification.+ that currently does fingerprint generation, signature generation, and+ signature verification (for RSA keys only). .- It is intended that you use qualified imports with this library. If importing both modules, something like this will do:+ It is intended that you use qualified imports with this library. If importing+ both modules, something like this will do: . > import qualified Data.OpenPGP as OpenPGP > import qualified Data.OpenPGP.Crypto as OpenPGP