Replay HTTP traffic

Григорий Сморкалов g.smorkalov at crazypanda.ru
Mon May 17 13:41:57 UTC 2021


Hello. I am trying to debug some ssl related code and I need some help.

We have a HTTP client based on libuv and libopenssl for TLS. It is an
internal C++ library with its own TCP wrapper around lubuv and HTTP parser.
It works fine and our servers make millions of HTTPS requests to social
networks with it. If it is one connection per request (Connection: Close)
there is no problem at all. But sometimes connections with keep-alive
receive strange ssl errors:

error:04067084:rsa routines:rsa_ossl_public_decrypt:data too large for
modulus , or error:04067072:rsa routines:rsa_ossl_public_decrypt:padding
check failed

It is a really rare event, once per million I think. The error is returned
from SSL_read when new data comes from the server. It is never the first
response, usually there are more than ten requests/responses in the
connection before the error.

We have a tcpdump of such connections and keylog made with
SSL_CTX_set_keylog_callback. Wireshark opens this dump and decrypts it
normally using keylog as pre-master keyfile. The last packet produces an
error in our HTTP client but in wireshark it is ok and it contains normal
HTTP response with 200 OK. No sign of any error or data corruption. That
fact makes me think that data is ok and my openssl usage has some problems.

I want to reproduce this situation and replay this tcpdump. It means run
our server (actually only http client part) and give it captured data. It
is no problem to make a server that sends exactly the same data from tcp
dump. It is no problem to make exactly the same http request. But I need to
use the pre-master key from the keylog on the client side. I cannot find
any function that sets keys to SSL_CTX* or SSL*. Is there any?

I tried to build my own libopenssl with constant keys. I put
memcpy(s->session->master_key, overriden_secret, 48) in
ssl_generate_master_secret and tls13_generate_secret. Also
memcpy(s->s3->client_random, overriden_random, 32); in
tls_construct_client_hello and tls_early_post_process_client_hello. It
doesn't work and produces ssl error on handshake phase error:1416C095:SSL
routines:tls_process_finished:digest check failed. Client Hello produced by
this patched libopenssl is always different, this means I haven't replaced
all keys. It is something in s->tmp structure I cannot understand to
replace all usages and values.

Is there a simpler way?

Without reproducing it is practically impossible to find a bug. Even if it
does not reproduce, I'll get some information. Maybe it is UB in a
different place.

I've asked the same question on stackoverflow, so you can answer there if
it is easier or better for you:
https://stackoverflow.com/questions/67570255/how-to-replay-encrypted-traffic-with-libopenssl

Thank you!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mta.openssl.org/pipermail/openssl-users/attachments/20210517/d09456ca/attachment.html>


More information about the openssl-users mailing list