Support for remotes that are chunkable and encryptable.

I'd have liked to keep these two concepts entirely separate,
but that are entagled: Storing a key in an encrypted and chunked remote
need to generate chunk keys, encrypt the keys, chunk the data, encrypt the
chunks, and send them to the remote. Similar for retrieval, etc.

So, here's an implemnetation of all of that.

The total win here is that every remote was implementing encrypted storage
and retrival, and now it can move into this single place. I expect this
to result in several hundred lines of code being removed from git-annex
eventually!

This commit was sponsored by Henrik Ahlgren.
This commit is contained in:
Joey Hess 2014-07-26 20:14:09 -04:00
parent d4d68f57e5
commit 1400cbb032
4 changed files with 254 additions and 15 deletions

View file

@ -70,10 +70,8 @@ encryptionSetup c = maybe genCipher updateCipher $ extractCipher c
-- remotes (while being backward-compatible).
[ "keyid", "keyid+", "keyid-", "highRandomQuality" ]
{- Modifies a Remote to support encryption.
-
- Two additional functions must be provided by the remote,
- to support storing and retrieving encrypted content. -}
{- Modifies a Remote to support encryption. -}
-- TODO: deprecated
encryptableRemote
:: RemoteConfig
-> ((Cipher, Key) -> Key -> MeterUpdate -> Annex Bool)
@ -83,23 +81,30 @@ encryptableRemote
encryptableRemote c storeKeyEncrypted retrieveKeyFileEncrypted r = r
{ storeKey = \k f p -> cip k >>= maybe
(storeKey r k f p)
(\enck -> storeKeyEncrypted enck k p)
(\v -> storeKeyEncrypted v k p)
, retrieveKeyFile = \k f d p -> cip k >>= maybe
(retrieveKeyFile r k f d p)
(\enck -> retrieveKeyFileEncrypted enck k d p)
(\v -> retrieveKeyFileEncrypted v k d p)
, retrieveKeyFileCheap = \k d -> cip k >>= maybe
(retrieveKeyFileCheap r k d)
(\_ -> return False)
, removeKey = withkey $ removeKey r
, hasKey = withkey $ hasKey r
, removeKey = \k -> cip k >>= maybe
(removeKey r k)
(\(_, enckey) -> removeKey r enckey)
, hasKey = \k -> cip k >>= maybe
(hasKey r k)
(\(_, enckey) -> hasKey r enckey)
, cost = maybe
(cost r)
(const $ cost r + encryptedRemoteCostAdj)
(extractCipher c)
}
where
withkey a k = cip k >>= maybe (a k) (a . snd)
cip = cipherKey c
cip k = do
v <- cipherKey c
return $ case v of
Nothing -> Nothing
Just (cipher, enck) -> Just (cipher, enck k)
{- Gets encryption Cipher. The decrypted Ciphers are cached in the Annex
- state. -}
@ -132,11 +137,11 @@ embedCreds c
| isJust (M.lookup "cipherkeys" c) && isJust (M.lookup "cipher" c) = True
| otherwise = False
{- Gets encryption Cipher, and encrypted version of Key. -}
cipherKey :: RemoteConfig -> Key -> Annex (Maybe (Cipher, Key))
cipherKey c k = fmap make <$> remoteCipher c
{- Gets encryption Cipher, and key encryptor. -}
cipherKey :: RemoteConfig -> Annex (Maybe (Cipher, EncKey))
cipherKey c = fmap make <$> remoteCipher c
where
make ciphertext = (ciphertext, encryptKey mac ciphertext k)
make ciphertext = (ciphertext, encryptKey mac ciphertext)
mac = fromMaybe defaultMac $ M.lookup "mac" c >>= readMac
{- Stores an StorableCipher in a remote's configuration. -}