mirror of
https://github.com/AGWA/git-crypt.git
synced 2025-12-22 23:26:11 -08:00
Pull out openssl code into separate crypto-openssl.cpp file
This will allow the use of different crypto libraries in the future. Modified-by: Andrew Ayer <agwa@andrewayer.name> * Don't include openssl/err.h from git-crypt.cpp * Fix whitespace and other style to conform to project conventions * Remove unnecessary operators from Aes_ctr_encryptor * Rename crypto_init to init_crypto, for consistency with init_std_streams()
This commit is contained in:
14
Makefile
14
Makefile
@@ -1,9 +1,19 @@
|
|||||||
CXX := c++
|
CXX := c++
|
||||||
CXXFLAGS := -Wall -pedantic -Wno-long-long -O2
|
CXXFLAGS := -Wall -pedantic -Wno-long-long -O2
|
||||||
LDFLAGS := -lcrypto
|
LDFLAGS :=
|
||||||
PREFIX := /usr/local
|
PREFIX := /usr/local
|
||||||
|
|
||||||
OBJFILES = git-crypt.o commands.o crypto.o gpg.o key.o util.o parse_options.o
|
OBJFILES = \
|
||||||
|
git-crypt.o \
|
||||||
|
commands.o \
|
||||||
|
crypto.o \
|
||||||
|
gpg.o \
|
||||||
|
key.o \
|
||||||
|
util.o \
|
||||||
|
parse_options.o
|
||||||
|
|
||||||
|
OBJFILES += crypto-openssl.o
|
||||||
|
LDFLAGS += -lcrypto
|
||||||
|
|
||||||
all: git-crypt
|
all: git-crypt
|
||||||
|
|
||||||
|
|||||||
108
crypto-openssl.cpp
Normal file
108
crypto-openssl.cpp
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012, 2014 Andrew Ayer
|
||||||
|
*
|
||||||
|
* This file is part of git-crypt.
|
||||||
|
*
|
||||||
|
* git-crypt is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* git-crypt is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* 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 "crypto.hpp"
|
||||||
|
#include "key.hpp"
|
||||||
|
#include <openssl/aes.h>
|
||||||
|
#include <openssl/sha.h>
|
||||||
|
#include <openssl/hmac.h>
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <openssl/rand.h>
|
||||||
|
#include <openssl/err.h>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
void init_crypto ()
|
||||||
|
{
|
||||||
|
ERR_load_crypto_strings();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Aes_impl {
|
||||||
|
AES_KEY key;
|
||||||
|
};
|
||||||
|
|
||||||
|
Aes_ecb_encryptor::Aes_ecb_encryptor (const unsigned char* raw_key)
|
||||||
|
{
|
||||||
|
impl = new Aes_impl;
|
||||||
|
if (AES_set_encrypt_key(raw_key, KEY_LEN * 8, &(impl->key)) != 0) {
|
||||||
|
throw Crypto_error("Aes_ctr_encryptor::Aes_ctr_encryptor", "AES_set_encrypt_key failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Aes_ecb_encryptor::~Aes_ecb_encryptor ()
|
||||||
|
{
|
||||||
|
delete impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Aes_ecb_encryptor::encrypt(const unsigned char* plain, unsigned char* cipher)
|
||||||
|
{
|
||||||
|
AES_encrypt(plain, cipher, &(impl->key));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Hmac_impl {
|
||||||
|
HMAC_CTX ctx;
|
||||||
|
};
|
||||||
|
|
||||||
|
Hmac_sha1_state::Hmac_sha1_state (const unsigned char* key, size_t key_len)
|
||||||
|
{
|
||||||
|
impl = new Hmac_impl;
|
||||||
|
HMAC_Init(&(impl->ctx), key, key_len, EVP_sha1());
|
||||||
|
}
|
||||||
|
|
||||||
|
Hmac_sha1_state::~Hmac_sha1_state ()
|
||||||
|
{
|
||||||
|
HMAC_cleanup(&(impl->ctx));
|
||||||
|
delete impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hmac_sha1_state::add (const unsigned char* buffer, size_t buffer_len)
|
||||||
|
{
|
||||||
|
HMAC_Update(&(impl->ctx), buffer, buffer_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Hmac_sha1_state::get (unsigned char* digest)
|
||||||
|
{
|
||||||
|
unsigned int len;
|
||||||
|
HMAC_Final(&(impl->ctx), digest, &len);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void random_bytes (unsigned char* buffer, size_t len)
|
||||||
|
{
|
||||||
|
if (RAND_bytes(buffer, len) != 1) {
|
||||||
|
std::ostringstream message;
|
||||||
|
while (unsigned long code = ERR_get_error()) {
|
||||||
|
char error_string[120];
|
||||||
|
ERR_error_string_n(code, error_string, sizeof(error_string));
|
||||||
|
message << "OpenSSL Error: " << error_string << "; ";
|
||||||
|
}
|
||||||
|
throw Crypto_error("random_bytes", message.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
50
crypto.cpp
50
crypto.cpp
@@ -30,22 +30,11 @@
|
|||||||
|
|
||||||
#include "crypto.hpp"
|
#include "crypto.hpp"
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
#include <openssl/aes.h>
|
|
||||||
#include <openssl/sha.h>
|
|
||||||
#include <openssl/hmac.h>
|
|
||||||
#include <openssl/evp.h>
|
|
||||||
#include <openssl/rand.h>
|
|
||||||
#include <openssl/err.h>
|
|
||||||
#include <sstream>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdlib>
|
|
||||||
|
|
||||||
Aes_ctr_encryptor::Aes_ctr_encryptor (const unsigned char* raw_key, const unsigned char* arg_nonce)
|
Aes_ctr_encryptor::Aes_ctr_encryptor (const unsigned char* raw_key, const unsigned char* arg_nonce)
|
||||||
|
: ecb(raw_key)
|
||||||
{
|
{
|
||||||
if (AES_set_encrypt_key(raw_key, KEY_LEN * 8, &key) != 0) {
|
|
||||||
throw Crypto_error("Aes_ctr_encryptor::Aes_ctr_encryptor", "AES_set_encrypt_key failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::memcpy(nonce, arg_nonce, NONCE_LEN);
|
std::memcpy(nonce, arg_nonce, NONCE_LEN);
|
||||||
byte_counter = 0;
|
byte_counter = 0;
|
||||||
std::memset(otp, '\0', sizeof(otp));
|
std::memset(otp, '\0', sizeof(otp));
|
||||||
@@ -64,7 +53,7 @@ void Aes_ctr_encryptor::process (const unsigned char* in, unsigned char* out, si
|
|||||||
store_be32(ctr + NONCE_LEN, byte_counter / BLOCK_LEN);
|
store_be32(ctr + NONCE_LEN, byte_counter / BLOCK_LEN);
|
||||||
|
|
||||||
// Generate a new OTP
|
// Generate a new OTP
|
||||||
AES_encrypt(ctr, otp, &key);
|
ecb.encrypt(ctr, otp);
|
||||||
}
|
}
|
||||||
|
|
||||||
// encrypt one byte
|
// encrypt one byte
|
||||||
@@ -76,28 +65,6 @@ void Aes_ctr_encryptor::process (const unsigned char* in, unsigned char* out, si
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Hmac_sha1_state::Hmac_sha1_state (const unsigned char* key, size_t key_len)
|
|
||||||
{
|
|
||||||
HMAC_Init(&ctx, key, key_len, EVP_sha1());
|
|
||||||
}
|
|
||||||
|
|
||||||
Hmac_sha1_state::~Hmac_sha1_state ()
|
|
||||||
{
|
|
||||||
HMAC_cleanup(&ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Hmac_sha1_state::add (const unsigned char* buffer, size_t buffer_len)
|
|
||||||
{
|
|
||||||
HMAC_Update(&ctx, buffer, buffer_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Hmac_sha1_state::get (unsigned char* digest)
|
|
||||||
{
|
|
||||||
unsigned int len;
|
|
||||||
HMAC_Final(&ctx, digest, &len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Encrypt/decrypt an entire input stream, writing to the given output stream
|
// Encrypt/decrypt an entire input stream, writing to the given output stream
|
||||||
void Aes_ctr_encryptor::process_stream (std::istream& in, std::ostream& out, const unsigned char* key, const unsigned char* nonce)
|
void Aes_ctr_encryptor::process_stream (std::istream& in, std::ostream& out, const unsigned char* key, const unsigned char* nonce)
|
||||||
{
|
{
|
||||||
@@ -111,16 +78,3 @@ void Aes_ctr_encryptor::process_stream (std::istream& in, std::ostream& out, con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void random_bytes (unsigned char* buffer, size_t len)
|
|
||||||
{
|
|
||||||
if (RAND_bytes(buffer, len) != 1) {
|
|
||||||
std::ostringstream message;
|
|
||||||
while (unsigned long code = ERR_get_error()) {
|
|
||||||
char error_string[120];
|
|
||||||
ERR_error_string_n(code, error_string, sizeof(error_string));
|
|
||||||
message << "OpenSSL Error: " << error_string << "; ";
|
|
||||||
}
|
|
||||||
throw Crypto_error("random_bytes", message.str());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
38
crypto.hpp
38
crypto.hpp
@@ -32,13 +32,13 @@
|
|||||||
#define GIT_CRYPT_CRYPTO_HPP
|
#define GIT_CRYPT_CRYPTO_HPP
|
||||||
|
|
||||||
#include "key.hpp"
|
#include "key.hpp"
|
||||||
#include <openssl/aes.h>
|
|
||||||
#include <openssl/hmac.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <iosfwd>
|
#include <iosfwd>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
void init_crypto ();
|
||||||
|
|
||||||
struct Crypto_error {
|
struct Crypto_error {
|
||||||
std::string where;
|
std::string where;
|
||||||
std::string message;
|
std::string message;
|
||||||
@@ -46,6 +46,28 @@ struct Crypto_error {
|
|||||||
Crypto_error (const std::string& w, const std::string& m) : where(w), message(m) { }
|
Crypto_error (const std::string& w, const std::string& m) : where(w), message(m) { }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Aes_impl;
|
||||||
|
|
||||||
|
class Aes_ecb_encryptor {
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
KEY_LEN = AES_KEY_LEN,
|
||||||
|
BLOCK_LEN = 16
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
Aes_impl* impl;
|
||||||
|
|
||||||
|
// disallow copy/assignment:
|
||||||
|
Aes_ecb_encryptor (const Aes_ecb_encryptor&);
|
||||||
|
Aes_ecb_encryptor& operator= (const Aes_ecb_encryptor&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
Aes_ecb_encryptor (const unsigned char* key);
|
||||||
|
~Aes_ecb_encryptor ();
|
||||||
|
void encrypt (const unsigned char* plain, unsigned char* cipher);
|
||||||
|
};
|
||||||
|
|
||||||
class Aes_ctr_encryptor {
|
class Aes_ctr_encryptor {
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
@@ -56,10 +78,10 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AES_KEY key;
|
Aes_ecb_encryptor ecb;
|
||||||
char nonce[NONCE_LEN];// First 96 bits of counter
|
char nonce[NONCE_LEN];// First 96 bits of counter
|
||||||
uint32_t byte_counter; // How many bytes processed so far?
|
uint32_t byte_counter; // How many bytes processed so far?
|
||||||
unsigned char otp[BLOCK_LEN]; // The current OTP that's in use
|
unsigned char otp[BLOCK_LEN]; // The current OTP that's in use
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Aes_ctr_encryptor (const unsigned char* key, const unsigned char* nonce);
|
Aes_ctr_encryptor (const unsigned char* key, const unsigned char* nonce);
|
||||||
@@ -72,6 +94,8 @@ public:
|
|||||||
|
|
||||||
typedef Aes_ctr_encryptor Aes_ctr_decryptor;
|
typedef Aes_ctr_encryptor Aes_ctr_decryptor;
|
||||||
|
|
||||||
|
struct Hmac_impl;
|
||||||
|
|
||||||
class Hmac_sha1_state {
|
class Hmac_sha1_state {
|
||||||
public:
|
public:
|
||||||
enum {
|
enum {
|
||||||
@@ -80,7 +104,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HMAC_CTX ctx;
|
Hmac_impl* impl;
|
||||||
|
|
||||||
// disallow copy/assignment:
|
// disallow copy/assignment:
|
||||||
Hmac_sha1_state (const Hmac_sha1_state&) { }
|
Hmac_sha1_state (const Hmac_sha1_state&) { }
|
||||||
|
|||||||
@@ -39,7 +39,6 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <openssl/err.h>
|
|
||||||
|
|
||||||
const char* argv0;
|
const char* argv0;
|
||||||
|
|
||||||
@@ -90,7 +89,7 @@ try {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
init_std_streams();
|
init_std_streams();
|
||||||
ERR_load_crypto_strings();
|
init_crypto();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse command line arguments
|
* Parse command line arguments
|
||||||
|
|||||||
Reference in New Issue
Block a user