82dbad89f6
for openssl-1.1.0 compatibility OBS-URL: https://build.opensuse.org/package/show/systemsmanagement/cfengine?expand=0&rev=165
1903 lines
61 KiB
Diff
1903 lines
61 KiB
Diff
From 15e035116bf2d3ccba251fc7bc39f5e2e5b7eed7 Mon Sep 17 00:00:00 2001
|
|
From: Dimitrios Apostolou <jimis@northern.tech>
|
|
Date: Wed, 25 Oct 2017 17:03:39 +0200
|
|
Subject: [PATCH 3/3] Merge pull request #2916 from jimis/openssl_1_1
|
|
|
|
CFE-2629: Openssl 1.1 compatibility
|
|
---
|
|
cf-agent/cf-agent.c | 2 +
|
|
cf-key/cf-key-functions.c | 6 +-
|
|
cf-key/cf-key-functions.h | 1 +
|
|
cf-serverd/cf-serverd-functions.c | 8 +-
|
|
cf-serverd/server_classic.c | 49 ++-
|
|
cf-serverd/server_common.c | 27 +-
|
|
cf-serverd/server_tls.c | 4 +-
|
|
configure.ac | 2 +-
|
|
libcfnet/client_code.c | 32 +-
|
|
libcfnet/client_protocol.c | 34 +-
|
|
libcfnet/connection_info.h | 2 +
|
|
libcfnet/key.h | 4 +-
|
|
libcfnet/tls_generic.c | 4 +-
|
|
libpromises/crypto.c | 58 +--
|
|
libpromises/files_hashes.c | 111 +++---
|
|
libpromises/files_hashes.h | 2 +-
|
|
libpromises/generic_agent.c | 12 +-
|
|
libpromises/locks.c | 32 +-
|
|
libutils/Makefile.am | 1 +
|
|
libutils/encode.c | 1 +
|
|
libutils/hash.c | 69 ++--
|
|
libutils/hashes.c | 22 +-
|
|
libutils/libcrypto-compat.c | 414 +++++++++++++++++++++
|
|
libutils/libcrypto-compat.h | 62 +++
|
|
libutils/string_lib.c | 2 +
|
|
.../serial/nondefault_ciphers_tlsversion.srv | 4 +-
|
|
tests/unit/Makefile.am | 12 -
|
|
tests/unit/crypto_symmetric_test.c | 8 +-
|
|
tests/unit/tls_generic_test.c | 11 +
|
|
29 files changed, 806 insertions(+), 190 deletions(-)
|
|
create mode 100644 libutils/libcrypto-compat.c
|
|
create mode 100644 libutils/libcrypto-compat.h
|
|
|
|
diff --git a/cf-agent/cf-agent.c b/cf-agent/cf-agent.c
|
|
index 9578b291b4ac..a11f6ff4daad 100644
|
|
--- a/cf-agent/cf-agent.c
|
|
+++ b/cf-agent/cf-agent.c
|
|
@@ -241,6 +241,8 @@ int main(int argc, char *argv[])
|
|
|
|
GenericAgentDiscoverContext(ctx, config);
|
|
|
|
+ /* FIXME: (CFE-2709) ALWAYS_VALIDATE will always be false here, since it can
|
|
+ * only change in KeepPromises(), five lines later on. */
|
|
Policy *policy = SelectAndLoadPolicy(config, ctx, ALWAYS_VALIDATE, true);
|
|
|
|
if (!policy)
|
|
diff --git a/cf-key/cf-key-functions.c b/cf-key/cf-key-functions.c
|
|
index 68b1657e9ed8..ee994af6ad38 100644
|
|
--- a/cf-key/cf-key-functions.c
|
|
+++ b/cf-key/cf-key-functions.c
|
|
@@ -27,6 +27,7 @@
|
|
|
|
#include <openssl/bn.h> /* BN_*, BIGNUM */
|
|
#include <openssl/rand.h> /* RAND_* */
|
|
+#include <libcrypto-compat.h>
|
|
|
|
#include <lastseen.h>
|
|
#include <dir.h>
|
|
@@ -48,6 +49,7 @@ RSA *LoadPublicKey(const char *filename)
|
|
{
|
|
FILE *fp;
|
|
RSA *key;
|
|
+ const BIGNUM *n, *e;
|
|
|
|
fp = safe_fopen(filename, "r");
|
|
if (fp == NULL)
|
|
@@ -69,7 +71,9 @@ RSA *LoadPublicKey(const char *filename)
|
|
|
|
fclose(fp);
|
|
|
|
- if (BN_num_bits(key->e) < 2 || !BN_is_odd(key->e))
|
|
+ RSA_get0_key(key, &n, &e, NULL);
|
|
+
|
|
+ if (BN_num_bits(e) < 2 || !BN_is_odd(e))
|
|
{
|
|
Log(LOG_LEVEL_ERR, "Error while reading public key '%s' - RSA Exponent is too small or not odd. (BN_num_bits: %s)",
|
|
filename, GetErrorStr());
|
|
diff --git a/cf-key/cf-key-functions.h b/cf-key/cf-key-functions.h
|
|
index 59b33a56cc6d..7080b2c624fa 100644
|
|
--- a/cf-key/cf-key-functions.h
|
|
+++ b/cf-key/cf-key-functions.h
|
|
@@ -39,6 +39,7 @@
|
|
#include <eval_context.h>
|
|
#include <crypto.h>
|
|
|
|
+
|
|
extern bool LOOKUP_HOSTS;
|
|
|
|
RSA *LoadPublicKey(const char *filename);
|
|
diff --git a/cf-serverd/cf-serverd-functions.c b/cf-serverd/cf-serverd-functions.c
|
|
index 8d10a0f5487f..346c6493f925 100644
|
|
--- a/cf-serverd/cf-serverd-functions.c
|
|
+++ b/cf-serverd/cf-serverd-functions.c
|
|
@@ -869,7 +869,13 @@ static void AcceptAndHandle(EvalContext *ctx, int sd)
|
|
int StartServer(EvalContext *ctx, Policy **policy, GenericAgentConfig *config)
|
|
{
|
|
InitSignals();
|
|
- ServerTLSInitialize();
|
|
+
|
|
+ bool tls_init_ok = ServerTLSInitialize();
|
|
+ if (!tls_init_ok)
|
|
+ {
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
int sd = SetServerListenState(ctx, QUEUESIZE, SERVER_LISTEN, &InitServer);
|
|
|
|
/* Necessary for our use of select() to work in WaitForIncoming(): */
|
|
diff --git a/cf-serverd/server_classic.c b/cf-serverd/server_classic.c
|
|
index 97bc8abb0c90..2ebec9a390c4 100644
|
|
--- a/cf-serverd/server_classic.c
|
|
+++ b/cf-serverd/server_classic.c
|
|
@@ -23,7 +23,9 @@
|
|
*/
|
|
#include <platform.h>
|
|
|
|
-#include <openssl/bn.h> /* BN_* */
|
|
+#include <openssl/bn.h> /* BN_* */
|
|
+#include <openssl/err.h> /* ERR_get_error */
|
|
+#include <libcrypto-compat.h>
|
|
|
|
#include <cf3.defs.h>
|
|
#include <item_lib.h> /* IsMatchItemIn */
|
|
@@ -36,6 +38,7 @@
|
|
#include <files_hashes.h> /* HashString */
|
|
#include <crypto.h> /* HavePublicKey */
|
|
#include <cf-serverd-enterprise-stubs.h> /* ReceiveCollectCall */
|
|
+#include <tls_generic.h>
|
|
|
|
#include "server.h" /* ServerConnectionState */
|
|
#include "server_common.h" /* ListPersistentClasses */
|
|
@@ -579,7 +582,11 @@ static int CheckStoreKey(ServerConnectionState *conn, RSA *key)
|
|
"A public key was already known from %s/%s - no trust required",
|
|
conn->hostname, conn->ipaddr);
|
|
|
|
- if ((BN_cmp(savedkey->e, key->e) == 0) && (BN_cmp(savedkey->n, key->n) == 0))
|
|
+ const BIGNUM *key_n, *key_e, *savedkey_n, *savedkey_e;
|
|
+ RSA_get0_key(key, &key_n, &key_e, NULL);
|
|
+ RSA_get0_key(savedkey, &savedkey_n, &savedkey_e, NULL);
|
|
+
|
|
+ if ((BN_cmp(savedkey_e, key_e) == 0) && (BN_cmp(savedkey_n, key_n) == 0))
|
|
{
|
|
Log(LOG_LEVEL_VERBOSE,
|
|
"The public key identity was confirmed as %s@%s",
|
|
@@ -770,8 +777,9 @@ char iscrypt, enterprise_field;
|
|
HashString(challenge, challenge_len, digest, digestType);
|
|
}
|
|
|
|
+BIGNUM *newkey_n, *newkey_e;
|
|
+
|
|
/* proposition C2 - Receive client's public key modulus */
|
|
-RSA *newkey = RSA_new();
|
|
{
|
|
|
|
int len_n = ReceiveTransaction(conn->conn_info, recvbuffer, NULL);
|
|
@@ -779,16 +787,14 @@ RSA *newkey = RSA_new();
|
|
{
|
|
Log(LOG_LEVEL_ERR, "Authentication failure: "
|
|
"error while receiving public key modulus");
|
|
- RSA_free(newkey);
|
|
return false;
|
|
}
|
|
|
|
- if ((newkey->n = BN_mpi2bn(recvbuffer, len_n, NULL)) == NULL)
|
|
+ if ((newkey_n = BN_mpi2bn(recvbuffer, len_n, NULL)) == NULL)
|
|
{
|
|
Log(LOG_LEVEL_ERR, "Authentication failure: "
|
|
"private decrypt of received public key modulus failed "
|
|
"(%s)", CryptoLastErrorString());
|
|
- RSA_free(newkey);
|
|
return false;
|
|
}
|
|
}
|
|
@@ -800,20 +806,38 @@ RSA *newkey = RSA_new();
|
|
{
|
|
Log(LOG_LEVEL_ERR, "Authentication failure: "
|
|
"error while receiving public key exponent");
|
|
- RSA_free(newkey);
|
|
return false;
|
|
}
|
|
|
|
- if ((newkey->e = BN_mpi2bn(recvbuffer, len_e, NULL)) == NULL)
|
|
+ if ((newkey_e = BN_mpi2bn(recvbuffer, len_e, NULL)) == NULL)
|
|
{
|
|
Log(LOG_LEVEL_ERR, "Authentication failure: "
|
|
"private decrypt of received public key exponent failed "
|
|
"(%s)", CryptoLastErrorString());
|
|
- RSA_free(newkey);
|
|
+ BN_free(newkey_n);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
+RSA *newkey = RSA_new();
|
|
+if (newkey == NULL)
|
|
+{
|
|
+ Log(LOG_LEVEL_ERR, "Failed to allocate RSA key: %s",
|
|
+ TLSErrorString(ERR_get_error()));
|
|
+ BN_free(newkey_n);
|
|
+ BN_free(newkey_e);
|
|
+ return false;
|
|
+}
|
|
+if (RSA_set0_key(newkey, newkey_n, newkey_e, NULL) != 1)
|
|
+{
|
|
+ Log(LOG_LEVEL_ERR, "Failed to set RSA key: %s",
|
|
+ TLSErrorString(ERR_get_error()));
|
|
+ BN_free(newkey_n);
|
|
+ BN_free(newkey_e);
|
|
+ RSA_free(newkey);
|
|
+ return false;
|
|
+}
|
|
+
|
|
/* Compute and store hash of the client's public key. */
|
|
{
|
|
Key *key = KeyNew(newkey, CF_DEFAULT_DIGEST);
|
|
@@ -897,12 +921,15 @@ RSA *newkey = RSA_new();
|
|
|
|
char bignum_buf[CF_BUFSIZE] = { 0 };
|
|
|
|
+ const BIGNUM *n, *e;
|
|
+ RSA_get0_key(PUBKEY, &n, &e, NULL);
|
|
+
|
|
/* proposition S4 - conditional */
|
|
- int len_n = BN_bn2mpi(PUBKEY->n, bignum_buf);
|
|
+ int len_n = BN_bn2mpi(n, bignum_buf);
|
|
SendTransaction(conn->conn_info, bignum_buf, len_n, CF_DONE);
|
|
|
|
/* proposition S5 - conditional */
|
|
- int len_e = BN_bn2mpi(PUBKEY->e, bignum_buf);
|
|
+ int len_e = BN_bn2mpi(e, bignum_buf);
|
|
SendTransaction(conn->conn_info, bignum_buf, len_e, CF_DONE);
|
|
}
|
|
}
|
|
diff --git a/cf-serverd/server_common.c b/cf-serverd/server_common.c
|
|
index 931689dff977..4cce4a7e9a1f 100644
|
|
--- a/cf-serverd/server_common.c
|
|
+++ b/cf-serverd/server_common.c
|
|
@@ -43,6 +43,7 @@ static const int CF_NOSIZE = -1;
|
|
#include <pipes.h>
|
|
#include <classic.h> /* SendSocketStream */
|
|
#include <net.h> /* SendTransaction,ReceiveTransaction */
|
|
+#include <openssl/err.h> /* ERR_get_error */
|
|
#include <tls_generic.h> /* TLSSend */
|
|
#include <rlist.h>
|
|
#include <cf-serverd-enterprise-stubs.h>
|
|
@@ -557,7 +558,6 @@ void CfEncryptGetFile(ServerFileGetState *args)
|
|
unsigned char iv[32] =
|
|
{ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 };
|
|
int blocksize = CF_BUFSIZE - 4 * CF_INBAND_OFFSET;
|
|
- EVP_CIPHER_CTX ctx;
|
|
char *key, enctype;
|
|
struct stat sb;
|
|
ConnectionInfo *conn_info = args->conn->conn_info;
|
|
@@ -579,9 +579,16 @@ void CfEncryptGetFile(ServerFileGetState *args)
|
|
Log(LOG_LEVEL_INFO, "REFUSE access to file: %s", filename);
|
|
RefuseAccess(args->conn, args->replyfile);
|
|
FailedTransfer(conn_info);
|
|
+ return;
|
|
}
|
|
|
|
- EVP_CIPHER_CTX_init(&ctx);
|
|
+ EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
|
+ if (ctx == NULL)
|
|
+ {
|
|
+ Log(LOG_LEVEL_ERR, "Failed to allocate cipher: %s",
|
|
+ TLSErrorString(ERR_get_error()));
|
|
+ return;
|
|
+ }
|
|
|
|
if ((fd = safe_open(filename, O_RDONLY)) == -1)
|
|
{
|
|
@@ -630,20 +637,20 @@ void CfEncryptGetFile(ServerFileGetState *args)
|
|
|
|
if (n_read > 0)
|
|
{
|
|
- EVP_EncryptInit_ex(&ctx, CfengineCipher(enctype), NULL, key, iv);
|
|
+ EVP_EncryptInit_ex(ctx, CfengineCipher(enctype), NULL, key, iv);
|
|
|
|
- if (!EVP_EncryptUpdate(&ctx, out, &cipherlen, sendbuffer, n_read))
|
|
+ if (!EVP_EncryptUpdate(ctx, out, &cipherlen, sendbuffer, n_read))
|
|
{
|
|
FailedTransfer(conn_info);
|
|
- EVP_CIPHER_CTX_cleanup(&ctx);
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
close(fd);
|
|
return;
|
|
}
|
|
|
|
- if (!EVP_EncryptFinal_ex(&ctx, out + cipherlen, &finlen))
|
|
+ if (!EVP_EncryptFinal_ex(ctx, out + cipherlen, &finlen))
|
|
{
|
|
FailedTransfer(conn_info);
|
|
- EVP_CIPHER_CTX_cleanup(&ctx);
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
close(fd);
|
|
return;
|
|
}
|
|
@@ -654,7 +661,7 @@ void CfEncryptGetFile(ServerFileGetState *args)
|
|
if (SendTransaction(conn_info, out, cipherlen + finlen, CF_DONE) == -1)
|
|
{
|
|
Log(LOG_LEVEL_VERBOSE, "Send failed in GetFile. (send: %s)", GetErrorStr());
|
|
- EVP_CIPHER_CTX_cleanup(&ctx);
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
close(fd);
|
|
return;
|
|
}
|
|
@@ -666,14 +673,14 @@ void CfEncryptGetFile(ServerFileGetState *args)
|
|
{
|
|
Log(LOG_LEVEL_VERBOSE, "Send failed in GetFile. (send: %s)", GetErrorStr());
|
|
close(fd);
|
|
- EVP_CIPHER_CTX_cleanup(&ctx);
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
- EVP_CIPHER_CTX_cleanup(&ctx);
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
close(fd);
|
|
}
|
|
|
|
diff --git a/cf-serverd/server_tls.c b/cf-serverd/server_tls.c
|
|
index 2bbc17f55f1b..0edcfc9b3a54 100644
|
|
--- a/cf-serverd/server_tls.c
|
|
+++ b/cf-serverd/server_tls.c
|
|
@@ -186,7 +186,9 @@ void ServerTLSDeInitialize()
|
|
*/
|
|
int ServerTLSPeek(ConnectionInfo *conn_info)
|
|
{
|
|
- assert(SSLSERVERCONTEXT != NULL && PRIVKEY != NULL && PUBKEY != NULL);
|
|
+ assert(SSLSERVERCONTEXT != NULL);
|
|
+ assert(PRIVKEY != NULL);
|
|
+ assert(PUBKEY != NULL);
|
|
|
|
assert(ConnectionInfoProtocolVersion(conn_info) == CF_PROTOCOL_UNDEFINED);
|
|
|
|
diff --git a/configure.ac b/configure.ac
|
|
index 93323facd299..2eab4527e85c 100644
|
|
--- a/configure.ac
|
|
+++ b/configure.ac
|
|
@@ -435,7 +435,7 @@ fi
|
|
|
|
CF3_WITH_LIBRARY(openssl, [
|
|
AC_CHECK_LIB(crypto, RSA_generate_key_ex, [], [])
|
|
- AC_CHECK_LIB(ssl, SSL_library_init, [], [])
|
|
+ AC_CHECK_LIB(ssl, SSL_free, [], [])
|
|
AC_CHECK_DECLS([SSL_CTX_clear_options], [], [], [[#include <openssl/ssl.h>]])
|
|
AC_CHECK_HEADERS([openssl/opensslv.h], [], [AC_MSG_ERROR(Cannot find OpenSSL)])
|
|
|
|
diff --git a/libcfnet/client_code.c b/libcfnet/client_code.c
|
|
index f6348a16e021..0c1314d720f9 100644
|
|
--- a/libcfnet/client_code.c
|
|
+++ b/libcfnet/client_code.c
|
|
@@ -28,6 +28,8 @@
|
|
#include <connection_info.h>
|
|
#include <classic.h> /* RecvSocketStream */
|
|
#include <net.h> /* SendTransaction,ReceiveTransaction */
|
|
+#include <openssl/err.h> /* ERR_get_error */
|
|
+#include <libcrypto-compat.h>
|
|
#include <tls_client.h> /* TLSTry */
|
|
#include <tls_generic.h> /* TLSVerifyPeer */
|
|
#include <dir.h>
|
|
@@ -42,7 +44,6 @@
|
|
#include <string_lib.h> /* MemSpan,MemSpanInverse */
|
|
#include <misc_lib.h> /* ProgrammingError */
|
|
#include <printsize.h> /* PRINTSIZE */
|
|
-
|
|
#include <lastseen.h> /* LastSaw */
|
|
|
|
|
|
@@ -514,7 +515,6 @@ int EncryptCopyRegularFileNet(const char *source, const char *dest, off_t size,
|
|
char *buf, in[CF_BUFSIZE], out[CF_BUFSIZE], workbuf[CF_BUFSIZE], cfchangedstr[265];
|
|
unsigned char iv[32] =
|
|
{ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 };
|
|
- EVP_CIPHER_CTX crypto_ctx;
|
|
|
|
snprintf(cfchangedstr, 255, "%s%s", CF_CHANGEDSTR1, CF_CHANGEDSTR2);
|
|
|
|
@@ -543,7 +543,6 @@ int EncryptCopyRegularFileNet(const char *source, const char *dest, off_t size,
|
|
}
|
|
|
|
workbuf[0] = '\0';
|
|
- EVP_CIPHER_CTX_init(&crypto_ctx);
|
|
|
|
snprintf(in, CF_BUFSIZE - CF_PROTO_OFFSET, "GET dummykey %s", source);
|
|
cipherlen = EncryptString(out, sizeof(out), in, strlen(in) + 1, conn->encryption_type, conn->session_key);
|
|
@@ -568,6 +567,15 @@ int EncryptCopyRegularFileNet(const char *source, const char *dest, off_t size,
|
|
return false;
|
|
}
|
|
|
|
+ EVP_CIPHER_CTX *crypto_ctx = EVP_CIPHER_CTX_new();
|
|
+ if (crypto_ctx == NULL)
|
|
+ {
|
|
+ Log(LOG_LEVEL_ERR, "Failed to allocate cipher: %s",
|
|
+ TLSErrorString(ERR_get_error()));
|
|
+ close(dd);
|
|
+ return false;
|
|
+ }
|
|
+
|
|
buf = xmalloc(CF_BUFSIZE + sizeof(int));
|
|
|
|
bool last_write_made_hole = false;
|
|
@@ -577,7 +585,9 @@ int EncryptCopyRegularFileNet(const char *source, const char *dest, off_t size,
|
|
{
|
|
if ((cipherlen = ReceiveTransaction(conn->conn_info, buf, &more)) == -1)
|
|
{
|
|
+ close(dd);
|
|
free(buf);
|
|
+ EVP_CIPHER_CTX_free(crypto_ctx);
|
|
return false;
|
|
}
|
|
|
|
@@ -591,6 +601,7 @@ int EncryptCopyRegularFileNet(const char *source, const char *dest, off_t size,
|
|
Log(LOG_LEVEL_INFO, "Network access to '%s:%s' denied", conn->this_server, source);
|
|
close(dd);
|
|
free(buf);
|
|
+ EVP_CIPHER_CTX_free(crypto_ctx);
|
|
return false;
|
|
}
|
|
|
|
@@ -599,22 +610,25 @@ int EncryptCopyRegularFileNet(const char *source, const char *dest, off_t size,
|
|
Log(LOG_LEVEL_INFO, "Source '%s:%s' changed while copying", conn->this_server, source);
|
|
close(dd);
|
|
free(buf);
|
|
+ EVP_CIPHER_CTX_free(crypto_ctx);
|
|
return false;
|
|
}
|
|
|
|
- EVP_DecryptInit_ex(&crypto_ctx, CfengineCipher(CfEnterpriseOptions()), NULL, conn->session_key, iv);
|
|
+ EVP_DecryptInit_ex(crypto_ctx, CfengineCipher(CfEnterpriseOptions()), NULL, conn->session_key, iv);
|
|
|
|
- if (!EVP_DecryptUpdate(&crypto_ctx, workbuf, &plainlen, buf, cipherlen))
|
|
+ if (!EVP_DecryptUpdate(crypto_ctx, workbuf, &plainlen, buf, cipherlen))
|
|
{
|
|
close(dd);
|
|
free(buf);
|
|
+ EVP_CIPHER_CTX_free(crypto_ctx);
|
|
return false;
|
|
}
|
|
|
|
- if (!EVP_DecryptFinal_ex(&crypto_ctx, workbuf + plainlen, &finlen))
|
|
+ if (!EVP_DecryptFinal_ex(crypto_ctx, workbuf + plainlen, &finlen))
|
|
{
|
|
close(dd);
|
|
free(buf);
|
|
+ EVP_CIPHER_CTX_free(crypto_ctx);
|
|
return false;
|
|
}
|
|
|
|
@@ -631,7 +645,7 @@ int EncryptCopyRegularFileNet(const char *source, const char *dest, off_t size,
|
|
unlink(dest);
|
|
close(dd);
|
|
conn->error = true;
|
|
- EVP_CIPHER_CTX_cleanup(&crypto_ctx);
|
|
+ EVP_CIPHER_CTX_free(crypto_ctx);
|
|
return false;
|
|
}
|
|
|
|
@@ -646,12 +660,12 @@ int EncryptCopyRegularFileNet(const char *source, const char *dest, off_t size,
|
|
{
|
|
unlink(dest);
|
|
free(buf);
|
|
- EVP_CIPHER_CTX_cleanup(&crypto_ctx);
|
|
+ EVP_CIPHER_CTX_free(crypto_ctx);
|
|
return false;
|
|
}
|
|
|
|
free(buf);
|
|
- EVP_CIPHER_CTX_cleanup(&crypto_ctx);
|
|
+ EVP_CIPHER_CTX_free(crypto_ctx);
|
|
return true;
|
|
}
|
|
|
|
diff --git a/libcfnet/client_protocol.c b/libcfnet/client_protocol.c
|
|
index ca2ddb4f94b1..db5909999ebe 100644
|
|
--- a/libcfnet/client_protocol.c
|
|
+++ b/libcfnet/client_protocol.c
|
|
@@ -24,7 +24,9 @@
|
|
|
|
#include <client_protocol.h>
|
|
|
|
-#include <openssl/bn.h> /* BN_* */
|
|
+#include <openssl/bn.h> /* BN_* */
|
|
+#include <openssl/err.h> /* ERR_get_error */
|
|
+#include <libcrypto-compat.h>
|
|
|
|
#include <communication.h>
|
|
#include <net.h>
|
|
@@ -43,6 +45,7 @@ extern char VFQNAME[];
|
|
#include <known_dirs.h>
|
|
#include <hash.h>
|
|
#include <connection_info.h>
|
|
+#include <tls_generic.h> /* TLSErrorString */
|
|
|
|
|
|
/*********************************************************************/
|
|
@@ -196,7 +199,10 @@ static bool SetSessionKey(AgentConnection *conn)
|
|
return false;
|
|
}
|
|
|
|
- conn->session_key = (unsigned char *) bp->d;
|
|
+ conn->session_key = xmalloc(BN_num_bytes(bp));
|
|
+ BN_bn2bin(bp, conn->session_key);
|
|
+
|
|
+ BN_clear_free(bp);
|
|
return true;
|
|
}
|
|
|
|
@@ -293,13 +299,16 @@ int AuthenticateAgent(AgentConnection *conn, bool trust_key)
|
|
/*Send the public key - we don't know if server has it */
|
|
/* proposition C2 */
|
|
|
|
+ const BIGNUM *pubkey_n, *pubkey_e;
|
|
+ RSA_get0_key(PUBKEY, &pubkey_n, &pubkey_e, NULL);
|
|
+
|
|
memset(sendbuffer, 0, CF_EXPANDSIZE);
|
|
- len = BN_bn2mpi(PUBKEY->n, sendbuffer);
|
|
+ len = BN_bn2mpi(pubkey_n, sendbuffer);
|
|
SendTransaction(conn->conn_info, sendbuffer, len, CF_DONE); /* No need to encrypt the public key ... */
|
|
|
|
/* proposition C3 */
|
|
memset(sendbuffer, 0, CF_EXPANDSIZE);
|
|
- len = BN_bn2mpi(PUBKEY->e, sendbuffer);
|
|
+ len = BN_bn2mpi(pubkey_e, sendbuffer);
|
|
SendTransaction(conn->conn_info, sendbuffer, len, CF_DONE);
|
|
|
|
/* check reply about public key - server can break conn_info here */
|
|
@@ -432,7 +441,8 @@ int AuthenticateAgent(AgentConnection *conn, bool trust_key)
|
|
return false;
|
|
}
|
|
|
|
- if ((newkey->n = BN_mpi2bn(in, len, NULL)) == NULL)
|
|
+ BIGNUM *newkey_n, *newkey_e;
|
|
+ if ((newkey_n = BN_mpi2bn(in, len, NULL)) == NULL)
|
|
{
|
|
Log(LOG_LEVEL_ERR,
|
|
"Private key decrypt failed. (BN_mpi2bn: %s)",
|
|
@@ -447,15 +457,27 @@ int AuthenticateAgent(AgentConnection *conn, bool trust_key)
|
|
{
|
|
Log(LOG_LEVEL_INFO, "Protocol error in RSA authentation from IP '%s'",
|
|
conn->this_server);
|
|
+ BN_clear_free(newkey_n);
|
|
RSA_free(newkey);
|
|
return false;
|
|
}
|
|
|
|
- if ((newkey->e = BN_mpi2bn(in, len, NULL)) == NULL)
|
|
+ if ((newkey_e = BN_mpi2bn(in, len, NULL)) == NULL)
|
|
{
|
|
Log(LOG_LEVEL_ERR,
|
|
"Public key decrypt failed. (BN_mpi2bn: %s)",
|
|
CryptoLastErrorString());
|
|
+ BN_clear_free(newkey_n);
|
|
+ RSA_free(newkey);
|
|
+ return false;
|
|
+ }
|
|
+
|
|
+ if (RSA_set0_key(newkey, newkey_n, newkey_e, NULL) != 1)
|
|
+ {
|
|
+ Log(LOG_LEVEL_ERR, "Failed to set RSA key: %s",
|
|
+ TLSErrorString(ERR_get_error()));
|
|
+ BN_clear_free(newkey_e);
|
|
+ BN_clear_free(newkey_n);
|
|
RSA_free(newkey);
|
|
return false;
|
|
}
|
|
diff --git a/libcfnet/connection_info.h b/libcfnet/connection_info.h
|
|
index 4d1dfff2d73a..d2eaf46a95d0 100644
|
|
--- a/libcfnet/connection_info.h
|
|
+++ b/libcfnet/connection_info.h
|
|
@@ -27,7 +27,9 @@
|
|
|
|
|
|
#include <platform.h>
|
|
+
|
|
#include <openssl/ssl.h>
|
|
+
|
|
#include <key.h>
|
|
|
|
|
|
diff --git a/libcfnet/key.h b/libcfnet/key.h
|
|
index 5ddab0e09a9d..efebce763a7e 100644
|
|
--- a/libcfnet/key.h
|
|
+++ b/libcfnet/key.h
|
|
@@ -25,9 +25,11 @@
|
|
#ifndef KEY_H
|
|
#define KEY_H
|
|
|
|
-#include <hash.h>
|
|
#include <openssl/rsa.h>
|
|
|
|
+#include <hash.h>
|
|
+
|
|
+
|
|
/**
|
|
@brief Structure to simplify the key management.
|
|
|
|
diff --git a/libcfnet/tls_generic.c b/libcfnet/tls_generic.c
|
|
index db74be34221d..0e255a4441d0 100644
|
|
--- a/libcfnet/tls_generic.c
|
|
+++ b/libcfnet/tls_generic.c
|
|
@@ -88,7 +88,7 @@ static int CompareCertToRSA(X509 *cert, RSA *rsa_key)
|
|
TLSErrorString(ERR_get_error()));
|
|
goto ret1;
|
|
}
|
|
- if (EVP_PKEY_type(cert_pkey->type) != EVP_PKEY_RSA)
|
|
+ if (EVP_PKEY_base_id(cert_pkey) != EVP_PKEY_RSA)
|
|
{
|
|
Log(LOG_LEVEL_ERR,
|
|
"Received key of unknown type, only RSA currently supported!");
|
|
@@ -300,7 +300,7 @@ int TLSVerifyPeer(ConnectionInfo *conn_info, const char *remoteip, const char *u
|
|
retval = -1;
|
|
goto ret2;
|
|
}
|
|
- if (EVP_PKEY_type(received_pubkey->type) != EVP_PKEY_RSA)
|
|
+ if (EVP_PKEY_base_id(received_pubkey) != EVP_PKEY_RSA)
|
|
{
|
|
Log(LOG_LEVEL_ERR,
|
|
"Received key of unknown type, only RSA currently supported!");
|
|
diff --git a/libpromises/crypto.c b/libpromises/crypto.c
|
|
index 36fbb9c903c2..56138f7fbd2a 100644
|
|
--- a/libpromises/crypto.c
|
|
+++ b/libpromises/crypto.c
|
|
@@ -27,6 +27,7 @@
|
|
#include <openssl/err.h> /* ERR_* */
|
|
#include <openssl/rand.h> /* RAND_* */
|
|
#include <openssl/bn.h> /* BN_* */
|
|
+#include <libcrypto-compat.h>
|
|
|
|
#include <cf3.defs.h>
|
|
#include <lastseen.h>
|
|
@@ -220,11 +221,15 @@ bool LoadSecretKeys(void)
|
|
fclose(fp);
|
|
}
|
|
|
|
- if (PUBKEY != NULL
|
|
- && ((BN_num_bits(PUBKEY->e) < 2) || (!BN_is_odd(PUBKEY->e))))
|
|
+ if (PUBKEY != NULL)
|
|
{
|
|
- Log(LOG_LEVEL_ERR, "The public key RSA exponent is too small or not odd");
|
|
- return false;
|
|
+ const BIGNUM *n, *e;
|
|
+ RSA_get0_key(PUBKEY, &n, &e, NULL);
|
|
+ if ((BN_num_bits(e) < 2) || (!BN_is_odd(e)))
|
|
+ {
|
|
+ Log(LOG_LEVEL_ERR, "The public key RSA exponent is too small or not odd");
|
|
+ return false;
|
|
+ }
|
|
}
|
|
|
|
return true;
|
|
@@ -366,12 +371,16 @@ RSA *HavePublicKey(const char *username, const char *ipaddress, const char *dige
|
|
|
|
fclose(fp);
|
|
|
|
- if ((BN_num_bits(newkey->e) < 2) || (!BN_is_odd(newkey->e)))
|
|
{
|
|
- Log(LOG_LEVEL_ERR, "RSA Exponent too small or not odd for key: %s",
|
|
- newname);
|
|
- RSA_free(newkey);
|
|
- return NULL;
|
|
+ const BIGNUM *n, *e;
|
|
+ RSA_get0_key(newkey, &n, &e, NULL);
|
|
+ if ((BN_num_bits(e) < 2) || (!BN_is_odd(e)))
|
|
+ {
|
|
+ Log(LOG_LEVEL_ERR, "RSA Exponent too small or not odd for key: %s",
|
|
+ newname);
|
|
+ RSA_free(newkey);
|
|
+ return NULL;
|
|
+ }
|
|
}
|
|
|
|
return newkey;
|
|
@@ -438,7 +447,6 @@ int EncryptString(char *out, size_t out_size, const char *in, int plainlen,
|
|
int cipherlen = 0, tmplen;
|
|
unsigned char iv[32] =
|
|
{ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 };
|
|
- EVP_CIPHER_CTX ctx;
|
|
|
|
if (key == NULL)
|
|
ProgrammingError("EncryptString: session key == NULL");
|
|
@@ -451,18 +459,18 @@ int EncryptString(char *out, size_t out_size, const char *in, int plainlen,
|
|
max_ciphertext_size, out_size);
|
|
}
|
|
|
|
- EVP_CIPHER_CTX_init(&ctx);
|
|
- EVP_EncryptInit_ex(&ctx, CfengineCipher(type), NULL, key, iv);
|
|
+ EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
|
+ EVP_EncryptInit_ex(ctx, CfengineCipher(type), NULL, key, iv);
|
|
|
|
- if (!EVP_EncryptUpdate(&ctx, out, &cipherlen, in, plainlen))
|
|
+ if (!EVP_EncryptUpdate(ctx, out, &cipherlen, in, plainlen))
|
|
{
|
|
- EVP_CIPHER_CTX_cleanup(&ctx);
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
return -1;
|
|
}
|
|
|
|
- if (!EVP_EncryptFinal_ex(&ctx, out + cipherlen, &tmplen))
|
|
+ if (!EVP_EncryptFinal_ex(ctx, out + cipherlen, &tmplen))
|
|
{
|
|
- EVP_CIPHER_CTX_cleanup(&ctx);
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
return -1;
|
|
}
|
|
|
|
@@ -474,7 +482,7 @@ int EncryptString(char *out, size_t out_size, const char *in, int plainlen,
|
|
cipherlen, max_ciphertext_size);
|
|
}
|
|
|
|
- EVP_CIPHER_CTX_cleanup(&ctx);
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
return cipherlen;
|
|
}
|
|
|
|
@@ -521,7 +529,6 @@ int DecryptString(char *out, size_t out_size, const char *in, int cipherlen,
|
|
int plainlen = 0, tmplen;
|
|
unsigned char iv[32] =
|
|
{ 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 };
|
|
- EVP_CIPHER_CTX ctx;
|
|
|
|
if (key == NULL)
|
|
ProgrammingError("DecryptString: session key == NULL");
|
|
@@ -534,22 +541,22 @@ int DecryptString(char *out, size_t out_size, const char *in, int cipherlen,
|
|
max_plaintext_size, out_size);
|
|
}
|
|
|
|
- EVP_CIPHER_CTX_init(&ctx);
|
|
- EVP_DecryptInit_ex(&ctx, CfengineCipher(type), NULL, key, iv);
|
|
+ EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
|
+ EVP_DecryptInit_ex(ctx, CfengineCipher(type), NULL, key, iv);
|
|
|
|
- if (!EVP_DecryptUpdate(&ctx, out, &plainlen, in, cipherlen))
|
|
+ if (!EVP_DecryptUpdate(ctx, out, &plainlen, in, cipherlen))
|
|
{
|
|
Log(LOG_LEVEL_ERR, "Failed to decrypt string");
|
|
- EVP_CIPHER_CTX_cleanup(&ctx);
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
return -1;
|
|
}
|
|
|
|
- if (!EVP_DecryptFinal_ex(&ctx, out + plainlen, &tmplen))
|
|
+ if (!EVP_DecryptFinal_ex(ctx, out + plainlen, &tmplen))
|
|
{
|
|
unsigned long err = ERR_get_error();
|
|
|
|
Log(LOG_LEVEL_ERR, "Failed to decrypt at final of cipher length %d. (EVP_DecryptFinal_ex: %s)", cipherlen, ERR_error_string(err, NULL));
|
|
- EVP_CIPHER_CTX_cleanup(&ctx);
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
return -1;
|
|
}
|
|
|
|
@@ -561,8 +568,7 @@ int DecryptString(char *out, size_t out_size, const char *in, int cipherlen,
|
|
plainlen, max_plaintext_size);
|
|
}
|
|
|
|
- EVP_CIPHER_CTX_cleanup(&ctx);
|
|
-
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
return plainlen;
|
|
}
|
|
|
|
diff --git a/libpromises/files_hashes.c b/libpromises/files_hashes.c
|
|
index 8663e2d06081..ce9d54ea129d 100644
|
|
--- a/libpromises/files_hashes.c
|
|
+++ b/libpromises/files_hashes.c
|
|
@@ -24,8 +24,10 @@
|
|
|
|
#include <files_hashes.h>
|
|
|
|
+#include <openssl/err.h> /* ERR_* */
|
|
#include <openssl/bn.h> /* BN_* */
|
|
#include <openssl/evp.h> /* EVP_* */
|
|
+#include <libcrypto-compat.h>
|
|
|
|
#include <dbm_api.h>
|
|
#include <files_interfaces.h>
|
|
@@ -40,7 +42,6 @@
|
|
void HashFile(const char *filename, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type)
|
|
{
|
|
FILE *file;
|
|
- EVP_MD_CTX context;
|
|
int len, md_len;
|
|
unsigned char buffer[1024];
|
|
const EVP_MD *md = NULL;
|
|
@@ -48,30 +49,37 @@ void HashFile(const char *filename, unsigned char digest[EVP_MAX_MD_SIZE + 1], H
|
|
if ((file = safe_fopen(filename, "rb")) == NULL)
|
|
{
|
|
Log(LOG_LEVEL_INFO, "Cannot open file for hashing '%s'. (fopen: %s)", filename, GetErrorStr());
|
|
+ return;
|
|
}
|
|
- else
|
|
- {
|
|
- md = EVP_get_digestbyname(HashNameFromId(type));
|
|
|
|
- EVP_DigestInit(&context, md);
|
|
+ md = EVP_get_digestbyname(HashNameFromId(type));
|
|
|
|
+ EVP_MD_CTX *context = EVP_MD_CTX_new();
|
|
+ if (context == NULL)
|
|
+ {
|
|
+ Log(LOG_LEVEL_ERR, "Failed to allocate openssl hashing context");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (EVP_DigestInit(context, md) == 1)
|
|
+ {
|
|
while ((len = fread(buffer, 1, 1024, file)))
|
|
{
|
|
- EVP_DigestUpdate(&context, buffer, len);
|
|
+ EVP_DigestUpdate(context, buffer, len);
|
|
}
|
|
|
|
- EVP_DigestFinal(&context, digest, &md_len);
|
|
-
|
|
- /* Digest length stored in md_len */
|
|
- fclose(file);
|
|
+ EVP_DigestFinal(context, digest, &md_len);
|
|
}
|
|
+
|
|
+ /* Digest length stored in md_len */
|
|
+ fclose(file);
|
|
+ EVP_MD_CTX_free(context);
|
|
}
|
|
|
|
/*******************************************************************/
|
|
|
|
void HashString(const char *buffer, int len, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type)
|
|
{
|
|
- EVP_MD_CTX context;
|
|
const EVP_MD *md = NULL;
|
|
int md_len;
|
|
|
|
@@ -89,10 +97,18 @@ void HashString(const char *buffer, int len, unsigned char digest[EVP_MAX_MD_SIZ
|
|
{
|
|
Log(LOG_LEVEL_INFO, "Digest type %s not supported by OpenSSL library", HashNameFromId(type));
|
|
}
|
|
- else if (EVP_DigestInit(&context, md))
|
|
+
|
|
+ EVP_MD_CTX *context = EVP_MD_CTX_new();
|
|
+ if (context == NULL)
|
|
+ {
|
|
+ Log(LOG_LEVEL_ERR, "Failed to allocate openssl hashing context");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ if (EVP_DigestInit(context, md) == 1)
|
|
{
|
|
- EVP_DigestUpdate(&context, (unsigned char *) buffer, (size_t) len);
|
|
- EVP_DigestFinal(&context, digest, &md_len);
|
|
+ EVP_DigestUpdate(context, buffer, len);
|
|
+ EVP_DigestFinal(context, digest, &md_len);
|
|
}
|
|
else
|
|
{
|
|
@@ -100,63 +116,60 @@ void HashString(const char *buffer, int len, unsigned char digest[EVP_MAX_MD_SIZ
|
|
// TODO: handle this someway
|
|
}
|
|
|
|
+ EVP_MD_CTX_free(context);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*******************************************************************/
|
|
|
|
-void HashPubKey(RSA *key, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type)
|
|
+void HashPubKey(const RSA *key, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type)
|
|
{
|
|
- EVP_MD_CTX context;
|
|
- const EVP_MD *md = NULL;
|
|
- int md_len, i, buf_len, actlen;
|
|
- unsigned char *buffer;
|
|
-
|
|
- if (key->n)
|
|
+ if (type == HASH_METHOD_CRYPT)
|
|
{
|
|
- buf_len = (size_t) BN_num_bytes(key->n);
|
|
+ Log(LOG_LEVEL_ERR, "The crypt support is not presently implemented, please use sha256 instead");
|
|
+ return;
|
|
}
|
|
- else
|
|
+
|
|
+ const EVP_MD *md = EVP_get_digestbyname(HashNameFromId(type));
|
|
+ if (md == NULL)
|
|
{
|
|
- buf_len = 0;
|
|
+ Log(LOG_LEVEL_INFO, "Digest type %s not supported by OpenSSL library", HashNameFromId(type));
|
|
}
|
|
|
|
- if (key->e)
|
|
+ EVP_MD_CTX *context = EVP_MD_CTX_new();
|
|
+ if (context == NULL)
|
|
{
|
|
- if (buf_len < (i = (size_t) BN_num_bytes(key->e)))
|
|
- {
|
|
- buf_len = i;
|
|
- }
|
|
+ Log(LOG_LEVEL_ERR, "Failed to allocate openssl hashing context");
|
|
+ return;
|
|
}
|
|
|
|
- buffer = xmalloc(buf_len + 10);
|
|
+ const BIGNUM *n, *e;
|
|
+ RSA_get0_key(key, &n, &e, NULL);
|
|
|
|
- switch (type)
|
|
- {
|
|
- case HASH_METHOD_CRYPT:
|
|
- Log(LOG_LEVEL_ERR, "The crypt support is not presently implemented, please use sha256 instead");
|
|
- break;
|
|
+ size_t n_len = (n == NULL) ? 0 : (size_t) BN_num_bytes(n);
|
|
+ size_t e_len = (e == NULL) ? 0 : (size_t) BN_num_bytes(e);
|
|
+ size_t buf_len = MAX(n_len, e_len);
|
|
|
|
- default:
|
|
- md = EVP_get_digestbyname(HashNameFromId(type));
|
|
+ unsigned char buffer[buf_len];
|
|
+ int md_len, actlen;
|
|
|
|
- if (md == NULL)
|
|
- {
|
|
- Log(LOG_LEVEL_INFO, "Digest type %s not supported by OpenSSL library", HashNameFromId(type));
|
|
- }
|
|
+ if (EVP_DigestInit(context, md) == 1)
|
|
+ {
|
|
+ actlen = BN_bn2bin(n, buffer);
|
|
+ CF_ASSERT(actlen <= buf_len, "Buffer overflow n, %d > %zu!",
|
|
+ actlen, buf_len);
|
|
+ EVP_DigestUpdate(context, buffer, actlen);
|
|
|
|
- EVP_DigestInit(&context, md);
|
|
+ actlen = BN_bn2bin(e, buffer);
|
|
+ CF_ASSERT(actlen <= buf_len, "Buffer overflow e, %d > %zu!",
|
|
+ actlen, buf_len);
|
|
+ EVP_DigestUpdate(context, buffer, actlen);
|
|
|
|
- actlen = BN_bn2bin(key->n, buffer);
|
|
- EVP_DigestUpdate(&context, buffer, actlen);
|
|
- actlen = BN_bn2bin(key->e, buffer);
|
|
- EVP_DigestUpdate(&context, buffer, actlen);
|
|
- EVP_DigestFinal(&context, digest, &md_len);
|
|
- break;
|
|
+ EVP_DigestFinal(context, digest, &md_len);
|
|
}
|
|
|
|
- free(buffer);
|
|
+ EVP_MD_CTX_free(context);
|
|
}
|
|
|
|
/*******************************************************************/
|
|
diff --git a/libpromises/files_hashes.h b/libpromises/files_hashes.h
|
|
index 0f6194291593..636a9ab2cd35 100644
|
|
--- a/libpromises/files_hashes.h
|
|
+++ b/libpromises/files_hashes.h
|
|
@@ -40,7 +40,7 @@ int HashesMatch(const unsigned char digest1[EVP_MAX_MD_SIZE + 1],
|
|
char *HashPrintSafe(char *dst, size_t dst_size, const unsigned char *digest,
|
|
HashMethod type, bool use_prefix);
|
|
char *SkipHashType(char *hash);
|
|
-void HashPubKey(RSA *key, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type);
|
|
+void HashPubKey(const RSA *key, unsigned char digest[EVP_MAX_MD_SIZE + 1], HashMethod type);
|
|
|
|
|
|
#endif
|
|
diff --git a/libpromises/generic_agent.c b/libpromises/generic_agent.c
|
|
index b8c32f0baf59..0a247e55ee83 100644
|
|
--- a/libpromises/generic_agent.c
|
|
+++ b/libpromises/generic_agent.c
|
|
@@ -66,6 +66,9 @@
|
|
#include <loading.h>
|
|
#include <signals.h>
|
|
#include <addr_lib.h>
|
|
+#include <openssl/evp.h>
|
|
+#include <libcrypto-compat.h>
|
|
+
|
|
|
|
static pthread_once_t pid_cleanup_once = PTHREAD_ONCE_INIT; /* GLOBAL_T */
|
|
|
|
@@ -1163,16 +1166,17 @@ static bool GeneratePolicyReleaseIDFromTree(char *release_id_out, size_t out_siz
|
|
}
|
|
|
|
// fallback, produce some pseudo sha1 hash
|
|
- EVP_MD_CTX crypto_ctx;
|
|
- EVP_DigestInit(&crypto_ctx, EVP_get_digestbyname(HashNameFromId(GENERIC_AGENT_CHECKSUM_METHOD)));
|
|
+ EVP_MD_CTX *crypto_ctx = EVP_MD_CTX_new();
|
|
+ EVP_DigestInit(crypto_ctx, EVP_get_digestbyname(HashNameFromId(GENERIC_AGENT_CHECKSUM_METHOD)));
|
|
|
|
bool success = HashDirectoryTree(policy_dir,
|
|
(const char *[]) { ".cf", ".dat", ".txt", ".conf", ".mustache", ".json", ".yaml", NULL},
|
|
- &crypto_ctx);
|
|
+ crypto_ctx);
|
|
|
|
int md_len;
|
|
unsigned char digest[EVP_MAX_MD_SIZE + 1] = { 0 };
|
|
- EVP_DigestFinal(&crypto_ctx, digest, &md_len);
|
|
+ EVP_DigestFinal(crypto_ctx, digest, &md_len);
|
|
+ EVP_MD_CTX_free(crypto_ctx);
|
|
|
|
HashPrintSafe(release_id_out, out_size, digest,
|
|
GENERIC_AGENT_CHECKSUM_METHOD, false);
|
|
diff --git a/libpromises/locks.c b/libpromises/locks.c
|
|
index 8ebac0cd4a92..5f2542ee4def 100644
|
|
--- a/libpromises/locks.c
|
|
+++ b/libpromises/locks.c
|
|
@@ -39,6 +39,9 @@
|
|
#include <misc_lib.h>
|
|
#include <known_dirs.h>
|
|
#include <sysinfo.h>
|
|
+#include <openssl/evp.h>
|
|
+#include <libcrypto-compat.h>
|
|
+
|
|
|
|
#define CFLOGSIZE 1048576 /* Size of lock-log before rotation */
|
|
#define CF_LOCKHORIZON ((time_t)(SECONDS_PER_WEEK * 4))
|
|
@@ -509,7 +512,7 @@ void PromiseRuntimeHash(const Promise *pp, const char *salt, unsigned char diges
|
|
{
|
|
static const char PACK_UPIFELAPSED_SALT[] = "packageuplist";
|
|
|
|
- EVP_MD_CTX context;
|
|
+ EVP_MD_CTX *context = EVP_MD_CTX_new();
|
|
int md_len;
|
|
const EVP_MD *md = NULL;
|
|
Rlist *rp;
|
|
@@ -520,29 +523,29 @@ void PromiseRuntimeHash(const Promise *pp, const char *salt, unsigned char diges
|
|
|
|
md = EVP_get_digestbyname(HashNameFromId(type));
|
|
|
|
- EVP_DigestInit(&context, md);
|
|
+ EVP_DigestInit(context, md);
|
|
|
|
// multiple packages (promisers) may share same package_list_update_ifelapsed lock
|
|
if ( (!salt) || strcmp(salt, PACK_UPIFELAPSED_SALT) )
|
|
{
|
|
- EVP_DigestUpdate(&context, pp->promiser, strlen(pp->promiser));
|
|
+ EVP_DigestUpdate(context, pp->promiser, strlen(pp->promiser));
|
|
}
|
|
|
|
if (pp->comment)
|
|
{
|
|
- EVP_DigestUpdate(&context, pp->comment, strlen(pp->comment));
|
|
+ EVP_DigestUpdate(context, pp->comment, strlen(pp->comment));
|
|
}
|
|
|
|
if (pp->parent_promise_type && pp->parent_promise_type->parent_bundle)
|
|
{
|
|
if (pp->parent_promise_type->parent_bundle->ns)
|
|
{
|
|
- EVP_DigestUpdate(&context, pp->parent_promise_type->parent_bundle->ns, strlen(pp->parent_promise_type->parent_bundle->ns));
|
|
+ EVP_DigestUpdate(context, pp->parent_promise_type->parent_bundle->ns, strlen(pp->parent_promise_type->parent_bundle->ns));
|
|
}
|
|
|
|
if (pp->parent_promise_type->parent_bundle->name)
|
|
{
|
|
- EVP_DigestUpdate(&context, pp->parent_promise_type->parent_bundle->name, strlen(pp->parent_promise_type->parent_bundle->name));
|
|
+ EVP_DigestUpdate(context, pp->parent_promise_type->parent_bundle->name, strlen(pp->parent_promise_type->parent_bundle->name));
|
|
}
|
|
}
|
|
|
|
@@ -550,7 +553,7 @@ void PromiseRuntimeHash(const Promise *pp, const char *salt, unsigned char diges
|
|
|
|
if (salt)
|
|
{
|
|
- EVP_DigestUpdate(&context, salt, strlen(salt));
|
|
+ EVP_DigestUpdate(context, salt, strlen(salt));
|
|
}
|
|
|
|
if (pp->conlist)
|
|
@@ -559,7 +562,7 @@ void PromiseRuntimeHash(const Promise *pp, const char *salt, unsigned char diges
|
|
{
|
|
Constraint *cp = SeqAt(pp->conlist, i);
|
|
|
|
- EVP_DigestUpdate(&context, cp->lval, strlen(cp->lval));
|
|
+ EVP_DigestUpdate(context, cp->lval, strlen(cp->lval));
|
|
|
|
// don't hash rvals that change (e.g. times)
|
|
doHash = true;
|
|
@@ -581,13 +584,13 @@ void PromiseRuntimeHash(const Promise *pp, const char *salt, unsigned char diges
|
|
switch (cp->rval.type)
|
|
{
|
|
case RVAL_TYPE_SCALAR:
|
|
- EVP_DigestUpdate(&context, cp->rval.item, strlen(cp->rval.item));
|
|
+ EVP_DigestUpdate(context, cp->rval.item, strlen(cp->rval.item));
|
|
break;
|
|
|
|
case RVAL_TYPE_LIST:
|
|
for (rp = cp->rval.item; rp != NULL; rp = rp->next)
|
|
{
|
|
- EVP_DigestUpdate(&context, RlistScalarValue(rp), strlen(RlistScalarValue(rp)));
|
|
+ EVP_DigestUpdate(context, RlistScalarValue(rp), strlen(RlistScalarValue(rp)));
|
|
}
|
|
break;
|
|
|
|
@@ -597,18 +600,18 @@ void PromiseRuntimeHash(const Promise *pp, const char *salt, unsigned char diges
|
|
|
|
fp = (FnCall *) cp->rval.item;
|
|
|
|
- EVP_DigestUpdate(&context, fp->name, strlen(fp->name));
|
|
+ EVP_DigestUpdate(context, fp->name, strlen(fp->name));
|
|
|
|
for (rp = fp->args; rp != NULL; rp = rp->next)
|
|
{
|
|
switch (rp->val.type)
|
|
{
|
|
case RVAL_TYPE_SCALAR:
|
|
- EVP_DigestUpdate(&context, RlistScalarValue(rp), strlen(RlistScalarValue(rp)));
|
|
+ EVP_DigestUpdate(context, RlistScalarValue(rp), strlen(RlistScalarValue(rp)));
|
|
break;
|
|
|
|
case RVAL_TYPE_FNCALL:
|
|
- EVP_DigestUpdate(&context, RlistFnCallValue(rp)->name, strlen(RlistFnCallValue(rp)->name));
|
|
+ EVP_DigestUpdate(context, RlistFnCallValue(rp)->name, strlen(RlistFnCallValue(rp)->name));
|
|
break;
|
|
|
|
default:
|
|
@@ -624,7 +627,8 @@ void PromiseRuntimeHash(const Promise *pp, const char *salt, unsigned char diges
|
|
}
|
|
}
|
|
|
|
- EVP_DigestFinal(&context, digest, &md_len);
|
|
+ EVP_DigestFinal(context, digest, &md_len);
|
|
+ EVP_MD_CTX_free(context);
|
|
|
|
/* Digest length stored in md_len */
|
|
}
|
|
diff --git a/libutils/Makefile.am b/libutils/Makefile.am
|
|
index c55379418a7a..f9dc629ceb6e 100644
|
|
--- a/libutils/Makefile.am
|
|
+++ b/libutils/Makefile.am
|
|
@@ -75,6 +75,7 @@ libutils_la_SOURCES = \
|
|
regex.c regex.h \
|
|
encode.c encode.h \
|
|
pcre_wrap.c pcre_wrap.h \
|
|
+ libcrypto-compat.c libcrypto-compat.h \
|
|
printsize.h
|
|
|
|
if !NT
|
|
diff --git a/libutils/encode.c b/libutils/encode.c
|
|
index c0ee32714767..dc03729f8f1d 100644
|
|
--- a/libutils/encode.c
|
|
+++ b/libutils/encode.c
|
|
@@ -28,6 +28,7 @@
|
|
#include <openssl/buffer.h> /* BUF_MEM */
|
|
#include <openssl/bio.h> /* BIO_* */
|
|
#include <openssl/evp.h> /* BIO_f_base64 */
|
|
+#include <libcrypto-compat.h>
|
|
|
|
#include <alloc.h>
|
|
|
|
diff --git a/libutils/hash.c b/libutils/hash.c
|
|
index 4e27152698ff..9a52944fb8f4 100644
|
|
--- a/libutils/hash.c
|
|
+++ b/libutils/hash.c
|
|
@@ -26,10 +26,13 @@
|
|
|
|
#include <openssl/evp.h> /* EVP_* */
|
|
#include <openssl/bn.h> /* BN_bn2bin */
|
|
+#include <libcrypto-compat.h>
|
|
|
|
#include <alloc.h>
|
|
#include <logging.h>
|
|
#include <hash.h>
|
|
+#include <misc_lib.h>
|
|
+
|
|
|
|
static const char *const CF_DIGEST_TYPES[10] =
|
|
{
|
|
@@ -198,49 +201,55 @@ Hash *HashNewFromKey(const RSA *rsa, HashMethod method)
|
|
{
|
|
return NULL;
|
|
}
|
|
- EVP_MD_CTX *context = NULL;
|
|
- const EVP_MD *md = NULL;
|
|
- int md_len = 0;
|
|
- unsigned char *buffer = NULL;
|
|
- int buffer_length = 0;
|
|
- int actual_length = 0;
|
|
|
|
- if (rsa->n)
|
|
- {
|
|
- buffer_length = (size_t) BN_num_bytes(rsa->n);
|
|
- }
|
|
- else
|
|
+ const BIGNUM *n, *e;
|
|
+ RSA_get0_key(rsa, &n, &e, NULL);
|
|
+
|
|
+ size_t n_len = (n == NULL) ? 0 : (size_t) BN_num_bytes(n);
|
|
+ size_t e_len = (e == NULL) ? 0 : (size_t) BN_num_bytes(e);
|
|
+ size_t buf_len = MAX(n_len, e_len);
|
|
+
|
|
+ const EVP_MD *md = EVP_get_digestbyname(CF_DIGEST_TYPES[method]);
|
|
+ if (md == NULL)
|
|
{
|
|
- buffer_length = 0;
|
|
+ Log(LOG_LEVEL_INFO, "Digest type %s not supported by OpenSSL library", CF_DIGEST_TYPES[method]);
|
|
+ return NULL;
|
|
}
|
|
|
|
- if (rsa->e)
|
|
+ EVP_MD_CTX *context = EVP_MD_CTX_new();
|
|
+ if (context == NULL)
|
|
{
|
|
- if (buffer_length < (size_t) BN_num_bytes(rsa->e))
|
|
- {
|
|
- buffer_length = (size_t) BN_num_bytes(rsa->e);
|
|
- }
|
|
+ Log(LOG_LEVEL_ERR, "Failed to allocate openssl hashing context");
|
|
+ return NULL;
|
|
}
|
|
- md = EVP_get_digestbyname(CF_DIGEST_TYPES[method]);
|
|
- if (md == NULL)
|
|
+
|
|
+ if (EVP_DigestInit_ex(context, md, NULL) != 1)
|
|
{
|
|
- Log(LOG_LEVEL_INFO, "Digest type %s not supported by OpenSSL library", CF_DIGEST_TYPES[method]);
|
|
+ EVP_MD_CTX_free(context);
|
|
return NULL;
|
|
}
|
|
+
|
|
+ unsigned char buffer[buf_len];
|
|
+ int md_len, actlen;
|
|
+
|
|
+ actlen = BN_bn2bin(n, buffer);
|
|
+ CF_ASSERT(actlen <= buf_len, "Buffer overflow n, %d > %zu!",
|
|
+ actlen, buf_len);
|
|
+ EVP_DigestUpdate(context, buffer, actlen);
|
|
+
|
|
+ actlen = BN_bn2bin(e, buffer);
|
|
+ CF_ASSERT(actlen <= buf_len, "Buffer overflow e, %d > %zu!",
|
|
+ actlen, buf_len);
|
|
+ EVP_DigestUpdate(context, buffer, actlen);
|
|
+
|
|
Hash *hash = HashBasicInit(method);
|
|
- context = EVP_MD_CTX_create();
|
|
- EVP_DigestInit_ex(context, md, NULL);
|
|
- buffer = xmalloc(buffer_length);
|
|
- actual_length = BN_bn2bin(rsa->n, buffer);
|
|
- EVP_DigestUpdate(context, buffer, actual_length);
|
|
- actual_length = BN_bn2bin(rsa->e, buffer);
|
|
- EVP_DigestUpdate(context, buffer, actual_length);
|
|
EVP_DigestFinal_ex(context, hash->digest, &md_len);
|
|
- EVP_MD_CTX_destroy(context);
|
|
- free (buffer);
|
|
+
|
|
+ EVP_MD_CTX_free(context);
|
|
+
|
|
/* Update the printable representation */
|
|
HashCalculatePrintableRepresentation(hash);
|
|
- /* Return the hash */
|
|
+
|
|
return hash;
|
|
}
|
|
|
|
diff --git a/libutils/hashes.c b/libutils/hashes.c
|
|
index b074ed2e43c5..1213c886ca77 100644
|
|
--- a/libutils/hashes.c
|
|
+++ b/libutils/hashes.c
|
|
@@ -27,6 +27,7 @@
|
|
#include <file_lib.h>
|
|
|
|
#include <openssl/evp.h>
|
|
+#include <libcrypto-compat.h>
|
|
|
|
|
|
int FileChecksum(const char *filename, unsigned char digest[EVP_MAX_MD_SIZE + 1])
|
|
@@ -40,25 +41,36 @@ int FileChecksum(const char *filename, unsigned char digest[EVP_MAX_MD_SIZE + 1]
|
|
else
|
|
{
|
|
const EVP_MD *md = EVP_get_digestbyname("md5");
|
|
-
|
|
if (!md)
|
|
{
|
|
fclose(file);
|
|
return 0;
|
|
}
|
|
|
|
- EVP_MD_CTX context;
|
|
- EVP_DigestInit(&context, md);
|
|
+ EVP_MD_CTX *context = EVP_MD_CTX_new();
|
|
+ if (context == NULL)
|
|
+ {
|
|
+ fclose(file);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ if (EVP_DigestInit_ex(context, md, NULL) != 1)
|
|
+ {
|
|
+ fclose(file);
|
|
+ EVP_MD_CTX_free(context);
|
|
+ return 0;
|
|
+ }
|
|
|
|
int len = 0;
|
|
unsigned char buffer[1024];
|
|
while ((len = fread(buffer, 1, 1024, file)))
|
|
{
|
|
- EVP_DigestUpdate(&context, buffer, len);
|
|
+ EVP_DigestUpdate(context, buffer, len);
|
|
}
|
|
|
|
unsigned int md_len = 0;
|
|
- EVP_DigestFinal(&context, digest, &md_len);
|
|
+ EVP_DigestFinal(context, digest, &md_len);
|
|
+ EVP_MD_CTX_free(context);
|
|
fclose(file);
|
|
|
|
return md_len;
|
|
diff --git a/libutils/libcrypto-compat.c b/libutils/libcrypto-compat.c
|
|
new file mode 100644
|
|
index 000000000000..3fc39092a16d
|
|
--- /dev/null
|
|
+++ b/libutils/libcrypto-compat.c
|
|
@@ -0,0 +1,414 @@
|
|
+/*
|
|
+ * 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 <libcrypto-compat.h>
|
|
+
|
|
+
|
|
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
+
|
|
+#include <string.h>
|
|
+#include <openssl/engine.h>
|
|
+#include <openssl/bn.h> /* BN_* */
|
|
+
|
|
+
|
|
+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;
|
|
+}
|
|
+
|
|
+void DH_get0_pqg(const DH *dh,
|
|
+ const BIGNUM **p, const BIGNUM **q, const BIGNUM **g)
|
|
+{
|
|
+ if (p != NULL)
|
|
+ *p = dh->p;
|
|
+ if (q != NULL)
|
|
+ *q = dh->q;
|
|
+ if (g != NULL)
|
|
+ *g = dh->g;
|
|
+}
|
|
+
|
|
+int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g)
|
|
+{
|
|
+ /* If the fields p and g in d are NULL, the corresponding input
|
|
+ * parameters MUST be non-NULL. q may remain NULL.
|
|
+ */
|
|
+ if ((dh->p == NULL && p == NULL)
|
|
+ || (dh->g == NULL && g == NULL))
|
|
+ return 0;
|
|
+
|
|
+ if (p != NULL) {
|
|
+ BN_free(dh->p);
|
|
+ dh->p = p;
|
|
+ }
|
|
+ if (q != NULL) {
|
|
+ BN_free(dh->q);
|
|
+ dh->q = q;
|
|
+ }
|
|
+ if (g != NULL) {
|
|
+ BN_free(dh->g);
|
|
+ dh->g = g;
|
|
+ }
|
|
+
|
|
+ if (q != NULL) {
|
|
+ dh->length = BN_num_bits(q);
|
|
+ }
|
|
+
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key)
|
|
+{
|
|
+ if (pub_key != NULL)
|
|
+ *pub_key = dh->pub_key;
|
|
+ if (priv_key != NULL)
|
|
+ *priv_key = dh->priv_key;
|
|
+}
|
|
+
|
|
+int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key)
|
|
+{
|
|
+ /* If the field pub_key in dh is NULL, the corresponding input
|
|
+ * parameters MUST be non-NULL. The priv_key field may
|
|
+ * be left NULL.
|
|
+ */
|
|
+ if (dh->pub_key == NULL && pub_key == NULL)
|
|
+ return 0;
|
|
+
|
|
+ if (pub_key != NULL) {
|
|
+ BN_free(dh->pub_key);
|
|
+ dh->pub_key = pub_key;
|
|
+ }
|
|
+ if (priv_key != NULL) {
|
|
+ BN_free(dh->priv_key);
|
|
+ dh->priv_key = priv_key;
|
|
+ }
|
|
+
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+int DH_set_length(DH *dh, long length)
|
|
+{
|
|
+ dh->length = length;
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx)
|
|
+{
|
|
+ return ctx->iv;
|
|
+}
|
|
+
|
|
+unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx)
|
|
+{
|
|
+ return ctx->iv;
|
|
+}
|
|
+
|
|
+EVP_MD_CTX *EVP_MD_CTX_new(void)
|
|
+{
|
|
+ return OPENSSL_zalloc(sizeof(EVP_MD_CTX));
|
|
+}
|
|
+
|
|
+void EVP_MD_CTX_free(EVP_MD_CTX *ctx)
|
|
+{
|
|
+ EVP_MD_CTX_cleanup(ctx);
|
|
+ OPENSSL_free(ctx);
|
|
+}
|
|
+
|
|
+RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth)
|
|
+{
|
|
+ RSA_METHOD *ret;
|
|
+
|
|
+ ret = OPENSSL_malloc(sizeof(RSA_METHOD));
|
|
+
|
|
+ if (ret != NULL) {
|
|
+ memcpy(ret, meth, sizeof(*meth));
|
|
+ ret->name = OPENSSL_strdup(meth->name);
|
|
+ if (ret->name == NULL) {
|
|
+ OPENSSL_free(ret);
|
|
+ return NULL;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+int RSA_meth_set1_name(RSA_METHOD *meth, const char *name)
|
|
+{
|
|
+ char *tmpname;
|
|
+
|
|
+ tmpname = OPENSSL_strdup(name);
|
|
+ if (tmpname == NULL) {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ OPENSSL_free((char *)meth->name);
|
|
+ meth->name = tmpname;
|
|
+
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+int RSA_meth_set_priv_enc(RSA_METHOD *meth,
|
|
+ int (*priv_enc) (int flen, const unsigned char *from,
|
|
+ unsigned char *to, RSA *rsa,
|
|
+ int padding))
|
|
+{
|
|
+ meth->rsa_priv_enc = priv_enc;
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+int RSA_meth_set_priv_dec(RSA_METHOD *meth,
|
|
+ int (*priv_dec) (int flen, const unsigned char *from,
|
|
+ unsigned char *to, RSA *rsa,
|
|
+ int padding))
|
|
+{
|
|
+ meth->rsa_priv_dec = priv_dec;
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa))
|
|
+{
|
|
+ meth->finish = finish;
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+void RSA_meth_free(RSA_METHOD *meth)
|
|
+{
|
|
+ if (meth != NULL) {
|
|
+ OPENSSL_free((char *)meth->name);
|
|
+ OPENSSL_free(meth);
|
|
+ }
|
|
+}
|
|
+
|
|
+int RSA_bits(const RSA *r)
|
|
+{
|
|
+ return (BN_num_bits(r->n));
|
|
+}
|
|
+
|
|
+RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey)
|
|
+{
|
|
+ if (pkey->type != EVP_PKEY_RSA) {
|
|
+ return NULL;
|
|
+ }
|
|
+ return pkey->pkey.rsa;
|
|
+}
|
|
+
|
|
+
|
|
+#endif /* OPENSSL_VERSION_NUMBER */
|
|
diff --git a/libutils/libcrypto-compat.h b/libutils/libcrypto-compat.h
|
|
new file mode 100644
|
|
index 000000000000..fa3eb1444a1e
|
|
--- /dev/null
|
|
+++ b/libutils/libcrypto-compat.h
|
|
@@ -0,0 +1,62 @@
|
|
+#ifndef LIBCRYPTO_COMPAT_H
|
|
+#define LIBCRYPTO_COMPAT_H
|
|
+
|
|
+#include <platform.h>
|
|
+#include <openssl/opensslv.h>
|
|
+
|
|
+
|
|
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
|
+
|
|
+#include <openssl/bn.h>
|
|
+#include <openssl/rsa.h>
|
|
+#include <openssl/dsa.h>
|
|
+#include <openssl/ecdsa.h>
|
|
+#include <openssl/dh.h>
|
|
+#include <openssl/evp.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);
|
|
+
|
|
+void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g);
|
|
+int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g);
|
|
+void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key);
|
|
+int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key);
|
|
+int DH_set_length(DH *dh, long length);
|
|
+
|
|
+const unsigned char *EVP_CIPHER_CTX_iv(const EVP_CIPHER_CTX *ctx);
|
|
+unsigned char *EVP_CIPHER_CTX_iv_noconst(EVP_CIPHER_CTX *ctx);
|
|
+EVP_MD_CTX *EVP_MD_CTX_new(void);
|
|
+void EVP_MD_CTX_free(EVP_MD_CTX *ctx);
|
|
+#define EVP_CIPHER_impl_ctx_size(e) e->ctx_size
|
|
+#define EVP_CIPHER_CTX_get_cipher_data(ctx) ctx->cipher_data
|
|
+
|
|
+RSA_METHOD *RSA_meth_dup(const RSA_METHOD *meth);
|
|
+int RSA_meth_set1_name(RSA_METHOD *meth, const char *name);
|
|
+#define RSA_meth_get_finish(meth) meth->finish
|
|
+int RSA_meth_set_priv_enc(RSA_METHOD *meth, int (*priv_enc) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding));
|
|
+int RSA_meth_set_priv_dec(RSA_METHOD *meth, int (*priv_dec) (int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding));
|
|
+int RSA_meth_set_finish(RSA_METHOD *meth, int (*finish) (RSA *rsa));
|
|
+void RSA_meth_free(RSA_METHOD *meth);
|
|
+
|
|
+int RSA_bits(const RSA *r);
|
|
+
|
|
+RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey);
|
|
+
|
|
+#endif /* OPENSSL_VERSION_NUMBER */
|
|
+
|
|
+#endif /* LIBCRYPTO_COMPAT_H */
|
|
diff --git a/libutils/string_lib.c b/libutils/string_lib.c
|
|
index 8f4d58dcb376..2b8ef041eee6 100644
|
|
--- a/libutils/string_lib.c
|
|
+++ b/libutils/string_lib.c
|
|
@@ -28,12 +28,14 @@
|
|
#include <openssl/buffer.h> /* BUF_MEM */
|
|
#include <openssl/bio.h> /* BIO_* */
|
|
#include <openssl/evp.h> /* BIO_f_base64 */
|
|
+#include <libcrypto-compat.h>
|
|
|
|
#include <alloc.h>
|
|
#include <writer.h>
|
|
#include <misc_lib.h>
|
|
#include <logging.h>
|
|
|
|
+
|
|
char *StringVFormat(const char *fmt, va_list ap)
|
|
{
|
|
char *value;
|
|
diff --git a/tests/acceptance/16_cf-serverd/serial/nondefault_ciphers_tlsversion.srv b/tests/acceptance/16_cf-serverd/serial/nondefault_ciphers_tlsversion.srv
|
|
index 39ed761fbc9d..9dad9f2a066d 100644
|
|
--- a/tests/acceptance/16_cf-serverd/serial/nondefault_ciphers_tlsversion.srv
|
|
+++ b/tests/acceptance/16_cf-serverd/serial/nondefault_ciphers_tlsversion.srv
|
|
@@ -14,8 +14,8 @@ body server control
|
|
{
|
|
port => "9888";
|
|
|
|
- # Only this non-default cipher is to be accepted
|
|
- allowciphers => "RC4-MD5";
|
|
+ # Only this cipher is to be accepted
|
|
+ allowciphers => "AES128-GCM-SHA256";
|
|
|
|
# Allow only TLSv1.1 or higher
|
|
allowtlsversion => "1.1";
|
|
diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am
|
|
index 9db71ed02184..073973c64158 100644
|
|
--- a/tests/unit/Makefile.am
|
|
+++ b/tests/unit/Makefile.am
|
|
@@ -420,18 +420,6 @@ mon_load_test_LDADD = ../../libpromises/libpromises.la libtest.la
|
|
mon_processes_test_SOURCES = mon_processes_test.c ../../cf-monitord/mon.h ../../cf-monitord/mon_processes.c
|
|
mon_processes_test_LDADD = ../../libpromises/libpromises.la libtest.la
|
|
|
|
-# tls_generic_test uses stub functions interposition which does not work (yet)
|
|
-# under OS X. Another way of stubbing functions from libpromises is needed.
|
|
-if !XNU
|
|
-check_PROGRAMS += tls_generic_test
|
|
-tls_generic_test_SOURCES = tls_generic_test.c
|
|
-tls_generic_test_LDADD = libtest.la \
|
|
- ../../libutils/libutils.la \
|
|
- ../../libpromises/libpromises.la \
|
|
- ../../libcfnet/libcfnet.la \
|
|
- ../../cf-serverd/libcf-serverd.la
|
|
-endif
|
|
-
|
|
version_test_SOURCES = version_test.c
|
|
|
|
hash_test_SOURCES = hash_test.c
|
|
diff --git a/tests/unit/crypto_symmetric_test.c b/tests/unit/crypto_symmetric_test.c
|
|
index 8bbdc4546079..89a34d040f31 100644
|
|
--- a/tests/unit/crypto_symmetric_test.c
|
|
+++ b/tests/unit/crypto_symmetric_test.c
|
|
@@ -30,11 +30,11 @@ static void test_cipher_init(void)
|
|
{
|
|
unsigned char key[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
|
|
unsigned char iv[] = {1,2,3,4,5,6,7,8};
|
|
- EVP_CIPHER_CTX ctx;
|
|
+ EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
|
|
|
|
- EVP_CIPHER_CTX_init(&ctx);
|
|
- EVP_EncryptInit_ex(&ctx, EVP_bf_cbc(), NULL, key, iv);
|
|
- EVP_CIPHER_CTX_cleanup(&ctx);
|
|
+ EVP_CIPHER_CTX_init(ctx);
|
|
+ EVP_EncryptInit_ex(ctx, EVP_bf_cbc(), NULL, key, iv);
|
|
+ EVP_CIPHER_CTX_free(ctx);
|
|
}
|
|
|
|
static void test_symmetric_encrypt(void)
|
|
diff --git a/tests/unit/tls_generic_test.c b/tests/unit/tls_generic_test.c
|
|
index 69579ecbf457..4b98c901c999 100644
|
|
--- a/tests/unit/tls_generic_test.c
|
|
+++ b/tests/unit/tls_generic_test.c
|
|
@@ -1,3 +1,14 @@
|
|
+/*
|
|
+ * WARNING: THIS TEST HAS BEEN DISABLED
|
|
+ *
|
|
+ * This test is written in a very unportable manner: it replicates source code
|
|
+ * of OpenSSL, it uses internals of data structures etc. Do not re-enable it
|
|
+ * unless you delete all the code from the OpenSSL internals, and refactor it
|
|
+ * to mock the library routines properly, for example with `ld --wrap`. See
|
|
+ * "CMocka" and "Mimick" unit testing frameworks.
|
|
+ */
|
|
+
|
|
+
|
|
#include <test.h>
|
|
|
|
#include <sys/socket.h>
|
|
--
|
|
2.15.0
|
|
|