]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/lib/crypto.c
crypto: convert EVP_PKEY access and remainings bits for OpenSSL 1.1
[bacula/bacula] / bacula / src / lib / crypto.c
index 66b377ff908e0389346c67ad1cde9cb1e57300f4..0cb4f9feef60ab448adb04412b99751b037e6ed3 100644 (file)
@@ -1,37 +1,26 @@
 /*
-   Bacula® - The Network Backup Solution
-
-   Copyright (C) 2005-2007 Free Software Foundation Europe e.V.
-
-   The main author of Bacula is Kern Sibbald, with contributions from
-   many others, a complete list can be found in the file AUTHORS.
-   This program is Free Software; you can redistribute it and/or
-   modify it under the terms of version two of the GNU General Public
-   License as published by the Free Software Foundation and included
-   in the file LICENSE.
-
-   This program 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 this program; if not, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-   Bacula® is a registered trademark of John Walker.
-   The licensor of Bacula is the Free Software Foundation Europe
-   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
-   Switzerland, email:ftf@fsfeurope.org.
+   Bacula(R) - The Network Backup Solution
+
+   Copyright (C) 2000-2016 Kern Sibbald
+
+   The original author of Bacula is Kern Sibbald, with contributions
+   from many others, a complete list can be found in the file AUTHORS.
+
+   You may use this file and others of this release according to the
+   license defined in the LICENSE file, which includes the Affero General
+   Public License, v3.0 ("AGPLv3") and some additional permissions and
+   terms pursuant to its AGPLv3 Section 7.
+
+   This notice must be preserved when any source code is 
+   conveyed and/or propagated.
+
+   Bacula(R) is a registered trademark of Kern Sibbald.
 */
 /*
  * crypto.c Encryption support functions
  *
  * Author: Landon Fuller <landonf@opendarwin.org>
  *
- * Version $Id$
- *
  * This file was contributed to the Bacula project by Landon Fuller.
  *
  * Landon Fuller has been granted a perpetual, worldwide, non-exclusive,
 #include "jcr.h"
 #include <assert.h>
 
+/**
+ * For OpenSSL version 1.x, EVP_PKEY_encrypt no longer
+ *  exists.  It was not an official API.
+ */
+#ifdef HAVE_OPENSSLv1
+#define EVP_PKEY_encrypt EVP_PKEY_encrypt_old
+#define EVP_PKEY_decrypt EVP_PKEY_decrypt_old
+#endif
+
 /*
  * Bacula ASN.1 Syntax
  *
 #ifdef HAVE_CRYPTO /* Is encryption enabled? */
 #ifdef HAVE_OPENSSL /* How about OpenSSL? */
 
-/* Are we initialized? */
-static int crypto_initialized = false;
+#include "openssl-compat.h"
 
 /* ASN.1 Declarations */
 #define BACULA_ASN1_VERSION 0
@@ -197,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.
  */
@@ -225,7 +224,7 @@ IMPLEMENT_STACK_OF(RecipientInfo)
 #define sk_SignerInfo_is_sorted(st) SKM_sk_is_sorted(SignerInfo, (st))
 
 #define d2i_ASN1_SET_OF_SignerInfo(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
-        SKM_ASN1_SET_OF_d2i(SignerInfo, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+        SKM_ASN1_SET_OF_d2i(SignerInfo, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
 #define i2d_ASN1_SET_OF_SignerInfo(st, pp, i2d_func, ex_tag, ex_class, is_set) \
         SKM_ASN1_SET_OF_i2d(SignerInfo, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
 #define ASN1_seq_pack_SignerInfo(st, i2d_func, buf, len) \
@@ -255,7 +254,7 @@ IMPLEMENT_STACK_OF(RecipientInfo)
 #define sk_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(RecipientInfo, (st))
 
 #define d2i_ASN1_SET_OF_RecipientInfo(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \
-        SKM_ASN1_SET_OF_d2i(RecipientInfo, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) 
+        SKM_ASN1_SET_OF_d2i(RecipientInfo, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class))
 #define i2d_ASN1_SET_OF_RecipientInfo(st, pp, i2d_func, ex_tag, ex_class, is_set) \
         SKM_ASN1_SET_OF_i2d(RecipientInfo, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set))
 #define ASN1_seq_pack_RecipientInfo(st, i2d_func, buf, len) \
@@ -263,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 {
@@ -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 */
@@ -304,20 +304,16 @@ 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) {
    X509_EXTENSION *ext;
-   X509V3_EXT_METHOD *method;
+   const X509V3_EXT_METHOD *method;
    ASN1_OCTET_STRING *keyid;
    int i;
-#if (OPENSSL_VERSION_NUMBER >= 0x0090800FL)
+   const ASN1_STRING *asn1_ext_val;
    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);
@@ -334,26 +330,22 @@ 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 (OPENSSL_VERSION_NUMBER > 0x00907000L)
    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));
    }
 
-#else
-   keyid = (ASN1_OCTET_STRING *) method->d2i(NULL, &ext_value_data, ext->value->length);
-#endif
-
    return keyid;
 }
 
@@ -362,7 +354,7 @@ static ASN1_OCTET_STRING *openssl_cert_keyid(X509 *cert) {
  *  Returns: A pointer to a X509 KEYPAIR object on success.
  *           NULL on failure.
  */
-X509_KEYPAIR *crypto_keypair_new(void) 
+X509_KEYPAIR *crypto_keypair_new(void)
 {
    X509_KEYPAIR *keypair;
 
@@ -386,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();
 
@@ -396,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;
 }
 
 
@@ -451,15 +449,15 @@ int crypto_keypair_load_cert(X509_KEYPAIR *keypair, const char *file)
 
    /* Extract the subjectKeyIdentifier extension field */
    if ((keypair->keyid = openssl_cert_keyid(cert)) == NULL) {
-      Jmsg0(get_jcr_from_tid(), M_ERROR, 0,
+      Jmsg0(NULL, M_ERROR, 0,
          _("Provided certificate does not include the required subjectKeyIdentifier extension."));
       goto err;
    }
 
    /* Validate the public key type (only RSA is supported) */
-   if (EVP_PKEY_type(keypair->pubkey->type) != EVP_PKEY_RSA) {
-       Jmsg1(get_jcr_from_tid(), M_ERROR, 0, 
-             _("Unsupported key type provided: %d\n"), EVP_PKEY_type(keypair->pubkey->type));
+   if (EVP_PKEY_base_id(keypair->pubkey) != EVP_PKEY_RSA) {
+       Jmsg1(NULL, M_ERROR, 0,
+             _("Unsupported key type provided: %d\n"), EVP_PKEY_id(keypair->pubkey));
        goto err;
    }
 
@@ -579,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);
 }
@@ -597,10 +595,13 @@ DIGEST *crypto_digest_new(JCR *jcr, crypto_digest_t type)
    digest = (DIGEST *)malloc(sizeof(DIGEST));
    digest->type = type;
    digest->jcr = jcr;
-   Dmsg1(50, "crypto_digest_new jcr=%p\n", jcr);
+   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) {
@@ -624,7 +625,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;
    }
 
@@ -632,7 +633,7 @@ DIGEST *crypto_digest_new(JCR *jcr, crypto_digest_t type)
 
 err:
    /* This should not happen, but never say never ... */
-   Dmsg0(50, "Digest init failed.\n");
+   Dmsg0(150, "Digest init failed.\n");
    openssl_post_errors(jcr, M_ERROR, _("OpenSSL digest initialization failed"));
    crypto_digest_free(digest);
    return NULL;
@@ -645,11 +646,11 @@ err:
  */
 bool crypto_digest_update(DIGEST *digest, const uint8_t *data, uint32_t length)
 {
-   if (EVP_DigestUpdate(&digest->ctx, data, length) == 0) {
-      Dmsg0(50, "digest update failed\n");
+   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;
-   } else { 
+   } else {
       return true;
    }
 }
@@ -663,8 +664,8 @@ 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)) {
-      Dmsg0(50, "digest finalize failed\n");
+   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;
    } else {
@@ -677,7 +678,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);
 }
 
@@ -697,7 +698,7 @@ SIGNATURE *crypto_sign_new(JCR *jcr)
 
    sig->sigData = SignatureData_new();
    sig->jcr = jcr;
-   Dmsg1(50, "crypto_sign_new jcr=%p\n", jcr);
+   Dmsg1(150, "crypto_sign_new jcr=%p\n", jcr);
 
    if (!sig->sigData) {
       /* Allocation failed in OpenSSL */
@@ -718,7 +719,7 @@ SIGNATURE *crypto_sign_new(JCR *jcr)
  * Returns: CRYPTO_ERROR_NONE on success, with the newly allocated DIGEST in digest.
  *          A crypto_error_t value on failure.
  */
-crypto_error_t crypto_sign_get_digest(SIGNATURE *sig, X509_KEYPAIR *keypair, 
+crypto_error_t crypto_sign_get_digest(SIGNATURE *sig, X509_KEYPAIR *keypair,
                                       crypto_digest_t &type, DIGEST **digest)
 {
    STACK_OF(SignerInfo) *signers;
@@ -729,9 +730,9 @@ 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(50, "crypto_sign_get_digest jcr=%p\n", sig->jcr);
+         Dmsg1(150, "crypto_sign_get_digest jcr=%p\n", sig->jcr);
          switch (OBJ_obj2nid(si->digestAlgorithm)) {
          case NID_md5:
             Dmsg0(100, "sign digest algorithm is MD5\n");
@@ -788,23 +789,19 @@ 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;
 
    /* 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);
+         ok = EVP_VerifyFinal(digest->ctx, sigData, sigLen, keypair->pubkey);
          if (ok >= 1) {
             return CRYPTO_ERROR_NONE;
          } else if (ok == 0) {
@@ -866,24 +863,24 @@ 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(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;
    }
 
    /* 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;
    }
@@ -939,11 +936,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) {
@@ -1033,7 +1026,7 @@ CRYPTO_SESSION *crypto_session_new (crypto_cipher_t cipher, alist *pubkeys)
       ec = EVP_bf_cbc();
       break;
    default:
-      Jmsg0(get_jcr_from_tid(), M_ERROR, 0, _("Unsupported cipher type specified\n"));
+      Jmsg0(NULL, M_ERROR, 0, _("Unsupported cipher type specified\n"));
       crypto_session_free(cs);
       return NULL;
    }
@@ -1060,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);
@@ -1089,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 */
@@ -1108,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);
@@ -1161,11 +1154,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) {
@@ -1206,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 */
@@ -1222,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"));
@@ -1271,52 +1260,58 @@ 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
     */
    if ((ec = EVP_get_cipherbyobj(cs->cryptoData->contentEncryptionAlgorithm)) == NULL) {
-      Jmsg1(get_jcr_from_tid(), M_ERROR, 0, 
+      Jmsg1(NULL, M_ERROR, 0,
          _("Unsupported contentEncryptionAlgorithm: %d\n"), OBJ_obj2nid(cs->cryptoData->contentEncryptionAlgorithm));
       free(cipher_ctx);
       return NULL;
    }
 
    /* 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:
@@ -1332,7 +1327,7 @@ err:
  */
 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 {
@@ -1350,7 +1345,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 {
@@ -1364,83 +1359,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);
 }
 
-
-/*
- * Perform global initialization of OpenSSL
- * This function is not thread safe.
- *  Returns: 0 on success
- *           errno on failure
- */
-int init_crypto (void)
-{
-   int stat;
-
-   if ((stat = openssl_init_threads()) != 0) {
-      berrno be;
-      Jmsg1(get_jcr_from_tid(), M_ABORT, 0, 
-        _("Unable to init OpenSSL threading: ERR=%s\n"), be.bstrerror(stat));
-   }
-
-   /* Load libssl and libcrypto human-readable error strings */
-   SSL_load_error_strings();
-
-   /* Initialize OpenSSL SSL  library */
-   SSL_library_init();
-
-   /* Register OpenSSL ciphers and digests */
-   OpenSSL_add_all_algorithms();
-
-   if (!openssl_seed_prng()) {
-      Jmsg0(get_jcr_from_tid(), M_ERROR_TERM, 0, _("Failed to seed OpenSSL PRNG\n"));
-   }
-
-   crypto_initialized = true;
-
-   return stat;
-}
-
-/*
- * Perform global cleanup of OpenSSL
- * All cryptographic operations must be completed before calling this function.
- * This function is not thread safe.
- *  Returns: 0 on success
- *           errno on failure
- */
-int cleanup_crypto (void)
-{
-   /*
-    * Ensure that we've actually been initialized; Doing this here decreases the
-    * complexity of client's termination/cleanup code.
-    */
-   if (!crypto_initialized) {
-      return 0;
-   }
-
-   if (!openssl_save_prng()) {
-      Jmsg0(get_jcr_from_tid(), M_ERROR, 0, _("Failed to save OpenSSL PRNG\n"));
-   }
-
-   openssl_cleanup_threads();
-
-   /* Free libssl and libcrypto error strings */
-   ERR_free_strings();
-
-   /* Free all ciphers and digests */
-   EVP_cleanup();
-
-   /* Free memory used by PRNG */
-   RAND_cleanup();
-
-   crypto_initialized = false;
-
-   return 0;
-}
-
-
 #else /* HAVE_OPENSSL */
 # error No encryption library available
 #endif /* HAVE_OPENSSL */
@@ -1502,7 +1424,7 @@ bool crypto_digest_update(DIGEST *digest, const uint8_t *data, uint32_t length)
       if ((ret = SHA1Update(&digest->sha1, (const u_int8_t *) data, length)) == shaSuccess) {
          return true;
       } else {
-         Jmsg1(get_jcr_from_tid(), M_ERROR, 0, _("SHA1Update() returned an error: %d\n"), ret);
+         Jmsg1(NULL, M_ERROR, 0, _("SHA1Update() returned an error: %d\n"), ret);
          return false;
       }
       break;
@@ -1511,7 +1433,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) 
+bool crypto_digest_finalize(DIGEST *digest, uint8_t *dest, uint32_t *length)
 {
    switch (digest->type) {
    case CRYPTO_DIGEST_MD5:
@@ -1545,13 +1467,12 @@ void crypto_digest_free(DIGEST *digest)
    free(digest);
 }
 
-/* Dummy routines */
-int init_crypto (void) { return 0; }
-int cleanup_crypto (void) { return 0; }
-
 SIGNATURE *crypto_sign_new(JCR *jcr) { return NULL; }
 
-crypto_error_t crypto_sign_get_digest (SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST **digest) { return CRYPTO_ERROR_INTERNAL; }
+crypto_error_t crypto_sign_get_digest (SIGNATURE *sig, X509_KEYPAIR *keypair,
+                                       crypto_digest_t &type, DIGEST **digest)
+   { return CRYPTO_ERROR_INTERNAL; }
+
 crypto_error_t crypto_sign_verify (SIGNATURE *sig, X509_KEYPAIR *keypair, DIGEST *digest) { return CRYPTO_ERROR_INTERNAL; }
 
 int crypto_sign_add_signer (SIGNATURE *sig, DIGEST *digest, X509_KEYPAIR *keypair) { return false; }
@@ -1596,7 +1517,7 @@ int crypto_default_pem_callback(char *buf, int size, const void *userdata)
  * Returns the ASCII name of the digest type.
  * Returns: ASCII name of digest type.
  */
-const char *crypto_digest_name(DIGEST *digest) 
+const char *crypto_digest_name(DIGEST *digest)
 {
    switch (digest->type) {
    case CRYPTO_DIGEST_MD5: