Skip to content

Instantly share code, notes, and snippets.

@melvyn-sopacua
Created November 15, 2016 11:22
Show Gist options
  • Save melvyn-sopacua/f66152c790ca759b20beb110a8b9366a to your computer and use it in GitHub Desktop.
Save melvyn-sopacua/f66152c790ca759b20beb110a8b9366a to your computer and use it in GitHub Desktop.
Patch for archivers/libarchive to work with security/openssl-devel
From dcb7b18f53289861af3b540723c759372777f60f Mon Sep 17 00:00:00 2001
From: Melvyn Sopacua <noreply@github.com>
Date: Tue, 15 Nov 2016 12:07:35 +0100
Subject: [PATCH] Fix port to build with openssl-devel:
* Do some macro hacking to rework *_init(ctx) to ctx = *_new() caused by
making (most) types Opaque
* libmd(3) will now be used for generic hashing functions
* -lcrypto has to be added since CRYPTO_CHECK(*, openssl, *) now fails
* Temporarily set PATCH_STRIP to allow git patches to apply cleanly
This is by no means a proper fix: The OpenSSL project has decided to
make some types opaque, removing _init() and _cleanup() functions and
replacing them with _new() and _free().
Since other supported crypto implementations have not followed suit, it
will require a redesign of the data structures and handling of these
hashing/crypto contexts.
---
archivers/libarchive/Makefile | 5 +
archivers/libarchive/files/patch-openssl11-compat | 288 ++++++++++++++++++++++
2 files changed, 293 insertions(+)
create mode 100644 archivers/libarchive/files/patch-openssl11-compat
diff --git a/archivers/libarchive/Makefile b/archivers/libarchive/Makefile
index 1143786..34d05e1 100644
--- a/archivers/libarchive/Makefile
+++ b/archivers/libarchive/Makefile
@@ -24,6 +24,7 @@ USES= cpe iconv libtool pathfix
GNU_CONFIGURE= yes
INSTALL_TARGET= install-strip
USE_LDCONFIG= yes
+PATCH_STRIP= -p1
CONFIGURE_ARGS= --without-xml2
@@ -108,6 +109,10 @@ CONFIGURE_ENV+= ac_cv_header_localcharset_h=no \
ac_cv_lib_charset_locale_charset=no
.endif
+.if ${SSL_DEFAULT} == "openssl-devel"
+CFLAGS+= -DHAVE_EVP_CIPHER_CTX_NEW -DHAVE_HMAC_CTX_NEW
+LDFLAGS+= -lcrypto
+.endif
check:
@(cd ${WRKSRC} && ${SETENV} ${MAKE_ENV} ${MAKE_CMD} check)
diff --git a/archivers/libarchive/files/patch-openssl11-compat b/archivers/libarchive/files/patch-openssl11-compat
new file mode 100644
index 0000000..b6e9fe7
--- /dev/null
+++ b/archivers/libarchive/files/patch-openssl11-compat
@@ -0,0 +1,288 @@
+diff --git a/libarchive/archive_cryptor.c b/libarchive/archive_cryptor.c
+index 0be30c6..ce8b4bf 100644
+--- a/libarchive/archive_cryptor.c
++++ b/libarchive/archive_cryptor.c
+@@ -298,6 +298,17 @@ aes_ctr_release(archive_crypto_ctx *ctx)
+ }
+
+ #elif defined(HAVE_LIBCRYPTO)
++#ifdef HAVE_EVP_CIPHER_CTX_NEW
++#define CIPHER_CTX_PTR(acc) acc->ctx
++#define INIT_CIPHER_CTX(acc) acc->ctx = EVP_CIPHER_CTX_new()
++#define CLEANUP_CIPHER_CTX(acc) EVP_CIPHER_CTX_free(acc->ctx); \
++ acc->ctx = NULL;
++#else
++#define CIPHER_CTX_PTR(acc) &(acc->ctx)
++#define INIT_CIPHER_CTX(acc) EVP_CIPHER_CTX_init(CIPHER_CTX_PTR(acc))
++#define CLEANUP_CIPHER_CTX(acc) EVP_CIPHER_CTX_cleanup(CIPHER_CTX_PTR(acc)); \
++ memset(CIPHER_CTX_PTR(acc), 0, sizeof(EVP_CIPHER_CTX));
++#endif
+
+ static int
+ aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
+@@ -314,7 +325,7 @@ aes_ctr_init(archive_crypto_ctx *ctx, const uint8_t *key, size_t key_len)
+ memcpy(ctx->key, key, key_len);
+ memset(ctx->nonce, 0, sizeof(ctx->nonce));
+ ctx->encr_pos = AES_BLOCK_SIZE;
+- EVP_CIPHER_CTX_init(&ctx->ctx);
++ INIT_CIPHER_CTX(ctx);
+ return 0;
+ }
+
+@@ -324,11 +335,12 @@ aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
+ int outl = 0;
+ int r;
+
+- r = EVP_EncryptInit_ex(&ctx->ctx, ctx->type, NULL, ctx->key, NULL);
++ r = EVP_EncryptInit_ex(CIPHER_CTX_PTR(ctx), ctx->type, NULL, ctx->key,
++ NULL);
+ if (r == 0)
+ return -1;
+- r = EVP_EncryptUpdate(&ctx->ctx, ctx->encr_buf, &outl, ctx->nonce,
+- AES_BLOCK_SIZE);
++ r = EVP_EncryptUpdate(CIPHER_CTX_PTR(ctx), ctx->encr_buf, &outl,
++ ctx->nonce, AES_BLOCK_SIZE);
+ if (r == 0 || outl != AES_BLOCK_SIZE)
+ return -1;
+ return 0;
+@@ -337,7 +349,7 @@ aes_ctr_encrypt_counter(archive_crypto_ctx *ctx)
+ static int
+ aes_ctr_release(archive_crypto_ctx *ctx)
+ {
+- EVP_CIPHER_CTX_cleanup(&ctx->ctx);
++ CLEANUP_CIPHER_CTX(ctx);
+ memset(ctx->key, 0, ctx->key_len);
+ memset(ctx->nonce, 0, sizeof(ctx->nonce));
+ return 0;
+diff --git a/libarchive/archive_cryptor_private.h b/libarchive/archive_cryptor_private.h
+index 37eaad3..5c20ec1 100644
+--- a/libarchive/archive_cryptor_private.h
++++ b/libarchive/archive_cryptor_private.h
+@@ -104,7 +104,11 @@ typedef struct {
+ #define AES_MAX_KEY_SIZE 32
+
+ typedef struct {
++#ifdef HAVE_EVP_CIPHER_CTX_NEW
++ void *ctx;
++#else
+ EVP_CIPHER_CTX ctx;
++#endif
+ const EVP_CIPHER *type;
+ uint8_t key[AES_MAX_KEY_SIZE];
+ unsigned key_len;
+diff --git a/libarchive/archive_hmac.c b/libarchive/archive_hmac.c
+index 7857c0f..9caa96e 100644
+--- a/libarchive/archive_hmac.c
++++ b/libarchive/archive_hmac.c
+@@ -172,11 +172,21 @@ __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
+ }
+
+ #elif defined(HAVE_LIBCRYPTO)
++#ifdef HAVE_HMAC_CTX_NEW
++#define HMAC_CTX_INIT(ctx) HMAC_CTX *tmp = HMAC_CTX_new(); \
++ HMAC_CTX_copy(ctx, tmp); \
++ HMAC_CTX_free(tmp);
++#define HMAC_CTX_CLEANUP(ctx) HMAC_CTX_free(ctx); ctx = NULL;
++#else
++#define HMAC_CTX_INIT HMAC_CTX_init
++#define HMAC_CTX_CLEANUP(ctx) HMAC_CTX_cleanup(ctx); \
++ memset(ctx, 0, sizeof(*ctx));
++#endif
+
+ static int
+ __hmac_sha1_init(archive_hmac_sha1_ctx *ctx, const uint8_t *key, size_t key_len)
+ {
+- HMAC_CTX_init(ctx);
++ HMAC_CTX_INIT(ctx);
+ HMAC_Init(ctx, key, key_len, EVP_sha1());
+ return 0;
+ }
+@@ -199,8 +209,7 @@ __hmac_sha1_final(archive_hmac_sha1_ctx *ctx, uint8_t *out, size_t *out_len)
+ static void
+ __hmac_sha1_cleanup(archive_hmac_sha1_ctx *ctx)
+ {
+- HMAC_CTX_cleanup(ctx);
+- memset(ctx, 0, sizeof(*ctx));
++ HMAC_CTX_CLEANUP(ctx);
+ }
+
+ #else
+diff --git a/libarchive/archive_read_support_format_zip.c b/libarchive/archive_read_support_format_zip.c
+index 9796fca..f622c42 100644
+--- a/libarchive/archive_read_support_format_zip.c
++++ b/libarchive/archive_read_support_format_zip.c
+@@ -203,7 +203,13 @@ struct zip {
+ /* Contexts used for AES decryption. */
+ archive_crypto_ctx cctx;
+ char cctx_valid;
++#if defined(HAVE_LIBCRYPTO) && defined(HAVE_HMAC_CTX_NEW)
++ archive_hmac_sha1_ctx *hctx;
++#define HMAC_CTX_PTR(z) (z->hctx)
++#else
+ archive_hmac_sha1_ctx hctx;
++#define HMAC_CTX_PTR(z) (&(z->hctx))
++#endif
+ char hctx_valid;
+
+ /* Strong encryption's decryption header information. */
+@@ -1058,7 +1064,8 @@ check_authentication_code(struct archive_read *a, const void *_p)
+ size_t hmac_len = 20;
+ int cmp;
+
+- archive_hmac_sha1_final(&zip->hctx, hmac, &hmac_len);
++ archive_hmac_sha1_final(HMAC_CTX_PTR(zip), hmac,
++ &hmac_len);
+ if (_p == NULL) {
+ /* Read authentication code. */
+ p = __archive_read_ahead(a, AUTH_CODE_SIZE, NULL);
+@@ -1223,7 +1230,7 @@ zip_read_data_none(struct archive_read *a, const void **_buff,
+ zip->decrypted_buffer, dec_size);
+ } else {
+ size_t dsize = dec_size;
+- archive_hmac_sha1_update(&zip->hctx,
++ archive_hmac_sha1_update(HMAC_CTX_PTR(zip),
+ (const uint8_t *)buff, dec_size);
+ archive_decrypto_aes_ctr_update(&zip->cctx,
+ (const uint8_t *)buff, dec_size,
+@@ -1400,7 +1407,7 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
+ }
+ /* Calculate compressed data as much as we used.*/
+ if (zip->hctx_valid)
+- archive_hmac_sha1_update(&zip->hctx, sp, bytes_avail);
++ archive_hmac_sha1_update(HMAC_CTX_PTR(zip), sp, bytes_avail);
+ __archive_read_consume(a, bytes_avail);
+ zip->entry_bytes_remaining -= bytes_avail;
+ zip->entry_compressed_bytes_read += bytes_avail;
+@@ -1796,7 +1803,8 @@ init_WinZip_AES_decryption(struct archive_read *a)
+ "Decryption is unsupported due to lack of crypto library");
+ return (ARCHIVE_FAILED);
+ }
+- r = archive_hmac_sha1_init(&zip->hctx, derived_key + key_len, key_len);
++ r = archive_hmac_sha1_init(HMAC_CTX_PTR(zip), derived_key + key_len,
++ key_len);
+ if (r != 0) {
+ archive_decrypto_aes_ctr_release(&zip->cctx);
+ archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
+@@ -1954,7 +1962,7 @@ archive_read_format_zip_cleanup(struct archive_read *a)
+ if (zip->cctx_valid)
+ archive_decrypto_aes_ctr_release(&zip->cctx);
+ if (zip->hctx_valid)
+- archive_hmac_sha1_cleanup(&zip->hctx);
++ archive_hmac_sha1_cleanup(HMAC_CTX_PTR(zip));
+ free(zip->iv);
+ free(zip->erd);
+ free(zip->v_data);
+diff --git a/libarchive/archive_write_set_format_zip.c b/libarchive/archive_write_set_format_zip.c
+index e4edb81..48f4420 100644
+--- a/libarchive/archive_write_set_format_zip.c
++++ b/libarchive/archive_write_set_format_zip.c
+@@ -139,7 +139,13 @@ struct zip {
+ unsigned aes_vendor;
+ archive_crypto_ctx cctx;
+ char cctx_valid;
++#if defined(HAVE_LIBCRYPTO) && defined(HAVE_HMAC_CTX_NEW)
++ archive_hmac_sha1_ctx *hctx;
++#define HMAC_CTX_PTR(z) (z->hctx)
++#else
+ archive_hmac_sha1_ctx hctx;
++#define HMAC_CTX_PTR(z) (&(z->hctx))
++#endif
+ char hctx_valid;
+
+ unsigned char *file_header;
+@@ -572,7 +578,7 @@ archive_write_zip_header(struct archive_write *a, struct archive_entry *entry)
+ if (zip->cctx_valid)
+ archive_encrypto_aes_ctr_release(&zip->cctx);
+ if (zip->hctx_valid)
+- archive_hmac_sha1_cleanup(&zip->hctx);
++ archive_hmac_sha1_cleanup(HMAC_CTX_PTR(zip));
+ zip->tctx_valid = zip->cctx_valid = zip->hctx_valid = 0;
+
+ if (type == AE_IFREG
+@@ -1059,8 +1065,8 @@ archive_write_zip_data(struct archive_write *a, const void *buff, size_t s)
+ "Failed to encrypt file");
+ return (ARCHIVE_FAILED);
+ }
+- archive_hmac_sha1_update(&zip->hctx,
+- zip->buf, l);
++ archive_hmac_sha1_update(
++ HMAC_CTX_PTR(zip), zip->buf, l);
+ }
+ ret = __archive_write_output(a, zip->buf, l);
+ if (ret != ARCHIVE_OK)
+@@ -1102,8 +1108,9 @@ archive_write_zip_data(struct archive_write *a, const void *buff, size_t s)
+ "Failed to encrypt file");
+ return (ARCHIVE_FAILED);
+ }
+- archive_hmac_sha1_update(&zip->hctx,
+- zip->buf, zip->len_buf);
++ archive_hmac_sha1_update(
++ HMAC_CTX_PTR(zip), zip->buf,
++ zip->len_buf);
+ }
+ ret = __archive_write_output(a, zip->buf,
+ zip->len_buf);
+@@ -1161,7 +1168,7 @@ archive_write_zip_finish_entry(struct archive_write *a)
+ "Failed to encrypt file");
+ return (ARCHIVE_FAILED);
+ }
+- archive_hmac_sha1_update(&zip->hctx,
++ archive_hmac_sha1_update(HMAC_CTX_PTR(zip),
+ zip->buf, remainder);
+ }
+ ret = __archive_write_output(a, zip->buf, remainder);
+@@ -1181,7 +1188,7 @@ archive_write_zip_finish_entry(struct archive_write *a)
+ uint8_t hmac[20];
+ size_t hmac_len = 20;
+
+- archive_hmac_sha1_final(&zip->hctx, hmac, &hmac_len);
++ archive_hmac_sha1_final(HMAC_CTX_PTR(zip), hmac, &hmac_len);
+ ret = __archive_write_output(a, hmac, AUTH_CODE_SIZE);
+ if (ret != ARCHIVE_OK)
+ return (ret);
+@@ -1360,7 +1367,7 @@ archive_write_zip_free(struct archive_write *a)
+ if (zip->cctx_valid)
+ archive_encrypto_aes_ctr_release(&zip->cctx);
+ if (zip->hctx_valid)
+- archive_hmac_sha1_cleanup(&zip->hctx);
++ archive_hmac_sha1_cleanup(HMAC_CTX_PTR(zip));
+ /* TODO: Free opt_sconv, sconv_default */
+
+ free(zip);
+@@ -1617,7 +1624,7 @@ init_winzip_aes_encryption(struct archive_write *a)
+ "Decryption is unsupported due to lack of crypto library");
+ return (ARCHIVE_FAILED);
+ }
+- ret = archive_hmac_sha1_init(&zip->hctx, derived_key + key_len,
++ ret = archive_hmac_sha1_init(HMAC_CTX_PTR(zip), derived_key + key_len,
+ key_len);
+ if (ret != 0) {
+ archive_encrypto_aes_ctr_release(&zip->cctx);
+@@ -1647,7 +1654,13 @@ is_winzip_aes_encryption_supported(int encryption)
+ uint8_t salt[16 + 2];
+ uint8_t derived_key[MAX_DERIVED_KEY_BUF_SIZE];
+ archive_crypto_ctx cctx;
++#if defined(HAVE_LIBCRYPTO) && defined(HAVE_HMAC_CTX_NEW)
++ archive_hmac_sha1_ctx *hctx;
++#define CTX_PTR(c) (c)
++#else
+ archive_hmac_sha1_ctx hctx;
++#define CTX_PTR(c) (&c)
++#endif
+ int ret;
+
+ if (encryption == ENCRYPTION_WINZIP_AES128) {
+@@ -1668,11 +1681,11 @@ is_winzip_aes_encryption_supported(int encryption)
+ ret = archive_encrypto_aes_ctr_init(&cctx, derived_key, key_len);
+ if (ret != 0)
+ return (0);
+- ret = archive_hmac_sha1_init(&hctx, derived_key + key_len,
++ ret = archive_hmac_sha1_init(CTX_PTR(hctx), derived_key + key_len,
+ key_len);
+ archive_encrypto_aes_ctr_release(&cctx);
+ if (ret != 0)
+ return (0);
+- archive_hmac_sha1_cleanup(&hctx);
++ archive_hmac_sha1_cleanup(CTX_PTR(hctx));
+ return (1);
+ }
--
2.10.1
@alonlavian
Copy link

Hi, did you submit a pull request for libarchive?
this could be very useful

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment