Package:git-crypt
Version:0.7.0-0.1
When git-crypt is built with openssl 3.0 or later it uses API which have been
deprecated.
In our derived distribution we build without deprecated API which causes
git-crypt to completely fail to build.
To resolve this a patch is attached (formatted to be added to
debian/patches/series) which builds using the "modern" EVP openssl API.
--- a/crypto-openssl-11.cpp
+++ b/crypto-openssl-11.cpp
@@ -30,7 +30,7 @@
#include <openssl/opensslconf.h>
-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L && OPENSSL_VERSION_NUMBER < 0x30000000L
#include "crypto.hpp"
#include "key.hpp"
--- a/Makefile
+++ b/Makefile
@@ -24,7 +24,7 @@
coprocess.o \
fhstream.o
-OBJFILES += crypto-openssl-10.o crypto-openssl-11.o
+OBJFILES += crypto-openssl-10.o crypto-openssl-11.o crypto-openssl-30.o
LDFLAGS += -lcrypto
XSLTPROC ?= xsltproc
--- /dev/null
+++ b/crypto-openssl-30.cpp
@@ -0,0 +1,145 @@
+/*
+ * 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 <openssl/opensslconf.h>
+
+#if OPENSSL_VERSION_NUMBER >= 0x30000000L
+
+#include "crypto.hpp"
+#include "key.hpp"
+#include "util.hpp"
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/err.h>
+#include <sstream>
+#include <cstring>
+
+void init_crypto ()
+{
+}
+
+struct Aes_ecb_encryptor::Aes_impl {
+ EVP_CIPHER_CTX *ctx;
+};
+
+Aes_ecb_encryptor::Aes_ecb_encryptor (const unsigned char* raw_key)
+: impl(new Aes_impl)
+{
+
+ impl->ctx = EVP_CIPHER_CTX_new();
+ if(impl->ctx == NULL) {
+ throw Crypto_error("Aes_ctr_encryptor::Aes_ctr_encryptor", "EVP_CIPHER_CTX_new failed");
+ }
+
+ /* convert key length into cipher specifier */
+ const EVP_CIPHER *cipher=NULL;
+ switch (KEY_LEN) {
+ case 16: /* 128 bits */
+ cipher = EVP_aes_128_ecb();
+ break;
+ case 24: /* 192 bits */
+ cipher = EVP_aes_192_ecb();
+ break;
+ case 32: /* 256 bits */
+ cipher = EVP_aes_256_ecb();
+ break;
+ default:
+ throw Crypto_error("Aes_ctr_encryptor::Aes_ctr_encryptor", "Unknown AES cipher key length");
+ }
+
+
+ if (EVP_EncryptInit_ex(impl->ctx, cipher, NULL, raw_key, NULL) != 1) {
+ throw Crypto_error("Aes_ctr_encryptor::Aes_ctr_encryptor", "EVP_EncryptInit_ex failed");
+ }
+}
+
+Aes_ecb_encryptor::~Aes_ecb_encryptor ()
+{
+ EVP_CIPHER_CTX_free(impl->ctx);
+}
+
+void Aes_ecb_encryptor::encrypt(const unsigned char* plain, unsigned char* cipher)
+{
+ int len;
+ // TODO: original implementation did not check error code, this should
+ EVP_EncryptUpdate(impl->ctx, cipher, &len, plain, BLOCK_LEN);
+}
+
+struct Hmac_sha1_state::Hmac_impl {
+ EVP_MAC *mac;
+ EVP_MAC_CTX *ctx;
+};
+
+Hmac_sha1_state::Hmac_sha1_state (const unsigned char* key, size_t key_len)
+: impl(new Hmac_impl)
+{
+ OSSL_PARAM params[2];
+ char digest_name[] = "SHA1";
+ params[0] = OSSL_PARAM_construct_utf8_string("digest", digest_name, 0);
+ params[1] = OSSL_PARAM_construct_end();
+
+ impl->mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
+ impl->ctx = EVP_MAC_CTX_new(impl->mac);
+ EVP_MAC_init(impl->ctx, key, key_len, params);
+}
+
+Hmac_sha1_state::~Hmac_sha1_state ()
+{
+ EVP_MAC_CTX_free(impl->ctx);
+ EVP_MAC_free(impl->mac);
+}
+
+void Hmac_sha1_state::add (const unsigned char* buffer, size_t buffer_len)
+{
+ EVP_MAC_update(impl->ctx, buffer, buffer_len);
+}
+
+void Hmac_sha1_state::get (unsigned char* digest)
+{
+ // TODO: original implementation did not check error code, this should
+ size_t final_l;
+ EVP_MAC_final(impl->ctx, digest, &final_l, Hmac_sha1_state::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());
+ }
+}
+
+#endif