lsquic icon indicating copy to clipboard operation
lsquic copied to clipboard

check_ssl_ctx_x509_method failed on the android platform

Open recnac-itna opened this issue 4 years ago • 8 comments

I am working on porting lsquic to Android platform. I have cross-compiled lsquic and dependent libraries successfully by Android ndk. Now I can run lsquic test demo like echo_server and echo_client on my Android device.

But now I encounter a problem when echo_client connects to echo_server. Here are the steps:

  1. launch echo_server by adb shell on the android device ./echo_server -s 127.0.0.1:4433 -c www.example.com,ca.crt,ca.key -L debug

echo_server seems work well accrording the info log:

16:37:31.486 [DEBUG] tokgen: TOKGEN1 does not exist: generate 16:37:31.490 [INFO] tokgen: inserted TOKGEN1 of size 110 16:37:31.490 [DEBUG] tokgen: initialized 16:37:31.491 [INFO] prq: initialized queue of size 10000 16:37:31.491 [INFO] purga: create purgatory, min life 30000000 usec 16:37:31.491 [INFO] engine: instantiated engine 16:37:31.493 [INFO] socket buffer size: 229376 bytes; max # packets is set to 6 16:37:31.494 [DEBUG] local address: 127.0.0.1:4433 16:37:31.494 [DEBUG] entering event loop

  1. launch echo_client by another adb shell on the same android device: ./echo_client -s 127.0.0.1:4433

echo_server aborted caused by the following error:

... 16:38:27.876 [DEBUG] [QUIC:48D1324707EDE3C3] mini-conn: read 226 bytes at offset 226 on enc level 0 16:38:27.877 [DEBUG] [QUIC:48D1324707EDE3C3] handshake: cert lookup: server name is not set 16:38:27.877 [INFO] SNI is not set 16:38:27.877 [DEBUG] [QUIC:48D1324707EDE3C3] handshake: looked up cert for <no S NI> /root/lsquic-lib/boringssl/ssl/ssl_x509.cc:170: void bssl::check_ssl_ctx_x509_method(const SSL_CTX *): assertion "ctx == NULL || ctx->x509_method == &ssl_crypto_x509_method" failed Aborted

I have test it works in linux platform with the same steps.

I found check_ssl_ctx_x509_method is used by a serise of SSL_XXX methods. From the debug log, we can see this assertion passed successfully before echo_client connects, such as SSL_CTX_set_default_verify_paths in load_cert and prog_init_server. But when echo_client connects to echo_server, this assertion failed in echo_server.

I have located the error is in line 1060 of lsquic_enc_sess_ietf.c:

static int iquic_lookup_cert (SSL *ssl, void *arg)
{
...
 if (ssl_ctx)
    {
        if (SSL_set_SSL_CTX(enc_sess->esi_ssl, ssl_ctx))
        {
            LSQ_DEBUG("looked up cert for %s", server_name
                                                ? server_name : "<no SNI>");
            if (enc_sess->esi_enpub->enp_kli)
                SSL_CTX_set_keylog_callback(ssl_ctx, keylog_callback);
 --->   SSL_set_verify(enc_sess->esi_ssl,
                                    SSL_CTX_get_verify_mode(ssl_ctx), NULL);
            SSL_set_verify_depth(enc_sess->esi_ssl,
                                    SSL_CTX_get_verify_depth(ssl_ctx));
            SSL_clear_options(enc_sess->esi_ssl,
                                    SSL_get_options(enc_sess->esi_ssl));
            SSL_set_options(enc_sess->esi_ssl,
                            SSL_CTX_get_options(ssl_ctx) & ~SSL_OP_NO_TLSv1_3);
            return 1;
...

I cannot find more information about this assertion of the check_ssl_ctx_x509_method in boringssl. And I have no idea how to solve or skip this problem. Thanks for any help.

recnac-itna avatar Mar 23 '20 07:03 recnac-itna

The assertion inside BoringSSL is a likely indicator of a bug in BoringSSL itself. Normally, I would recommend using the latest BoringSSL, but its QUIC interface recently changed and we haven't added support for it yet.

One thing to try is to specify SNI using echo_client's -H command-line option. In your case, it would be -H www.example.com.

P.S. It is interesting that a Google library would assert on a Google platform. You could try submitting a bug report to BoringSSL.

dtikhonov avatar Mar 23 '20 12:03 dtikhonov

@dtikhonov Thanks for your suggestions.

I am still confused about why the assertion is OK when echo_server launched but only occurs when echo_client connects to echo_server on the Android platform.

static void check_ssl_x509_method(const SSL *ssl) {
  assert(ssl == NULL || ssl->ctx->x509_method == &ssl_crypto_x509_method);
}

I haven't dig into lsquic code deeply. Is there a possibility that we change the enc_sess->esi_ssl when a client is connected in?

recnac-itna avatar Mar 23 '20 12:03 recnac-itna

Without a client connection, there is no "encryption session" (enc_sess). There is one of these per connection. When echo_server starts, this code is not executed.

dtikhonov avatar Mar 23 '20 12:03 dtikhonov

I tried several ways to solve this problem. Now I resolved it by editting boringssl's source code and skip the verification. Everything works fine up to this point.

recnac-itna avatar Mar 25 '20 05:03 recnac-itna

OK. I am curious how your Android porting effort will turn out. Please keep us posted.

dtikhonov avatar Mar 25 '20 14:03 dtikhonov

@dtikhonov No problem. I'm glad to share the instructions to build and run lsquic on the Android platform. But in order to reach my goal as soon as possible, I cropped some modules and dependent libraries to skip the ndk-build problems, including some hardcode in CMakeList file. So currently it may not be a standard guideline. For sharing with others, I need some time to optimize the process.

recnac-itna avatar Mar 28 '20 03:03 recnac-itna

@dtikhonov I also want to use lsquic without libevent, can you give a simple example without libevent?

gongjiancheng123 avatar Jul 08 '20 01:07 gongjiancheng123

@recnac-itna Hello, I'm sorry to disturb you. I'd like to know the process of compiling Android. If you can, can you provide me with a reference document. In particular, I want to know which version of NDK you are using, and how to execute the command when you compile lsquic with cmakelists.txt. Thank you for your reply.

ghost avatar Jun 09 '21 12:06 ghost