-- Expirations.hs: OpenPGP (RFC4880) expiration checking
-- Copyright © 2014-2015  Clint Adams
-- This software is released under the terms of the Expat license.
-- (See the LICENSE file).
module Codec.Encryption.OpenPGP.Expirations
  ( isTKTimeValid
  , getKeyExpirationTimesFromSignature
  ) where

import Control.Lens ((&), (^.), _1)
import Data.Time.Clock (UTCTime)
import Data.Time.Clock.POSIX (posixSecondsToUTCTime)

import Codec.Encryption.OpenPGP.Ontology (isKET)
import Codec.Encryption.OpenPGP.Types

-- this assumes that all key expiration time subpackets are valid
isTKTimeValid :: UTCTime -> TK -> Bool
isTKTimeValid ct key = ct >= keyCreationTime && ct < keyExpirationTime
  where
    keyCreationTime =
      key ^. tkKey . _1 . timestamp & posixSecondsToUTCTime . realToFrac
    keyExpirationTime =
      posixSecondsToUTCTime . realToFrac .
      ((key ^. tkKey . _1 . timestamp & unThirtyTwoBitTimeStamp) +) .
      unThirtyTwoBitDuration .
      newest .
      concatMap getKeyExpirationTimesFromSignature $
      (concatMap snd (key ^. tkUIDs) ++ concatMap snd (key ^. tkUAts))
    newest [] = maxBound
    newest xs = maximum xs

getKeyExpirationTimesFromSignature :: SignaturePayload -> [ThirtyTwoBitDuration]
getKeyExpirationTimesFromSignature (SigV4 _ _ _ xs _ _ _) =
  map (\(SigSubPacket _ (KeyExpirationTime x)) -> x) $ filter isKET xs