1From a801d10a081e3130e24042256a43190c9eb6c112 Mon Sep 17 00:00:00 2001
2From: Eneas Queiroz <35331380+cotequeiroz@users.noreply.github.com>
3Date: Wed, 23 May 2018 03:09:02 -0300
4Subject: [PATCH] ibrcommon: added openssl 1.1 compatibility (#264)
5
6This patch adds compatibility to openssl 1.1.0.
7
8Backported from master branch:
9https://github.com/ibrdtn/ibrdtn/commit/a801d10a081e3130e24042256a43190c9eb6c112
10
11Signed-off-by: Eneas U de Queiroz <cote2004-github@yahoo.com>
12Signed-off-by: Bernd Kuhls <bernd.kuhls@t-online.de>
13---
14 ibrcommon/ibrcommon/ssl/HMacStream.cpp      | 11 +++---
15 ibrcommon/ibrcommon/ssl/HMacStream.h        |  2 +-
16 ibrcommon/ibrcommon/ssl/RSASHA256Stream.cpp | 28 +++++++------
17 ibrcommon/ibrcommon/ssl/RSASHA256Stream.h   |  2 +-
18 ibrcommon/ibrcommon/ssl/iostreamBIO.cpp     | 44 ++++++++++++++++-----
19 ibrcommon/ibrcommon/ssl/openssl_compat.h    | 38 ++++++++++++++++++
20 6 files changed, 95 insertions(+), 30 deletions(-)
21 create mode 100644 ibrcommon/ibrcommon/ssl/openssl_compat.h
22
23diff --git a/ibrcommon/ssl/HMacStream.cpp b/ibrcommon/ssl/HMacStream.cpp
24index e5d317e3..66d8ce42 100644
25--- a/ibrcommon/ssl/HMacStream.cpp
26+++ b/ibrcommon/ssl/HMacStream.cpp
27@@ -20,29 +20,30 @@
28  */
29
30 #include "ibrcommon/ssl/HMacStream.h"
31+#include "openssl_compat.h"
32
33 namespace ibrcommon
34 {
35 	HMacStream::HMacStream(const unsigned char * const key, const int key_size)
36 	 : HashStream(EVP_MAX_MD_SIZE, BUFF_SIZE), key_(key), key_size_(key_size)
37 	{
38-		HMAC_CTX_init(&ctx_);
39-		HMAC_Init_ex(&ctx_, key_, key_size_, EVP_sha1(), NULL);
40+		ctx_ = HMAC_CTX_new();
41+		HMAC_Init_ex(ctx_, key_, key_size_, EVP_sha1(), NULL);
42 	}
43
44 	HMacStream::~HMacStream()
45 	{
46-		HMAC_CTX_cleanup(&ctx_);
47+		HMAC_CTX_free(ctx_);
48 	}
49
50 	void HMacStream::update(char *buf, const size_t size)
51 	{
52 		// hashing
53-		HMAC_Update(&ctx_, (unsigned char*)buf, size);
54+		HMAC_Update(ctx_, (unsigned char*)buf, size);
55 	}
56
57 	void HMacStream::finalize(char * hash, unsigned int &size)
58 	{
59-		HMAC_Final(&ctx_, (unsigned char*)hash, &size);
60+		HMAC_Final(ctx_, (unsigned char*)hash, &size);
61 	}
62 }
63diff --git a/ibrcommon/ssl/HMacStream.h b/ibrcommon/ssl/HMacStream.h
64index 7dcea168..d04bceb8 100644
65--- a/ibrcommon/ssl/HMacStream.h
66+++ b/ibrcommon/ssl/HMacStream.h
67@@ -44,7 +44,7 @@ namespace ibrcommon
68 		const unsigned char * const key_;
69 		const int key_size_;
70
71-		HMAC_CTX ctx_;
72+		HMAC_CTX* ctx_;
73 	};
74 }
75
76diff --git a/ibrcommon/ssl/RSASHA256Stream.cpp b/ibrcommon/ssl/RSASHA256Stream.cpp
77index d94430ed..d25c5d2f 100644
78--- a/ibrcommon/ssl/RSASHA256Stream.cpp
79+++ b/ibrcommon/ssl/RSASHA256Stream.cpp
80@@ -21,6 +21,7 @@
81
82 #include "ibrcommon/ssl/RSASHA256Stream.h"
83 #include "ibrcommon/Logger.h"
84+#include "openssl_compat.h"
85 #include <openssl/err.h>
86
87 namespace ibrcommon
88@@ -30,11 +31,11 @@ namespace ibrcommon
89 	{
90 		// Initialize get pointer.  This should be zero so that underflow is called upon first read.
91 		setp(&out_buf_[0], &out_buf_[BUFF_SIZE - 1]);
92-		EVP_MD_CTX_init(&_ctx);
93+		_ctx = EVP_MD_CTX_new();
94
95 		if (!_verify)
96 		{
97-			if (!EVP_SignInit_ex(&_ctx, EVP_sha256(), NULL))
98+			if (!EVP_SignInit_ex(_ctx, EVP_sha256(), NULL))
99 			{
100 				IBRCOMMON_LOGGER_TAG("RSASHA256Stream", critical) << "failed to initialize the signature function" << IBRCOMMON_LOGGER_ENDL;
101 				ERR_print_errors_fp(stderr);
102@@ -42,7 +43,7 @@ namespace ibrcommon
103 		}
104 		else
105 		{
106-			if (!EVP_VerifyInit_ex(&_ctx, EVP_sha256(), NULL))
107+			if (!EVP_VerifyInit_ex(_ctx, EVP_sha256(), NULL))
108 			{
109 				IBRCOMMON_LOGGER_TAG("RSASHA256Stream", critical) << "failed to initialize the verification function" << IBRCOMMON_LOGGER_ENDL;
110 				ERR_print_errors_fp(stderr);
111@@ -52,18 +53,19 @@ namespace ibrcommon
112
113 	RSASHA256Stream::~RSASHA256Stream()
114 	{
115-		EVP_MD_CTX_cleanup(&_ctx);
116+		EVP_MD_CTX_free(_ctx);
117 	}
118
119 	void RSASHA256Stream::reset()
120 	{
121-		EVP_MD_CTX_cleanup(&_ctx);
122-
123-		EVP_MD_CTX_init(&_ctx);
124+#if OPENSSL_VERSION_NUMBER < 0x10100000L
125+		EVP_MD_CTX_cleanup(_ctx);
126+#endif
127+		EVP_MD_CTX_init(_ctx);
128
129 		if (!_verify)
130 		{
131-			if (!EVP_SignInit_ex(&_ctx, EVP_sha256(), NULL))
132+			if (!EVP_SignInit_ex(_ctx, EVP_sha256(), NULL))
133 			{
134 				IBRCOMMON_LOGGER_TAG("RSASHA256Stream", critical) << "failed to initialize the signature function" << IBRCOMMON_LOGGER_ENDL;
135 				ERR_print_errors_fp(stderr);
136@@ -71,7 +73,7 @@ namespace ibrcommon
137 		}
138 		else
139 		{
140-			if (!EVP_VerifyInit_ex(&_ctx, EVP_sha256(), NULL))
141+			if (!EVP_VerifyInit_ex(_ctx, EVP_sha256(), NULL))
142 			{
143 				IBRCOMMON_LOGGER_TAG("RSASHA256Stream", critical) << "failed to initialize the verfication function" << IBRCOMMON_LOGGER_ENDL;
144 				ERR_print_errors_fp(stderr);
145@@ -91,7 +93,7 @@ namespace ibrcommon
146 			std::vector<unsigned char> sign(EVP_PKEY_size(_pkey));
147 			unsigned int size = EVP_PKEY_size(_pkey);
148
149-			_return_code = EVP_SignFinal(&_ctx, &sign[0], &size, _pkey);
150+			_return_code = EVP_SignFinal(_ctx, &sign[0], &size, _pkey);
151
152 			_sign = std::string((const char*)&sign[0], size);
153
154@@ -107,7 +109,7 @@ namespace ibrcommon
155 		if (!_sign_valid)
156 		{
157 			sync();
158-			_return_code = EVP_VerifyFinal(&_ctx, reinterpret_cast<const unsigned char *>(their_sign.c_str()), static_cast<unsigned int>(their_sign.size()), _pkey);
159+			_return_code = EVP_VerifyFinal(_ctx, reinterpret_cast<const unsigned char *>(their_sign.c_str()), static_cast<unsigned int>(their_sign.size()), _pkey);
160 			_sign_valid = true;
161 		}
162 		return _return_code;
163@@ -145,7 +147,7 @@ namespace ibrcommon
164 		if (!_verify)
165 			// hashing
166 		{
167-			if (!EVP_SignUpdate(&_ctx, &out_buf_[0], iend - ibegin))
168+			if (!EVP_SignUpdate(_ctx, &out_buf_[0], iend - ibegin))
169 			{
170 				IBRCOMMON_LOGGER_TAG("RSASHA256Stream", critical) << "failed to feed data into the signature function" << IBRCOMMON_LOGGER_ENDL;
171 				ERR_print_errors_fp(stderr);
172@@ -153,7 +155,7 @@ namespace ibrcommon
173 		}
174 		else
175 		{
176-			if (!EVP_VerifyUpdate(&_ctx, &out_buf_[0], iend - ibegin))
177+			if (!EVP_VerifyUpdate(_ctx, &out_buf_[0], iend - ibegin))
178 			{
179 				IBRCOMMON_LOGGER_TAG("RSASHA256Stream", critical) << "failed to feed data into the verification function" << IBRCOMMON_LOGGER_ENDL;
180 				ERR_print_errors_fp(stderr);
181diff --git a/ibrcommon/ssl/RSASHA256Stream.h b/ibrcommon/ssl/RSASHA256Stream.h
182index 344f8e10..6f3a1168 100644
183--- a/ibrcommon/ssl/RSASHA256Stream.h
184+++ b/ibrcommon/ssl/RSASHA256Stream.h
185@@ -106,7 +106,7 @@ namespace ibrcommon
186
187 		/** the context in which the streamed data will be feed into for
188 		calculation of the hash/signature */
189-		EVP_MD_CTX _ctx;
190+		EVP_MD_CTX * _ctx;
191
192 		/** tells if the context needs to be finalized to get a valid signature or
193 		verification */
194diff --git a/ibrcommon/ssl/iostreamBIO.cpp b/ibrcommon/ssl/iostreamBIO.cpp
195index 18c1b55c..ea6c63eb 100644
196--- a/ibrcommon/ssl/iostreamBIO.cpp
197+++ b/ibrcommon/ssl/iostreamBIO.cpp
198@@ -23,6 +23,7 @@
199
200 #include "ibrcommon/Logger.h"
201
202+#include "openssl_compat.h"
203 #include <openssl/err.h>
204
205 namespace ibrcommon
206@@ -42,7 +43,20 @@ static int create(BIO *bio);
207 //static int destroy(BIO *bio);
208 //static long (*callback_ctrl)(BIO *, int, bio_info_cb *);
209
210-
211+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
212+BIO_METHOD * BIO_iostream_method()
213+{
214+	static BIO_METHOD *iostream_method = NULL;
215+	if (iostream_method) {
216+		iostream_method = BIO_meth_new(iostreamBIO::type, iostreamBIO::name);
217+		BIO_meth_set_write(iostream_method, bwrite);
218+		BIO_meth_set_read(iostream_method, bread);
219+		BIO_meth_set_ctrl(iostream_method, ctrl);
220+		BIO_meth_set_create(iostream_method, create);
221+	}
222+	return iostream_method;
223+}
224+#else
225 static BIO_METHOD iostream_method =
226 {
227 		iostreamBIO::type,
228@@ -56,12 +70,17 @@ static BIO_METHOD iostream_method =
229 		NULL,//destroy,
230 		NULL//callback_ctrl
231 };
232+BIO_METHOD * BIO_iostream_method()
233+{
234+	return &iostream_method;
235+}
236+#endif
237
238 iostreamBIO::iostreamBIO(iostream *stream)
239 	:	_stream(stream)
240 {
241 	/* create BIO */
242-	_bio = BIO_new(&iostream_method);
243+	_bio = BIO_new(BIO_iostream_method());
244 	if(!_bio){
245 		/* creation failed, throw exception */
246 		char err_buf[ERR_BUF_SIZE];
247@@ -72,7 +91,7 @@ iostreamBIO::iostreamBIO(iostream *stream)
248 	}
249
250 	/* save the iostream in the bio object */
251-	_bio->ptr = stream;
252+	BIO_set_data(_bio, (void *) stream);
253 }
254
255 BIO * iostreamBIO::getBIO(){
256@@ -81,10 +100,10 @@ BIO * iostreamBIO::getBIO(){
257
258 static int create(BIO *bio)
259 {
260-	bio->ptr = NULL;
261-	/* (from openssl memory bio) */
262-	bio->shutdown=1;
263-	bio->init=1;
264+	BIO_set_data(bio, NULL);
265+	BIO_set_shutdown(bio, 1);
266+	BIO_set_init(bio, 1);
267+#if OPENSSL_VERSION_NUMBER < 0x10100000L
268 	/* from bss_mem.c (openssl):
269 	 * bio->num is used to hold the value to return on 'empty', if it is
270 	 * 0, should_retry is not set
271@@ -93,6 +112,7 @@ static int create(BIO *bio)
272 	 * it is set to 0 since the underlying stream is blocking
273 	 */
274 	bio->num= 0;
275+#endif
276
277 	return 1;
278 }
279@@ -102,7 +122,7 @@ static int create(BIO *bio)
280 static long ctrl(BIO *bio, int cmd, long  num, void *)
281 {
282 	long ret;
283-	iostream *stream = reinterpret_cast<iostream*>(bio->ptr);
284+	iostream *stream = reinterpret_cast<iostream*>(BIO_get_data(bio));
285
286 	IBRCOMMON_LOGGER_DEBUG_TAG("iostreamBIO", 90) << "ctrl called, cmd: " << cmd << ", num: " << num << "." << IBRCOMMON_LOGGER_ENDL;
287
288@@ -147,8 +167,12 @@ static long ctrl(BIO *bio, int cmd, long  num, void *)
289
290 static int bread(BIO *bio, char *buf, int len)
291 {
292-	iostream *stream = reinterpret_cast<iostream*>(bio->ptr);
293+	iostream *stream = reinterpret_cast<iostream*>(BIO_get_data(bio));
294+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
295+	int num_bytes = 0;
296+#else
297 	int num_bytes = bio->num;
298+#endif
299
300 	try{
301 		/* make sure to read at least 1 byte and then read as much as we can */
302@@ -170,7 +194,7 @@ static int bwrite(BIO *bio, const char *buf, int len)
303 	if(len == 0){
304 		return 0;
305 	}
306-	iostream *stream = reinterpret_cast<iostream*>(bio->ptr);
307+	iostream *stream = reinterpret_cast<iostream*>(BIO_get_data(bio));
308
309 	/* write the data */
310 	try{
311diff --git a/ibrcommon/ssl/openssl_compat.h b/ibrcommon/ssl/openssl_compat.h
312new file mode 100644
313index 00000000..e491677f
314--- /dev/null
315+++ b/ibrcommon/ssl/openssl_compat.h
316@@ -0,0 +1,38 @@
317+#ifndef OPENSSL_COMPAT_H
318+#define OPENSSL_COMPAT_H
319+
320+#include <openssl/crypto.h>
321+#if OPENSSL_VERSION_NUMBER < 0x10100000L
322+
323+#include <openssl/evp.h>
324+#include <openssl/hmac.h>
325+
326+static inline EVP_MD_CTX * EVP_MD_CTX_new()
327+{
328+	EVP_MD_CTX *ctx;
329+
330+	ctx = (EVP_MD_CTX *) OPENSSL_malloc(sizeof(EVP_MD_CTX));
331+	EVP_MD_CTX_init(ctx);
332+        return ctx;
333+}
334+#define EVP_MD_CTX_free(c) if (c != NULL) OPENSSL_free(c)
335+
336+static inline HMAC_CTX * HMAC_CTX_new()
337+{
338+        HMAC_CTX *ctx;
339+
340+        ctx = (HMAC_CTX *) OPENSSL_malloc(sizeof(HMAC_CTX));
341+        HMAC_CTX_init(ctx);
342+        return ctx;
343+}
344+#define HMAC_CTX_free(c) if (c != NULL) OPENSSL_free(c)
345+
346+#define BIO_get_data(b) b->ptr
347+#define BIO_set_data(b, v) b->ptr=v
348+#define BIO_set_shutdown(b, v) b->shutdown=v
349+#define BIO_set_init(b, v) b->init=v
350+
351+#endif /* OPENSSL_VERSION_NUMBER */
352+
353+#endif /* OPENSSL_COMPAT_H */
354+
355--
3562.18.0
357
358