Introduce LFS operation authorization token for FS backend

Issue:
Literally anyone can download/upload LFS objects if object SHA-256 is
known (one can see it in LFS debug mode).

Solution:
Introduce request signing that is similar to what LFS for S3 backend
does: operation specific token is generated that in addition to SHA-256
includes timeout beyond which operation is no longer possible anyway.

Design:
128 bit AES was selected as encryption algorithm. In fact the following
transformation is used: AES/CBC/PKCS5PADDING where
CBC - CipherBlockChining (see details in [1])
PKCS5PADDING - is for padding for input text to be multiplication of key
size (16 bytes)

AES symmetric-key is generated each time when LfsFsRequestAuthorizer is
instantiated (which happens only when LFS plugin gets loaded). In
addition, for each operation, random initialization vector (called IV in
[1]) parameter is generated so that even the same set of input
parameters (unlikely to happen) will not generate the same token. It
gets added at the beginning of security token (before Base64 encoding)
and used when token is verified. Token contains 3 values:
- operation (download, upload)
- SHA-256
- date and time until token is valid (default timeout is 10s)
Upon successful token decrypt, in LfsFsContentServlet, all three values
are examined and in case they are not valid SC_UNAUTHORIZED (401) error
is sent back to client.

[1] https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation
Change-Id: I6ec304cd4a8d694aa45fdd71767f4da75791a1e9
Signed-off-by: Jacek Centkowski <geminica.programs@gmail.com>
9 files changed
tree: 6ff568879d6ff35f65e985d02213e5f69c33d7df
  1. lib/
  2. src/
  3. .buckconfig
  4. .gitignore
  5. BUCK