Can Root CA be Selectively Applied to TLS Instance? (CYW943907AEVAL1F)

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
ChMa_3922746
Level 5
Level 5
10 likes received 10 likes given 5 likes given

I have a few TLS services running on the WICED device, such as:

  • HTTPS server
  • HTTPS client
  • TLS to support SMTP email

I would like to enable mutual authentication on the HTTPS server only.  When I call wiced_tls_init_root_ca_certificates(), then client authentication is enabled for all TLS activities -- something that is very undesirable as you can imagine.

I am using wiced_https_server_start() to start the HTTPS server.  However, there is no mechanism that I can find that would enable client authentication to be applied only to the server.  I see a function wiced_tls_set_context_root_ca_certificates() in wiced_tls.c that looks interesting, but it requires a wiced_tls_context_t

A connection between the high level start function and lower functions in ssl_tls.c appears to be missing to help me out.  I could use a TCP port number as a criteria in ssl_tls.c to enable/disable client authentication, but those functions only care about an mbedtls_ssl_context which lacks basic port numbers.

I wonder if anyone has tried something like this?

Thanks!

0 Likes
1 Solution

Thanks for that.  By the way, I found that jamming a new cert in the function wiced_generic_start_tls_with_ciphers() is a workaround.

I added a field to tls_context so that I can detect when client cert is required.  Then, I added the following after the #if that contains the line "if( opt_config.debug_level > 0 )" that is called when the field is set:

tls_context->context.client_auth = 1;

wiced_tls_set_context_root_ca_certificates(tls_context, rootCA_cert, strlen(rootCA_cert));

Not pretty, but seems to work at the moment.

View solution in original post

0 Likes
8 Replies
PriyaM_16
Moderator
Moderator
Moderator
250 replies posted 100 replies posted 50 replies posted

You can initialize a tls context by calling wiced_tls_init_context(). This API requires a tls identity. the tls identity is initialized using wiced_tls_init_identity() API.

You can than call wiced_tls_set_context_root_ca_certificates() for initializing the rootca for that particular context.

0 Likes

Thanks so much.  I did try that out.  I used:

  • wiced_tls_init_identity(&server_tls_identity, security_dct->private_key, strlen(security_dct->private_key), (uint8_t*) security_dct->certificate, strlen(security_dct->certificate));
  • wiced_tls_init_context(&server_tls_context, &server_tls_identity, "");
  • wiced_tls_set_context_root_ca_certificates(&server_tls_context, rootCA_cert, strlen(rootCA_cert));

They do return SUCCESS and TLS runs fine.  However, the rootCA certificate is never realized by the function mbedtls_ssl_write_certificate() in ssl_tls.c:

crt = mbedtls_ssl_own_cert( ssl ) always returns NULL.  (This means that mutual authentication is never done.)

I can't seem to find where the cert is being lost.  The biggest disconnect for me is how on earth the cert makes it into the mbedtls_ssl_context that mbedtls_ssl_write_certificate() uses.  Any help is appreciated!

0 Likes

Looks like there is another check for client authentication.

If the variable ssl->client_auth is set to 0, the client authentication is skipped.

I am trying to enable the client_auth to 1 but I am facing some issues.

The call stack (tested using https_client) is:

1.application_thread_main() at wiced_rtos.c

2.application_start() at httpbin_org.c

3.http_client_connect() at http_client.c

4.wiced_tcp_connect() at tcpip.c

5. wiced_tcp_start_tls() at wiced_tls.c

6. wiced_generic_start_tls_with_ciphers() at wiced_tls.c

7. mbedtls_ssl_handshake() at ssl_tls.c

8. mbedtls_ssl_handshake_step() at ssl_tls.c

9. mbedtls_ssl_handshake_client_step() at ssl_cli.c

10. mbedtls_ssl_write_certificate() at ssl_tls.c

0 Likes

Right.  That is the call stack I was chasing down, too.  I came across "client_auth" earlier but did not see it being set anywhere.

0 Likes

I found that the cert is being lost somewhere on its way to the function wiced_generic_start_tls_with_ciphers().  Therefore, the statement if (tls_context->root_ca_certificates != NULL) always returns NULL.

0 Likes

PriyaM_16 wrote:

Looks like there is another check for client authentication.

If the variable ssl->client_auth is set to 0, the client authentication is skipped.

I am trying to enable the client_auth to 1 but I am facing some issues.

Any fix for this issue?

0 Likes

The client_auth parameter is set based on the server request.

Please refer the ssl_parse_certificate_request() in ssl_cli.c file. The client_auth parameter is set as follows:

ssl->client_auth = ( ssl->in_msg[0] == MBEDTLS_SSL_HS_CERTIFICATE_REQUEST );

    MBEDTLS_SSL_DEBUG_MSG( 3, ( "got %s certificate request",

                        ssl->client_auth ? "a" : "no" ) );

Thanks for that.  By the way, I found that jamming a new cert in the function wiced_generic_start_tls_with_ciphers() is a workaround.

I added a field to tls_context so that I can detect when client cert is required.  Then, I added the following after the #if that contains the line "if( opt_config.debug_level > 0 )" that is called when the field is set:

tls_context->context.client_auth = 1;

wiced_tls_set_context_root_ca_certificates(tls_context, rootCA_cert, strlen(rootCA_cert));

Not pretty, but seems to work at the moment.

0 Likes