summaryrefslogtreecommitdiff
path: root/Types
diff options
context:
space:
mode:
authorGravatar Joey Hess <joeyh@joeyh.name>2017-02-24 11:17:07 -0400
committerGravatar Joey Hess <joeyh@joeyh.name>2017-02-24 11:22:15 -0400
commit52249bd6c6c27df089969e956d9952b1a432ca45 (patch)
tree83c4df66d20abf6929b6face397e21906e02c341 /Types
parent845cce262c5f593e00e5cc5ebd7619595d848f36 (diff)
make file2key reject E* backend keys with a long extension
I am not happy that I had to put backend-specific code in file2key. But it would be very difficult to avoid this layering violation. Most of the time, when parsing a Key from a symlink target, git-annex never looks up its Backend at all, so adding this check to a method of the Backend object would not work. The Key could be made to contain the appropriate Backend, but since Backend is parameterized on an "a" that is fixed to the Annex monad later, that would need Key to change to "Key a". The only way to clean this up that I can see would be to have the Key contain a LowlevelBackend, and put the validation in LowlevelBackend. Perhaps later, but that would be an extensive change, so let's not do it in this commit which may want to cherry-pick to backports. This commit was sponsored by Ethan Aubin.
Diffstat (limited to 'Types')
-rw-r--r--Types/Key.hs29
1 files changed, 27 insertions, 2 deletions
diff --git a/Types/Key.hs b/Types/Key.hs
index 23648dd03..d4a4d3728 100644
--- a/Types/Key.hs
+++ b/Types/Key.hs
@@ -1,6 +1,6 @@
{- git-annex Key data type
-
- - Copyright 2011-2016 Joey Hess <id@joeyh.name>
+ - Copyright 2011-2017 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU GPL version 3 or higher.
-}
@@ -104,7 +104,7 @@ file2key s
_ -> Nothing
findfields (c:v) (Just k)
- | c == fieldSep = Just $ k { keyName = v }
+ | c == fieldSep = addkeyname k v
| otherwise = sepfield k v $ addfield c
findfields _ v = v
@@ -134,6 +134,31 @@ file2key s
_ -> Nothing
addfield _ _ _ = Nothing
+ addkeyname k v
+ | validKeyName k v = Just $ k { keyName = v }
+ | otherwise = Nothing
+
+{- A key with a backend ending in "E" is an extension preserving key,
+ - using some hash.
+ -
+ - The length of the extension is limited in order to mitigate against
+ - SHA1 collision attacks (specifically, chosen-prefix attacks).
+ - In such an attack, the extension of the key could be made to contain
+ - the collision generation data, with the result that a signed git commit
+ - including such keys would not be secure.
+ -
+ - The maximum extension length ever generated for such a key was 8
+ - characters; 20 is used here to give a little future wiggle-room.
+ - The SHA1 common-prefix attack used 128 bytes of data.
+ -
+ - This code is here, and not in Backend.Hash (where it really belongs)
+ - so that file2key can check it whenever a Key is constructed.
+ -}
+validKeyName :: Key -> String -> Bool
+validKeyName k v
+ | end (keyBackendName k) == "E" = length (takeExtensions v) <= 20
+ | otherwise = True
+
instance ToJSON Key where
toJSON = toJSON . key2file