[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Build libssh against openssl 1.1.0
[Thread Prev] | [Thread Next]
- Subject: Re: Build libssh against openssl 1.1.0
- From: Andreas Schneider <asn@xxxxxxxxxxxxxx>
- Reply-to: libssh@xxxxxxxxxx
- Date: Sat, 05 Nov 2016 17:02:13 +0100
- To: libssh@xxxxxxxxxx
- Cc: Jakub Jelen <jjelen@xxxxxxxxxx>
On Wednesday, 2 November 2016 17:58:01 CET Jakub Jelen wrote: > Andreas, > thank you for the comments. I reworked the patch (attached) to smaller > parts that finally build and passes the testsuite in master for both > OpenSSL versions (sorry for the first bad version). It also improves the > readability of some constructions according to your hints. Thank you very much. I split up one patch which didn't have your sign off. The patchset is attached. I need your ok to add your sign-off and push it. Cheers, Andreas -- Andreas Schneider GPG-ID: CC014E3D www.cryptomilk.org asn@xxxxxxxxxxxxxx
From e86d8d12722e299cec3145cfdf625f40697a93d8 Mon Sep 17 00:00:00 2001 From: Jakub Jelen <jjelen@xxxxxxxxxx> Date: Wed, 2 Nov 2016 16:20:46 +0100 Subject: [PATCH 1/6] libcrypto: Remove AES_ctr128_encrypt() This is for OpenSSL 1.1.0. Signed-off-by: Jakub Jelen <jjelen@xxxxxxxxxx> Reviewed-by: Andreas Schneider <asn@xxxxxxxxxxxxxx> --- src/libcrypto.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libcrypto.c b/src/libcrypto.c index ac95010..19065bd 100644 --- a/src/libcrypto.c +++ b/src/libcrypto.c @@ -587,7 +587,11 @@ static void aes_ctr_encrypt(struct ssh_cipher_struct *cipher, void *in, void *ou * Same for num, which is being used to store the current offset in blocksize in CTR * function. */ +# if OPENSSL_VERSION_NUMBER >= 0x10100000L + CRYPTO_ctr128_encrypt(in, out, len, &cipher->aes_key->key, cipher->aes_key->IV, tmp_buffer, &num, (block128_f)AES_encrypt); +# else AES_ctr128_encrypt(in, out, len, &cipher->aes_key->key, cipher->aes_key->IV, tmp_buffer, &num); +# endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */ } static void aes_ctr_cleanup(struct ssh_cipher_struct *cipher){ -- 2.10.1 From 79a7ac204f83439c63fcaba840eec9e5b4211989 Mon Sep 17 00:00:00 2001 From: Jakub Jelen <jjelen@xxxxxxxxxx> Date: Wed, 2 Nov 2016 16:38:09 +0100 Subject: [PATCH 2/6] libcrypto: Introduce a libcrypto compat file This is for OpenSSL 1.1.0 support. Signed-off-by: Jakub Jelen <jjelen@xxxxxxxxxx> Reviewed-by: Andreas Schneider <asn@xxxxxxxxxxxxxx> --- src/CMakeLists.txt | 1 + src/libcrypto-compat.c | 335 +++++++++++++++++++++++++++++++++++++++++++++++++ src/libcrypto-compat.h | 42 +++++++ 3 files changed, 378 insertions(+) create mode 100644 src/libcrypto-compat.c create mode 100644 src/libcrypto-compat.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ab9f184..3c22dfa 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -126,6 +126,7 @@ set(libssh_SRCS known_hosts.c legacy.c libcrypto.c + libcrypto-compat.c log.c match.c messages.c diff --git a/src/libcrypto-compat.c b/src/libcrypto-compat.c new file mode 100644 index 0000000..1f27dd5 --- /dev/null +++ b/src/libcrypto-compat.c @@ -0,0 +1,335 @@ +/* + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <openssl/opensslv.h> +#if OPENSSL_VERSION_NUMBER < 0x10100000L + +#include <string.h> +#include <openssl/engine.h> +#include "libcrypto-compat.h" + +static void *OPENSSL_zalloc(size_t num) +{ + void *ret = OPENSSL_malloc(num); + + if (ret != NULL) + memset(ret, 0, num); + return ret; +} + +int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d) +{ + /* If the fields n and e in r are NULL, the corresponding input + * parameters MUST be non-NULL for n and e. d may be + * left NULL (in case only the public key is used). + */ + if ((r->n == NULL && n == NULL) + || (r->e == NULL && e == NULL)) + return 0; + + if (n != NULL) { + BN_free(r->n); + r->n = n; + } + if (e != NULL) { + BN_free(r->e); + r->e = e; + } + if (d != NULL) { + BN_free(r->d); + r->d = d; + } + + return 1; +} + +int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q) +{ + /* If the fields p and q in r are NULL, the corresponding input + * parameters MUST be non-NULL. + */ + if ((r->p == NULL && p == NULL) + || (r->q == NULL && q == NULL)) + return 0; + + if (p != NULL) { + BN_free(r->p); + r->p = p; + } + if (q != NULL) { + BN_free(r->q); + r->q = q; + } + + return 1; +} + +int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) +{ + /* If the fields dmp1, dmq1 and iqmp in r are NULL, the corresponding input + * parameters MUST be non-NULL. + */ + if ((r->dmp1 == NULL && dmp1 == NULL) + || (r->dmq1 == NULL && dmq1 == NULL) + || (r->iqmp == NULL && iqmp == NULL)) + return 0; + + if (dmp1 != NULL) { + BN_free(r->dmp1); + r->dmp1 = dmp1; + } + if (dmq1 != NULL) { + BN_free(r->dmq1); + r->dmq1 = dmq1; + } + if (iqmp != NULL) { + BN_free(r->iqmp); + r->iqmp = iqmp; + } + + return 1; +} + +void RSA_get0_key(const RSA *r, + const BIGNUM **n, const BIGNUM **e, const BIGNUM **d) +{ + if (n != NULL) + *n = r->n; + if (e != NULL) + *e = r->e; + if (d != NULL) + *d = r->d; +} + +void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q) +{ + if (p != NULL) + *p = r->p; + if (q != NULL) + *q = r->q; +} + +void RSA_get0_crt_params(const RSA *r, + const BIGNUM **dmp1, const BIGNUM **dmq1, + const BIGNUM **iqmp) +{ + if (dmp1 != NULL) + *dmp1 = r->dmp1; + if (dmq1 != NULL) + *dmq1 = r->dmq1; + if (iqmp != NULL) + *iqmp = r->iqmp; +} + +void DSA_get0_pqg(const DSA *d, + const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) +{ + if (p != NULL) + *p = d->p; + if (q != NULL) + *q = d->q; + if (g != NULL) + *g = d->g; +} + +int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) +{ + /* If the fields p, q and g in d are NULL, the corresponding input + * parameters MUST be non-NULL. + */ + if ((d->p == NULL && p == NULL) + || (d->q == NULL && q == NULL) + || (d->g == NULL && g == NULL)) + return 0; + + if (p != NULL) { + BN_free(d->p); + d->p = p; + } + if (q != NULL) { + BN_free(d->q); + d->q = q; + } + if (g != NULL) { + BN_free(d->g); + d->g = g; + } + + return 1; +} + +void DSA_get0_key(const DSA *d, + const BIGNUM **pub_key, const BIGNUM **priv_key) +{ + if (pub_key != NULL) + *pub_key = d->pub_key; + if (priv_key != NULL) + *priv_key = d->priv_key; +} + +int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) +{ + /* If the field pub_key in d is NULL, the corresponding input + * parameters MUST be non-NULL. The priv_key field may + * be left NULL. + */ + if (d->pub_key == NULL && pub_key == NULL) + return 0; + + if (pub_key != NULL) { + BN_free(d->pub_key); + d->pub_key = pub_key; + } + if (priv_key != NULL) { + BN_free(d->priv_key); + d->priv_key = priv_key; + } + + return 1; +} + +void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) +{ + if (pr != NULL) + *pr = sig->r; + if (ps != NULL) + *ps = sig->s; +} + +int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) +{ + if (r == NULL || s == NULL) + return 0; + BN_clear_free(sig->r); + BN_clear_free(sig->s); + sig->r = r; + sig->s = s; + return 1; +} + +void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) +{ + if (pr != NULL) + *pr = sig->r; + if (ps != NULL) + *ps = sig->s; +} + +int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) +{ + if (r == NULL || s == NULL) + return 0; + BN_clear_free(sig->r); + BN_clear_free(sig->s); + sig->r = r; + sig->s = s; + return 1; +} + +EVP_MD_CTX *EVP_MD_CTX_new(void) +{ + return OPENSSL_zalloc(sizeof(EVP_MD_CTX)); +} + +static void OPENSSL_clear_free(void *str, size_t num) +{ + if (str == NULL) + return; + if (num) + OPENSSL_cleanse(str, num); + OPENSSL_free(str); +} + +/* This call frees resources associated with the context */ +int EVP_MD_CTX_reset(EVP_MD_CTX *ctx) +{ + if (ctx == NULL) + return 1; + + /* + * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because + * sometimes only copies of the context are ever finalised. + */ + if (ctx->digest && ctx->digest->cleanup + && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED)) + ctx->digest->cleanup(ctx); + if (ctx->digest && ctx->digest->ctx_size && ctx->md_data + && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) { + OPENSSL_clear_free(ctx->md_data, ctx->digest->ctx_size); + } + EVP_PKEY_CTX_free(ctx->pctx); +#ifndef OPENSSL_NO_ENGINE + ENGINE_finish(ctx->engine); +#endif + OPENSSL_cleanse(ctx, sizeof(*ctx)); + + return 1; +} + +void EVP_MD_CTX_free(EVP_MD_CTX *ctx) +{ + EVP_MD_CTX_reset(ctx); + OPENSSL_free(ctx); +} + +HMAC_CTX *HMAC_CTX_new(void) +{ + HMAC_CTX *ctx = OPENSSL_zalloc(sizeof(HMAC_CTX)); + + if (ctx != NULL) { + if (!HMAC_CTX_reset(ctx)) { + HMAC_CTX_free(ctx); + return NULL; + } + } + return ctx; +} + +static void hmac_ctx_cleanup(HMAC_CTX *ctx) +{ + EVP_MD_CTX_reset(&ctx->i_ctx); + EVP_MD_CTX_reset(&ctx->o_ctx); + EVP_MD_CTX_reset(&ctx->md_ctx); + ctx->md = NULL; + ctx->key_length = 0; + OPENSSL_cleanse(ctx->key, sizeof(ctx->key)); +} + +void HMAC_CTX_free(HMAC_CTX *ctx) +{ + if (ctx != NULL) { + hmac_ctx_cleanup(ctx); + EVP_MD_CTX_free(&ctx->i_ctx); + EVP_MD_CTX_free(&ctx->o_ctx); + EVP_MD_CTX_free(&ctx->md_ctx); + OPENSSL_free(ctx); + } +} + +int HMAC_CTX_reset(HMAC_CTX *ctx) +{ + HMAC_CTX_init(ctx); + return 1; +} + +EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) +{ + return OPENSSL_zalloc(sizeof(EVP_CIPHER_CTX)); +} + +void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) +{ + /* EVP_CIPHER_CTX_reset(ctx); alias */ + EVP_CIPHER_CTX_init(ctx); + OPENSSL_free(ctx); +} + +#else +typedef int iso_c_forbids_an_empty_source_file; +#endif /* OPENSSL_VERSION_NUMBER */ diff --git a/src/libcrypto-compat.h b/src/libcrypto-compat.h new file mode 100644 index 0000000..21542c6 --- /dev/null +++ b/src/libcrypto-compat.h @@ -0,0 +1,42 @@ +#ifndef LIBCRYPTO_COMPAT_H +#define LIBCRYPTO_COMPAT_H + +#include <openssl/opensslv.h> +#if OPENSSL_VERSION_NUMBER < 0x10100000L + +#include <openssl/rsa.h> +#include <openssl/dsa.h> +#include <openssl/ecdsa.h> +#include <openssl/dh.h> +#include <openssl/evp.h> +#include <openssl/hmac.h> + +int RSA_set0_key(RSA *r, BIGNUM *n, BIGNUM *e, BIGNUM *d); +int RSA_set0_factors(RSA *r, BIGNUM *p, BIGNUM *q); +int RSA_set0_crt_params(RSA *r, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp); +void RSA_get0_key(const RSA *r, const BIGNUM **n, const BIGNUM **e, const BIGNUM **d); +void RSA_get0_factors(const RSA *r, const BIGNUM **p, const BIGNUM **q); +void RSA_get0_crt_params(const RSA *r, const BIGNUM **dmp1, const BIGNUM **dmq1, const BIGNUM **iqmp); + +void DSA_get0_pqg(const DSA *d, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g); +int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g); +void DSA_get0_key(const DSA *d, const BIGNUM **pub_key, const BIGNUM **priv_key); +int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key); + +void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); +int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s); + +void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps); +int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s); + +int EVP_MD_CTX_reset(EVP_MD_CTX *ctx); +EVP_MD_CTX *EVP_MD_CTX_new(void); +void EVP_MD_CTX_free(EVP_MD_CTX *ctx); + +HMAC_CTX *HMAC_CTX_new(void); +int HMAC_CTX_reset(HMAC_CTX *ctx); +void HMAC_CTX_free(HMAC_CTX *ctx); + +#endif /* OPENSSL_VERSION_NUMBER */ + +#endif /* LIBCRYPTO_COMPAT_H */ -- 2.10.1 From 826b504d9327e50854fa07309c8e629dbc68997e Mon Sep 17 00:00:00 2001 From: Jakub Jelen <jjelen@xxxxxxxxxx> Date: Sat, 5 Nov 2016 16:51:05 +0100 Subject: [PATCH 3/6] SIGN-OFF libcrypto: Use newer API ofr HMAC This is for OpenSSL 1.1.0 support. --- src/libcrypto.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/libcrypto.c b/src/libcrypto.c index 19065bd..64c92ea 100644 --- a/src/libcrypto.c +++ b/src/libcrypto.c @@ -378,32 +378,33 @@ void ssh_mac_final(unsigned char *md, ssh_mac_ctx ctx) { HMACCTX hmac_init(const void *key, int len, enum ssh_hmac_e type) { HMACCTX ctx = NULL; - ctx = malloc(sizeof(*ctx)); + ctx = HMAC_CTX_new(); if (ctx == NULL) { return NULL; } #ifndef OLD_CRYPTO - HMAC_CTX_init(ctx); // openssl 0.9.7 requires it. + HMAC_CTX_reset(ctx); // openssl 0.9.7 requires it. #endif switch(type) { case SSH_HMAC_SHA1: - HMAC_Init(ctx, key, len, EVP_sha1()); + HMAC_Init_ex(ctx, key, len, EVP_sha1(), NULL); break; case SSH_HMAC_SHA256: - HMAC_Init(ctx, key, len, EVP_sha256()); + HMAC_Init_ex(ctx, key, len, EVP_sha256(), NULL); break; case SSH_HMAC_SHA384: - HMAC_Init(ctx, key, len, EVP_sha384()); + HMAC_Init_ex(ctx, key, len, EVP_sha384(), NULL); break; case SSH_HMAC_SHA512: - HMAC_Init(ctx, key, len, EVP_sha512()); + HMAC_Init_ex(ctx, key, len, EVP_sha512(), NULL); break; case SSH_HMAC_MD5: - HMAC_Init(ctx, key, len, EVP_md5()); + HMAC_Init_ex(ctx, key, len, EVP_md5(), NULL); break; default: + HMAC_CTX_free(ctx); SAFE_FREE(ctx); ctx = NULL; } @@ -419,7 +420,7 @@ void hmac_final(HMACCTX ctx, unsigned char *hashmacbuf, unsigned int *len) { HMAC_Final(ctx,hashmacbuf,len); #ifndef OLD_CRYPTO - HMAC_CTX_cleanup(ctx); + HMAC_CTX_reset(ctx); #else HMAC_cleanup(ctx); #endif -- 2.10.1 From 4abe9412b050270b16bf817023a83c9865c041b8 Mon Sep 17 00:00:00 2001 From: Jakub Jelen <jjelen@xxxxxxxxxx> Date: Sat, 5 Nov 2016 16:52:41 +0100 Subject: [PATCH 4/6] SIGN-OFF libcrypto: Use a pointer for EVP_MD_CTX This is for OpenSSL 1.1.0 support. --- src/libcrypto.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/libcrypto.c b/src/libcrypto.c index 64c92ea..622b447 100644 --- a/src/libcrypto.c +++ b/src/libcrypto.c @@ -135,18 +135,19 @@ static const EVP_MD *nid_to_evpmd(int nid) void evp(int nid, unsigned char *digest, int len, unsigned char *hash, unsigned int *hlen) { const EVP_MD *evp_md = nid_to_evpmd(nid); - EVP_MD_CTX md; + EVP_MD_CTX *md = EVP_MD_CTX_new(); - EVP_DigestInit(&md, evp_md); - EVP_DigestUpdate(&md, digest, len); - EVP_DigestFinal(&md, hash, hlen); + EVP_DigestInit(md, evp_md); + EVP_DigestUpdate(md, digest, len); + EVP_DigestFinal(md, hash, hlen); + EVP_MD_CTX_free(md); } EVPCTX evp_init(int nid) { const EVP_MD *evp_md = nid_to_evpmd(nid); - EVPCTX ctx = malloc(sizeof(EVP_MD_CTX)); + EVPCTX ctx = EVP_MD_CTX_new(); if (ctx == NULL) { return NULL; } -- 2.10.1 From d1c6127dd435935eaa43b93ba73a6e4211c71728 Mon Sep 17 00:00:00 2001 From: Jakub Jelen <jjelen@xxxxxxxxxx> Date: Sat, 5 Nov 2016 16:54:02 +0100 Subject: [PATCH 5/6] SIGN-OFF libcrypto: Use a pointer for EVP_CIPHER_CTX This has been made opaque and it needs to be a pointer. This is for OpenSSL 1.1.0 support. --- include/libssh/crypto.h | 2 +- src/libcrypto.c | 23 ++++++++++++++--------- src/wrapper.c | 11 +++++++++++ 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/include/libssh/crypto.h b/include/libssh/crypto.h index 102c8d7..4c79c8c 100644 --- a/include/libssh/crypto.h +++ b/include/libssh/crypto.h @@ -130,7 +130,7 @@ struct ssh_cipher_struct { struct ssh_3des_key_schedule *des3_key; struct ssh_aes_key_schedule *aes_key; const EVP_CIPHER *cipher; - EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX *ctx; #endif unsigned int keysize; /* bytes of key used. != keylen */ /* sets the new key for immediate use */ diff --git a/src/libcrypto.c b/src/libcrypto.c index 622b447..10956b6 100644 --- a/src/libcrypto.c +++ b/src/libcrypto.c @@ -43,6 +43,7 @@ #include <openssl/hmac.h> #include <openssl/opensslv.h> #include <openssl/rand.h> +#include "libcrypto-compat.h" #ifdef HAVE_OPENSSL_AES_H #define HAS_AES @@ -430,6 +431,10 @@ void hmac_final(HMACCTX ctx, unsigned char *hashmacbuf, unsigned int *len) { } static void evp_cipher_init(struct ssh_cipher_struct *cipher) { + if (cipher->ctx == NULL) { + cipher->ctx = EVP_CIPHER_CTX_new(); + } + switch(cipher->ciphertype){ case SSH_AES128_CBC: cipher->cipher = EVP_aes_128_cbc(); @@ -480,14 +485,14 @@ static int evp_cipher_set_encrypt_key(struct ssh_cipher_struct *cipher, int rc; evp_cipher_init(cipher); - EVP_CIPHER_CTX_init(&cipher->ctx); + EVP_CIPHER_CTX_init(cipher->ctx); - rc = EVP_EncryptInit_ex(&cipher->ctx, cipher->cipher, NULL, key, IV); + rc = EVP_EncryptInit_ex(cipher->ctx, cipher->cipher, NULL, key, IV); if (rc != 1){ SSH_LOG(SSH_LOG_WARNING, "EVP_EncryptInit_ex failed"); return SSH_ERROR; } - EVP_CIPHER_CTX_set_padding(&cipher->ctx, 0); + EVP_CIPHER_CTX_set_padding(cipher->ctx, 0); return SSH_OK; } @@ -497,14 +502,14 @@ static int evp_cipher_set_decrypt_key(struct ssh_cipher_struct *cipher, int rc; evp_cipher_init(cipher); - EVP_CIPHER_CTX_init(&cipher->ctx); + EVP_CIPHER_CTX_init(cipher->ctx); - rc = EVP_DecryptInit_ex(&cipher->ctx, cipher->cipher, NULL, key, IV); + rc = EVP_DecryptInit_ex(cipher->ctx, cipher->cipher, NULL, key, IV); if (rc != 1){ SSH_LOG(SSH_LOG_WARNING, "EVP_DecryptInit_ex failed"); return SSH_ERROR; } - EVP_CIPHER_CTX_set_padding(&cipher->ctx, 0); + EVP_CIPHER_CTX_set_padding(cipher->ctx, 0); return SSH_OK; } @@ -517,7 +522,7 @@ static void evp_cipher_encrypt(struct ssh_cipher_struct *cipher, int outlen = 0; int rc = 0; - rc = EVP_EncryptUpdate(&cipher->ctx, (unsigned char *)out, &outlen, (unsigned char *)in, len); + rc = EVP_EncryptUpdate(cipher->ctx, (unsigned char *)out, &outlen, (unsigned char *)in, len); if (rc != 1){ SSH_LOG(SSH_LOG_WARNING, "EVP_EncryptUpdate failed"); return; @@ -535,7 +540,7 @@ static void evp_cipher_decrypt(struct ssh_cipher_struct *cipher, int outlen = 0; int rc = 0; - rc = EVP_DecryptUpdate(&cipher->ctx, (unsigned char *)out, &outlen, (unsigned char *)in, len); + rc = EVP_DecryptUpdate(cipher->ctx, (unsigned char *)out, &outlen, (unsigned char *)in, len); if (rc != 1){ SSH_LOG(SSH_LOG_WARNING, "EVP_DecryptUpdate failed"); return; @@ -547,7 +552,7 @@ static void evp_cipher_decrypt(struct ssh_cipher_struct *cipher, } static void evp_cipher_cleanup(struct ssh_cipher_struct *cipher) { - EVP_CIPHER_CTX_cleanup(&cipher->ctx); + EVP_CIPHER_CTX_cleanup(cipher->ctx); } #ifndef HAVE_OPENSSL_EVP_AES_CTR diff --git a/src/wrapper.c b/src/wrapper.c index a7511f0..eaad255 100644 --- a/src/wrapper.c +++ b/src/wrapper.c @@ -100,6 +100,14 @@ static struct ssh_cipher_struct *cipher_new(int offset) { /* note the memcpy will copy the pointers : so, you shouldn't free them */ memcpy(cipher, &ssh_get_ciphertab()[offset], sizeof(*cipher)); +#ifdef HAVE_LIBCRYPTO + cipher->ctx = EVP_CIPHER_CTX_new(); + if (cipher->ctx == NULL) { + free(cipher); + return NULL; + } +#endif + return cipher; } @@ -123,6 +131,9 @@ void ssh_cipher_clear(struct ssh_cipher_struct *cipher){ if (cipher->cleanup != NULL){ cipher->cleanup(cipher); } +#ifdef HAVE_LIBCRYPTO + EVP_CIPHER_CTX_free(cipher->ctx); +#endif } static void cipher_free(struct ssh_cipher_struct *cipher) { -- 2.10.1 From 80ff20672d293bda08ab23cda94891ad59aba598 Mon Sep 17 00:00:00 2001 From: Jakub Jelen <jjelen@xxxxxxxxxx> Date: Wed, 2 Nov 2016 17:02:58 +0100 Subject: [PATCH 6/6] pki_crypto: Use getters and setters for opaque keys and signatures This is for OpenSSL 1.1.0 support. Signed-off-by: Jakub Jelen <jjelen@xxxxxxxxxx> Reviewed-by: Andreas Schneider <asn@xxxxxxxxxxxxxx> --- src/pki_crypto.c | 295 ++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 203 insertions(+), 92 deletions(-) diff --git a/src/pki_crypto.c b/src/pki_crypto.c index dabf54b..70ac685 100644 --- a/src/pki_crypto.c +++ b/src/pki_crypto.c @@ -31,6 +31,7 @@ #include <openssl/dsa.h> #include <openssl/err.h> #include <openssl/rsa.h> +#include "libcrypto-compat.h" #ifdef HAVE_OPENSSL_EC_H #include <openssl/ec.h> @@ -230,7 +231,10 @@ ssh_key pki_key_dup(const ssh_key key, int demote) } switch (key->type) { - case SSH_KEYTYPE_DSS: + case SSH_KEYTYPE_DSS: { + const BIGNUM *p = NULL, *q = NULL, *g = NULL, + *pub_key = NULL, *priv_key = NULL; + BIGNUM *np, *nq, *ng, *npub_key, *npriv_key; new->dsa = DSA_new(); if (new->dsa == NULL) { goto fail; @@ -243,36 +247,54 @@ ssh_key pki_key_dup(const ssh_key key, int demote) * pub_key = public key y = g^x * priv_key = private key x */ - new->dsa->p = BN_dup(key->dsa->p); - if (new->dsa->p == NULL) { + DSA_get0_pqg(key->dsa, &p, &q, &g); + np = BN_dup(p); + nq = BN_dup(q); + ng = BN_dup(g); + if (np == NULL || nq == NULL || ng == NULL) { + BN_free(np); + BN_free(nq); + BN_free(ng); goto fail; } - new->dsa->q = BN_dup(key->dsa->q); - if (new->dsa->q == NULL) { + rc = DSA_set0_pqg(new->dsa, np, nq, ng); + if (rc == 0) { + BN_free(np); + BN_free(nq); + BN_free(ng); goto fail; } - new->dsa->g = BN_dup(key->dsa->g); - if (new->dsa->g == NULL) { + DSA_get0_key(key->dsa, &pub_key, &priv_key); + npub_key = BN_dup(pub_key); + if (npub_key == NULL) { goto fail; } - new->dsa->pub_key = BN_dup(key->dsa->pub_key); - if (new->dsa->pub_key == NULL) { + rc = DSA_set0_key(new->dsa, npub_key, NULL); + if (rc == 0) { goto fail; } if (!demote && (key->flags & SSH_KEY_FLAG_PRIVATE)) { - new->dsa->priv_key = BN_dup(key->dsa->priv_key); - if (new->dsa->priv_key == NULL) { + npriv_key = BN_dup(priv_key); + if (npriv_key == NULL) { + goto fail; + } + + rc = DSA_set0_key(new->dsa, NULL, npriv_key); + if (rc == 0) { goto fail; } } break; + } case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: + case SSH_KEYTYPE_RSA1: { + const BIGNUM *n = NULL, *e = NULL, *d = NULL; + BIGNUM *nn, *ne, *nd; new->rsa = RSA_new(); if (new->rsa == NULL) { goto fail; @@ -288,62 +310,82 @@ ssh_key pki_key_dup(const ssh_key key, int demote) * dmq1 = d mod (q-1) * iqmp = q^-1 mod p */ - new->rsa->n = BN_dup(key->rsa->n); - if (new->rsa->n == NULL) { + RSA_get0_key(key->rsa, &n, &e, &d); + nn = BN_dup(n); + ne = BN_dup(e); + if (nn == NULL || ne == NULL) { + BN_free(nn); + BN_free(ne); goto fail; } - new->rsa->e = BN_dup(key->rsa->e); - if (new->rsa->e == NULL) { + rc = RSA_set0_key(new->rsa, nn, ne, NULL); + if (rc == 0) { + BN_free(nn); + BN_free(ne); goto fail; } if (!demote && (key->flags & SSH_KEY_FLAG_PRIVATE)) { - new->rsa->d = BN_dup(key->rsa->d); - if (new->rsa->d == NULL) { + const BIGNUM *p = NULL, *q = NULL, *dmp1 = NULL, + *dmq1 = NULL, *iqmp = NULL; + BIGNUM *np, *nq, *ndmp1, *ndmq1, *niqmp; + + nd = BN_dup(d); + if (nd == NULL) { + goto fail; + } + + rc = RSA_set0_key(new->rsa, NULL, NULL, nd); + if (rc == 0) { goto fail; } /* p, q, dmp1, dmq1 and iqmp may be NULL in private keys, but the * RSA operations are much faster when these values are available. */ - if (key->rsa->p != NULL) { - new->rsa->p = BN_dup(key->rsa->p); - if (new->rsa->p == NULL) { + RSA_get0_factors(key->rsa, &p, &q); + if (p != NULL && q != NULL) { /* need to set both of them */ + np = BN_dup(p); + nq = BN_dup(q); + if (np == NULL || nq == NULL) { + BN_free(np); + BN_free(nq); goto fail; } - } - if (key->rsa->q != NULL) { - new->rsa->q = BN_dup(key->rsa->q); - if (new->rsa->q == NULL) { + rc = RSA_set0_factors(new->rsa, np, nq); + if (rc == 0) { + BN_free(np); + BN_free(nq); goto fail; } } - if (key->rsa->dmp1 != NULL) { - new->rsa->dmp1 = BN_dup(key->rsa->dmp1); - if (new->rsa->dmp1 == NULL) { + RSA_get0_crt_params(key->rsa, &dmp1, &dmq1, &iqmp); + if (dmp1 != NULL || dmq1 != NULL || iqmp != NULL) { + ndmp1 = BN_dup(dmp1); + ndmq1 = BN_dup(dmq1); + niqmp = BN_dup(iqmp); + if (ndmp1 == NULL || ndmq1 == NULL || niqmp == NULL) { + BN_free(ndmp1); + BN_free(ndmq1); + BN_free(niqmp); goto fail; } - } - if (key->rsa->dmq1 != NULL) { - new->rsa->dmq1 = BN_dup(key->rsa->dmq1); - if (new->rsa->dmq1 == NULL) { - goto fail; - } - } - - if (key->rsa->iqmp != NULL) { - new->rsa->iqmp = BN_dup(key->rsa->iqmp); - if (new->rsa->iqmp == NULL) { + rc = RSA_set0_crt_params(new->rsa, ndmp1, ndmq1, niqmp); + if (rc == 0) { + BN_free(ndmp1); + BN_free(ndmq1); + BN_free(niqmp); goto fail; } } } break; + } case SSH_KEYTYPE_ECDSA: #ifdef HAVE_OPENSSL_ECC new->ecdsa_nid = key->ecdsa_nid; @@ -466,51 +508,64 @@ int pki_key_compare(const ssh_key k1, enum ssh_keycmp_e what) { switch (k1->type) { - case SSH_KEYTYPE_DSS: + case SSH_KEYTYPE_DSS: { + const BIGNUM *p1, *p2, *q1, *q2, *g1, *g2, + *pub_key1, *pub_key2, *priv_key1, *priv_key2; if (DSA_size(k1->dsa) != DSA_size(k2->dsa)) { return 1; } - if (bignum_cmp(k1->dsa->p, k2->dsa->p) != 0) { + DSA_get0_pqg(k1->dsa, &p1, &q1, &g1); + DSA_get0_pqg(k2->dsa, &p2, &q2, &g2); + if (bignum_cmp(p1, p2) != 0) { return 1; } - if (bignum_cmp(k1->dsa->q, k2->dsa->q) != 0) { + if (bignum_cmp(q1, q2) != 0) { return 1; } - if (bignum_cmp(k1->dsa->g, k2->dsa->g) != 0) { + if (bignum_cmp(g1, g2) != 0) { return 1; } - if (bignum_cmp(k1->dsa->pub_key, k2->dsa->pub_key) != 0) { + DSA_get0_key(k1->dsa, &pub_key1, &priv_key1); + DSA_get0_key(k2->dsa, &pub_key2, &priv_key2); + if (bignum_cmp(pub_key1, pub_key2) != 0) { return 1; } if (what == SSH_KEY_CMP_PRIVATE) { - if (bignum_cmp(k1->dsa->priv_key, k2->dsa->priv_key) != 0) { + if (bignum_cmp(priv_key1, priv_key2) != 0) { return 1; } } break; + } case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: + case SSH_KEYTYPE_RSA1: { + const BIGNUM *e1, *e2, *n1, *n2, *p1, *p2, *q1, *q2; if (RSA_size(k1->rsa) != RSA_size(k2->rsa)) { return 1; } - if (bignum_cmp(k1->rsa->e, k2->rsa->e) != 0) { + RSA_get0_key(k1->rsa, &n1, &e1, NULL); + RSA_get0_key(k2->rsa, &n2, &e2, NULL); + if (bignum_cmp(e1, e2) != 0) { return 1; } - if (bignum_cmp(k1->rsa->n, k2->rsa->n) != 0) { + if (bignum_cmp(n1, n2) != 0) { return 1; } if (what == SSH_KEY_CMP_PRIVATE) { - if (bignum_cmp(k1->rsa->p, k2->rsa->p) != 0) { + RSA_get0_factors(k1->rsa, &p1, &q1); + RSA_get0_factors(k2->rsa, &p2, &q2); + if (bignum_cmp(p1, p2) != 0) { return 1; } - if (bignum_cmp(k1->rsa->q, k2->rsa->q) != 0) { + if (bignum_cmp(q1, q2) != 0) { return 1; } } break; + } case SSH_KEYTYPE_ECDSA: #ifdef HAVE_OPENSSL_ECC { @@ -826,43 +881,65 @@ int pki_pubkey_build_dss(ssh_key key, ssh_string q, ssh_string g, ssh_string pubkey) { + int rc; + BIGNUM *bp, *bq, *bg, *bpub_key; + key->dsa = DSA_new(); if (key->dsa == NULL) { return SSH_ERROR; } - key->dsa->p = ssh_make_string_bn(p); - key->dsa->q = ssh_make_string_bn(q); - key->dsa->g = ssh_make_string_bn(g); - key->dsa->pub_key = ssh_make_string_bn(pubkey); - if (key->dsa->p == NULL || - key->dsa->q == NULL || - key->dsa->g == NULL || - key->dsa->pub_key == NULL) { - DSA_free(key->dsa); - return SSH_ERROR; + bp = ssh_make_string_bn(p); + bq = ssh_make_string_bn(q); + bg = ssh_make_string_bn(g); + bpub_key = ssh_make_string_bn(pubkey); + if (bp == NULL || bq == NULL || + bg == NULL || bpub_key == NULL) { + goto fail; + } + + rc = DSA_set0_pqg(key->dsa, bp, bq, bg); + if (rc == 0) { + goto fail; + } + + rc = DSA_set0_key(key->dsa, bpub_key, NULL); + if (rc == 0) { + goto fail; } return SSH_OK; +fail: + DSA_free(key->dsa); + return SSH_ERROR; } int pki_pubkey_build_rsa(ssh_key key, ssh_string e, ssh_string n) { + int rc; + BIGNUM *be, *bn; + key->rsa = RSA_new(); if (key->rsa == NULL) { return SSH_ERROR; } - key->rsa->e = ssh_make_string_bn(e); - key->rsa->n = ssh_make_string_bn(n); - if (key->rsa->e == NULL || - key->rsa->n == NULL) { - RSA_free(key->rsa); - return SSH_ERROR; + be = ssh_make_string_bn(e); + bn = ssh_make_string_bn(n); + if (be == NULL || bn == NULL) { + goto fail; + } + + rc = RSA_set0_key(key->rsa, bn, be, NULL); + if (rc == 0) { + goto fail; } return SSH_OK; +fail: + RSA_free(key->rsa); + return SSH_ERROR; } ssh_string pki_publickey_to_blob(const ssh_key key) @@ -905,23 +982,26 @@ ssh_string pki_publickey_to_blob(const ssh_key key) } switch (key->type) { - case SSH_KEYTYPE_DSS: - p = ssh_make_bignum_string(key->dsa->p); + case SSH_KEYTYPE_DSS: { + const BIGNUM *bp, *bq, *bg, *bpub_key; + DSA_get0_pqg(key->dsa, &bp, &bq, &bg); + p = ssh_make_bignum_string((BIGNUM *)bp); if (p == NULL) { goto fail; } - q = ssh_make_bignum_string(key->dsa->q); + q = ssh_make_bignum_string((BIGNUM *)bq); if (q == NULL) { goto fail; } - g = ssh_make_bignum_string(key->dsa->g); + g = ssh_make_bignum_string((BIGNUM *)bg); if (g == NULL) { goto fail; } - n = ssh_make_bignum_string(key->dsa->pub_key); + DSA_get0_key(key->dsa, &bpub_key, NULL); + n = ssh_make_bignum_string((BIGNUM *)bpub_key); if (n == NULL) { goto fail; } @@ -953,14 +1033,17 @@ ssh_string pki_publickey_to_blob(const ssh_key key) n = NULL; break; + } case SSH_KEYTYPE_RSA: - case SSH_KEYTYPE_RSA1: - e = ssh_make_bignum_string(key->rsa->e); + case SSH_KEYTYPE_RSA1: { + const BIGNUM *be, *bn; + RSA_get0_key(key->rsa, &bn, &be, NULL); + e = ssh_make_bignum_string((BIGNUM *)be); if (e == NULL) { goto fail; } - n = ssh_make_bignum_string(key->rsa->n); + n = ssh_make_bignum_string((BIGNUM *)bn); if (n == NULL) { goto fail; } @@ -980,6 +1063,7 @@ ssh_string pki_publickey_to_blob(const ssh_key key) n = NULL; break; + } case SSH_KEYTYPE_ECDSA: #ifdef HAVE_OPENSSL_ECC rc = ssh_buffer_reinit(buffer); @@ -1082,13 +1166,15 @@ int pki_export_pubkey_rsa1(const ssh_key key, char *e; char *n; int rsa_size = RSA_size(key->rsa); + const BIGNUM *be, *bn; - e = bignum_bn2dec(key->rsa->e); + RSA_get0_key(key->rsa, &bn, &be, NULL); + e = bignum_bn2dec(be); if (e == NULL) { return SSH_ERROR; } - n = bignum_bn2dec(key->rsa->n); + n = bignum_bn2dec(bn); if (n == NULL) { OPENSSL_free(e); return SSH_ERROR; @@ -1153,6 +1239,7 @@ static ssh_string pki_dsa_signature_to_blob(const ssh_signature sig) { char buffer[40] = { 0 }; ssh_string sig_blob = NULL; + const BIGNUM *pr, *ps; ssh_string r; int r_len, r_offset_in, r_offset_out; @@ -1160,12 +1247,13 @@ static ssh_string pki_dsa_signature_to_blob(const ssh_signature sig) ssh_string s; int s_len, s_offset_in, s_offset_out; - r = ssh_make_bignum_string(sig->dsa_sig->r); + DSA_SIG_get0(sig->dsa_sig, &pr, &ps); + r = ssh_make_bignum_string((BIGNUM *)pr); if (r == NULL) { return NULL; } - s = ssh_make_bignum_string(sig->dsa_sig->s); + s = ssh_make_bignum_string((BIGNUM *)ps); if (s == NULL) { ssh_string_free(r); return NULL; @@ -1218,13 +1306,15 @@ ssh_string pki_signature_to_blob(const ssh_signature sig) ssh_string s; ssh_buffer b; int rc; + const BIGNUM *pr, *ps; b = ssh_buffer_new(); if (b == NULL) { return NULL; } - r = ssh_make_bignum_string(sig->ecdsa_sig->r); + ECDSA_SIG_get0(sig->ecdsa_sig, &pr, &ps); + r = ssh_make_bignum_string((BIGNUM *)pr); if (r == NULL) { ssh_buffer_free(b); return NULL; @@ -1236,7 +1326,7 @@ ssh_string pki_signature_to_blob(const ssh_signature sig) return NULL; } - s = ssh_make_bignum_string(sig->ecdsa_sig->s); + s = ssh_make_bignum_string((BIGNUM *)ps); if (s == NULL) { ssh_buffer_free(b); return NULL; @@ -1345,6 +1435,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey, ssh_string s; size_t len; int rc; + BIGNUM *pr = NULL, *ps = NULL; sig = ssh_signature_new(); if (sig == NULL) { @@ -1385,9 +1476,9 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey, } ssh_string_fill(r, ssh_string_data(sig_blob), 20); - sig->dsa_sig->r = ssh_make_string_bn(r); + pr = ssh_make_string_bn(r); ssh_string_free(r); - if (sig->dsa_sig->r == NULL) { + if (pr == NULL) { ssh_signature_free(sig); return NULL; } @@ -1399,9 +1490,15 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey, } ssh_string_fill(s, (char *)ssh_string_data(sig_blob) + 20, 20); - sig->dsa_sig->s = ssh_make_string_bn(s); + ps = ssh_make_string_bn(s); ssh_string_free(s); - if (sig->dsa_sig->s == NULL) { + if (ps == NULL) { + ssh_signature_free(sig); + return NULL; + } + + rc = DSA_SIG_set0(sig->dsa_sig, pr, ps); + if (rc == 0) { ssh_signature_free(sig); return NULL; } @@ -1449,10 +1546,10 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey, ssh_print_hexa("r", ssh_string_data(r), ssh_string_len(r)); #endif - ssh_make_string_bn_inplace(r, sig->ecdsa_sig->r); + pr = ssh_make_string_bn(r); ssh_string_burn(r); ssh_string_free(r); - if (sig->ecdsa_sig->r == NULL) { + if (pr == NULL) { ssh_buffer_free(b); ssh_signature_free(sig); return NULL; @@ -1470,10 +1567,16 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey, ssh_print_hexa("s", ssh_string_data(s), ssh_string_len(s)); #endif - ssh_make_string_bn_inplace(s, sig->ecdsa_sig->s); + ps = ssh_make_string_bn(s); ssh_string_burn(s); ssh_string_free(s); - if (sig->ecdsa_sig->s == NULL) { + if (ps == NULL) { + ssh_signature_free(sig); + return NULL; + } + + rc = ECDSA_SIG_set0(sig->ecdsa_sig, pr, ps); + if (rc == 0) { ssh_signature_free(sig); return NULL; } @@ -1601,8 +1704,12 @@ ssh_signature pki_do_sign(const ssh_key privkey, } #ifdef DEBUG_CRYPTO - ssh_print_bignum("r", sig->dsa_sig->r); - ssh_print_bignum("s", sig->dsa_sig->s); + { + const BIGNUM *pr, *ps; + DSA_SIG_get0(sig->dsa_sig, &pr, &ps); + ssh_print_bignum("r", (BIGNUM *) pr); + ssh_print_bignum("s", (BIGNUM *) ps); + } #endif break; @@ -1624,8 +1731,12 @@ ssh_signature pki_do_sign(const ssh_key privkey, } # ifdef DEBUG_CRYPTO - ssh_print_bignum("r", sig->ecdsa_sig->r); - ssh_print_bignum("s", sig->ecdsa_sig->s); + { + const BIGNUM *pr, *ps; + ECDSA_SIG_get0(sig->ecdsa_sig, &pr, &ps); + ssh_print_bignum("r", (BIGNUM *) pr); + ssh_print_bignum("s", (BIGNUM *) ps); + } # endif /* DEBUG_CRYPTO */ break; -- 2.10.1
Re: Build libssh against openssl 1.1.0 | Andreas Schneider <asn@xxxxxxxxxxxxxx> |
Re: Build libssh against openssl 1.1.0 | Jakub Jelen <jjelen@xxxxxxxxxx> |
Build libssh against openssl 1.1.0 | Jakub Jelen <jjelen@xxxxxxxxxx> |
Re: Build libssh against openssl 1.1.0 | Andreas Schneider <asn@xxxxxxxxxxxxxx> |
Re: Build libssh against openssl 1.1.0 | Jakub Jelen <jjelen@xxxxxxxxxx> |