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