diff options
Diffstat (limited to 'Data/OpenPGP/Util/Sign.hs')
-rw-r--r-- | Data/OpenPGP/Util/Sign.hs | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/Data/OpenPGP/Util/Sign.hs b/Data/OpenPGP/Util/Sign.hs index 466f05c..8663a0d 100644 --- a/Data/OpenPGP/Util/Sign.hs +++ b/Data/OpenPGP/Util/Sign.hs | |||
@@ -1,4 +1,5 @@ | |||
1 | {-# LANGUAGE ScopedTypeVariables #-} | 1 | {-# LANGUAGE ScopedTypeVariables #-} |
2 | {-# LANGUAGE CPP #-} | ||
2 | module Data.OpenPGP.Util.Sign where | 3 | module Data.OpenPGP.Util.Sign where |
3 | 4 | ||
4 | import qualified Data.OpenPGP as OpenPGP | 5 | import qualified Data.OpenPGP as OpenPGP |
@@ -8,10 +9,16 @@ import qualified Data.ByteString as BS | |||
8 | import qualified Data.ByteString.Lazy as LZ | 9 | import qualified Data.ByteString.Lazy as LZ |
9 | import Data.Bits ( (.|.), shiftL ) | 10 | import Data.Bits ( (.|.), shiftL ) |
10 | import Control.Applicative ( (<$>) ) | 11 | import Control.Applicative ( (<$>) ) |
12 | #if defined(VERSION_cryptonite) | ||
13 | import Data.Hourglass | ||
14 | import System.Hourglass | ||
15 | #else | ||
11 | import Data.Time.Clock.POSIX | 16 | import Data.Time.Clock.POSIX |
17 | #endif | ||
12 | import Control.Exception as Exception (IOException(..),catch) | 18 | import Control.Exception as Exception (IOException(..),catch) |
13 | 19 | ||
14 | import Data.OpenPGP.Util.Fingerprint (fingerprint) | 20 | import Data.OpenPGP.Util.Fingerprint (fingerprint) |
21 | import Data.OpenPGP.Util.Gen | ||
15 | 22 | ||
16 | import qualified Crypto.Random as Vincent | 23 | import qualified Crypto.Random as Vincent |
17 | import qualified Crypto.PubKey.DSA as Vincent.DSA | 24 | import qualified Crypto.PubKey.DSA as Vincent.DSA |
@@ -44,14 +51,12 @@ privateRSAkey k = | |||
44 | q = keyParam 'q' k | 51 | q = keyParam 'q' k |
45 | pubkey = rsaKey k | 52 | pubkey = rsaKey k |
46 | 53 | ||
47 | |||
48 | |||
49 | -- | Make a signature | 54 | -- | Make a signature |
50 | -- | 55 | -- |
51 | -- In order to set more options on a signature, pass in a signature packet. | 56 | -- In order to set more options on a signature, pass in a signature packet. |
52 | -- Operation is unsafe in that it silently re-uses "random" bytes when | 57 | -- Operation is unsafe in that it silently re-uses "random" bytes when |
53 | -- entropy runs out. Use pgpSign for a safer interface. | 58 | -- entropy runs out. Use pgpSign for a safer interface. |
54 | unsafeSign :: (Vincent.CPRG g) => -- CryptoRandomGen g) => | 59 | unsafeSign :: (RG g) => -- CryptoRandomGen g) => |
55 | OpenPGP.Message -- ^ SecretKeys, one of which will be used | 60 | OpenPGP.Message -- ^ SecretKeys, one of which will be used |
56 | -> OpenPGP.SignatureOver -- ^ Data to sign, and optional signature packet | 61 | -> OpenPGP.SignatureOver -- ^ Data to sign, and optional signature packet |
57 | -> OpenPGP.HashAlgorithm -- ^ HashAlgorithm to use in signature | 62 | -> OpenPGP.HashAlgorithm -- ^ HashAlgorithm to use in signature |
@@ -67,11 +72,22 @@ unsafeSign keys over hsh keyid timestamp g = (over {OpenPGP.signatures_over = [s | |||
67 | kalgo | kalgo `elem` [OpenPGP.RSA,OpenPGP.RSA_S] -> ([toNum rsaFinal], g) | 72 | kalgo | kalgo `elem` [OpenPGP.RSA,OpenPGP.RSA_S] -> ([toNum rsaFinal], g) |
68 | | otherwise -> | 73 | | otherwise -> |
69 | error ("Unsupported key algorithm " ++ show kalgo ++ " in sign") | 74 | error ("Unsupported key algorithm " ++ show kalgo ++ " in sign") |
75 | #if defined(VERSION_cryptonite) | ||
76 | (Vincent.DSA.Signature dsaR dsaS,dsaG) = let k' = privateDSAkey k in | ||
77 | case desc of | ||
78 | HashDescr h -> Vincent.withDRG g $ Vincent.DSA.sign k' h dta -- XXX: What happend to dsaTruncate ? | ||
79 | (Vincent.ECDSA.Signature ecdsaR ecdsaS,ecdsaG) = let k' = privateECDSAkey k in | ||
80 | case desc of | ||
81 | HashDescr h -> Vincent.withDRG g $ Vincent.ECDSA.sign k' h dta | ||
82 | (Right rsaFinal,_) = case desc of | ||
83 | HashDescr h -> Vincent.withDRG g $ Vincent.RSA.signSafer (Just h) (privateRSAkey k) dta | ||
84 | #else | ||
70 | (Vincent.DSA.Signature dsaR dsaS,dsaG) = let k' = privateDSAkey k in | 85 | (Vincent.DSA.Signature dsaR dsaS,dsaG) = let k' = privateDSAkey k in |
71 | Vincent.DSA.sign g k' (dsaTruncate k' . bhash) dta | 86 | Vincent.DSA.sign g k' (dsaTruncate k' . bhash) dta |
72 | (Vincent.ECDSA.Signature ecdsaR ecdsaS,ecdsaG) = let k' = privateECDSAkey k in | 87 | (Vincent.ECDSA.Signature ecdsaR ecdsaS,ecdsaG) = let k' = privateECDSAkey k in |
73 | Vincent.ECDSA.sign g k' bhash dta | 88 | Vincent.ECDSA.sign g k' bhash dta |
74 | (Right rsaFinal,_) = Vincent.RSA.signSafer g desc (privateRSAkey k) dta | 89 | (Right rsaFinal,_) = Vincent.RSA.signSafer g desc (privateRSAkey k) dta |
90 | #endif | ||
75 | dsaTruncate (Vincent.DSA.PrivateKey (Vincent.DSA.Params _ _ q) _) = BS.take (integerBytesize q) | 91 | dsaTruncate (Vincent.DSA.PrivateKey (Vincent.DSA.Params _ _ q) _) = BS.take (integerBytesize q) |
76 | dta = toStrictBS $ encode over `LZ.append` OpenPGP.trailer sig | 92 | dta = toStrictBS $ encode over `LZ.append` OpenPGP.trailer sig |
77 | sig = findSigOrDefault (listToMaybe $ OpenPGP.signatures_over over) | 93 | sig = findSigOrDefault (listToMaybe $ OpenPGP.signatures_over over) |
@@ -126,8 +142,6 @@ unsafeSign keys over hsh keyid timestamp g = (over {OpenPGP.signatures_over = [s | |||
126 | 142 | ||
127 | 143 | ||
128 | 144 | ||
129 | now = floor <$> Data.Time.Clock.POSIX.getPOSIXTime | ||
130 | |||
131 | stampit timestamp sig = sig { OpenPGP.hashed_subpackets = hashed' } | 145 | stampit timestamp sig = sig { OpenPGP.hashed_subpackets = hashed' } |
132 | where | 146 | where |
133 | hashed_stamps = filter isStamp (OpenPGP.hashed_subpackets sig) | 147 | hashed_stamps = filter isStamp (OpenPGP.hashed_subpackets sig) |
@@ -150,10 +164,11 @@ pgpSign :: | |||
150 | -> IO (Maybe OpenPGP.SignatureOver) | 164 | -> IO (Maybe OpenPGP.SignatureOver) |
151 | pgpSign seckeys dta hash_algo keyid = | 165 | pgpSign seckeys dta hash_algo keyid = |
152 | handleIO_ (return Nothing) $ do | 166 | handleIO_ (return Nothing) $ do |
153 | timestamp <- now | 167 | timestamp <- currentTime |
154 | -- g <- Thomas.newGenIO :: IO Thomas.SystemRandom | 168 | -- g <- Thomas.newGenIO :: IO Thomas.SystemRandom |
155 | g <- fmap Vincent.cprgCreate $ Vincent.createEntropyPool | 169 | -- g <- fmap Vincent.cprgCreate $ Vincent.createEntropyPool |
156 | let _ = g :: Vincent.SystemRNG | 170 | g <- makeGen Nothing |
171 | let _ = g :: RNG | ||
157 | let sigs = map (stampit timestamp) $ OpenPGP.signatures_over dta | 172 | let sigs = map (stampit timestamp) $ OpenPGP.signatures_over dta |
158 | dta' = dta { OpenPGP.signatures_over = sigs } | 173 | dta' = dta { OpenPGP.signatures_over = sigs } |
159 | let (r,g') = unsafeSign seckeys dta' hash_algo keyid timestamp g | 174 | let (r,g') = unsafeSign seckeys dta' hash_algo keyid timestamp g |