packages feed

keystore 0.4.0.0 → 0.5.0.1

raw patch · 8 files changed

+302/−110 lines, 8 filesdep −attoparsec

Dependencies removed: attoparsec

Files

changelog view
@@ -28,3 +28,13 @@ 	* Write Haddock annotations for Sections module. 	* Tidy cabal file 	* Revise readme and cabal documentation++0.5.0.0 Chris Dornan <chrisd@irisconnect.co.uk> 2014-07-27+	* expose getKeystore, getState, getCtxState, putCtxState in Data.KeyStore.IO+	* add proxy arguments to verifyKeystore & locateKeys in Data.KeyStore.Sections+	* opened up the export of Data.KeyStore.Types+	* added getSettingsOpt' to Data.KeyStore.KS.Opt+	* Fix #1, (section, key and host prefixes)++0.5.0.1 Chris Dornan <chrisd@irisconnect.co.uk> 2014-07-28+	* fix default sectionPWEnvVar in Sections class
examples/deploy/deploy.hs view
@@ -57,7 +57,7 @@ sign_ks ic = signKeystore ic sections >>= B.writeFile ks_mac_fp  verify_ks :: Bool -> IC -> IO ()-verify_ks fatal ic = chk =<< catch (B.readFile ks_mac_fp >>= verifyKeystore ic) hdl+verify_ks fatal ic = chk =<< catch (B.readFile ks_mac_fp >>= verifyKeystore ic sections) hdl   where     chk True              = return ()     chk False | fatal     = error msg
keystore.cabal view
@@ -1,5 +1,5 @@ Name:                   keystore-Version:                0.4.0.0+Version:                0.5.0.1 Synopsis:               Managing stores of secret things Homepage:               http://github.com/cdornan/keystore Author:                 Chris Dornan@@ -160,7 +160,6 @@         crypto-random          >= 0.0.7             ,         aeson                  >= 0.6.2             ,         aeson-pretty           >= 0.7               ,-        attoparsec             >= 0.10.4.0          ,         base                   >= 4                 ,         base64-bytestring      >= 1.0               ,         byteable               >= 0.1               ,
src/Data/KeyStore/CLI.hs view
@@ -18,7 +18,7 @@   version :: String-version = "0.4.0.0"+version = "0.5.0.1"  cli :: IO () cli = parseCLI >>= command Nothing
src/Data/KeyStore/IO.hs view
@@ -62,6 +62,10 @@     , verify     , verify_     , run+    , getKeystore+    , getState+    , getCtxState+    , putCtxState     ) where  import           Data.KeyStore.IO.IC@@ -105,7 +109,7 @@ -- context to be cached between calls to these access functions. instanceCtx :: CtxParams -> IO IC instanceCtx cp =- do ctx_st <- get $ instanceCtx_ cp+ do ctx_st <- getCtxState $ instanceCtx_ cp     IC cp . Just <$> newIORef ctx_st  -- | This functional method will generate an IC that will not cache any@@ -268,7 +272,7 @@  -- | Return all of the keys in the keystore. keys :: IC -> IO [Key]-keys ic = Map.elems . _ks_keymap <$> get_keystore ic+keys ic = Map.elems . _ks_keymap <$> getKeystore ic  -- | Delete a list of keys from the keystore. deleteKeys :: IC -> [Name] -> IO ()@@ -345,14 +349,14 @@ -- debug logging and errors. run :: IC -> KS a -> IO a run ic p =- do (ctx,st0) <- get ic+ do (ctx,st0) <- getCtxState ic     st1 <- scan_env ctx st0     let msg         = "[Keystore: " ++ ctx_store ctx ++"]\n"         (e,st2,les) = run_ ctx st1 $ debugLog msg >> p     r <- e2io e     mapM_ (logit ctx) les     st' <- backup_env ctx st2-    put ic ctx st'+    putCtxState ic ctx st'     return r  scan_env :: Ctx -> State -> IO State@@ -371,20 +375,20 @@   where     (e,st',les') = run_ ctx st0 backupKeysKS -get_keystore :: IC -> IO KeyStore-get_keystore ic = st_keystore <$> get_state ic+getKeystore :: IC -> IO KeyStore+getKeystore ic = st_keystore <$> getState ic -get_state :: IC -> IO State-get_state ic = snd <$> get ic+getState :: IC -> IO State+getState ic = snd <$> getCtxState ic -get :: IC -> IO (Ctx,State)-get IC{..} =+getCtxState :: IC -> IO (Ctx,State)+getCtxState IC{..} =     case ic_cache of       Nothing -> determineCtx ic_ctx_params       Just rf -> readIORef rf -put :: IC -> Ctx -> State -> IO ()-put IC{..} ctx st =+putCtxState :: IC -> Ctx -> State -> IO ()+putCtxState IC{..} ctx st =  do maybe (return ()) (flip writeIORef (ctx,st)) ic_cache     when (not $ maybe False id $ cp_readonly ic_ctx_params) $         LBS.writeFile (ctx_store ctx) $ keyStoreBytes $ st_keystore st
src/Data/KeyStore/KS/Opt.hs view
@@ -7,9 +7,11 @@     , OptEnum(..)     , opt_enum     , getSettingsOpt+    , getSettingsOpt'     , setSettingsOpt     , opt__debug_enabled     , opt__verify_enabled+    , opt__sections_fix     , opt__backup_keys     , opt__hash_comment     , opt__hash_prf@@ -39,6 +41,7 @@ import           Data.Maybe import           Data.Char import           Text.Printf+import           Control.Applicative   data Opt a@@ -58,9 +61,11 @@     deriving Show  getSettingsOpt :: Opt a -> Settings -> a-getSettingsOpt Opt{..} (Settings hm) =-                maybe opt_default opt_from $ HM.lookup (optName opt_enum) hm+getSettingsOpt opt = maybe (opt_default opt) id . getSettingsOpt' opt +getSettingsOpt' :: Opt a -> Settings -> Maybe a+getSettingsOpt' Opt{..} (Settings hm) = opt_from <$> HM.lookup (optName opt_enum) hm+ setSettingsOpt :: Opt a -> a -> Settings -> Settings setSettingsOpt Opt{..} x (Settings hm) =                   Settings $ HM.insert (optName opt_enum) (opt_to x) hm@@ -72,6 +77,9 @@ opt__verify_enabled       :: Opt Bool opt__verify_enabled       = bool_opt vfy_help                            False       Verify__enabled +opt__sections_fix         :: Opt Bool+opt__sections_fix         = bool_opt sfx_help                            False       Sections__fix+ opt__backup_keys          :: Opt [Name] opt__backup_keys          = backup_opt bku_help                                      Backup__keys @@ -106,6 +114,7 @@ data OptEnum     = Debug__enabled     | Verify__enabled+    | Sections__fix     | Backup__keys     | Hash__comment     | Hash__prf@@ -125,6 +134,7 @@     case enm of       Debug__enabled        -> Opt_ opt__debug_enabled       Verify__enabled       -> Opt_ opt__verify_enabled+      Sections__fix         -> Opt_ opt__sections_fix       Backup__keys          -> Opt_ opt__backup_keys       Hash__comment         -> Opt_ opt__hash_comment       Hash__prf             -> Opt_ opt__hash_prf@@ -258,7 +268,7 @@      typ   = T.intercalate "|" $ map shw [minBound..maxBound] -dbg_help, vfy_help, bku_help, hcm_help, hpr_help, hit_help, hwd_help,+dbg_help, vfy_help, sfx_help, bku_help, hcm_help, hpr_help, hit_help, hwd_help,     hna_help, ccy_help, cpr_help, cit_help, cna_help :: [T.Text]  dbg_help =@@ -269,6 +279,11 @@   , "in which the secret text loaded from environment"   , "variables is checked against the stored MACs."   , "These checks can consume a lot of compute time."+  ]+sfx_help =+  [ "Set when a 'Sections' keystore has been fixed so that"+  , "section, key and host names no longer contrained to avoid"+  , "prefixes."   ] bku_help =   [ "Controls the default keys that will be used to make secret copies"
src/Data/KeyStore/Sections.hs view
@@ -31,17 +31,23 @@   where  import           Data.KeyStore.IO+import           Data.KeyStore.KS import qualified Data.Text                      as T import qualified Data.ByteString.Char8          as B import qualified Data.ByteString.Lazy.Char8     as LBS import qualified Data.Aeson                     as A import qualified Data.HashMap.Strict            as HM import qualified Data.Vector                    as V+import qualified Data.Map                       as Map import           Data.Maybe import           Data.List+import           Data.Char import           Data.Ord+import           Data.String import           Data.Monoid+import           Control.Lens import           Control.Applicative+import           Control.Monad import           Text.Printf import           System.FilePath import           Safe@@ -106,7 +112,7 @@    describeSection     s = "The '" ++ encode s ++ "' Section." -  sectionPWEnvVar       = EnvVar . T.pack . ("KEY_" ++) . _name . passwordName+  sectionPWEnvVar       = EnvVar . T.pack . ("KEY_pw_" ++) . encode   -- | Sections are used to hold the top (master) key for the keystore,@@ -150,7 +156,7 @@ -- procedure. initialise :: Sections h s k => CtxParams -> KeyPredicate h s k -> IO () initialise cp kp = do-    stgs <- scs kp Nothing+    stgs <- setSettingsOpt opt__sections_fix True <$> scs kp Nothing     newKeyStore (the_keystore cp) stgs     ic <- instanceCtx cp     mapM_ (mks kp ic) [minBound..maxBound]@@ -165,26 +171,34 @@  -- | Rotate in a set of keys spwecified by the predicate. rotate :: Sections h s k => IC -> KeyPredicate h s k -> IO ()-rotate ic kp = sequence_ [ rotate' ic mb_h s k | (mb_h,s,k)<-host_keys++non_host_keys, kp mb_h s k ]+rotate ic kp = reformat ic' $ sequence_ [ rotate' ic mb_h s k | (mb_h,s,k)<-host_keys++non_host_keys, kp mb_h s k ]   where     host_keys     = [ (Just h ,s,k) | k<-[minBound..maxBound], Just isp<-[keyIsHostIndexed k], h<-[minBound..maxBound], isp h, let s = key_section h k ]     non_host_keys = [ (Nothing,s,k) | k<-[minBound..maxBound], Nothing <-[keyIsHostIndexed k], s<-[minBound..maxBound], keyIsInSection k s             ] +    ic' = kp_RFT kp ic+ -- | Retrieve the keys for a given host from the store. Note that the whole history for the given key is returned. -- Note also that the secret text may not be present if it si not accessible (depnding upon hwich section passwords -- are correctly bound in the process environment). Note also that the 'Retrieve' diagnostic should not fail if a -- coherent model has been ddefined for 'Sections'. retrieve :: Sections h s k => IC -> h -> k -> IO (Retrieve [Key])-retrieve ic h k = either (return . Left) (\nm->Right <$> locateKeys ic nm) $ keyName h k+retrieve ic h k = reformat ic' $ either (return . Left) (\nm->Right <$> locate_keys ic' nm) $ keyName h k+  where+    ic' = h_RFT h ic  -- | Sign the keystore. (Requites the password for the signing section to be correctly -- bound in the environment) signKeystore :: Sections h s k => IC -> SECTIONS h s k -> IO B.ByteString-signKeystore ic scn = B.readFile (the_keystore $ ic_ctx_params ic) >>= sign_ ic (sgn_nme $ signing_key scn)+signKeystore ic scn = reformat ic' $ B.readFile (the_keystore $ ic_ctx_params ic) >>= sign_ ic (sgn_nme $ signing_key scn)+  where+    ic' = scn_RFT scn ic  -- Verify that the signature for a keystore matches the keystore.-verifyKeystore :: IC -> B.ByteString -> IO Bool-verifyKeystore ic sig = B.readFile (the_keystore $ ic_ctx_params ic) >>= flip (verify_ ic) sig+verifyKeystore :: Sections h s k => IC -> SECTIONS h s k -> B.ByteString -> IO Bool+verifyKeystore ic scn sig = reformat ic' $ B.readFile (the_keystore $ ic_ctx_params ic) >>= flip (verify_ ic) sig+  where+    ic' = scn_RFT scn ic  -- | A predicate specifying all of the keys in the store. noKeys :: KeyPredicate h s k@@ -254,28 +268,37 @@ -- to work the password for the top section (or the passwords for all of the sections -- must be bound if the store does not maintain a top key). secretKeySummary :: Sections h s k => IC -> SECTIONS h s k -> IO T.Text-secretKeySummary ic scn = T.unlines <$> mapM f (sections scn)+secretKeySummary ic scn = reformat ic' $ T.unlines <$> mapM f (sections scn)   where     f s = do       sec <- T.pack . B.unpack <$> (showSecret ic False $ passwordName s)       return $ T.concat ["export ",_EnvVar $ sectionPWEnvVar s,"=",sec] +    ic' = scn_RFT scn ic+ -- | List a shell script for storing the public signing key for the store. publicKeySummary :: Sections h s k => IC -> SECTIONS h s k -> FilePath -> IO T.Text-publicKeySummary ic scn fp = f <$> showPublic ic True (sgn_nme $ signing_key scn)+publicKeySummary ic scn fp = reformat ic' $ f <$> showPublic ic True (sgn_nme $ signing_key scn)   where     f b = T.pack $ "echo '" ++ B.unpack b ++ "' >" ++ fp ++ "\n" +    ic' = scn_RFT scn ic+ -- | List all of the keys that have the given name as their prefix. If the -- generic name of a key is given then it will list the complete history for -- the key, the current (or most recent) entry first.-locateKeys :: IC -> Name -> IO [Key]-locateKeys ic nm = sortBy (flip $ comparing _key_name) . filter yup <$> keys ic+locateKeys :: Sections h s k => IC -> SECTIONS h s k -> Name -> IO [Key]+locateKeys ic scn nm = locate_keys ic' nm   where+    ic' = scn_RFT scn ic++locate_keys :: Sections h s k => REFORMAT h s k -> Name -> IO [Key]+locate_keys ic' nm = reformat ic' $ sortBy (flip $ comparing _key_name) . filter yup <$> keys ic+  where     yup     = isp . _key_name     isp nm' = nm_s `isPrefixOf` _name nm'-     nm_s    = _name nm+    ic      = _REFORMAT ic'  -- | Return the genertic name for a given key thst is used by the specified -- host, returning a failure diagnostic if the host does not have such a key@@ -304,7 +327,7 @@  -- | The name of the key that stores the password for a given sections. passwordName :: Sections h s k => s -> Name-passwordName s = name' $ "pw_"   ++ encode s+passwordName s = name' $ "/pw/"   ++ encode s  fmt :: Code a => (a->Bool) -> String fmt p  = unwords [ encode h | h<-[minBound..maxBound], p h ]@@ -385,18 +408,18 @@ backup_password ic s sv_s = secureKey ic (passwordName s) $ safeguard [sve_nme sv_s]  key_nme :: Sections h s k => Maybe h -> s -> k -> Name-key_nme mb_h s k = name' $ encode s ++ "_" ++ encode k ++ hst_sfx+key_nme mb_h s k = name' $ encode s ++ "/" ++ encode k ++ hst_sfx   where-    hst_sfx = maybe "" (\h -> "_" ++ encode h) mb_h+    hst_sfx = maybe "" (\h -> "/" ++ encode h) mb_h  sgn_nme :: Sections h s k => s -> Name-sgn_nme s = name' $ encode s ++ "_keystore_signing_key"+sgn_nme s = name' $ encode s ++ "/keystore_signing_key"  sve_nme :: Sections h s k => s -> Name-sve_nme s = name' $ "save_" ++ encode s+sve_nme s = name' $ "/save/" ++ encode s  scn_pattern :: Sections h s k => s -> Pattern-scn_pattern s = pattern $ "^" ++ encode s ++ "_.*"+scn_pattern s = pattern $ "^" ++ encode s ++ "/.*"  unique_nme :: IC -> Name -> IO Name unique_nme ic nm =@@ -411,10 +434,7 @@     c_nms = [ nm | i<-[length nms+1..], let nm=nname i nm0, nm `notElem` nms ]      nname :: Int -> Name -> Name-    nname i nm_ = name' $ _name nm_ ++ printf "_%03d" i--name' :: String -> Name-name' = either (error.show) id . name+    nname i nm_ = name' $ _name nm_ ++ printf "/%03d" i  the_keystore :: CtxParams -> FilePath the_keystore = maybe "keystore.json" id . cp_store@@ -432,3 +452,213 @@       }   where     fp sfx = sd </> encode k ++ sfx+++--------------------------------------------------------------------------------+--+-- Regormating the KeyStore Names to Allow Prefixes (#3)+--+--------------------------------------------------------------------------------+++reformat :: Sections h s k => REFORMAT h s k -> IO a -> IO a+reformat rft@(REFORMAT ic) p = reformat_ic (encoding rft) ic >> p++-- Proxy city!++data REFORMAT h s k = REFORMAT { _REFORMAT :: IC }++data CODE a = CODE++scn_RFT :: SECTIONS     h s k -> IC -> REFORMAT h s k+kp_RFT  :: KeyPredicate h s k -> IC -> REFORMAT h s k+h_RFT   ::              h     -> IC -> REFORMAT h s k++scn_RFT _ ic = REFORMAT ic+kp_RFT  _ ic = REFORMAT ic+h_RFT   _ ic = REFORMAT ic++reformat_ic :: Encoding -> IC -> IO ()+reformat_ic enc ic = do+  (ctx,st) <- getCtxState ic+  putCtxState ic ctx $+    st { st_keystore = reformat_keystore enc $ st_keystore st }++reformat_keystore :: Encoding -> KeyStore -> KeyStore+reformat_keystore enc ks =+  case getSettingsOpt opt__sections_fix $ _cfg_settings $ _ks_config ks of+    True  -> ks+    False -> over ks_config (reformat_config  enc) $+             over ks_keymap (reformat_key_map enc) ks++reformat_config :: Encoding -> Configuration -> Configuration+reformat_config enc =+  over cfg_settings (setSettingsOpt opt__sections_fix True) .+  over cfg_settings (reformat_settings enc) .+  over cfg_triggers (reformat_triggers enc)++reformat_triggers :: Encoding -> TriggerMap -> TriggerMap+reformat_triggers enc = Map.map $+  over trg_pattern  (reformat_pattern  enc) .+  over trg_settings (reformat_settings enc)++reformat_settings :: Encoding -> Settings -> Settings+reformat_settings enc stgs =+  case getSettingsOpt' opt__backup_keys stgs of+    Nothing  -> stgs+    Just nms -> setSettingsOpt opt__backup_keys (map (reformat_name enc) nms) stgs++reformat_pattern :: Encoding -> Pattern -> Pattern+reformat_pattern enc pat = maybe oops id $ run_munch (m_pattern enc) $ _pat_string pat+  where+    oops = error $ "reformat_pattern: bad pattern format: " ++ _pat_string pat++reformat_key_map :: Encoding -> KeyMap -> KeyMap+reformat_key_map enc km = Map.fromList [ (reformat_name enc nm,r_ky ky) | (nm,ky)<-Map.toList km ]+  where+    r_ky =+      over key_name          (reformat_name enc) .+      over key_secret_copies (reformat_ecm  enc)++reformat_ecm :: Encoding -> EncrypedCopyMap -> EncrypedCopyMap+reformat_ecm enc ecm = Map.fromList [ (reformat_sg enc sg,r_ec ec) | (sg,ec)<-Map.toList ecm ]+  where+    r_ec = over ec_safeguard (reformat_sg enc)++reformat_sg :: Encoding -> Safeguard -> Safeguard+reformat_sg enc = safeguard . map (reformat_name enc) . safeguardKeys++reformat_name :: Encoding -> Name -> Name+reformat_name enc nm = maybe oops id $ run_munch (m_name enc) $ _name nm+  where+    oops = error $ "reformat_name: bad name format: " ++ _name nm++m_pattern :: Encoding -> Munch Pattern+m_pattern enc = do+  munch_ "^"+  s <- enc_s enc+  munch_ "_.*"+  return $ fromString $ "^" ++ s ++ "/.*"++m_name, m_save, m_pw, m_section :: Encoding -> Munch Name++m_name enc = m_save enc <|> m_pw enc <|> m_section enc++m_save enc = do+  munch_ "save_"+  s <- enc_s enc+  return $ name' $ "/save/" ++ s++m_pw enc = do+  munch_ "pw_"+  s <- enc_s enc+  return $ name' $ "/pw/" ++ s++m_section enc = do+  s <- enc_s enc+  m_section_signing enc s <|> m_section_key enc s++m_section_key, m_section_signing  :: Encoding -> String -> Munch Name++m_section_signing _ s = do+  munch_ "_keystore_signing_key"+  return $ name' $ s ++ "/keystore_signing_key"++m_section_key enc s = do+  munch_ "_"+  k <- enc_k enc+  m_section_key_host enc s k <|> m_section_key_vrn enc s k++m_section_key_vrn, m_section_key_host :: Encoding -> String -> String -> Munch Name++m_section_key_vrn _ s k = do+  munch_ "_"+  v <- munch_vrn+  return $ name' $ s ++"/" ++ k ++ "/" ++ v++m_section_key_host enc s k = do+  munch_ "_"+  h <- enc_h enc+  munch_ "_"+  v <- munch_vrn+  return $ name' $ s ++"/" ++ k ++ "/" ++ h ++ "/" ++ v++munch_vrn :: Munch String+munch_vrn = do+  c1 <- munch1 isDigit+  c2 <- munch1 isDigit+  c3 <- munch1 isDigit+  return [c1,c2,c3]++-- Capturing the host, section and key encodings in a nice convenient+-- monotype that we can pass around.++data Encoding =+  Encoding+    { enc_h, enc_s, enc_k :: Munch String+    }++encoding :: Sections h s k => REFORMAT h s k -> Encoding+encoding rft =+  Encoding+    { enc_h = code_m $ host_c    rft+    , enc_s = code_m $ section_c rft+    , enc_k = code_m $ key_c     rft+    }+  where+    host_c      :: Sections h s k => REFORMAT h s k -> CODE h+    host_c    _ = CODE++    section_c   :: Sections h s k => REFORMAT h s k -> CODE s+    section_c _ = CODE++    key_c       :: Sections h s k => REFORMAT h s k -> CODE k+    key_c     _ = CODE++code_m :: Code a => CODE a -> Munch String+code_m c = foldr (<|>) empty $ [ munch $ encode x | x<-bds c ]+  where+    bds :: Code a => CODE a -> [a]+    bds _ = [minBound..maxBound]++-- our Munch Monad++newtype Munch a = Munch { _Munch :: String -> Maybe (a,String) }++instance Functor Munch where+  fmap f m = m >>= \x -> return $ f x++instance Applicative Munch where+  pure  = return+  (<*>) = ap++instance Alternative Munch where+  empty     = Munch $ const Nothing+  (<|>) x y = Munch $ \s -> _Munch x s <|> _Munch y s++instance Monad Munch where+  return x  = Munch $ \s -> Just (x,s)+  (>>=) m f = Munch $ \s -> _Munch m s >>= \(x,s') -> _Munch (f x) s'++run_munch :: Munch a -> String -> Maybe a+run_munch (Munch f) str = case f str of+  Just (x,"") -> Just x+  _           -> Nothing++munch1 :: (Char->Bool) -> Munch Char+munch1 p = Munch $ \str -> case str of+  c:t | p c -> Just (c,t)+  _         -> Nothing++munch_ :: String -> Munch ()+munch_ s = const () <$> munch s++munch :: String -> Munch String+munch str_p = Munch $ \str -> case str_p `isPrefixOf` str of+  True  -> Just (str_p,drop (length str_p) str)+  False -> Nothing++--------------------------------------------------------------------------------++name' :: String -> Name+name' = either (error.show) id . name
src/Data/KeyStore/Types.hs view
@@ -27,77 +27,11 @@ -- marked down in <https://github.com/cdornan/keystore/blob/master/schema.md>.  module Data.KeyStore.Types-    ( KeyStore(..)-    , ks_keymap-    , ks_config-    , Configuration(..)-    , TriggerMap-    , Trigger(..)-    , Settings(..)-    , cfg_settings-    , cfg_triggers-    , TextJsonAssoc(..)-    , KeyMap-    , NameKeyAssoc(..)-    , Key(..)-    , key_name-    , key_comment-    , key_identity-    , key_is_binary-    , key_env_var-    , key_hash-    , key_public-    , key_secret_copies-    , key_clear_text-    , key_clear_private-    , key_created_at-    , Hash(..)-    , HashDescription(..)-    , EncrypedCopyMap-    , EncrypedCopy(..)-    , EncrypedCopyData(..)-    , RSASecretData(..)-    , AESSecretData(..)-    , PublicKey(..)-    , PrivateKey(..)-    , Cipher(..)-    , _text_Cipher-    , HashPRF(..)-    , _text_HashPRF-    , EncryptionKey(..)-    , FragmentID(..)-    , Pattern(..)-    , Iterations(..)-    , Octets(..)-    , Identity(..)-    , SettingID(..)-    , TriggerID(..)-    , Comment(..)-    , EnvVar(..)-    , ClearText(..)-    , Salt(..)-    , IV(..)-    , HashData(..)-    , AESKey(..)-    , SecretData(..)-    , RSAEncryptedKey(..)-    , RSASecretBytes(..)-    , RSASignature(..)-    , EncryptionPacket(..)-    , SignaturePacket(..)-    , Void(..)-    , Dirctn(..)-    , void_-    , pattern-    , defaultSettings-    , checkSettingsCollisions-    , emptyKeyStore-    , emptyKeyMap-    , defaultConfiguration-    , pbkdf-    , keyWidth+    ( module Data.KeyStore.Types     , module Data.KeyStore.Types.NameAndSafeguard     , module Data.KeyStore.Types.E+    , PublicKey(..)+    , PrivateKey(..)     ) where  import           Data.KeyStore.Types.Schema