From: Andre Noll Date: Tue, 27 Dec 2016 15:29:29 +0000 (+0100) Subject: Merge branch 'refs/heads/t/openssl-1.1' X-Git-Tag: v0.5.7~12 X-Git-Url: http://git.tuebingen.mpg.de/?p=paraslash.git;a=commitdiff_plain;h=9165680a9639a8412adef13b96e466efdbb9d806;hp=-c Merge branch 'refs/heads/t/openssl-1.1' In openssl-1.1 several structures have been made opaque, breaking both the stream cipher and the public key functions in crypt.c. This series deals with these issues, trying to minimize the ifdeffery. * refs/heads/t/openssl-1.1 (cooking for three months): openssl: RSA fixes for openssl-1.1. openssl: Use EVP API for AES. --- 9165680a9639a8412adef13b96e466efdbb9d806 diff --combined NEWS.md index 37d855b9,71eb6cb2..cad0169b --- a/NEWS.md +++ b/NEWS.md @@@ -1,19 -1,6 +1,20 @@@ NEWS ==== +------------------------------------------ +0.5.7 (to be announced) "semantic density" +------------------------------------------ +- Speedup of the base64 decoder. +- One of the two source browsers has been removed from the web pages. + The doxygen API reference still contains an HTML version of each + source file. +- Two race conditions in para_server have been fixed. +- ls -p is now deprecated in favor of -F or -b. See the help text of + the ls command for details. ++- The openssl code has been adjusted to work also with openssl-1.1. + +Download: [tarball](./releases/paraslash-git.tar.bz2) + --------------------------------------- 0.5.6 (2016-07-10) "cascading gradient" --------------------------------------- diff --combined configure.ac index 8d4ce59a,e502e0a6..74f3fd97 --- a/configure.ac +++ b/configure.ac @@@ -116,6 -116,10 +116,10 @@@ LIB_ARG_WITH([openssl], [-lssl -lcrypto AC_CHECK_HEADER(openssl/ssl.h, [], [HAVE_OPENSSL=no]) AC_CHECK_LIB([crypto], [RAND_bytes], [], [HAVE_OPENSSL=no]) LIB_SUBST_FLAGS(openssl) + if test $HAVE_OPENSSL = yes; then + AC_CHECK_LIB([crypto], [RSA_set0_key], + AC_DEFINE([HAVE_RSA_SET0_KEY], [1], [openssl-1.1])) + fi UNSTASH_FLAGS ######################################################################### gcrypt STASH_FLAGS @@@ -418,7 -422,6 +422,7 @@@ if test -n "$CRYPTOLIB" && test $HAVE_O close_on_fork mm crypt_common + base64 ipc dccp_send fd @@@ -481,7 -484,6 +485,7 @@@ if test -n "$CRYPTOLIB"; the client_common buffer_tree crypt_common + base64 version ggo " @@@ -525,7 -527,6 +529,7 @@@ if test -n "$CRYPTOLIB"; the stat net crypt_common + base64 sideband time grab_client diff --combined crypt.c index f227eb39,e819e8be..8116fb6e --- a/crypt.c +++ b/crypt.c @@@ -23,7 -23,6 +23,7 @@@ #include "crypt.h" #include "fd.h" #include "crypt_backend.h" +#include "base64.h" struct asymmetric_key { RSA *rsa; @@@ -134,18 -133,25 +134,25 @@@ static int read_rsa_bignums(const unsig { int ret; RSA *rsa; + BIGNUM *n, *e; const unsigned char *p = blob, *end = blob + blen; rsa = RSA_new(); if (!rsa) return -E_BIGNUM; - ret = read_bignum(p, end - p, &rsa->e); + ret = read_bignum(p, end - p, &e); if (ret < 0) goto fail; p += ret; - ret = read_bignum(p, end - p, &rsa->n); + ret = read_bignum(p, end - p, &n); if (ret < 0) goto fail; + #ifdef HAVE_RSA_SET0_KEY + RSA_set0_key(rsa, n, e, NULL); + #else + rsa->n = n; + rsa->e = e; + #endif *result = rsa; return 1; fail: @@@ -159,7 -165,7 +166,7 @@@ int get_asymmetric_key(const char *key_ struct asymmetric_key *key = NULL; void *map = NULL; unsigned char *blob = NULL; - size_t map_size, blob_size, decoded_size; + size_t map_size, encoded_size, decoded_size; int ret, ret2; char *cp; @@@ -181,11 -187,16 +188,11 @@@ goto out; } cp = map + ret; + encoded_size = map_size - ret; PARA_INFO_LOG("decoding public rsa-ssh key %s\n", key_file); - ret = -ERRNO_TO_PARA_ERROR(EOVERFLOW); - if (map_size > INT_MAX / 4) - goto out_unmap; - blob_size = 2 * map_size; - blob = para_malloc(blob_size); - ret = uudecode(cp, blob, blob_size); + ret = uudecode(cp, encoded_size, (char **)&blob, &decoded_size); if (ret < 0) goto out_unmap; - decoded_size = ret; ret = check_ssh_key_header(blob, decoded_size); if (ret < 0) goto out_unmap; @@@ -256,27 -267,18 +263,18 @@@ int pub_encrypt(struct asymmetric_key * return ret < 0? -E_ENCRYPT : ret; } - struct aes_ctr_128_context { - AES_KEY key; - unsigned char ivec[AES_CRT128_BLOCK_SIZE]; - unsigned char ecount[AES_CRT128_BLOCK_SIZE]; - unsigned int num; - }; - struct stream_cipher { bool use_aes; union { RC4_KEY rc4_key; - struct aes_ctr_128_context aes; + EVP_CIPHER_CTX *aes; } context; }; struct stream_cipher *sc_new(const unsigned char *data, int len, bool use_aes) { - int ret; struct stream_cipher *sc = para_malloc(sizeof(*sc)); - struct aes_ctr_128_context *aes; sc->use_aes = use_aes; if (!use_aes) { @@@ -284,17 -286,17 +282,17 @@@ return sc; } assert(len >= 2 * AES_CRT128_BLOCK_SIZE); - aes = &sc->context.aes; - ret = AES_set_encrypt_key(data, AES_CRT128_BLOCK_SIZE * 8 /* bits */, - &aes->key); - assert(ret == 0); - memcpy(aes->ivec, data + AES_CRT128_BLOCK_SIZE, AES_CRT128_BLOCK_SIZE); - aes->num = 0; + sc->context.aes = EVP_CIPHER_CTX_new(); + EVP_EncryptInit_ex(sc->context.aes, EVP_aes_128_ctr(), NULL, data, + data + AES_CRT128_BLOCK_SIZE); return sc; } void sc_free(struct stream_cipher *sc) { + if (!sc) + return; + EVP_CIPHER_CTX_free(sc->context.aes); free(sc); } @@@ -328,25 -330,29 +326,29 @@@ static void rc4_crypt(RC4_KEY *key, str ((char *)dst->iov_base)[len] = '\0'; } - static void aes_ctr128_crypt(struct aes_ctr_128_context *aes, struct iovec *src, + static void aes_ctr128_crypt(EVP_CIPHER_CTX *ctx, struct iovec *src, struct iovec *dst) { - size_t len = src->iov_len; + int ret, inlen = src->iov_len, outlen, tmplen; *dst = (typeof(*dst)) { /* Add one for the terminating zero byte. */ - .iov_base = para_malloc(len + 1), - .iov_len = len + .iov_base = para_malloc(inlen + 1), + .iov_len = inlen }; - AES_ctr128_encrypt(src->iov_base, dst->iov_base, len, - &aes->key, aes->ivec, aes->ecount, &aes->num); - ((char *)dst->iov_base)[len] = '\0'; + ret = EVP_EncryptUpdate(ctx, dst->iov_base, &outlen, src->iov_base, inlen); + assert(ret != 0); + ret = EVP_EncryptFinal_ex(ctx, dst->iov_base + outlen, &tmplen); + assert(ret != 0); + outlen += tmplen; + ((char *)dst->iov_base)[outlen] = '\0'; + dst->iov_len = outlen; } void sc_crypt(struct stream_cipher *sc, struct iovec *src, struct iovec *dst) { if (sc->use_aes) - return aes_ctr128_crypt(&sc->context.aes, src, dst); + return aes_ctr128_crypt(sc->context.aes, src, dst); return rc4_crypt(&sc->context.rc4_key, src, dst); }