mirror of
https://github.com/AGWA/git-crypt.git
synced 2026-01-02 08:10:41 -08:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d94b44be1 | ||
|
|
2b936c74f1 | ||
|
|
b10fbcd299 | ||
|
|
e184b39eaa | ||
|
|
490b7143b1 |
22
INSTALL
Normal file
22
INSTALL
Normal file
@@ -0,0 +1,22 @@
|
||||
DEPENDENCIES
|
||||
|
||||
To use git-crypt, you need:
|
||||
|
||||
* Git 1.6.0 or newer
|
||||
* OpenSSL
|
||||
* For decrypted git diff output, Git 1.6.1 or newer
|
||||
* For decrypted git blame output, Git 1.7.2 or newer
|
||||
|
||||
To build git-crypt, you need a C++ compiler and OpenSSL development
|
||||
headers.
|
||||
|
||||
|
||||
BUILDING GIT-CRYPT
|
||||
|
||||
The Makefile is tailored for g++, but should work with other compilers.
|
||||
|
||||
$ make
|
||||
$ cp git-crypt /usr/local/bin/
|
||||
|
||||
It doesn't matter where you install the git-crypt binary - choose wherever
|
||||
is most convenient for you.
|
||||
18
NEWS
Normal file
18
NEWS
Normal file
@@ -0,0 +1,18 @@
|
||||
v0.3 (2013-04-05)
|
||||
* Fix 'git-crypt init' on newer versions of Git. Previously,
|
||||
encrypted files were not being automatically decrypted after
|
||||
running 'git-crypt init' with recent versions of Git.
|
||||
* Allow 'git-crypt init' to be run even if the working tree contains
|
||||
untracked files.
|
||||
* 'git-crypt init' now properly escapes arguments to the filter
|
||||
commands it configures, allowing both the path to git-crypt and the
|
||||
path to the key file to contain arbitrary characters such as spaces.
|
||||
|
||||
v0.2 (2013-01-25)
|
||||
* Numerous improvements to 'git-crypt init' usability.
|
||||
* Fix gitattributes example in README: the old example showed a colon
|
||||
after the filename where there shouldn't be one.
|
||||
* Various build fixes and improvements.
|
||||
|
||||
v0.1 (2012-11-29)
|
||||
* Initial release.
|
||||
71
README
71
README
@@ -16,24 +16,7 @@ For more information, see <http://www.agwa.name/projects/git-crypt>.
|
||||
|
||||
BUILDING GIT-CRYPT
|
||||
|
||||
See below for dependencies. The Makefile is tailored for g++. If you
|
||||
have a different compiler, edit Makefile and change the CXX and CFLAGS
|
||||
variables. This will be made easier in a future release.
|
||||
|
||||
$ make
|
||||
$ cp git-crypt /usr/local/bin/
|
||||
|
||||
It doesn't matter where you install the git-crypt binary - choose wherever
|
||||
is most convenient for you.
|
||||
|
||||
|
||||
DEPENDENCIES
|
||||
|
||||
To use git-crypt, you need:
|
||||
|
||||
* OpenSSL
|
||||
* For decrypted git diff output, Git 1.6.1 or later
|
||||
* For decrypted git blame output, Git 1.7.2 or later
|
||||
See the INSTALL file.
|
||||
|
||||
|
||||
USING GIT-CRYPT
|
||||
@@ -64,3 +47,55 @@ Cloning a repository with encrypted files:
|
||||
|
||||
That's all you need to do - after running git-crypt init, you can use
|
||||
git normally - encryption and decryption happen transparently.
|
||||
|
||||
|
||||
CURRENT STATUS
|
||||
|
||||
The latest version of git-crypt is 0.3, released on 2013-04-05.
|
||||
git-crypt is not yet feature complete and the user experience is rough
|
||||
in places. There may also be compatibility-breaking changes introduced
|
||||
before version 1.0. That said, git-crypt is reliable and secure and
|
||||
used to protect content in real world repositories.
|
||||
|
||||
Development on git-crypt is currently focused on improving the user
|
||||
experience, especially around setting up repositories. There are also
|
||||
plans to add additional key management schemes, such as passphrase-derived
|
||||
keys and keys encrypted with PGP.
|
||||
|
||||
|
||||
SECURITY
|
||||
|
||||
git-crypt is more secure that other transparent git encryption systems.
|
||||
git-crypt encrypts files using AES-256 in CTR mode with a synthetic
|
||||
IV derived from the SHA-1 HMAC of the file. This is provably
|
||||
semantically secure under deterministic chosen-plaintext attack.
|
||||
That means that although the encryption is deterministic (which is
|
||||
required so git can distinguish when a file has and hasn't changed),
|
||||
it leaks no information beyond whether two files are identical or not.
|
||||
Other proposals for transparent git encryption use ECB or CBC with no
|
||||
IV. These systems are not semantically secure and leak information.
|
||||
|
||||
The AES key is stored unencrypted on disk. The user is responsible for
|
||||
protecting it and ensuring it's safely distributed only to authorized
|
||||
people. A future version of git-crypt may support encrypting the key
|
||||
with a passphrase.
|
||||
|
||||
|
||||
LIMITATIONS
|
||||
|
||||
git-crypt is not designed to encrypt an entire repository. Not only does
|
||||
that defeat the aim of git-crypt, which is the ability to selectively
|
||||
encrypt files and share the repository with less-trusted developers, there
|
||||
are probably better, more efficient ways to encrypt an entire repository,
|
||||
such as by storing it on an encrypted filesystem. Also note that
|
||||
git-crypt is somewhat of an abuse of git's smudge, clean, and textconv
|
||||
features. Junio Hamano, git's maintainer, has said not to do this
|
||||
<http://thread.gmane.org/gmane.comp.version-control.git/113124/focus=113221>,
|
||||
though his main objection ("making a pair of similar 'smudged' contents
|
||||
totally dissimilar in their 'clean' counterparts.") does not apply here
|
||||
since git-crypt uses deterministic encryption.
|
||||
|
||||
git-crypt does not itself provide any authentication. It assumes that
|
||||
either the master copy of your repository is stored securely, or that
|
||||
you are using git's existing facilities to ensure integrity (signed tags,
|
||||
remembering commit hashes, etc.).
|
||||
|
||||
85
commands.cpp
85
commands.cpp
@@ -15,6 +15,17 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with git-crypt. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional permission under GNU GPL version 3 section 7:
|
||||
*
|
||||
* If you modify the Program, or any covered work, by linking or
|
||||
* combining it with the OpenSSL project's OpenSSL library (or a
|
||||
* modified version of that library), containing parts covered by the
|
||||
* terms of the OpenSSL or SSLeay licenses, the licensors of the Program
|
||||
* grant you additional permission to convey the resulting work.
|
||||
* Corresponding Source for a non-source form of such a combination
|
||||
* shall include the source code for the parts of OpenSSL used as well
|
||||
* as that of the covered work.
|
||||
*/
|
||||
|
||||
#include "commands.hpp"
|
||||
@@ -27,6 +38,7 @@
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
@@ -182,16 +194,19 @@ void init (const char* argv0, const char* keyfile)
|
||||
}
|
||||
|
||||
// 0. Check to see if HEAD exists. See below why we do this.
|
||||
bool head_exists = system("git rev-parse HEAD >/dev/null 2>/dev/null") == 0;
|
||||
bool head_exists = system("git rev-parse HEAD >/dev/null 2>/dev/null") == 0;
|
||||
|
||||
// 1. Make sure working directory is clean
|
||||
int status;
|
||||
std::string status_output;
|
||||
status = exec_command("git status --porcelain", status_output);
|
||||
// 1. Make sure working directory is clean (ignoring untracked files)
|
||||
// We do this because we run 'git checkout -f HEAD' later and we don't
|
||||
// want the user to lose any changes. 'git checkout -f HEAD' doesn't touch
|
||||
// untracked files so it's safe to ignore those.
|
||||
int status;
|
||||
std::stringstream status_output;
|
||||
status = exec_command("git status -uno --porcelain", status_output);
|
||||
if (status != 0) {
|
||||
std::clog << "git status failed - is this a git repository?\n";
|
||||
std::exit(1);
|
||||
} else if (!status_output.empty() && head_exists) {
|
||||
} else if (status_output.peek() != -1 && head_exists) {
|
||||
// We only care that the working directory is dirty if HEAD exists.
|
||||
// If HEAD doesn't exist, we won't be resetting to it (see below) so
|
||||
// it doesn't matter that the working directory is dirty.
|
||||
@@ -200,18 +215,23 @@ void init (const char* argv0, const char* keyfile)
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
// 2. Determine the path to the top of the repository. We pass this as the argument
|
||||
// to 'git checkout' below. (Determine the path now so in case it fails we haven't already
|
||||
// mucked with the git config.)
|
||||
std::stringstream cdup_output;
|
||||
if (exec_command("git rev-parse --show-cdup", cdup_output) != 0) {
|
||||
std::clog << "git rev-parse --show-cdup failed\n";
|
||||
std::exit(1);
|
||||
}
|
||||
|
||||
// 3. Add config options to git
|
||||
|
||||
std::string git_crypt_path(std::strchr(argv0, '/') ? resolve_path(argv0) : argv0);
|
||||
std::string keyfile_path(resolve_path(keyfile));
|
||||
|
||||
|
||||
// 2. Add config options to git
|
||||
|
||||
// git config filter.git-crypt.smudge "git-crypt smudge /path/to/key"
|
||||
std::string command("git config filter.git-crypt.smudge \"");
|
||||
command += git_crypt_path;
|
||||
command += " smudge ";
|
||||
command += keyfile_path;
|
||||
command += "\"";
|
||||
std::string command("git config filter.git-crypt.smudge ");
|
||||
command += escape_shell_arg(escape_shell_arg(git_crypt_path) + " smudge " + escape_shell_arg(keyfile_path));
|
||||
|
||||
if (system(command.c_str()) != 0) {
|
||||
std::clog << "git config failed\n";
|
||||
@@ -219,11 +239,8 @@ void init (const char* argv0, const char* keyfile)
|
||||
}
|
||||
|
||||
// git config filter.git-crypt.clean "git-crypt clean /path/to/key"
|
||||
command = "git config filter.git-crypt.clean \"";
|
||||
command += git_crypt_path;
|
||||
command += " clean ";
|
||||
command += keyfile_path;
|
||||
command += "\"";
|
||||
command = "git config filter.git-crypt.clean ";
|
||||
command += escape_shell_arg(escape_shell_arg(git_crypt_path) + " clean " + escape_shell_arg(keyfile_path));
|
||||
|
||||
if (system(command.c_str()) != 0) {
|
||||
std::clog << "git config failed\n";
|
||||
@@ -231,11 +248,8 @@ void init (const char* argv0, const char* keyfile)
|
||||
}
|
||||
|
||||
// git config diff.git-crypt.textconv "git-crypt diff /path/to/key"
|
||||
command = "git config diff.git-crypt.textconv \"";
|
||||
command += git_crypt_path;
|
||||
command += " diff ";
|
||||
command += keyfile_path;
|
||||
command += "\"";
|
||||
command = "git config diff.git-crypt.textconv ";
|
||||
command += escape_shell_arg(escape_shell_arg(git_crypt_path) + " diff " + escape_shell_arg(keyfile_path));
|
||||
|
||||
if (system(command.c_str()) != 0) {
|
||||
std::clog << "git config failed\n";
|
||||
@@ -243,13 +257,26 @@ void init (const char* argv0, const char* keyfile)
|
||||
}
|
||||
|
||||
|
||||
// 3. Do a hard reset so any files that were previously checked out encrypted
|
||||
// 4. Do a force checkout so any files that were previously checked out encrypted
|
||||
// will now be checked out decrypted.
|
||||
// If HEAD doesn't exist (perhaps because this repo doesn't have any files yet)
|
||||
// just skip the reset.
|
||||
if (head_exists && system("git reset --hard HEAD") != 0) {
|
||||
std::clog << "git reset --hard failed\n";
|
||||
std::exit(1);
|
||||
// just skip the checkout.
|
||||
if (head_exists) {
|
||||
std::string path_to_top;
|
||||
std::getline(cdup_output, path_to_top);
|
||||
|
||||
command = "git checkout -f HEAD -- ";
|
||||
if (path_to_top.empty()) {
|
||||
command += ".";
|
||||
} else {
|
||||
command += escape_shell_arg(path_to_top);
|
||||
}
|
||||
|
||||
if (system(command.c_str()) != 0) {
|
||||
std::clog << "git checkout failed\n";
|
||||
std::clog << "git-crypt has been set up but existing encrypted files have not been decrypted\n";
|
||||
std::exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
11
commands.hpp
11
commands.hpp
@@ -15,6 +15,17 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with git-crypt. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional permission under GNU GPL version 3 section 7:
|
||||
*
|
||||
* If you modify the Program, or any covered work, by linking or
|
||||
* combining it with the OpenSSL project's OpenSSL library (or a
|
||||
* modified version of that library), containing parts covered by the
|
||||
* terms of the OpenSSL or SSLeay licenses, the licensors of the Program
|
||||
* grant you additional permission to convey the resulting work.
|
||||
* Corresponding Source for a non-source form of such a combination
|
||||
* shall include the source code for the parts of OpenSSL used as well
|
||||
* as that of the covered work.
|
||||
*/
|
||||
|
||||
#ifndef _COMMANDS_H
|
||||
|
||||
11
crypto.cpp
11
crypto.cpp
@@ -15,6 +15,17 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with git-crypt. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional permission under GNU GPL version 3 section 7:
|
||||
*
|
||||
* If you modify the Program, or any covered work, by linking or
|
||||
* combining it with the OpenSSL project's OpenSSL library (or a
|
||||
* modified version of that library), containing parts covered by the
|
||||
* terms of the OpenSSL or SSLeay licenses, the licensors of the Program
|
||||
* grant you additional permission to convey the resulting work.
|
||||
* Corresponding Source for a non-source form of such a combination
|
||||
* shall include the source code for the parts of OpenSSL used as well
|
||||
* as that of the covered work.
|
||||
*/
|
||||
|
||||
#define _BSD_SOURCE
|
||||
|
||||
11
crypto.hpp
11
crypto.hpp
@@ -15,6 +15,17 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with git-crypt. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional permission under GNU GPL version 3 section 7:
|
||||
*
|
||||
* If you modify the Program, or any covered work, by linking or
|
||||
* combining it with the OpenSSL project's OpenSSL library (or a
|
||||
* modified version of that library), containing parts covered by the
|
||||
* terms of the OpenSSL or SSLeay licenses, the licensors of the Program
|
||||
* grant you additional permission to convey the resulting work.
|
||||
* Corresponding Source for a non-source form of such a combination
|
||||
* shall include the source code for the parts of OpenSSL used as well
|
||||
* as that of the covered work.
|
||||
*/
|
||||
|
||||
#ifndef _CRYPTO_H
|
||||
|
||||
@@ -15,6 +15,17 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with git-crypt. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional permission under GNU GPL version 3 section 7:
|
||||
*
|
||||
* If you modify the Program, or any covered work, by linking or
|
||||
* combining it with the OpenSSL project's OpenSSL library (or a
|
||||
* modified version of that library), containing parts covered by the
|
||||
* terms of the OpenSSL or SSLeay licenses, the licensors of the Program
|
||||
* grant you additional permission to convey the resulting work.
|
||||
* Corresponding Source for a non-source form of such a combination
|
||||
* shall include the source code for the parts of OpenSSL used as well
|
||||
* as that of the covered work.
|
||||
*/
|
||||
|
||||
#include "commands.hpp"
|
||||
|
||||
29
util.cpp
29
util.cpp
@@ -15,6 +15,17 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with git-crypt. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional permission under GNU GPL version 3 section 7:
|
||||
*
|
||||
* If you modify the Program, or any covered work, by linking or
|
||||
* combining it with the OpenSSL project's OpenSSL library (or a
|
||||
* modified version of that library), containing parts covered by the
|
||||
* terms of the OpenSSL or SSLeay licenses, the licensors of the Program
|
||||
* grant you additional permission to convey the resulting work.
|
||||
* Corresponding Source for a non-source form of such a combination
|
||||
* shall include the source code for the parts of OpenSSL used as well
|
||||
* as that of the covered work.
|
||||
*/
|
||||
|
||||
#include "util.hpp"
|
||||
@@ -29,7 +40,7 @@
|
||||
#include <errno.h>
|
||||
#include <fstream>
|
||||
|
||||
int exec_command (const char* command, std::string& output)
|
||||
int exec_command (const char* command, std::ostream& output)
|
||||
{
|
||||
int pipefd[2];
|
||||
if (pipe(pipefd) == -1) {
|
||||
@@ -54,7 +65,7 @@ int exec_command (const char* command, std::string& output)
|
||||
char buffer[1024];
|
||||
ssize_t bytes_read;
|
||||
while ((bytes_read = read(pipefd[0], buffer, sizeof(buffer))) > 0) {
|
||||
output.append(buffer, bytes_read);
|
||||
output.write(buffer, bytes_read);
|
||||
}
|
||||
close(pipefd[0]);
|
||||
int status = 0;
|
||||
@@ -101,3 +112,17 @@ void open_tempfile (std::fstream& file, std::ios_base::openmode mode)
|
||||
delete[] path;
|
||||
}
|
||||
|
||||
std::string escape_shell_arg (const std::string& str)
|
||||
{
|
||||
std::string new_str;
|
||||
new_str.push_back('"');
|
||||
for (std::string::const_iterator it(str.begin()); it != str.end(); ++it) {
|
||||
if (*it == '"' || *it == '\\' || *it == '$' || *it == '`') {
|
||||
new_str.push_back('\\');
|
||||
}
|
||||
new_str.push_back(*it);
|
||||
}
|
||||
new_str.push_back('"');
|
||||
return new_str;
|
||||
}
|
||||
|
||||
|
||||
14
util.hpp
14
util.hpp
@@ -15,6 +15,17 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with git-crypt. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Additional permission under GNU GPL version 3 section 7:
|
||||
*
|
||||
* If you modify the Program, or any covered work, by linking or
|
||||
* combining it with the OpenSSL project's OpenSSL library (or a
|
||||
* modified version of that library), containing parts covered by the
|
||||
* terms of the OpenSSL or SSLeay licenses, the licensors of the Program
|
||||
* grant you additional permission to convey the resulting work.
|
||||
* Corresponding Source for a non-source form of such a combination
|
||||
* shall include the source code for the parts of OpenSSL used as well
|
||||
* as that of the covered work.
|
||||
*/
|
||||
|
||||
#ifndef _UTIL_H
|
||||
@@ -24,9 +35,10 @@
|
||||
#include <ios>
|
||||
#include <iosfwd>
|
||||
|
||||
int exec_command (const char* command, std::string& output);
|
||||
int exec_command (const char* command, std::ostream& output);
|
||||
std::string resolve_path (const char* path);
|
||||
void open_tempfile (std::fstream&, std::ios_base::openmode);
|
||||
std::string escape_shell_arg (const std::string&);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user