Page 1 of 1

How to verify the server when using openssl in esp32

Posted: Thu Jul 06, 2017 2:57 am
by tobewinner
I need to verify ther server when using openssl, however i found SSL_CTX_load_verify_locations not implemented.
is there any other way to verify the server when I have the root CA certificate?

In my case:the client(esp32) need to verify the server, and the server need to verify the client(esp32).
The client use SSL_CTX_use_certificate_ASN1 and SSL_CTX_use_PrivateKey_ASN1 to set its certificates info. but I can't find the funcs to verify the server's certificate.

Re: How to verify the server when using openssl in esp32

Posted: Thu Jul 06, 2017 12:25 pm
by tobewinner
OK, I rewrite my code with mbedtls, and duplex verification is reached.
Here is the code:

Code: Select all

const static char *TAG = "mbedtls_example";
char recv_buf[OPENSSL_EXAMPLE_RECV_BUF_LEN] = {0};
const char send_data[] = OPENSSL_EXAMPLE_REQUEST;
const int send_bytes = sizeof(send_data);

static int ssl_sig_hashes_for_test[] = {
    MBEDTLS_MD_SHA512,
    MBEDTLS_MD_SHA384,
    MBEDTLS_MD_SHA256,
    MBEDTLS_MD_SHA224,
    /* Allow SHA-1 as we use it extensively in tests. */
    MBEDTLS_MD_SHA1,
    MBEDTLS_MD_NONE
};

void mbedtls_example_task(void)
{
	int ret = -1;
	int recv_bytes = 0;

	mbedtls_net_context server_fd;
	mbedtls_entropy_context entropy;
	mbedtls_ctr_drbg_context ctr_drbg;
	mbedtls_ssl_context ssl;
	mbedtls_ssl_config conf;
	mbedtls_x509_crt cacert;
	mbedtls_x509_crt clicert;
	mbedtls_pk_context pkey;
    mbedtls_x509_crt_profile crt_profile_for_test = mbedtls_x509_crt_profile_default;

	ESP_LOGI(TAG, "MbedTls demo thread start OK");

	mbedtls_net_init( &server_fd );
	mbedtls_ssl_init( &ssl );
	mbedtls_ssl_config_init( &conf );
	mbedtls_x509_crt_init( &cacert );
	mbedtls_x509_crt_init( &clicert );
	mbedtls_pk_init( &pkey );
	mbedtls_ctr_drbg_init( &ctr_drbg );
	mbedtls_entropy_init( &entropy );

    mbedtls_esp_enable_debug_log(&conf, 0);

	ESP_LOGI(TAG, "mbedtls_ctr_drbg_seed ......");
	if((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0)) != 0) {
		ESP_LOGI(TAG, "Failed! ret=%d", ret);
		goto exit;
	}
	ESP_LOGI(TAG, "OK!");

	ESP_LOGI(TAG, "mbedtls_x509_crt_parse CaCrt ......");
	if((ret = mbedtls_x509_crt_parse(&cacert, (unsigned char *)CaCrt, sizeof(CaCrt))) != 0) {
		ESP_LOGI(TAG, "Failed! ret=%d", ret);
		goto exit;
	}
	ESP_LOGI(TAG, "OK!");

	mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL);
//	mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_NONE);
	mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_REQUIRED);

	ESP_LOGI(TAG, "mbedtls_x509_crt_parse LcCrt ......");
	if((ret = mbedtls_x509_crt_parse(&clicert, (unsigned char *)LcCrt, sizeof(LcCrt))) != 0) {
		ESP_LOGI(TAG, "Failed! ret=%d", ret);
		goto exit;
	}
	ESP_LOGI(TAG, "OK!");

	ESP_LOGI(TAG, "mbedtls_pk_parse_key ......");
	if((ret = mbedtls_pk_parse_key(&pkey, (const unsigned char *)LcKey, sizeof(LcKey), NULL, 0)) != 0) {
		ESP_LOGI(TAG, "Failed! ret=%d", ret);
		goto exit;
	}
	ESP_LOGI(TAG, "OK!");

	ESP_LOGI(TAG, "mbedtls_ssl_conf_own_cert ......");
	if((ret = mbedtls_ssl_conf_own_cert(&conf, &clicert, &pkey)) != 0) {
		ESP_LOGI(TAG, "Failed! ret=%d", ret);
		goto exit;
	}
	ESP_LOGI(TAG, "OK!");

	ESP_LOGI(TAG, "mbedtls_ssl_conf_min_version ......");
	mbedtls_ssl_conf_min_version(&conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3);
	ESP_LOGI(TAG, "mbedtls_ssl_conf_max_version ......");
	mbedtls_ssl_conf_max_version(&conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3);
	ESP_LOGI(TAG, "OK!");
//    mbedtls_ssl_conf_dbg &conf, my_debug, stdout );

	ESP_LOGI(TAG, "mbedtls_ssl_conf_rng ......");
	mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
	ESP_LOGI(TAG, "OK!");

	ESP_LOGI(TAG, "mbedtls_ssl_config_defaults ......");
	if((ret = mbedtls_ssl_config_defaults(&conf,
	                                      MBEDTLS_SSL_IS_CLIENT,
	                                      MBEDTLS_SSL_TRANSPORT_STREAM,
	                                      MBEDTLS_SSL_PRESET_DEFAULT)) != 0) {
		ESP_LOGI(TAG, "Failed! ret=%d", ret);
		goto exit;
	}
	ESP_LOGI(TAG, "OK!");

        crt_profile_for_test.allowed_mds |= MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA1 );
        crt_profile_for_test.rsa_min_bitlen = 1024;
        mbedtls_ssl_conf_cert_profile( &conf, &crt_profile_for_test );
        mbedtls_ssl_conf_sig_hashes( &conf, ssl_sig_hashes_for_test );

	ESP_LOGI(TAG, "mbedtls_net_connect ......");
	if((ret = mbedtls_net_connect(&server_fd, OPENSSL_EXAMPLE_TARGET_IP,
	                              OPENSSL_EXAMPLE_TARGET_TCP_PORT_S, MBEDTLS_NET_PROTO_TCP)) != 0) {
		ESP_LOGI(TAG, "Failed! ret=%d", ret);
		goto exit;
	}
	ESP_LOGI(TAG, "OK!");

	ESP_LOGI(TAG, "mbedtls_ssl_setup ......");
	if((ret = mbedtls_ssl_setup(&ssl, &conf)) != 0) {
		ESP_LOGI(TAG, "Failed! ret=%d", ret);
		goto exit;
	}
	ESP_LOGI(TAG, "OK!");

	ESP_LOGI(TAG, "mbedtls_ssl_set_bio ......");
	mbedtls_ssl_set_bio(&ssl, &server_fd, mbedtls_net_send, mbedtls_net_recv, mbedtls_net_recv_timeout);
	ESP_LOGI(TAG, "OK!");

	ESP_LOGI(TAG, "mbedtls_ssl_handshake ......");
	while ((ret = mbedtls_ssl_handshake( &ssl)) != 0) {
//		if (ret ==  MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) {
//			ESP_LOGI(TAG, "Failed! ret=-0x%x", -ret);
//			break;
//		}
		if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
			ESP_LOGI(TAG, "Failed! ret=-0x%x", -ret);
			goto exit;
		}
	}
	ESP_LOGI(TAG, "OK!");

	ret = mbedtls_ssl_get_record_expansion(&ssl);
	ESP_LOGI(TAG, "Protocol is %s, Ciphersuite is %s, Record expansion is %d.",
	         mbedtls_ssl_get_version(&ssl), mbedtls_ssl_get_ciphersuite(&ssl), ret);

	ESP_LOGI(TAG, "mbedtls_ssl_get_verify_result ......");
	if((ret = mbedtls_ssl_get_verify_result(&ssl)) != 0) {
		char vrfy_buf[512];

		mbedtls_x509_crt_verify_info(vrfy_buf, sizeof( vrfy_buf ), "  ! ", ret);
		ESP_LOGI(TAG, "Failed! ret=%d, verify_info=%s.", ret, vrfy_buf);
	}
	ESP_LOGI(TAG, "OK!");

	recv_bytes = send_bytes;
	do {
		if (recv_bytes >= send_bytes) {
			recv_bytes = 0;
			vTaskDelay(1000 / portTICK_PERIOD_MS);
			ESP_LOGI(TAG, "send data to %s port %d ......",
			         OPENSSL_EXAMPLE_TARGET_IP, OPENSSL_EXAMPLE_TARGET_TCP_PORT);
			ret = mbedtls_ssl_write(&ssl, (unsigned char *)send_data, send_bytes);
			if (ret != send_bytes) {
				ESP_LOGI(TAG, "failed:%d, %d.", ret, errno);
				goto exit;
			}
			ESP_LOGI(TAG, "OK");
		}
		ret = mbedtls_ssl_read(&ssl, (unsigned char *)recv_buf, OPENSSL_EXAMPLE_RECV_BUF_LEN - 1);
		if (ret <= 0) {
			ESP_LOGI(TAG, "SSL_read failed:%d, %d.", ret, errno);
			break;
		}
		recv_bytes += ret;
		ESP_LOGI(TAG, "Recv:%s,f=%u.", recv_buf, esp_get_free_heap_size());
	} while (1);
exit:

    mbedtls_net_free( &server_fd );

    mbedtls_x509_crt_free( &clicert );
    mbedtls_x509_crt_free( &cacert );
    mbedtls_pk_free( &pkey );

    mbedtls_ssl_free( &ssl );
    mbedtls_ssl_config_free( &conf );
    mbedtls_ctr_drbg_free( &ctr_drbg );
    mbedtls_entropy_free( &entropy );


	return ;
}