-- Verify.hs: OpenPGP (RFC4880) signature verification
-- Copyright © 2012-2016  Clint Adams
-- This software is released under the terms of the Expat license.
-- (See the LICENSE file).
module Data.Conduit.OpenPGP.Verify
  ( conduitVerify
  ) where

import Data.Conduit
import Data.Time.Clock (UTCTime)

import Codec.Encryption.OpenPGP.Internal (PktStreamContext(..), emptyPSC)
import Codec.Encryption.OpenPGP.Signatures (verifyAgainstKeyring, verifySigWith)
import Codec.Encryption.OpenPGP.Types
import qualified Data.Conduit.List as CL

conduitVerify ::
     Monad m
  => Keyring
  -> Maybe UTCTime
  -> ConduitT Pkt (Either String Verification) m ()
conduitVerify kr mt = CL.concatMapAccum (flip push) emptyPSC
  where
    push state ld@LiteralDataPkt {} = (state {lastLD = ld}, [])
    push state uid@(UserIdPkt _) = (state {lastUIDorUAt = uid}, [])
    push state uat@(UserAttributePkt _) = (state {lastUIDorUAt = uat}, [])
    push state pk@(PublicKeyPkt _) = (state {lastPrimaryKey = pk}, [])
    push state pk@(PublicSubkeyPkt _) = (state {lastSubkey = pk}, [])
    push state sk@(SecretKeyPkt _ _) = (state {lastPrimaryKey = sk}, [])
    push state sk@(SecretSubkeyPkt _ _) = (state {lastSubkey = sk}, [])
    push state sig@(SignaturePkt SigV4 {}) =
      ( state {lastSig = sig}
      , [verifySigWith (verifyAgainstKeyring kr) sig state mt])
    push state (OnePassSignaturePkt _ _ _ _ _ False) = (state, [])
    push state _ = (state, [])
    normLineEndings = id -- FIXME