static int conn_link_mbedtls_initialize(void) { if (g_https_data.initialized) return 0; g_https_data.mbedtls = calloc(1, sizeof(*g_https_data.mbedtls)); if (!g_https_data.mbedtls) return -1; mbedtls_platform_set_calloc_free(conn_link_mbedtls_calloc, conn_link_mbedtls_free); mbedtls_ssl_config_init(&g_https_data.mbedtls->conf); mbedtls_ssl_session_init(&g_https_data.mbedtls->saved_session); mbedtls_entropy_init(&g_https_data.mbedtls->entropy); #ifdef CONFIG_MBEDTLS_ENABLE_CTR_DRBG mbedtls_ctr_drbg_init(&g_https_data.mbedtls->drbg); if (mbedtls_ctr_drbg_seed(&g_https_data.mbedtls->drbg, mbedtls_entropy_func, &g_https_data.mbedtls->entropy, (const void *)"sfx", 3) != 0) { goto err_free; } #else const mbedtls_md_info_t *md_info = NULL; #ifdef MBEDTLS_SHA1_C md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); #elif defined(MBEDTLS_SHA256_C) md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); #elif defined(MBEDTLS_SHA512_C) md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); #endif DEBUGASSERT(md_info != NULL); mbedtls_hmac_drbg_init(&g_https_data.mbedtls->drbg); if (mbedtls_hmac_drbg_seed(&g_https_data.mbedtls->drbg, md_info, mbedtls_entropy_func, &g_https_data.mbedtls->entropy, (const void *)"sfx", 3) != 0) { goto err_free; } #endif if (mbedtls_ssl_config_defaults(&g_https_data.mbedtls->conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT) != 0) { goto err_free; } #ifdef CONFIG_MBEDTLS_ENABLE_CTR_DRBG mbedtls_ssl_conf_rng(&g_https_data.mbedtls->conf, mbedtls_ctr_drbg_random, &g_https_data.mbedtls->drbg); #else mbedtls_ssl_conf_rng(&g_https_data.mbedtls->conf, mbedtls_hmac_drbg_random, &g_https_data.mbedtls->drbg); #endif mbedtls_ssl_conf_authmode(&g_https_data.mbedtls->conf, MBEDTLS_SSL_VERIFY_NONE); #ifdef CONFIG_MBEDTLS_MAX_FRAGMENT mbedtls_ssl_conf_max_frag_len(&g_https_data.mbedtls->conf, MBEDTLS_SSL_MAX_FRAG_LEN_512); #endif #ifdef CONFIG_MBEDTLS_TRUNCATED_HMAC mbedtls_ssl_conf_truncated_hmac(&g_https_data.mbedtls->conf, MBEDTLS_SSL_TRUNC_HMAC_ENABLED); #endif #ifdef CONFIG_MBEDTLS_SESSION_TICKET /* Use SSL out-fragment buffer of at least 384 bytes with session tickets, * preferably at least 512 bytes. */ mbedtls_ssl_conf_session_tickets(&g_https_data.mbedtls->conf, MBEDTLS_SSL_SESSION_TICKETS_ENABLED); #endif g_https_data.initialized = true; return 0; err_free: #ifdef CONFIG_MBEDTLS_ENABLE_CTR_DRBG mbedtls_ctr_drbg_free(&g_https_data.mbedtls->drbg); #else mbedtls_hmac_drbg_free(&g_https_data.mbedtls->drbg); #endif mbedtls_ssl_session_free(&g_https_data.mbedtls->saved_session); mbedtls_ssl_config_free(&g_https_data.mbedtls->conf); free(g_https_data.mbedtls); g_https_data.mbedtls = NULL; mbedtls_platform_set_calloc_free(calloc, free); g_https_data.initialized = false; return -1; }
int main(void) { struct addrinfo hints; struct addrinfo *ai; struct sockaddr_in server; int sock; int res; char server_name[] = "www.eff.org"; char http_get[200] = "GET /index.html HTTP/1.1\r\n" "Host: www.eff.org\r\n" "\r\n"; char http_get_resp[200]; int cipher_list[] = { MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA, 0}; mbedtls_ssl_context ssl; mbedtls_ssl_config conf; mbedtls_x509_crt cacert; printf("Press any key to continue..."); getchar(); printf("\n"); mbedtls_ssl_init( &ssl ); mbedtls_ssl_config_init( &conf ); mbedtls_x509_crt_init( &cacert ); res = mbedtls_ssl_config_defaults( &conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT); if( res != 0 ) { mbedtls_printerr(res, "mbedtls_ssl_config_defaults"); return 1; } #if 0 mbedtls_ssl_conf_authmode( &conf, MBEDTLS_SSL_VERIFY_NONE); #endif mbedtls_ssl_conf_ciphersuites( &conf, cipher_list); #if 0 res = mbedtls_ssl_conf_max_frag_len( &conf, MBEDTLS_SSL_MAX_FRAG_LEN_512); if( res != 0 ) { mbedtls_printerr(res, "mbedtls_ssl_conf_max_frag_len"); return 1; } #endif mbedtls_ssl_conf_rng(&conf, wrap_rng, NULL); res = mbedtls_ssl_setup( &ssl, &conf); if( res != 0 ) { mbedtls_printerr(res, "mbedtls_ssl_setup"); return 1; } res = mbedtls_x509_crt_parse(&cacert, digicert_der, digicert_der_len); if( res != 0 ) { mbedtls_printerr(res, "mbedtls_x509_crt_parse"); return 1; } mbedtls_ssl_conf_ca_chain( &conf, &cacert, NULL ); res = mbedtls_ssl_set_hostname( &ssl, server_name); if( res != 0 ) { mbedtls_printerr(res, "mbedtls_ssl_set_hostname"); return 1; } hints.ai_flags = 0; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = 0; res = getaddrinfo(server_name, NULL, &hints, &ai); if (res != 0) { if (res == EAI_SYSTEM) { perror("getaddrinfo"); } else { fprintf(stderr, "error: getaddrinfo: %d\n", res); } return 1; } if (ai == NULL) { fprintf(stderr, "error: getaddrinfo : output is NULL\n"); return 1; } sock = socket(AF_INET , SOCK_STREAM , 0); if (sock == -1) { perror("socket creation failed"); return 1; } #if 1 server = *((const struct sockaddr_in *)ai->ai_addr); server.sin_port = htons( 443 ); /* HTTPS */ #else /* * nslookup www.eff.org -> 69.50.225.155 * socat TCP-LISTEN:44333 TCP:69.50.225.155:443 */ server.sin_family = AF_INET; server.sin_port = htons(44333); server.sin_addr.s_addr = inet_addr("192.168.1.173"); /* my PC */ #endif freeaddrinfo(ai); if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0) { perror("connect failed"); close(sock); return 1; } /* TLS connect */ mbedtls_ssl_set_bio( &ssl, &sock, wrap_send, wrap_recv, NULL); res = mbedtls_ssl_handshake( &ssl ); do { const mbedtls_x509_crt *peer_cert; peer_cert = mbedtls_ssl_get_peer_cert(&ssl); if (peer_cert == NULL) { fprintf(stderr, "no peer cert.\n"); } else { int n; char info_str[200]; n = mbedtls_x509_crt_info(info_str, sizeof(info_str), "", peer_cert); fputs("Certificate:\n", stderr); fputs(info_str, stderr); fputs("\n", stderr); } } while(0); if (res != 0) { mbedtls_printerr(res, "mbedtls_ssl_handshake"); close(sock); return 1; } res = mbedtls_ssl_write(&ssl, (unsigned char *)http_get, strlen(http_get)); if (res <= 0) { mbedtls_printerr(res, "mbedtls_ssl_write"); close(sock); return 1; } do { res = mbedtls_ssl_read(&ssl, (unsigned char *)http_get_resp, sizeof(http_get_resp)); if (res <= 0) { mbedtls_printerr(res, "mbedtls_ssl_read"); close(sock); return 1; } fwrite(http_get_resp, res, 1, stdout); } while(res == sizeof(http_get_resp)); //TODO: cleaner /* TLS disconnect */ mbedtls_ssl_free(&ssl); mbedtls_ssl_config_free(&conf); close(sock); return 0; }