XMPP Libstrophe Cert Validation Issues

We’ve been integrating Unreal’s XMPP systems into our project. While things work when certificate validation is disabled, enabling cert validation causes failures. This is a blocker, as cert validation will be required for our production launch.

We’ve confirmed that our XMPP server presents a valid certificate when tested with other XMPP clients, such as Profanity.

A [previous UDN [Content removed] by another engineer on our team describes the initial issue during our first pass at XMPP integration.

Since then, I’ve been digging into this issue further. When enabling TLS cert validation, we see the following errors in the logs:

VeryVerbose LogXmpp libstrophe[38660] xmpp debug: proceeding with TLS

VeryVerbose LogXmpp libstrophe[38660] tls debug: Certificate verification FAILED

VeryVerbose LogXmpp libstrophe[38660] tls debug: Certificate was not presented by peer

VeryVerbose LogXmpp libstrophe[38660] tls debug: error=1 errno=2

Unreal’s XMPP system uses the third party libstrophe under the hood. Specifically, a forked/modified version of libstrophe 0.9.3.

To investigate further, I began modifying the 0.9.3 libstrophe code and recompiling the lib files. Eventually I confirmed the core issue with a code change in the tls_openssl.c file to explicitly load certs from the Windows cert store (see attached tls_openssl_modification.c file).

This confirmed that the version of OpenSSL that libstrophe uses doesn’t automatically have access to the Windows cert store and whatever built-in/default it’s using won’t work with our XMPP cert. With the code change I made, we load the certs from the Windows cert store. I confirmed that with this change XMPP/libstrophe are working properly with cert validation enabled.

Ideally, though, we’d prefer to explicitly configure libstrophe to use the CA file already packaged with the game. This would make the solution portable across all our supported platforms.

I initially hoped upgrading Unreal’s libstrophe version to the official 0.11.0 libstrophe (which supports xmpp_conn_set_cafile) would be straightforward. However, we discovered that Unreal’s fork of 0.9.3 includes significant customizations (including WebSocket support) that aren’t present in the official libstrophe code.

Given that, it seems like our most straightforward path is to port the certificate authority code from libstrophe 0.11.0 into Unreal’s 0.9.3 libstrophe fork.

Before proceeding, I wanted to confirm that my understanding of the issue is accurate. Are there any alternative solutions I might be overlooking?

Hi Seph,

Sorry for the long waiting due to the summer vacation. I’m not aware of similiar issue related to this before. We used it in our game without setting specific flag. I checked our code in the cert manager: FWindowsPlatformSslCertificateManager::BuildRootCertificateArray function in WindowsPlatformSslCertificateManager.cpp, which seems to be the same as your modification. Can you confirm your game client went through that flow? Xmpp depends on WebSockets project, while WebSockets uses that SSL module which is shared between Http and Websockets, so it’s heavily used in our online ecosystem.

I didn’t find where do you make the changes in that file tls_open_modification.c. It’s the file under Engine\Source\ThirdParty\libstrophe\libstrophe-0.9.3\src right? Where did you put that code in that file?

Thank you,

Lorry

Hi Lorry,

The debug change in tls_openssl_modification.c file was applied to the tls_openssl.c file within the \Engine\Source\ThirdParty\libstrophe\libstrophe-0.9.3\src\ folder. It was added above line 117 (tls->ssl = SSL_new(tls->ssl_ctx);):

https://github.com/EpicGames/UnrealEngine/blob/release/Engine/Source/ThirdParty/libstrophe/libstrophe-0.9.3/src/tls_openssl.c#L117

From your comment, it sounds Unreal/Epic’s interactions with XMPP are typically done through websockets rather than through raw TCP.

I believe all the libstrophe 0.9.3 code related to websockets was done/forked directly by Epic.

You can see this if you compare the conn.c file in the official libstrophe 0.9.3 code:

https://github.com/strophe/libstrophe/blob/0.9.3/src/conn.c

Compared to Epic/Unreal’s fork of that file:

https://github.com/EpicGames/UnrealEngine/blob/release/Engine/Source/ThirdParty/libstrophe/libstrophe-0.9.3/src/conn.c

All of the xmpp_extsock_xxx functions don’t exist in the official libstrophe codebase (only in Epic’s fork)

SSL seems to be handled at the websocket layer (rather than in libstrophe in the tls_openssl.c file) when using Unreal XMPP through a websockets endpoint.

We were planning to interact with an XMPP server through raw TCP which is why we were running into this issue. I enabled a websockets endpoint on the same XMPP server (with the same cert) and it works without hitting the cert validation error. I think we’ll be able to move forward here only using websockets, but it would be nice to have the raw TCP option.

Thanks!

Seph

Hi Seph,

Thank you for the info.

I created an internal ticket to track and add that support, it will be low priority though. I assume this is not a blocker for you since you can use websockets. I’ll mark this ticket as closed.

Please let me know if the situation changes.

Best Regards,

Lorry