Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add OpenSSL 1.1 compatibility #83

Merged
merged 7 commits into from Mar 5, 2018
Merged

Conversation

gjasny
Copy link
Contributor

@gjasny gjasny commented Jul 13, 2017

Hello,

I tried to migrate reSIProcate to the OpenSSL 1.1 API. Those changes have been compile tested with OpenSSL 1.0.2 and OpenSSL 1.1.0.

Unfortunately my (D)TLS and OpenSSL knowledge is quite small. So I consider this PR just a discussion and review starter instead of a polished PR.

Thanks,
Gregor


len = SSL_read( ssl, pt, UdpTransport::MaxBufferSize ) ;
int err = SSL_get_error( ssl, len ) ;

/* done with the rbio */
BIO_free( ssl->rbio ) ;
ssl->rbio = mDummyBio ;
SSL_set0_rbio( ssl, mDummyBio );
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if this could lead to errors. Formerly BIO_free was used. Now BIO_free_all is used instead. IMHO the difference is that the later is freeing recursively. But our rbio seems to be not stacked, so the difference might not matter at all.

@gjasny
Copy link
Contributor Author

gjasny commented Aug 18, 2017

@gjasny
Copy link
Contributor Author

gjasny commented Aug 20, 2017

Hey @FauxFaux, I merged my patch (which preserves OpenSSL 1.0 compatibility) with yours. Could you please give it a review?

Differences from your patch to this PR are: https://gist.github.com/gjasny/04463e481d9b14e81c08d0fa3b9071af

@gjasny gjasny force-pushed the openssl-1.1 branch 3 times, most recently from e88b3b5 to c971c02 Compare August 20, 2017 18:13
@@ -181,7 +181,7 @@ class BaseSecurity
// retrieves a list of all certificate names (subjectAltNAme's and CommonName)
static void getCertNames(X509 *cert, std::list<PeerName> &peerNames, bool useEmailAsSIP = false);

static bool isSelfSigned(const X509* cert);
static bool isSelfSigned(X509* cert);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not be needed. The operation is not supposed to modify the certificate and both X509_get_issuer_name and X509_get_subject_name accept const X509*.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In OpenSSL 1.0.2 the property accessors just take a non-const X509 pointer.
See x509.h

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then, I believe, isSelfSigned should perform the const_cast internally or use the old code for OpenSSL 1.0.x. There is no reason to change the public interface of isSelfSigned.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

@@ -43,19 +58,28 @@ typedef struct BIO_F_DWRAP_CTX_

BIO_METHOD *BIO_f_dwrap(void)
{
return(&methods_dwrap);
BIO_METHOD *meth = BIO_meth_new(BIO_TYPE_DWRAP, "dtls_wrapper");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe, this memory leaks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will try to create an unit test and check for memory leaks.

@Lastique
Copy link
Contributor

Lastique commented Oct 3, 2017

Also, I believe, dwrap_free in reflow/dtls_wrapper/bf_dwrap.c needs to be updated. It should free the BIO_F_DWRAP_CTX structure allocated in dwrap_new, not the BIO object itself.

@Lastique
Copy link
Contributor

Lastique commented Oct 4, 2017

In rutil/ssl/OpenSSLInit.cxx, OpenSSLInit::~OpenSSLInit(), the call sk_SSL_COMP_free( SSL_COMP_get_compression_methods()) causes a crash with OpenSSL 1.1.0 because libssl does free the compression methods itself when being unloaded. This line is viable for OpenSSL until 1.0.2, which introduced SSL_COMP_free_compression_methods for this purpose. In OpenSSL 1.1.0 this call is not needed and should be removed.

@gjasny
Copy link
Contributor Author

gjasny commented Oct 24, 2017

@Lastique I think I addressed all of your comments. The dtls_wrapper tests no exit without leaked memory. (For enabling and fixing those tests see future PR).

The sk_SSL_COMP_free code seems to be commented out.

BIO_METHOD *BIO_f_dwrap(void)
{
if (!dtls_meth) {
dtls_meth = BIO_meth_new(BIO_TYPE_DWRAP, "dtls_wrapper");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not thread-safe. Not sure if there are cases when this code can run in different threads, though. I would recommend using pthread_once or atomics instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right but this codebase is still C++03. How about using a static auto_ptr holding the BIO_method? That would also enable me to get rid of the atexit hack.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A simpler solution is to convert dtls_meth to an object with a constructor and destructor and move the BIO_METHOD initialization to the constructor. This would still be not thread-safe, but in practical sense this would be better because the constructor will be run at library load time, when there are typically no multiple threads.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OTOH who knows if calling into OpenSSL works before initalization ...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about using a static auto_ptr holding the BIO_method?

This won't help. The race is between loading the pointer for testing against NULL and storing the allocated pointer. auto_ptr doesn't help with it.

Re atomics, I was meaning compiler-specific intrinsics. One would likely have to introduce some abstraction layer for portability. pthread_once is available for C++03 programs but not on Windows. I would probably use Interlocked* intrinsics on Windows and pthread_once everywhere else.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will work on something like this. But I have to finish some unrelated work first.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OTOH who knows if calling into OpenSSL works before initalization

I would assume it should work for the methods we need - those are just memory allocation and accessors, no apparent reason for them to not work.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Lastique I changed the code as you suggested. Could you pleas give it another review?

Thanks a lot for your time!

gjasny and others added 3 commits October 31, 2017 17:34
Copy link

@easassone easassone left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have compiled these changes with OpenSSL 1.1.0f successfully. Testing with TLS in our application using reSIProcate was successful also. thanks!

@gjasny
Copy link
Contributor Author

gjasny commented Mar 3, 2018

@sgodin Are you ok with merging this?

@sgodin
Copy link
Member

sgodin commented Mar 5, 2018 via email

@sgodin sgodin merged commit 190afbb into resiprocate:master Mar 5, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants