summaryrefslogtreecommitdiffhomepage
path: root/Crypto.hs
diff options
context:
space:
mode:
authorJoey Hess <joeyh@joeyh.name>2017-04-19 20:07:47 -0400
committerJoey Hess <joeyh@joeyh.name>2017-04-19 20:07:47 -0400
commitf7999cecc2bb0c76d88005444478e8500c624786 (patch)
tree9deccd684e1333dca028d980489892ac4189582b /Crypto.hs
parent6f7cf857b408401abdc4477c888495b4f13162c7 (diff)
downloaddebug-me-f7999cecc2bb0c76d88005444478e8500c624786.tar.gz
fully working signatures
This commit was sponsored by Ethan Aubin.
Diffstat (limited to 'Crypto.hs')
-rw-r--r--Crypto.hs75
1 files changed, 59 insertions, 16 deletions
diff --git a/Crypto.hs b/Crypto.hs
index a99d497..d973034 100644
--- a/Crypto.hs
+++ b/Crypto.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE OverloadedStrings, RankNTypes #-}
+
module Crypto where
import Val
@@ -13,27 +15,68 @@ import Data.ByteString
dummySignature :: Signature
dummySignature = OtherSignature (Val mempty)
--- | Sign any Hashable value.
-sign :: Hashable v => MySessionKey -> v -> Signature
+class Signed t where
+ getSignature :: t -> Signature
+ hashExceptSignature :: t -> Hash
+ mkSigned :: MySessionKey -> (Signature -> t) -> t
+ mkSigned sk mk =
+ let tmp = mk dummySignature
+ in mk (sign sk tmp)
+
+instance Hashable a => Signed (Activity a) where
+ getSignature = activitySignature
+ hashExceptSignature (Activity a mp _s) = hash $
+ Tagged "Activity" [hash a, hash mp]
+
+instance Signed Control where
+ getSignature = controlSignature
+ hashExceptSignature (Control a _s) = hash $
+ Tagged "Control" a
+
+instance Hashable t => Signed (Message t) where
+ getSignature (ActivityMessage a) = getSignature a
+ getSignature (ControlMessage c) = getSignature c
+ hashExceptSignature (ActivityMessage a) = hashExceptSignature a
+ hashExceptSignature (ControlMessage c) = hashExceptSignature c
+
+sign :: Signed v => MySessionKey -> v -> Signature
sign (MySessionKey sk pk) v = Ed25519Signature $ Val $ convert $
- Ed25519.sign sk pk $ val $ hashValue $ hash v
-
--- | Verifiy a signature of any Hashable value.
---
--- To avoid overhead of converting the PublicKey to the Ed25519.PublicKey
--- each time, partially evaluate this function.
-verify :: Hashable v => PublicKey -> v -> Signature -> Bool
-verify (PublicKey (Val pk) _) v (Ed25519Signature (Val s)) =
+ Ed25519.sign sk pk (toSign v)
+
+toSign :: Signed v => v -> ByteString
+toSign = val . hashValue . hashExceptSignature
+
+-- | Verifiy the signature of a Signed value.
+verifySigned :: Signed v => SigVerifier -> v -> Bool
+verifySigned (SigVerifier verifier) v =
+ case getSignature v of
+ Ed25519Signature (Val s) ->
+ case Ed25519.signature s of
+ CryptoPassed sig -> verifier (toSign v) sig
+ CryptoFailed _ -> False
+ OtherSignature _ -> False
+
+data SigVerifier = SigVerifier (ByteString -> Ed25519.Signature -> Bool)
+
+mkSigVerifier :: PublicKey -> SigVerifier
+mkSigVerifier (PublicKey (Val pk) _) =
case Ed25519.publicKey pk of
- CryptoPassed pk' -> case Ed25519.signature s of
- CryptoPassed sig ->
- Ed25519.verify pk' (val $ hashValue $ hash v) sig
- CryptoFailed _ -> False
- CryptoFailed _ -> False
-verify _ _ (OtherSignature _) = False
+ CryptoPassed pk' -> SigVerifier (Ed25519.verify pk')
+ CryptoFailed _ -> mempty
+
+instance Monoid SigVerifier where
+ mempty = SigVerifier $ \_b _s -> False
+ mappend (SigVerifier a) (SigVerifier b) =
+ SigVerifier $ \d s -> b d s || a d s
data MySessionKey = MySessionKey Ed25519.SecretKey Ed25519.PublicKey
+-- TODO add gpg signature when available
+myPublicKey :: MySessionKey -> IO PublicKey
+myPublicKey (MySessionKey _ pk) = do
+ let gpgsig = Nothing
+ return $ PublicKey (Val (convert pk)) gpgsig
+
genMySessionKey :: IO MySessionKey
genMySessionKey = do
-- Crypto.Random.Entropy may use rdrand, or /dev/random.