group-key-update

This commit is contained in:
Dmitry Zuikov 2023-09-27 12:43:07 +03:00
parent e22834f0f2
commit 9eff409b66
3 changed files with 80 additions and 4 deletions

View File

@ -0,0 +1,41 @@
NOTE: group-key-update-note
Операция group-key-update создаёт новый групповой ключ со
старым секретом.
Таким образом, можно добавить читателей и опубликовать ключ,
**И ЭТО НЕ ПРИВЕДЁТ К ПЕРЕШИФРОВАНИЮ ФАЙЛА**, будет новый блок
типа MTreeAnn со ссылкой на новый ключ. Нонс останется старый!
Следствия: если таким образом пользователи удалены, то они
все равно смогут читать "старую" версию дерева, если у них
останется ключ.
Таким образом можно добавить пользователей, имеющих доступ
к данным, но не удалить.
Для удаления - в принципе ничего не сделать, то, что однажды
опубликовано (и сохранено), уже невозможно разопубликовать.
Есть опции: поменять нонс, перешифровать старым секретом
Сгенерировать новый групповой ключ (с новым секретом).
Если контент еще не выкачан, то можно удалить старый контент,
и заменить новым.
Это глобальное ограничение таких систем: уже опубликованные
зашифрованные данные останутся доступны тем, кто их скачал и
мог когда-то расшифровать.
Новый контент, зашифрованный этим групповым ключом ---
будет сходу не будет доступен "удалённым" пользователям,
однако у них есть секрет, зашифрованный их публичным ключом,
т.е при должной настойчивости они смогут его достать и расшифровать
контент.
Таким образом, при удалении пользователей из ключа так, что бы
они не получили доступ к новому контенту --- НУЖНО ВСЕГДА
перегенерировать ключ.
Например, при удалении пользователей из шифрованного
репозитория git.

View File

@ -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)

View File

@ -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" )