On 2017-10-13 21:25:01 [+0200], Carsten Leonhardt wrote:
> Hi Sebastian,
Hi Carsten,

> I've checked all three distros, Fedora and Arch use OpenSSL 1.0 to build
> bacula. For Gentoo I'm not sure I can parse the ebuild-files correctly,
> but I think they use LibreSSL - in any case there's no patch to enable
> building with OpenSSL 1.1.

please find attached a few patches :) I can compile against 1.0.2 and
1.1 with them applied. Please do some testing. There is no testsuite so…

> Regards,
> 
> Carsten

Sebastian
From 2da5f9b134943f62fb7c22e6d5e64599b43011cc Mon Sep 17 00:00:00 2001
From: Sebastian Andrzej Siewior <sebast...@breakpoint.cc>
Date: Wed, 8 Nov 2017 14:37:31 +0100
Subject: [PATCH 1/5] crypto: remove support for ancient openssl
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

OpenSSL 1.0.2 is still supported. Everything earlier is not so the old
code for compat can be thrown away, especially the 0.9.8 support.

TLSv1_method() should not be used and SSLv23_method() should be
preferred because the latter supports TLS1.0…1.2 while the former _only_
tries TLS1.0.

Signed-off-by: Sebastian Andrzej Siewior <sebast...@breakpoint.cc>
---
 src/lib/crypto.c | 22 ----------------------
 src/lib/tls.c    | 14 +-------------
 2 files changed, 1 insertion(+), 35 deletions(-)

diff --git a/src/lib/crypto.c b/src/lib/crypto.c
index 9f309d58e473..b4403eb45618 100644
--- a/src/lib/crypto.c
+++ b/src/lib/crypto.c
@@ -307,12 +307,7 @@ static ASN1_OCTET_STRING *openssl_cert_keyid(X509 *cert) {
    const X509V3_EXT_METHOD *method;
    ASN1_OCTET_STRING *keyid;
    int i;
-#if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
    const unsigned char *ext_value_data;
-#else
-   unsigned char *ext_value_data;
-#endif
-
 
    /* Find the index to the subjectKeyIdentifier extension */
    i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1);
@@ -331,7 +326,6 @@ static ASN1_OCTET_STRING *openssl_cert_keyid(X509 *cert) {
 
    ext_value_data = ext->value->data;
 
-#if (OPENSSL_VERSION_NUMBER > 0x00907000L)
    if (method->it) {
       /* New style ASN1 */
 
@@ -345,10 +339,6 @@ static ASN1_OCTET_STRING *openssl_cert_keyid(X509 *cert) {
       keyid = (ASN1_OCTET_STRING *) method->d2i(NULL, &ext_value_data, ext->value->length);
    }
 
-#else
-   keyid = (ASN1_OCTET_STRING *) method->d2i(NULL, &ext_value_data, ext->value->length);
-#endif
-
    return keyid;
 }
 
@@ -783,11 +773,7 @@ crypto_error_t crypto_sign_verify(SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST
    SignerInfo *si;
    int ok, i;
    unsigned int sigLen;
-#if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
    const unsigned char *sigData;
-#else
-   unsigned char *sigData;
-#endif
 
    signers = sig->sigData->signerInfo;
 
@@ -934,11 +920,7 @@ int crypto_sign_encode(SIGNATURE *sig, uint8_t *dest, uint32_t *length)
 SIGNATURE *crypto_sign_decode(JCR *jcr, const uint8_t *sigData, uint32_t length)
 {
    SIGNATURE *sig;
-#if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
    const unsigned char *p = (const unsigned char *) sigData;
-#else
-   unsigned char *p = (unsigned char *)sigData;
-#endif
 
    sig = (SIGNATURE *)malloc(sizeof(SIGNATURE));
    if (!sig) {
@@ -1156,11 +1138,7 @@ crypto_error_t crypto_session_decode(const uint8_t *data, uint32_t length, alist
    X509_KEYPAIR *keypair;
    STACK_OF(RecipientInfo) *recipients;
    crypto_error_t retval = CRYPTO_ERROR_NONE;
-#if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
    const unsigned char *p = (const unsigned char *)data;
-#else
-   unsigned char *p = (unsigned char *)data;
-#endif
 
    /* bacula-fd.conf doesn't contains any key */
    if (!keypairs) {
diff --git a/src/lib/tls.c b/src/lib/tls.c
index f444a276a5e2..992265b38ad2 100644
--- a/src/lib/tls.c
+++ b/src/lib/tls.c
@@ -118,13 +118,10 @@ TLS_CONTEXT *new_tls_context(const char *ca_certfile, const char *ca_certdir,
    /* Allows SSLv3, TLSv1, TLSv1.1 and TLSv1.2 protocols */
    ctx->openssl = SSL_CTX_new(TLS_method());
 
-#elif (OPENSSL_VERSION_NUMBER >= 0x10000000L)
+#else
    /* Allows most all protocols */
    ctx->openssl = SSL_CTX_new(SSLv23_method());
 
-#else
-   /* Older method only understands TLSv1 */
-   ctx->openssl = SSL_CTX_new(TLSv1_method());
 #endif
 
    /* Use SSL_OP_ALL to turn on all "rather harmless" workarounds that
@@ -337,11 +334,7 @@ bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host
             STACK_OF(CONF_VALUE) *val;
             CONF_VALUE *nval;
             void *extstr = NULL;
-#if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
             const unsigned char *ext_value_data;
-#else
-            unsigned char *ext_value_data;
-#endif
 
             /* Get x509 extension method structure */
             if (!(method = X509V3_EXT_get(ext))) {
@@ -350,7 +343,6 @@ bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host
 
             ext_value_data = ext->value->data;
 
-#if (OPENSSL_VERSION_NUMBER > 0x00907000L)
             if (method->it) {
                /* New style ASN1 */
 
@@ -364,10 +356,6 @@ bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host
                extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
             }
 
-#else
-            extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
-#endif
-
             /* Iterate through to find the dNSName field(s) */
             val = method->i2v(method, extstr, NULL);
 
-- 
2.15.0

>From bdcf77673aeac0cb1de81f4148c23328cae0f4f7 Mon Sep 17 00:00:00 2001
From: Sebastian Andrzej Siewior <sebast...@breakpoint.cc>
Date: Wed, 8 Nov 2017 14:40:12 +0100
Subject: [PATCH 2/5] crypto: Add a tiny OpenSSL compat level

This header file provides a few OpenSSL 1.1 functions which are not
available in OpenSSL 1.0.2 and earlier. The body of the function
implements the pre-1.1 version of the function provided in 1.1.

Signed-off-by: Sebastian Andrzej Siewior <sebast...@breakpoint.cc>
---
 src/lib/crypto.c         |  2 ++
 src/lib/openssl-compat.h | 43 +++++++++++++++++++++++++++++++++++++++++++
 src/lib/tls.c            |  2 ++
 3 files changed, 47 insertions(+)
 create mode 100644 src/lib/openssl-compat.h

diff --git a/src/lib/crypto.c b/src/lib/crypto.c
index b4403eb45618..c172efb2b5d9 100644
--- a/src/lib/crypto.c
+++ b/src/lib/crypto.c
@@ -131,6 +131,8 @@
 #ifdef HAVE_CRYPTO /* Is encryption enabled? */
 #ifdef HAVE_OPENSSL /* How about OpenSSL? */
 
+#include "openssl-compat.h"
+
 /* ASN.1 Declarations */
 #define BACULA_ASN1_VERSION 0
 
diff --git a/src/lib/openssl-compat.h b/src/lib/openssl-compat.h
new file mode 100644
index 000000000000..2effcb6bc9bb
--- /dev/null
+++ b/src/lib/openssl-compat.h
@@ -0,0 +1,43 @@
+#ifndef __OPENSSL_COPMAT__H__
+#define __OPENSSL_COPMAT__H__
+
+#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+static int EVP_PKEY_up_ref(EVP_PKEY *pkey)
+{
+	CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+	return 0;
+}
+
+static void EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx)
+{
+	EVP_CIPHER_CTX_init(ctx);
+}
+
+static void EVP_MD_CTX_reset(EVP_MD_CTX *ctx)
+{
+	EVP_MD_CTX_init(ctx);
+}
+
+static EVP_MD_CTX *EVP_MD_CTX_new(void)
+{
+	EVP_MD_CTX *ctx;
+
+	ctx = (EVP_MD_CTX *)OPENSSL_malloc(sizeof(EVP_MD_CTX));
+	if (ctx)
+		memset(ctx, 0, sizeof(EVP_MD_CTX));
+	return ctx;
+}
+
+static void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
+{
+	EVP_MD_CTX_reset(ctx);
+	OPENSSL_free(ctx);
+}
+
+static const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *asn1)
+{
+	return asn1->data;
+}
+#endif
+
+#endif
diff --git a/src/lib/tls.c b/src/lib/tls.c
index 992265b38ad2..c71a4ad525fe 100644
--- a/src/lib/tls.c
+++ b/src/lib/tls.c
@@ -45,6 +45,8 @@
 
 #ifdef HAVE_OPENSSL /* How about OpenSSL? */
 
+#include "openssl-compat.h"
+
 /* No anonymous ciphers, no <128 bit ciphers, no export ciphers, no MD5 ciphers */
 #define TLS_DEFAULT_CIPHERS "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"
 
-- 
2.15.0

>From e8186c36805dcec1c9f4333a294288200a3ab9f1 Mon Sep 17 00:00:00 2001
From: Sebastian Andrzej Siewior <sebast...@breakpoint.cc>
Date: Wed, 8 Nov 2017 14:42:22 +0100
Subject: [PATCH 3/5] crypto: Use DEFINE_STACK_OF()

OpenSSL 1.1 makes it possible to use DEFINE_STACK_OF() instead of
IMPLEMENT_STACK_OF() + mkstack.pl's output.

Signed-off-by: Sebastian Andrzej Siewior <sebast...@breakpoint.cc>
---
 src/lib/crypto.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/lib/crypto.c b/src/lib/crypto.c
index c172efb2b5d9..4b9f0f2a2f3a 100644
--- a/src/lib/crypto.c
+++ b/src/lib/crypto.c
@@ -194,9 +194,11 @@ IMPLEMENT_ASN1_FUNCTIONS(SignerInfo)
 IMPLEMENT_ASN1_FUNCTIONS(RecipientInfo)
 IMPLEMENT_ASN1_FUNCTIONS(SignatureData)
 IMPLEMENT_ASN1_FUNCTIONS(CryptoData)
-IMPLEMENT_STACK_OF(SignerInfo)
-IMPLEMENT_STACK_OF(RecipientInfo)
 
+#if (OPENSSL_VERSION_NUMBER >= 0x10100000L)
+DEFINE_STACK_OF(SignerInfo);
+DEFINE_STACK_OF(RecipientInfo);
+#else
 /*
  * SignerInfo and RecipientInfo stack macros, generated by OpenSSL's util/mkstack.pl.
  */
@@ -260,6 +262,7 @@ IMPLEMENT_STACK_OF(RecipientInfo)
 #define ASN1_seq_unpack_RecipientInfo(buf, len, d2i_func, free_func) \
         SKM_ASN1_seq_unpack(RecipientInfo, (buf), (len), (d2i_func), (free_func))
 /* End of util/mkstack.pl block */
+#endif
 
 /* X509 Public/Private Key Pair Structure */
 struct X509_Keypair {
-- 
2.15.0

>From 44a8f9083ac6e5ecc9ea199074695b425ab2b050 Mon Sep 17 00:00:00 2001
From: Sebastian Andrzej Siewior <sebast...@breakpoint.cc>
Date: Wed, 8 Nov 2017 21:01:45 +0100
Subject: [PATCH 4/5] crypto: convert EVP_MD_CTX + EVP_CIPHER_CTX to OpenSSL
 1.1

Those digest structs became opaque and now they need to be allocated
and for access we need to use accessor functions.

Signed-off-by: Sebastian Andrzej Siewior <sebast...@breakpoint.cc>
---
 src/lib/crypto.c | 51 +++++++++++++++++++++++++++++----------------------
 1 file changed, 29 insertions(+), 22 deletions(-)

diff --git a/src/lib/crypto.c b/src/lib/crypto.c
index 4b9f0f2a2f3a..1dae063697c7 100644
--- a/src/lib/crypto.c
+++ b/src/lib/crypto.c
@@ -275,7 +275,7 @@ struct X509_Keypair {
 struct Digest {
    crypto_digest_t type;
    JCR *jcr;
-   EVP_MD_CTX ctx;
+   EVP_MD_CTX *ctx;
 };
 
 /* Message Signature Structure */
@@ -293,7 +293,7 @@ struct Crypto_Session {
 
 /* Symmetric Cipher Context */
 struct Cipher_Context {
-   EVP_CIPHER_CTX ctx;
+   EVP_CIPHER_CTX *ctx;
 };
 
 /* PEM Password Dispatch Context */
@@ -590,7 +590,10 @@ DIGEST *crypto_digest_new(JCR *jcr, crypto_digest_t type)
    Dmsg1(150, "crypto_digest_new jcr=%p\n", jcr);
 
    /* Initialize the OpenSSL message digest context */
-   EVP_MD_CTX_init(&digest->ctx);
+   digest->ctx = EVP_MD_CTX_new();
+   if (!digest->ctx)
+	   goto err;
+   EVP_MD_CTX_reset(digest->ctx);
 
    /* Determine the correct OpenSSL message digest type */
    switch (type) {
@@ -614,7 +617,7 @@ DIGEST *crypto_digest_new(JCR *jcr, crypto_digest_t type)
    }
 
    /* Initialize the backing OpenSSL context */
-   if (EVP_DigestInit_ex(&digest->ctx, md, NULL) == 0) {
+   if (EVP_DigestInit_ex(digest->ctx, md, NULL) == 0) {
       goto err;
    }
 
@@ -635,7 +638,7 @@ DIGEST *crypto_digest_new(JCR *jcr, crypto_digest_t type)
  */
 bool crypto_digest_update(DIGEST *digest, const uint8_t *data, uint32_t length)
 {
-   if (EVP_DigestUpdate(&digest->ctx, data, length) == 0) {
+   if (EVP_DigestUpdate(digest->ctx, data, length) == 0) {
       Dmsg0(150, "digest update failed\n");
       openssl_post_errors(digest->jcr, M_ERROR, _("OpenSSL digest update failed"));
       return false;
@@ -653,7 +656,7 @@ bool crypto_digest_update(DIGEST *digest, const uint8_t *data, uint32_t length)
  */
 bool crypto_digest_finalize(DIGEST *digest, uint8_t *dest, uint32_t *length)
 {
-   if (!EVP_DigestFinal(&digest->ctx, dest, (unsigned int *)length)) {
+   if (!EVP_DigestFinal(digest->ctx, dest, (unsigned int *)length)) {
       Dmsg0(150, "digest finalize failed\n");
       openssl_post_errors(digest->jcr, M_ERROR, _("OpenSSL digest finalize failed"));
       return false;
@@ -667,7 +670,7 @@ bool crypto_digest_finalize(DIGEST *digest, uint8_t *dest, uint32_t *length)
  */
 void crypto_digest_free(DIGEST *digest)
 {
-  EVP_MD_CTX_cleanup(&digest->ctx);
+  EVP_MD_CTX_free(digest->ctx);
   free(digest);
 }
 
@@ -790,7 +793,7 @@ crypto_error_t crypto_sign_verify(SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST
          sigLen = M_ASN1_STRING_length(si->signature);
          sigData = M_ASN1_STRING_data(si->signature);
 
-         ok = EVP_VerifyFinal(&digest->ctx, sigData, sigLen, keypair->pubkey);
+         ok = EVP_VerifyFinal(digest->ctx, sigData, sigLen, keypair->pubkey);
          if (ok >= 1) {
             return CRYPTO_ERROR_NONE;
          } else if (ok == 0) {
@@ -858,12 +861,12 @@ int crypto_sign_add_signer(SIGNATURE *sig, DIGEST *digest, X509_KEYPAIR *keypair
    /* Set our signature algorithm. We currently require RSA */
    assert(EVP_PKEY_type(keypair->pubkey->type) == EVP_PKEY_RSA);
    /* This is slightly evil. Reach into the MD structure and grab the key type */
-   si->signatureAlgorithm = OBJ_nid2obj(digest->ctx.digest->pkey_type);
+   si->signatureAlgorithm = OBJ_nid2obj(EVP_MD_pkey_type(EVP_MD_CTX_md(digest->ctx)));
 
    /* Finalize/Sign our Digest */
    len = EVP_PKEY_size(keypair->privkey);
    buf = (unsigned char *) malloc(len);
-   if (!EVP_SignFinal(&digest->ctx, buf, &len, keypair->privkey)) {
+   if (!EVP_SignFinal(digest->ctx, buf, &len, keypair->privkey)) {
       openssl_post_errors(M_ERROR, _("Signature creation failed"));
       goto err;
    }
@@ -1249,6 +1252,12 @@ CIPHER_CONTEXT *crypto_cipher_new(CRYPTO_SESSION *cs, bool encrypt, uint32_t *bl
    const EVP_CIPHER *ec;
 
    cipher_ctx = (CIPHER_CONTEXT *)malloc(sizeof(CIPHER_CONTEXT));
+   if (!cipher_ctx)
+	   return NULL;
+
+   cipher_ctx->ctx = EVP_CIPHER_CTX_new();
+   if (cipher_ctx->ctx)
+	   goto err;
 
    /*
     * Acquire a cipher instance for the given ASN.1 cipher NID
@@ -1261,40 +1270,40 @@ CIPHER_CONTEXT *crypto_cipher_new(CRYPTO_SESSION *cs, bool encrypt, uint32_t *bl
    }
 
    /* Initialize the OpenSSL cipher context */
-   EVP_CIPHER_CTX_init(&cipher_ctx->ctx);
+   EVP_CIPHER_CTX_reset(cipher_ctx->ctx);
    if (encrypt) {
       /* Initialize for encryption */
-      if (!EVP_CipherInit_ex(&cipher_ctx->ctx, ec, NULL, NULL, NULL, 1)) {
+      if (!EVP_CipherInit_ex(cipher_ctx->ctx, ec, NULL, NULL, NULL, 1)) {
          openssl_post_errors(M_ERROR, _("OpenSSL cipher context initialization failed"));
          goto err;
       }
    } else {
       /* Initialize for decryption */
-      if (!EVP_CipherInit_ex(&cipher_ctx->ctx, ec, NULL, NULL, NULL, 0)) {
+      if (!EVP_CipherInit_ex(cipher_ctx->ctx, ec, NULL, NULL, NULL, 0)) {
          openssl_post_errors(M_ERROR, _("OpenSSL cipher context initialization failed"));
          goto err;
       }
    }
 
    /* Set the key size */
-   if (!EVP_CIPHER_CTX_set_key_length(&cipher_ctx->ctx, cs->session_key_len)) {
+   if (!EVP_CIPHER_CTX_set_key_length(cipher_ctx->ctx, cs->session_key_len)) {
       openssl_post_errors(M_ERROR, _("Encryption session provided an invalid symmetric key"));
       goto err;
    }
 
    /* Validate the IV length */
-   if (EVP_CIPHER_iv_length(ec) != M_ASN1_STRING_length(cs->cryptoData->iv)) {
+   if (EVP_CIPHER_iv_length(ec) != ASN1_STRING_length(cs->cryptoData->iv)) {
       openssl_post_errors(M_ERROR, _("Encryption session provided an invalid IV"));
       goto err;
    }
 
    /* Add the key and IV to the cipher context */
-   if (!EVP_CipherInit_ex(&cipher_ctx->ctx, NULL, NULL, cs->session_key, M_ASN1_STRING_data(cs->cryptoData->iv), -1)) {
+   if (!EVP_CipherInit_ex(cipher_ctx->ctx, NULL, NULL, cs->session_key, ASN1_STRING_get0_data(cs->cryptoData->iv), -1)) {
       openssl_post_errors(M_ERROR, _("OpenSSL cipher context key/IV initialization failed"));
       goto err;
    }
 
-   *blocksize = EVP_CIPHER_CTX_block_size(&cipher_ctx->ctx);
+   *blocksize = EVP_CIPHER_CTX_block_size(cipher_ctx->ctx);
    return cipher_ctx;
 
 err:
@@ -1310,7 +1319,7 @@ CIPHER_CONTEXT *crypto_cipher_new(CRYPTO_SESSION *cs, bool encrypt, uint32_t *bl
  */
 bool crypto_cipher_update(CIPHER_CONTEXT *cipher_ctx, const uint8_t *data, uint32_t length, const uint8_t *dest, uint32_t *written)
 {
-   if (!EVP_CipherUpdate(&cipher_ctx->ctx, (unsigned char *)dest, (int *)written, (const unsigned char *)data, length)) {
+   if (!EVP_CipherUpdate(cipher_ctx->ctx, (unsigned char *)dest, (int *)written, (const unsigned char *)data, length)) {
       /* This really shouldn't fail */
       return false;
    } else {
@@ -1328,7 +1337,7 @@ bool crypto_cipher_update(CIPHER_CONTEXT *cipher_ctx, const uint8_t *data, uint3
  */
 bool crypto_cipher_finalize (CIPHER_CONTEXT *cipher_ctx, uint8_t *dest, uint32_t *written)
 {
-   if (!EVP_CipherFinal_ex(&cipher_ctx->ctx, (unsigned char *)dest, (int *) written)) {
+   if (!EVP_CipherFinal_ex(cipher_ctx->ctx, (unsigned char *)dest, (int *) written)) {
       /* This really shouldn't fail */
       return false;
    } else {
@@ -1342,12 +1351,10 @@ bool crypto_cipher_finalize (CIPHER_CONTEXT *cipher_ctx, uint8_t *dest, uint32_t
  */
 void crypto_cipher_free (CIPHER_CONTEXT *cipher_ctx)
 {
-   EVP_CIPHER_CTX_cleanup(&cipher_ctx->ctx);
+   EVP_CIPHER_CTX_free(cipher_ctx->ctx);
    free (cipher_ctx);
 }
 
-
-
 #else /* HAVE_OPENSSL */
 # error No encryption library available
 #endif /* HAVE_OPENSSL */
-- 
2.15.0

>From 8e5336b18826a9057912d55f5aafb3d1e392d195 Mon Sep 17 00:00:00 2001
From: Sebastian Andrzej Siewior <sebast...@breakpoint.cc>
Date: Wed, 8 Nov 2017 21:08:10 +0100
Subject: [PATCH 5/5] crypto_: convert EVP_PKEY access and remainings bits for
 OpenSSL 1.1

EVP_PKEY became opaque and can not be dereferences in OpenSSL 1.1 and
accessor functions need to be used. This is also true for X509_EXTENSION
relevant access.

Signed-off-by: Sebastian Andrzej Siewior <sebast...@breakpoint.cc>
---
 src/lib/crypto.c | 72 +++++++++++++++++++++++++++++++-------------------------
 src/lib/tls.c    |  8 ++++---
 2 files changed, 45 insertions(+), 35 deletions(-)

diff --git a/src/lib/crypto.c b/src/lib/crypto.c
index 1dae063697c7..3657c06aa8b0 100644
--- a/src/lib/crypto.c
+++ b/src/lib/crypto.c
@@ -304,7 +304,7 @@ typedef struct PEM_CB_Context {
 
 /*
  * Extract subjectKeyIdentifier from x509 certificate.
- * Returns: On success, an ASN1_OCTET_STRING that must be freed via M_ASN1_OCTET_STRING_free().
+ * Returns: On success, an ASN1_OCTET_STRING that must be freed via ASN1_OCTET_STRING_free().
  *          NULL on failure.
  */
 static ASN1_OCTET_STRING *openssl_cert_keyid(X509 *cert) {
@@ -312,6 +312,7 @@ static ASN1_OCTET_STRING *openssl_cert_keyid(X509 *cert) {
    const X509V3_EXT_METHOD *method;
    ASN1_OCTET_STRING *keyid;
    int i;
+   const ASN1_STRING *asn1_ext_val;
    const unsigned char *ext_value_data;
 
    /* Find the index to the subjectKeyIdentifier extension */
@@ -329,19 +330,20 @@ static ASN1_OCTET_STRING *openssl_cert_keyid(X509 *cert) {
       return NULL;
    }
 
-   ext_value_data = ext->value->data;
+   asn1_ext_val = X509_EXTENSION_get_data(ext);
+   ext_value_data = ASN1_STRING_get0_data(asn1_ext_val);
 
    if (method->it) {
       /* New style ASN1 */
 
       /* Decode ASN1 item in data */
-      keyid = (ASN1_OCTET_STRING *) ASN1_item_d2i(NULL, &ext_value_data, ext->value->length,
+      keyid = (ASN1_OCTET_STRING *) ASN1_item_d2i(NULL, &ext_value_data, ASN1_STRING_length(asn1_ext_val),
                                                   ASN1_ITEM_ptr(method->it));
    } else {
       /* Old style ASN1 */
 
       /* Decode ASN1 item in data */
-      keyid = (ASN1_OCTET_STRING *) method->d2i(NULL, &ext_value_data, ext->value->length);
+      keyid = (ASN1_OCTET_STRING *) method->d2i(NULL, &ext_value_data, ASN1_STRING_length(asn1_ext_val));
    }
 
    return keyid;
@@ -376,6 +378,7 @@ X509_KEYPAIR *crypto_keypair_new(void)
 X509_KEYPAIR *crypto_keypair_dup(X509_KEYPAIR *keypair)
 {
    X509_KEYPAIR *newpair;
+   int ret;
 
    newpair = crypto_keypair_new();
 
@@ -386,27 +389,32 @@ X509_KEYPAIR *crypto_keypair_dup(X509_KEYPAIR *keypair)
 
    /* Increment the public key ref count */
    if (keypair->pubkey) {
-      CRYPTO_add(&(keypair->pubkey->references), 1, CRYPTO_LOCK_EVP_PKEY);
+      ret = EVP_PKEY_up_ref(keypair->pubkey);
+      if (ret == 0)
+	      goto out_free_new;
       newpair->pubkey = keypair->pubkey;
    }
 
    /* Increment the private key ref count */
    if (keypair->privkey) {
-      CRYPTO_add(&(keypair->privkey->references), 1, CRYPTO_LOCK_EVP_PKEY);
+      ret = EVP_PKEY_up_ref(keypair->privkey);
+      if (ret == 0)
+	      goto out_free_new;
       newpair->privkey = keypair->privkey;
    }
 
    /* Duplicate the keyid */
    if (keypair->keyid) {
-      newpair->keyid = M_ASN1_OCTET_STRING_dup(keypair->keyid);
-      if (!newpair->keyid) {
-         /* Allocation failed */
-         crypto_keypair_free(newpair);
-         return NULL;
-      }
+      newpair->keyid = ASN1_OCTET_STRING_dup(keypair->keyid);
+      if (!newpair->keyid)
+	      goto out_free_new;
    }
 
    return newpair;
+
+out_free_new:
+   crypto_keypair_free(newpair);
+   return NULL;
 }
 
 
@@ -447,9 +455,9 @@ int crypto_keypair_load_cert(X509_KEYPAIR *keypair, const char *file)
    }
 
    /* Validate the public key type (only RSA is supported) */
-   if (EVP_PKEY_type(keypair->pubkey->type) != EVP_PKEY_RSA) {
+   if (EVP_PKEY_base_id(keypair->pubkey) != EVP_PKEY_RSA) {
        Jmsg1(NULL, M_ERROR, 0,
-             _("Unsupported key type provided: %d\n"), EVP_PKEY_type(keypair->pubkey->type));
+             _("Unsupported key type provided: %d\n"), EVP_PKEY_id(keypair->pubkey));
        goto err;
    }
 
@@ -569,7 +577,7 @@ void crypto_keypair_free(X509_KEYPAIR *keypair)
       EVP_PKEY_free(keypair->privkey);
    }
    if (keypair->keyid) {
-      M_ASN1_OCTET_STRING_free(keypair->keyid);
+      ASN1_OCTET_STRING_free(keypair->keyid);
    }
    free(keypair);
 }
@@ -722,7 +730,7 @@ crypto_error_t crypto_sign_get_digest(SIGNATURE *sig, X509_KEYPAIR *keypair,
 
    for (i = 0; i < sk_SignerInfo_num(signers); i++) {
       si = sk_SignerInfo_value(signers, i);
-      if (M_ASN1_OCTET_STRING_cmp(keypair->keyid, si->subjectKeyIdentifier) == 0) {
+      if (ASN1_OCTET_STRING_cmp(keypair->keyid, si->subjectKeyIdentifier) == 0) {
          /* Get the digest algorithm and allocate a digest context */
          Dmsg1(150, "crypto_sign_get_digest jcr=%p\n", sig->jcr);
          switch (OBJ_obj2nid(si->digestAlgorithm)) {
@@ -788,10 +796,10 @@ crypto_error_t crypto_sign_verify(SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST
    /* Find the signer */
    for (i = 0; i < sk_SignerInfo_num(signers); i++) {
       si = sk_SignerInfo_value(signers, i);
-      if (M_ASN1_OCTET_STRING_cmp(keypair->keyid, si->subjectKeyIdentifier) == 0) {
+      if (ASN1_OCTET_STRING_cmp(keypair->keyid, si->subjectKeyIdentifier) == 0) {
          /* Extract the signature data */
-         sigLen = M_ASN1_STRING_length(si->signature);
-         sigData = M_ASN1_STRING_data(si->signature);
+         sigLen = ASN1_STRING_length(si->signature);
+         sigData = ASN1_STRING_get0_data(si->signature);
 
          ok = EVP_VerifyFinal(digest->ctx, sigData, sigLen, keypair->pubkey);
          if (ok >= 1) {
@@ -855,11 +863,11 @@ int crypto_sign_add_signer(SIGNATURE *sig, DIGEST *digest, X509_KEYPAIR *keypair
    }
 
    /* Drop the string allocated by OpenSSL, and add our subjectKeyIdentifier */
-   M_ASN1_OCTET_STRING_free(si->subjectKeyIdentifier);
-   si->subjectKeyIdentifier = M_ASN1_OCTET_STRING_dup(keypair->keyid);
+   ASN1_OCTET_STRING_free(si->subjectKeyIdentifier);
+   si->subjectKeyIdentifier = ASN1_OCTET_STRING_dup(keypair->keyid);
 
    /* Set our signature algorithm. We currently require RSA */
-   assert(EVP_PKEY_type(keypair->pubkey->type) == EVP_PKEY_RSA);
+   assert(EVP_PKEY_base_id(keypair->pubkey) == EVP_PKEY_RSA);
    /* This is slightly evil. Reach into the MD structure and grab the key type */
    si->signatureAlgorithm = OBJ_nid2obj(EVP_MD_pkey_type(EVP_MD_CTX_md(digest->ctx)));
 
@@ -872,7 +880,7 @@ int crypto_sign_add_signer(SIGNATURE *sig, DIGEST *digest, X509_KEYPAIR *keypair
    }
 
    /* Add the signature to the SignerInfo structure */
-   if (!M_ASN1_OCTET_STRING_set(si->signature, buf, len)) {
+   if (!ASN1_OCTET_STRING_set(si->signature, buf, len)) {
       /* Allocation failed in OpenSSL */
       goto err;
    }
@@ -1045,7 +1053,7 @@ CRYPTO_SESSION *crypto_session_new (crypto_cipher_t cipher, alist *pubkeys)
       }
 
       /* Store it in our ASN.1 structure */
-      if (!M_ASN1_OCTET_STRING_set(cs->cryptoData->iv, iv, iv_len)) {
+      if (!ASN1_OCTET_STRING_set(cs->cryptoData->iv, iv, iv_len)) {
          /* Allocation failed in OpenSSL */
          crypto_session_free(cs);
          free(iv);
@@ -1074,11 +1082,11 @@ CRYPTO_SESSION *crypto_session_new (crypto_cipher_t cipher, alist *pubkeys)
       ASN1_INTEGER_set(ri->version, BACULA_ASN1_VERSION);
 
       /* Drop the string allocated by OpenSSL, and add our subjectKeyIdentifier */
-      M_ASN1_OCTET_STRING_free(ri->subjectKeyIdentifier);
-      ri->subjectKeyIdentifier = M_ASN1_OCTET_STRING_dup(keypair->keyid);
+      ASN1_OCTET_STRING_free(ri->subjectKeyIdentifier);
+      ri->subjectKeyIdentifier = ASN1_OCTET_STRING_dup(keypair->keyid);
 
       /* Set our key encryption algorithm. We currently require RSA */
-      assert(keypair->pubkey && EVP_PKEY_type(keypair->pubkey->type) == EVP_PKEY_RSA);
+      assert(keypair->pubkey && EVP_PKEY_base_id(keypair->pubkey) == EVP_PKEY_RSA);
       ri->keyEncryptionAlgorithm = OBJ_nid2obj(NID_rsaEncryption);
 
       /* Encrypt the session key */
@@ -1093,7 +1101,7 @@ CRYPTO_SESSION *crypto_session_new (crypto_cipher_t cipher, alist *pubkeys)
       }
 
       /* Store it in our ASN.1 structure */
-      if (!M_ASN1_OCTET_STRING_set(ri->encryptedKey, ekey, ekey_len)) {
+      if (!ASN1_OCTET_STRING_set(ri->encryptedKey, ekey, ekey_len)) {
          /* Allocation failed in OpenSSL */
          RecipientInfo_free(ri);
          crypto_session_free(cs);
@@ -1187,11 +1195,11 @@ crypto_error_t crypto_session_decode(const uint8_t *data, uint32_t length, alist
          ri = sk_RecipientInfo_value(recipients, i);
 
          /* Match against the subjectKeyIdentifier */
-         if (M_ASN1_OCTET_STRING_cmp(keypair->keyid, ri->subjectKeyIdentifier) == 0) {
+         if (ASN1_OCTET_STRING_cmp(keypair->keyid, ri->subjectKeyIdentifier) == 0) {
             /* Match found, extract symmetric encryption session data */
 
             /* RSA is required. */
-            assert(EVP_PKEY_type(keypair->privkey->type) == EVP_PKEY_RSA);
+            assert(EVP_PKEY_base_id(keypair->privkey) == EVP_PKEY_RSA);
 
             /* If we recieve a RecipientInfo structure that does not use
              * RSA, return an error */
@@ -1203,8 +1211,8 @@ crypto_error_t crypto_session_decode(const uint8_t *data, uint32_t length, alist
             /* Decrypt the session key */
             /* Allocate sufficient space for the largest possible decrypted data */
             cs->session_key = (unsigned char *)malloc(EVP_PKEY_size(keypair->privkey));
-            cs->session_key_len = EVP_PKEY_decrypt(cs->session_key, M_ASN1_STRING_data(ri->encryptedKey),
-                                  M_ASN1_STRING_length(ri->encryptedKey), keypair->privkey);
+            cs->session_key_len = EVP_PKEY_decrypt(cs->session_key, ASN1_STRING_get0_data(ri->encryptedKey),
+                                  ASN1_STRING_length(ri->encryptedKey), keypair->privkey);
 
             if (cs->session_key_len <= 0) {
                openssl_post_errors(M_ERROR, _("Failure decrypting the session key"));
diff --git a/src/lib/tls.c b/src/lib/tls.c
index c71a4ad525fe..01d3f94e8113 100644
--- a/src/lib/tls.c
+++ b/src/lib/tls.c
@@ -337,25 +337,27 @@ bool tls_postconnect_verify_host(JCR *jcr, TLS_CONNECTION *tls, const char *host
             CONF_VALUE *nval;
             void *extstr = NULL;
             const unsigned char *ext_value_data;
+            const ASN1_STRING *asn1_ext_val;
 
             /* Get x509 extension method structure */
             if (!(method = X509V3_EXT_get(ext))) {
                break;
             }
 
-            ext_value_data = ext->value->data;
+            asn1_ext_val = X509_EXTENSION_get_data(ext);
+            ext_value_data = ASN1_STRING_get0_data(asn1_ext_val);
 
             if (method->it) {
                /* New style ASN1 */
 
                /* Decode ASN1 item in data */
-               extstr = ASN1_item_d2i(NULL, &ext_value_data, ext->value->length,
+               extstr = ASN1_item_d2i(NULL, &ext_value_data, ASN1_STRING_length(asn1_ext_val),
                                       ASN1_ITEM_ptr(method->it));
             } else {
                /* Old style ASN1 */
 
                /* Decode ASN1 item in data */
-               extstr = method->d2i(NULL, &ext_value_data, ext->value->length);
+               extstr = method->d2i(NULL, &ext_value_data, ASN1_STRING_length(asn1_ext_val));
             }
 
             /* Iterate through to find the dNSName field(s) */
-- 
2.15.0

Reply via email to