diff options
Diffstat (limited to 'Data/OpenPGP/Util/Verify.hs')
-rw-r--r-- | Data/OpenPGP/Util/Verify.hs | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/Data/OpenPGP/Util/Verify.hs b/Data/OpenPGP/Util/Verify.hs new file mode 100644 index 0000000..b42e664 --- /dev/null +++ b/Data/OpenPGP/Util/Verify.hs | |||
@@ -0,0 +1,74 @@ | |||
1 | {-# LANGUAGE OverloadedStrings #-} | ||
2 | module Data.OpenPGP.Util.Verify where | ||
3 | |||
4 | import Debug.Trace | ||
5 | import qualified Data.OpenPGP as OpenPGP | ||
6 | import Data.Maybe | ||
7 | import Data.Binary (encode) | ||
8 | import Control.Monad | ||
9 | import qualified Data.ByteString as BS | ||
10 | import qualified Data.ByteString.Lazy as LZ | ||
11 | |||
12 | import qualified Crypto.PubKey.DSA as Vincent.DSA | ||
13 | import qualified Crypto.PubKey.RSA.PKCS15 as Vincent.RSA | ||
14 | import qualified Crypto.PubKey.ECC.ECDSA as Vincent.ECDSA | ||
15 | -- import Math.NumberTheory.Moduli | ||
16 | |||
17 | import Data.OpenPGP.Util.Base | ||
18 | |||
19 | |||
20 | dsaKey :: OpenPGP.Packet -> Vincent.DSA.PublicKey | ||
21 | dsaKey k = Vincent.DSA.PublicKey | ||
22 | (Vincent.DSA.Params (keyParam 'p' k) (keyParam 'g' k) (keyParam 'q' k)) | ||
23 | (keyParam 'y' k) | ||
24 | |||
25 | |||
26 | {- | ||
27 | applyCurve :: Vincent.ECDSA.CurveCommon -> Integer -> Integer | ||
28 | applyCurve curve x = x*x*x + x*a + b | ||
29 | where | ||
30 | a = Vincent.ECDSA.ecc_a curve | ||
31 | b = Vincent.ECDSA.ecc_b curve | ||
32 | -} | ||
33 | |||
34 | -- | Verify a message signature | ||
35 | verify :: | ||
36 | OpenPGP.Message -- ^ Keys that may have made the signature | ||
37 | -> OpenPGP.SignatureOver -- ^ Signatures to verify | ||
38 | -> OpenPGP.SignatureOver -- ^ Will only contain signatures that passed | ||
39 | verify keys over = | ||
40 | over {OpenPGP.signatures_over = mapMaybe (uncurry $ verifyOne keys) sigs} | ||
41 | where | ||
42 | sigs = map (\s -> (s, toStrictBS $ encode over `LZ.append` OpenPGP.trailer s)) | ||
43 | (OpenPGP.signatures_over over) | ||
44 | |||
45 | verifyOne :: OpenPGP.Message -> OpenPGP.Packet -> BS.ByteString -> Maybe OpenPGP.Packet | ||
46 | verifyOne keys sig over = fmap (const sig) $ maybeKey >>= verification >>= guard | ||
47 | where | ||
48 | verification = case OpenPGP.key_algorithm sig of | ||
49 | OpenPGP.DSA -> dsaVerify | ||
50 | OpenPGP.ECDSA -> ecdsaVerify | ||
51 | alg | alg `elem` [OpenPGP.RSA,OpenPGP.RSA_S] -> rsaVerify | ||
52 | | otherwise -> const Nothing | ||
53 | dsaVerify k = let k' = dsaKey k in | ||
54 | Just $ Vincent.DSA.verify (dsaTruncate k' . bhash) k' dsaSig over | ||
55 | ecdsaVerify k = let k' = ecdsaKey k | ||
56 | r = Just $ Vincent.ECDSA.verify bhash k' ecdsaSig over | ||
57 | in r -- trace ("ecdsaVerify: "++show r) r | ||
58 | rsaVerify k = Just $ Vincent.RSA.verify desc (rsaKey k) over rsaSig | ||
59 | [rsaSig] = map (toStrictBS . LZ.drop 2 . encode) (OpenPGP.signature sig) | ||
60 | dsaSig = let [OpenPGP.MPI r, OpenPGP.MPI s] = OpenPGP.signature sig in | ||
61 | Vincent.DSA.Signature r s | ||
62 | ecdsaSig = let [OpenPGP.MPI r, OpenPGP.MPI s] = OpenPGP.signature sig in | ||
63 | Vincent.ECDSA.Signature r s | ||
64 | dsaTruncate (Vincent.DSA.PublicKey (Vincent.DSA.Params _ _ q) _) = BS.take (integerBytesize q) | ||
65 | {- | ||
66 | ecdsaTruncate (Vincent.ECDSA.PublicKey _ (Vincent.ECDSA.Point x y)) = BS.take (integerBytesize x | ||
67 | + integerBytesize y ) | ||
68 | -} | ||
69 | bhash = hashBySymbol hash_algo . toLazyBS | ||
70 | desc = hashAlgoDesc hash_algo | ||
71 | hash_algo = OpenPGP.hash_algorithm sig | ||
72 | maybeKey = OpenPGP.signature_issuer sig >>= find_key keys | ||
73 | -- in trace ("maybeKey="++show (fmap OpenPGP.key_algorithm r)) r | ||
74 | |||