From 9eff409b6672eeefcd740f3a9420ed12df8f0830 Mon Sep 17 00:00:00 2001 From: Dmitry Zuikov Date: Wed, 27 Sep 2023 12:43:07 +0300 Subject: [PATCH] group-key-update --- docs/notes/group-key-update-note.txt | 41 +++++++++++++++++++++ hbs2-core/lib/HBS2/Net/Auth/GroupKeySymm.hs | 7 ++-- hbs2/Main.hs | 36 +++++++++++++++++- 3 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 docs/notes/group-key-update-note.txt diff --git a/docs/notes/group-key-update-note.txt b/docs/notes/group-key-update-note.txt new file mode 100644 index 00000000..6cc34c04 --- /dev/null +++ b/docs/notes/group-key-update-note.txt @@ -0,0 +1,41 @@ +NOTE: group-key-update-note + Операция group-key-update создаёт новый групповой ключ со + старым секретом. + + Таким образом, можно добавить читателей и опубликовать ключ, + **И ЭТО НЕ ПРИВЕДЁТ К ПЕРЕШИФРОВАНИЮ ФАЙЛА**, будет новый блок + типа MTreeAnn со ссылкой на новый ключ. Нонс останется старый! + + Следствия: если таким образом пользователи удалены, то они + все равно смогут читать "старую" версию дерева, если у них + останется ключ. + + Таким образом можно добавить пользователей, имеющих доступ + к данным, но не удалить. + + Для удаления - в принципе ничего не сделать, то, что однажды + опубликовано (и сохранено), уже невозможно разопубликовать. + + Есть опции: поменять нонс, перешифровать старым секретом + Сгенерировать новый групповой ключ (с новым секретом). + + Если контент еще не выкачан, то можно удалить старый контент, + и заменить новым. + + Это глобальное ограничение таких систем: уже опубликованные + зашифрованные данные останутся доступны тем, кто их скачал и + мог когда-то расшифровать. + + Новый контент, зашифрованный этим групповым ключом --- + будет сходу не будет доступен "удалённым" пользователям, + однако у них есть секрет, зашифрованный их публичным ключом, + т.е при должной настойчивости они смогут его достать и расшифровать + контент. + + Таким образом, при удалении пользователей из ключа так, что бы + они не получили доступ к новому контенту --- НУЖНО ВСЕГДА + перегенерировать ключ. + + Например, при удалении пользователей из шифрованного + репозитория git. + diff --git a/hbs2-core/lib/HBS2/Net/Auth/GroupKeySymm.hs b/hbs2-core/lib/HBS2/Net/Auth/GroupKeySymm.hs index a032b324..da6b205d 100644 --- a/hbs2-core/lib/HBS2/Net/Auth/GroupKeySymm.hs +++ b/hbs2-core/lib/HBS2/Net/Auth/GroupKeySymm.hs @@ -117,15 +117,16 @@ instance ( Serialise (GroupKey 'Asymm s) pretty . B8.unpack . toBase58 . LBS.toStrict . serialise $ c generateGroupKey :: forall s m . (ForGroupKeySymm s, MonadIO m) - => [PubKey 'Encrypt s] + => Maybe GroupSecretAsymm + -> [PubKey 'Encrypt s] -> m (GroupKey 'Symm s) -generateGroupKey pks' = GroupKeySymm <$> create +generateGroupKey mbk pks' = GroupKeySymm <$> create where pks = List.sort (List.nub pks') create = do - sk <- liftIO SK.newKey + sk <- maybe1 mbk (liftIO SK.newKey) pure forM pks $ \pk -> do box <- liftIO $ AK.boxSeal pk (LBS.toStrict $ serialise sk) <&> EncryptedBox pure (pk, box) diff --git a/hbs2/Main.hs b/hbs2/Main.hs index aea09c7f..7ce33dc2 100644 --- a/hbs2/Main.hs +++ b/hbs2/Main.hs @@ -587,6 +587,7 @@ main = join . customExecParser (prefs showHelpOnError) $ pGroupKeySymm = hsubparser ( command "gen" (info pGroupKeySymmGen (progDesc "generate") ) <> command "dump" (info pGroupKeySymmDump (progDesc "dump") ) + <> command "update" (info pGroupKeySymmUpdate (progDesc "update") ) ) pGroupKeySymmGen = do @@ -598,7 +599,7 @@ main = join . customExecParser (prefs showHelpOnError) $ | (ListVal (Key "member" [LitStrVal s]) ) <- syn ] & catMaybes - gk <- Symm.generateGroupKey @HBS2Basic members + gk <- Symm.generateGroupKey @HBS2Basic Nothing members print $ pretty (AsGroupKeyFile gk) pGroupKeySymmDump = do @@ -609,6 +610,39 @@ main = join . customExecParser (prefs showHelpOnError) $ print $ pretty gk + -- SEE: group-key-update-note + + pGroupKeySymmUpdate = do + keyringFile <- strOption ( long "keyring" <> short 'k' <> help "path to keyring file" ) + dsl <- strOption ( long "dsl" <> short 'D' <> help "dsl file" ) + fn <- strArgument ( metavar "FILE" <> help "group key file" ) + + pure do + + sc <- BS.readFile keyringFile + creds <- pure (parseCredentials @(Encryption L4Proto) (AsCredFile sc)) `orDie` "bad keyring file" + + gk <- ( LBS.readFile fn + <&> Symm.parseGroupKey @HBS2Basic . AsGroupKeyFile ) `orDie` "Invalid group key file" + + let keys = [ (view krPk x, view krSk x) | x <- view peerKeyring creds ] + + let gksec' = [ Symm.lookupGroupKey sk pk gk | (pk,sk) <- keys ] & catMaybes & headMay + + gsec <- pure gksec' `orDie` "Group key not found" + + syn <- readFile dsl <&> parseTop <&> fromRight mempty + + -- FIXME: fix-code-dup-members + let members = [ fromStringMay @(PubKey 'Encrypt HBS2Basic) (Text.unpack s) + | (ListVal (Key "member" [LitStrVal s]) ) <- syn + ] & catMaybes + + debug $ vcat (fmap (pretty.AsBase58) members) + + gkNew <- Symm.generateGroupKey @HBS2Basic (Just gsec) members + print $ pretty (AsGroupKeyFile gkNew) + pHash = do o <- common hash <- strArgument ( metavar "HASH" )