Commit Graph

35 Commits

Author SHA1 Message Date
Andrew Ayer
d417f97f8e Make argv arrays const 2014-07-05 14:22:55 -07:00
Andrew Ayer
3fe85bc928 Rename add-collab, etc. to add-gpg-key, etc.
Since GPG support might be used by a single user and not necessarily
among collaborators.
2014-07-05 11:46:51 -07:00
Andrew Ayer
2ba7f0e374 unlock: decrypt all possible keys when using GPG
It's no longer necessary to specify the -k option to unlock when
using GPG.  unlock will automatically decrypt all keys which the user
can access.
2014-07-02 22:12:18 -07:00
Andrew Ayer
3511033f7f Make key files extensible, store key name in key file
Storing the key name in the key file makes it unnecessary to pass the
--key-name option to git-crypt unlock.

This breaks compatibility with post-revamp keys.  On the plus side,
keys are now extensible so in the future it will be easier to make
changes to the format without breaking compatibility.
2014-06-29 22:10:04 -07:00
Andrew Ayer
3c8273cd4b Add .gpg filename extension to in-repo encrypted keys
This will help distinguish keys encrypted with GPG from keys encrypted by
other means.  (For example, a future version of git-crypt might support
passphrase-encrypted keys.)
2014-06-29 16:14:16 -07:00
Andrew Ayer
1afa71183e Initial implementation of multiple key support
The init, export-key, add-collab, and unlock commands now
take an optional -k (equivalently, --key-name) option to
specify an alternative key.  Files can be encrypted with
the alternative key by specifying the git-crypt-KEYNAME filter
in .gitattributes.  Alternative key support makes it possible
to encrypt different files with different keys.

Note that the -k option to unlock is temporary.  Unlock
will eventually auto-detect the name of the key you're
unlocking, either by looking in the symmetric key file,
or by scanning the .git-crypt/keys directory.

Note that the layout of the .git/git-crypt and .git-crypt
directories has changed as follows:

 * .git/git-crypt/key is now .git/git-crypt/keys/default
 * .git-crypt/keys is now .git-crypt/keys/default
2014-06-29 16:00:27 -07:00
Andrew Ayer
bec9e7f318 Add parse_options helper for parsing cmd line args 2014-06-29 13:49:10 -07:00
Andrew Ayer
f3390ff7ff Initial implementation of 'git-crypt status'
'git-crypt status' tells you which files are and aren't encrypted and
detects other problems with your git-crypt setup.

'git-crypt status -f' can be used to re-stage files that were incorrectly
staged unencrypted.

The UI needs work, and it needs to also output the overall repository
status (such as, is git-crypt even configured yet?), but this is a
good start.
2014-06-26 23:03:30 -07:00
Andrew Ayer
38b43a4415 Make 'add-collab' safe with filenames starting with '-' 2014-06-26 23:03:30 -07:00
Andrew Ayer
20c0b18fa2 Add a minor TODO comment 2014-06-26 23:03:30 -07:00
Andrew Ayer
188a8c15fc Minor pedantic changes to I/O code
Don't bother checking for !in because the gcount() check is quite
sufficient and having both checks was confusing.

Make some variables const because they can be.
2014-06-26 23:03:30 -07:00
Cyril Cleaud
df2b472cd9 Add umask and rename compatibility wrappers for Windows
umask() doesn't exist on Windows and is thus a no-op.

rename() only works if the destination doesn't already exist,
so we must unlink before renaming.
2014-06-26 23:03:30 -07:00
Andrew Ayer
6e43b2a1cd New exec_command() that takes command as array instead of string
This abstracts away the details of argument quoting, which differs
between Unix and Windows.

Also replace all uses of the system() library call with exec_command().
Although system() exists on Windows, it executes the command via cmd.exe,
which has ridiculous escaping rules.
2014-06-12 21:23:04 -07:00
Andrew Ayer
0774ed018c Lay groundwork for Windows support
Move Unix-specific code to util-unix.cpp, and place Windows equivalents
in util-win32.cpp.  Most of the Windows functions are just stubs at
the moment, and we need a build system that works on Windows.
2014-06-12 21:23:02 -07:00
Andrew Ayer
7687d11219 Initial GPG support
Run 'git-crypt add-collab KEYID' to authorize the holder of the given
GPG secret key to access the encrypted files.  The secret git-crypt key
will be encrypted with the corresponding GPG public key and stored in the
root of the Git repository under .git-crypt/keys.

After cloning a repo with encrypted files, run 'git-crypt unlock'
(with no arguments) to use a secret key in your GPG keyring to unlock
the repository.

Multiple collaborators are supported, however commands to list the
collaborators ('git-crypt ls-collabs') and to remove a collaborator
('git-crypt rm-collab') are not yet supported.
2014-03-28 14:02:25 -07:00
Andrew Ayer
b2bdc11330 Fix a typo in an error message 2014-03-28 13:53:12 -07:00
Andrew Ayer
df838947a0 Use successful_exit() helper for testing system() return value 2014-03-28 13:52:33 -07:00
Andrew Ayer
cd5f3534aa Rename some functions instead of overloading them
It's more clear this way.
2014-03-28 13:51:10 -07:00
Andrew Ayer
6a454b1fa1 Major revamp: new key paradigm, groundwork for GPG support
The active key is now stored in .git/git-crypt/key instead of being
stored outside the repo.  This will facilitate GPG support, where the
user may never interact directly with a key file.  It's also more
convenient, because it means you don't have to keep the key file
around in a fixed location (which can't be moved without breaking
git-crypt).

'git-crypt init' now takes no arguments and is used only when initializing
git-crypt for the very first time.  It generates a brand-new key, so
there's no longer a separate keygen step.

To export the key (for conveyance to another system or to a collaborator),
run 'git-crypt export-key FILENAME'.

To decrypt an existing repo using an exported key, run 'git-crypt unlock
KEYFILE'.  After running unlock, you can delete the key file you passed
to unlock.

Key files now use a new format that supports key versioning (which will
facilitate secure revocation in the future).

I've made these changes as backwards-compatible as possible.  Repos
already configured with git-crypt will continue to work without changes.
However, 'git-crypt unlock' expects a new format key.  You can use
the 'git-crypt migrate-key KEYFILE' command to migrate old keys to the
new format.

Note that old repos won't be able to use the new commands, like
export-key, or the future GPG support.  To migrate an old repo, migrate
its key file and then unlock the repo using the unlock command, as
described above.

While making these changes, I cleaned up the code significantly, adding
better error handling and improving robustness.

Next up: GPG support.
2014-03-23 11:40:29 -07:00
Andrew Ayer
34432e915e Use OpenSSL's RNG instead of /dev/random
Rationale:

 * /dev/random blocks unpredictably on Linux, leading to slow
   key generation.
 * OpenSSL's RNG is more cross-platform than /dev/(u)random.
   Some platforms might not have a (u)random device, or worse,
   have a /dev/(u)random that produces insecure random numbers
   (like Cygwin, apparently).
2013-12-30 14:37:21 -08:00
Andrew Ayer
9f20b8719c Fix a typo in a comment 2013-04-28 09:38:05 -07:00
Andrew Ayer
33f6d73a0c Improve usability of 'git-crypt keygen'
* Display message asking user to move the mouse, etc. to generate more
   entropy.
 * Disable buffering on the fstream so we don't read more randomness
   than we have to.
 * Refuse to overwrite an existing key file.
2013-04-28 09:36:17 -07:00
Andrew Ayer
2b936c74f1 Escape arguments to filter commands
This will allow both the path to git-crypt and the path to the key file
to contain arbitrary characters, notably spaces.
2013-04-04 18:53:03 -07:00
Andrew Ayer
b10fbcd299 Fix 'git-crypt init' for newer versions of Git
At some point between Git 1.7.1 and Git 1.8.1.3, both 'git reset' and
'git status' stopped noticing that files were modified after their
smudge filter changed.  Consequentially, 'git reset --hard HEAD' would
not decrypt existing encrypted files in the repo.

This commit changes 'git-crypt init' to use 'git checkout -f HEAD
/top/of/repo' instead, which does the job.
2013-04-04 17:43:38 -07:00
Andrew Ayer
e184b39eaa git-crypt init: Ignore untracked files when running git status
Untracked files are not touched by git reset, so git-crypt init
is safe even with untracked files present.

This relies on the -u option to git-status, which was added in Git
1.6.0, which was released in 2008.  Add Git 1.6.0 as a requirement in
the README.
2013-03-07 15:34:23 -08:00
Andrew Ayer
490b7143b1 Update copyright notice to include OpenSSL linking exception 2013-03-05 12:02:49 -08:00
Andrew Ayer
84b4f7ca1a Improve 'git-crypt init' usability
* Correctly check for existence of HEAD (use 'git rev-parse' instead
    of 'git show-ref').  Fixes bug where hard reset might be skipped
    after running 'git init'.
  * Don't require working directory to be clean if HEAD doesn't exist.
    (If HEAD doesn't exist, we won't be hard resetting so the working
    directory doesn't need to be clean.)
  * Overwrite existing git config values (instead of --add'ing them) so
    'git-crypt init' can be idempotent.
  * In the error message for a disrty working directory, advise user to
    commit changes or 'git stash' them.
2013-02-06 16:14:57 -08:00
Linus G Thiel
60d96ecf80 Include unistd.h for gcc 4.7
In gcc 4.7, some includes were removed. This fixes the build.

Signed-off-by: Andrew Ayer <agwa@andrewayer.name>
2013-02-06 14:52:43 -08:00
Andrew Ayer
3680884767 Restore original umask after running keygen 2013-01-24 22:02:42 -08:00
Andrew Ayer
a2e3d160bd Add README and copyright notices 2012-11-29 11:03:45 -08:00
Andrew Ayer
0dcf864798 When encrypting, use temporary file if file gets too big 2012-07-16 16:57:05 -07:00
Andrew Ayer
3f6523bd7f Improve comments about the encryption scheme 2012-07-08 22:40:01 -07:00
Andrew Ayer
d0b9ad84ae Create key file with umask of 077 2012-07-06 16:30:36 -07:00
Andrew Ayer
fab7860109 init: skip git reset if HEAD doesn't exist
This could happen if repo is brand-new with no files.
2012-07-06 16:03:30 -07:00
Andrew Ayer
6e3dd5a8d3 Initial version 2012-07-06 15:38:40 -07:00