Beispiel #1
0
/*
 * Checkup routine
 */
int mbedtls_ctr_drbg_self_test( int verbose )
{
    mbedtls_ctr_drbg_context ctx;
    unsigned char buf[16];

    mbedtls_ctr_drbg_init( &ctx );

    /*
     * Based on a NIST CTR_DRBG test vector (PR = True)
     */
    if( verbose != 0 )
        mbedtls_printf( "  CTR_DRBG (PR = TRUE) : " );

    test_offset = 0;
    CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
                                (void *) entropy_source_pr, nonce_pers_pr, 16, 32 ) );
    mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
    CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
    CHK( mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
    CHK( memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );

    mbedtls_ctr_drbg_free( &ctx );

    if( verbose != 0 )
        mbedtls_printf( "passed\n" );

    /*
     * Based on a NIST CTR_DRBG test vector (PR = FALSE)
     */
    if( verbose != 0 )
        mbedtls_printf( "  CTR_DRBG (PR = FALSE): " );

    mbedtls_ctr_drbg_init( &ctx );

    test_offset = 0;
    CHK( mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy,
                            (void *) entropy_source_nopr, nonce_pers_nopr, 16, 32 ) );
    CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
    CHK( mbedtls_ctr_drbg_reseed( &ctx, NULL, 0 ) );
    CHK( mbedtls_ctr_drbg_random( &ctx, buf, 16 ) );
    CHK( memcmp( buf, result_nopr, 16 ) );

    mbedtls_ctr_drbg_free( &ctx );

    if( verbose != 0 )
        mbedtls_printf( "passed\n" );

    if( verbose != 0 )
            mbedtls_printf( "\n" );

    return( 0 );
}
Beispiel #2
0
/*
 * Initialise the given ctr_drbg context, using a personalisation string and an
 * entropy gathering function.
 */
mbedtls_ctr_drbg_context *
rand_ctx_get()
{
    static mbedtls_entropy_context ec = {0};
    static mbedtls_ctr_drbg_context cd_ctx = {0};
    static bool rand_initialised = false;

    if (!rand_initialised)
    {
        struct gc_arena gc = gc_new();
        struct buffer pers_string = alloc_buf_gc(100, &gc);

        /*
         * Personalisation string, should be as unique as possible (see NIST
         * 800-90 section 8.7.1). We have very little information at this stage.
         * Include Program Name, memory address of the context and PID.
         */
        buf_printf(&pers_string, "OpenVPN %0u %p %s", platform_getpid(), &cd_ctx, time_string(0, 0, 0, &gc));

        /* Initialise mbed TLS RNG, and built-in entropy sources */
        mbedtls_entropy_init(&ec);

        mbedtls_ctr_drbg_init(&cd_ctx);
        if (!mbed_ok(mbedtls_ctr_drbg_seed(&cd_ctx, mbedtls_entropy_func, &ec,
                                           BPTR(&pers_string), BLEN(&pers_string))))
        {
            msg(M_FATAL, "Failed to initialize random generator");
        }

        gc_free(&gc);
        rand_initialised = true;
    }

    return &cd_ctx;
}
int ssh_crypto_init(void)
{
    size_t i;
    int rc;

    if (libmbedcrypto_initialized) {
        return SSH_OK;
    }

    mbedtls_entropy_init(&ssh_mbedtls_entropy);
    mbedtls_ctr_drbg_init(&ssh_mbedtls_ctr_drbg);

    rc = mbedtls_ctr_drbg_seed(&ssh_mbedtls_ctr_drbg, mbedtls_entropy_func,
            &ssh_mbedtls_entropy, NULL, 0);
    if (rc != 0) {
        mbedtls_ctr_drbg_free(&ssh_mbedtls_ctr_drbg);
    }

    for (i = 0; ssh_ciphertab[i].name != NULL; i++) {
        int cmp;

        cmp = strcmp(ssh_ciphertab[i].name, "*****@*****.**");
        if (cmp == 0) {
            memcpy(&ssh_ciphertab[i],
                   ssh_get_chacha20poly1305_cipher(),
                   sizeof(struct ssh_cipher_struct));
            break;
        }
    }

    libmbedcrypto_initialized = 1;

    return SSH_OK;
}
static int coap_security_handler_init(coap_security_t *sec){
    const char *pers = "dtls_client";
    mbedtls_ssl_init( &sec->_ssl );
    mbedtls_ssl_config_init( &sec->_conf );
    mbedtls_ctr_drbg_init( &sec->_ctr_drbg );
    mbedtls_entropy_init( &sec->_entropy );

#if defined(MBEDTLS_X509_CRT_PARSE_C)
    mbedtls_x509_crt_init( &sec->_cacert );
    mbedtls_x509_crt_init( &sec->_owncert );
#endif
    mbedtls_pk_init( &sec->_pkey );

    memset(&sec->_cookie, 0, sizeof(simple_cookie_t));
    memset(&sec->_keyblk, 0, sizeof(key_block_t));

    sec->_is_started = false;

    //TODO: Must have at least 1 strong entropy source, otherwise DTLS will fail.
    //This is NOT strong even we say it is!
    if( mbedtls_entropy_add_source( &sec->_entropy, entropy_poll, NULL,
                                128, 1 ) < 0 ){
        return -1;
    }

    if( ( mbedtls_ctr_drbg_seed( &sec->_ctr_drbg, mbedtls_entropy_func, &sec->_entropy,
                               (const unsigned char *) pers,
                               strlen( pers ) ) ) != 0 )
    {
        return -1;
    }
    return 0;
}
Beispiel #5
0
struct flb_tls_context *flb_tls_context_new()
{
    int ret;
    struct flb_tls_context *ctx;

    ctx = malloc(sizeof(struct flb_tls_context));
    if (!ctx) {
        perror("malloc");
        return NULL;
    }

    mbedtls_entropy_init(&ctx->entropy);
    mbedtls_ctr_drbg_init(&ctx->ctr_drbg);

    ret = mbedtls_ctr_drbg_seed(&ctx->ctr_drbg,
                                mbedtls_entropy_func,
                                &ctx->entropy,
                                (const unsigned char *) FLB_TLS_CLIENT,
                                sizeof(FLB_TLS_CLIENT) -1);
    if (ret == -1) {
        io_tls_error(ret);
        goto error;
    }

    return ctx;

 error:
    free(ctx);
    return NULL;
}
int iot_tls_init(Network *pNetwork) {
	IoT_Error_t ret_val = NONE_ERROR;
	const char *pers = "aws_iot_tls_wrapper";
	unsigned char buf[MBEDTLS_SSL_MAX_CONTENT_LEN + 1];

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

	DEBUG("\n  . Seeding the random number generator...");
	mbedtls_entropy_init(&entropy);
	if ((ret_val = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const unsigned char *) pers,
			strlen(pers))) != 0) {
		ERROR(" failed\n  ! mbedtls_ctr_drbg_seed returned -0x%x\n", -ret);
		return ret;
	} DEBUG("ok\n");

	pNetwork->my_socket = 0;
	pNetwork->connect = iot_tls_connect;
	pNetwork->mqttread = iot_tls_read;
	pNetwork->mqttwrite = iot_tls_write;
	pNetwork->disconnect = iot_tls_disconnect;
	pNetwork->isConnected = iot_tls_is_connected;
	pNetwork->destroy = iot_tls_destroy;

	return ret_val;
}
Beispiel #7
0
/* Initialize TLS library
 */
int init_tls_module(mbedtls_x509_crt *ca_certificates) {
	char version[16];

	if (mbedtls_version_get_number() < 0x02000000) {
		mbedtls_version_get_string(version);
		fprintf(stderr, "This Hiawatha installation requires at least mbed TLS v2.0.0 and you have v%s.", version);
		return -1;
	}

	if (mbedtls_version_check_feature("MBEDTLS_THREADING_PTHREAD") != 0) {
		fprintf(stderr, "mbed TLS was compiled without the required MBEDTLS_THREADING_PTHREAD compiler flag.\n");
		return -1;
	}

#ifdef ENABLE_DEBUG
	mbedtls_debug_set_threshold(TLS_DEBUG_LEVEL);
#endif

	/* Entropy settings
	 */
	mbedtls_entropy_init(&entropy);
	mbedtls_ctr_drbg_init(&ctr_drbg);
	if (mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (unsigned char*)"Hiawatha_RND", 10) != 0) {
		return -1;
	}
	mbedtls_ctr_drbg_set_prediction_resistance(&ctr_drbg, MBEDTLS_CTR_DRBG_PR_OFF);

	/* Cache settings
	 */
	mbedtls_ssl_cache_init(&cache);
	mbedtls_ssl_cache_set_max_entries(&cache, 100);

	/* Client SSL configuratiomn
	 */
	mbedtls_ssl_config_init(&client_config);
	if (mbedtls_ssl_config_defaults(&client_config, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT) != 0) {
		return -1;
	}
	mbedtls_ssl_conf_min_version(&client_config, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_1);
	mbedtls_ssl_conf_renegotiation(&client_config, MBEDTLS_SSL_RENEGOTIATION_DISABLED);
	mbedtls_ssl_conf_rng(&client_config, tls_random, &ctr_drbg);
#ifdef ENABLE_DEBUG
	mbedtls_ssl_conf_dbg(&client_config, tls_debug, &client_config);
#endif

	if (ca_certificates == NULL) {
		mbedtls_ssl_conf_authmode(&client_config, MBEDTLS_SSL_VERIFY_NONE);
	} else {
		mbedtls_ssl_conf_authmode(&client_config, MBEDTLS_SSL_VERIFY_REQUIRED);
		mbedtls_ssl_conf_ca_chain(&client_config, ca_certificates, NULL);
	}

	if (pthread_mutex_init(&random_mutex, NULL) != 0) {
		return -1;
	} else if (pthread_mutex_init(&cache_mutex, NULL) != 0) {
		return -1;
	}

	return 0;
}
Beispiel #8
0
void* ssl_socket_init(int fd, const char *domain)
{
   struct ssl_state *state = (struct ssl_state*)calloc(1, sizeof(*state));

   state->domain = domain;

   mbedtls_debug_set_threshold(DEBUG_LEVEL);

   mbedtls_net_init(&state->net_ctx);
   mbedtls_ssl_init(&state->ctx);
   mbedtls_ssl_config_init(&state->conf);
#if defined(MBEDTLS_X509_CRT_PARSE_C)
   mbedtls_x509_crt_init(&state->ca);
#endif
   mbedtls_ctr_drbg_init(&state->ctr_drbg);
   mbedtls_entropy_init(&state->entropy);

   state->net_ctx.fd = fd;

   if (mbedtls_ctr_drbg_seed(&state->ctr_drbg, mbedtls_entropy_func, &state->entropy, (const unsigned char*)pers, strlen(pers)) != 0)
      goto error;

#if defined(MBEDTLS_X509_CRT_PARSE_C)
   if (mbedtls_x509_crt_parse(&state->ca, (const unsigned char*)cacert_pem, sizeof(cacert_pem) / sizeof(cacert_pem[0])) < 0)
      goto error;
#endif

   return state;

error:
   if (state)
      free(state);
   return NULL;
}
static void mbedtls_msg_server_step(pmbedtls_msg msg)
{
	lwIP_ASSERT(msg);

	/*to prevent memory leaks, ensure that each allocated is deleted at every handshake*/
	if (msg->psession){
		mbedtls_session_free(&msg->psession);
	}
#if defined(ESP8266_PLATFORM)
    if (msg->quiet && msg->ssl.out_buf)
    {
        mbedtls_zeroize(msg->ssl.out_buf, MBEDTLS_SSL_OUTBUFFER_LEN);
        os_free(msg->ssl.out_buf);
        msg->ssl.out_buf = NULL;
    }
#endif
	mbedtls_entropy_free(&msg->entropy);
	mbedtls_ssl_free(&msg->ssl);
	mbedtls_ssl_config_free(&msg->conf);
	mbedtls_ctr_drbg_free(&msg->ctr_drbg);

	/*New connection ensure that each initial for next handshake */
	os_bzero(msg, sizeof(mbedtls_msg));
	msg->psession = mbedtls_session_new();
	if (msg->psession){
		mbedtls_net_init(&msg->fd);
		mbedtls_ssl_init(&msg->ssl);
		mbedtls_ssl_config_init(&msg->conf);
		mbedtls_ctr_drbg_init(&msg->ctr_drbg);
		mbedtls_entropy_init(&msg->entropy);
	}	
}
dtls_session_t *_DTLSSession_init()
{
    dtls_session_t *p_dtls_session = NULL;
    p_dtls_session = coap_malloc(sizeof(dtls_session_t));

    mbedtls_debug_set_threshold(0);
    mbedtls_platform_set_calloc_free(_DTLSCalloc_wrapper, _DTLSFree_wrapper);
    if (NULL != p_dtls_session) {
        mbedtls_net_init(&p_dtls_session->fd);
        mbedtls_ssl_init(&p_dtls_session->context);
        mbedtls_ssl_config_init(&p_dtls_session->conf);
        mbedtls_net_init(&p_dtls_session->fd);

        mbedtls_ssl_cookie_init(&p_dtls_session->cookie_ctx);

#ifdef MBEDTLS_X509_CRT_PARSE_C
        mbedtls_x509_crt_init(&p_dtls_session->cacert);
#endif
        mbedtls_ctr_drbg_init(&p_dtls_session->ctr_drbg);
        mbedtls_entropy_init(&p_dtls_session->entropy);
        DTLS_INFO("HAL_DTLSSession_init success\r\n");

    }

    return p_dtls_session;
}
Beispiel #11
0
// コンテキストを初期化します。
// mtls_alloc() に続いてコールしてください。
// 成功すれば 0、失敗すれば -1 を返します。
int
mtls_init(mtlsctx_t* ctx)
{
	int r;

	TRACE("start\n");

	// グローバルコンテキストの初期化
	if (gctx.initialized == 0) {
		mbedtls_ctr_drbg_init(&gctx.ctr_drbg);
		mbedtls_entropy_init(&gctx.entropy);
		// init RNG
		r = mbedtls_ctr_drbg_seed(&gctx.ctr_drbg, mbedtls_entropy_func,
			&gctx.entropy, "a", 1);
		if (r != 0) {
			ERROR("mbedtls_ctr_drbg_seed failed: %s\n", mtls_errmsg(r));
			goto errexit;
		}
		gctx.initialized = 1;
	}

	ctx->usessl = 0;
	mbedtls_net_init(&ctx->net);
	mbedtls_ssl_init(&ctx->ssl);
	mbedtls_ssl_config_init(&ctx->conf);

	// TLS config
	r = mbedtls_ssl_config_defaults(&ctx->conf,
			MBEDTLS_SSL_IS_CLIENT,
			MBEDTLS_SSL_TRANSPORT_STREAM,
			MBEDTLS_SSL_PRESET_DEFAULT);
	if (r != 0) {
		ERROR("mbedtls_ssl_config_defaults failed: %s\n", mtls_errmsg(r));
		goto errexit;
	}

	mbedtls_ssl_conf_authmode(&ctx->conf, MBEDTLS_SSL_VERIFY_NONE);
	mbedtls_ssl_conf_rng(&ctx->conf, mbedtls_ctr_drbg_random, &gctx.ctr_drbg);
	mbedtls_ssl_conf_dbg(&ctx->conf, debug_callback, stderr);

	r = mbedtls_ssl_setup(&ctx->ssl, &ctx->conf);
	if (r != 0) {
		ERROR("mbedtls_ssl_setup failed: %s\n", mtls_errmsg(r));
		goto errexit;
	}

	mbedtls_ssl_set_bio(&ctx->ssl, &ctx->net, mbedtls_net_send, mbedtls_net_recv, NULL);

	ctx->initialized = 1;
	TRACE("done\n");
	return 0;

 errexit:
	// cleanup
	TRACE("NG\n");
	return -1;
}
Beispiel #12
0
static void tls_server_init(struct server *s)
{
	mbedtls_net_init(&s->fd);
	mbedtls_entropy_init(&s->entropy);
	mbedtls_ctr_drbg_init(&s->ctr_drbg);
	mbedtls_ssl_config_init(&s->conf);
	mbedtls_x509_crt_init(&s->cacert);
	mbedtls_x509_crt_init(&s->srvcert);
	mbedtls_pk_init(&s->pkey);
}
Beispiel #13
0
static void ssl_init( SSLExt* ext )
{
    mbedtls_net_init( &ext->nc );
    mbedtls_ssl_init( &ext->sc );
    mbedtls_ssl_config_init( &ext->conf );
    mbedtls_ctr_drbg_init( &ext->ctr_drbg );
    mbedtls_entropy_init( &ext->entropy );

    //mbedtls_x509_crt_init( &ext->cacert );
}
Beispiel #14
0
void ssl_main() {
#if _MSC_VER
	mbedtls_threading_set_alt( threading_mutex_init_alt, threading_mutex_free_alt, 
                           threading_mutex_lock_alt, threading_mutex_unlock_alt );
#endif

	// Init RNG
	mbedtls_entropy_init( &entropy );
	mbedtls_ctr_drbg_init( &ctr_drbg );
	mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0 );
}
Beispiel #15
0
/**
* @brief         Initation the SSL client.
* @param[in]     ssl: mbedtls ssl struct.
* @param[in]     tcp_fd. The underlying file descriptor.
* @param[in]     custom_config: custome config.
* @return        The result. 0 is ok.
*/
static int nghttp2_ssl_client_init(mbedtls_ssl_context *ssl,
                                   mbedtls_net_context *tcp_fd,
                                   http2_ssl_custom_conf_t *custom_config)
{
    int ret = -1;


    http2_verify_source_t *verify_source = &custom_config->verify_source;
    mbedtls_ssl_config *conf = &(custom_config->conf);

    /*
     * 0. Initialize the RNG and the session data
     */
#if defined(MBEDTLS_DEBUG_C)
    mbedtls_debug_set_threshold(DEBUG_LEVEL);
#endif
    mbedtls_net_init( tcp_fd );
    mbedtls_ssl_init( ssl );
    mbedtls_ssl_config_init( conf );

    mbedtls_x509_crt_init( &(verify_source->cacertl) );
    mbedtls_ctr_drbg_init( &ctr_drbg );

    NGHTTP2_DBG( "\n  . Seeding the random number generator..." );

    mbedtls_entropy_init( &entropy );
    if ( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
                                        (const unsigned char *) pers,
                                        strlen( pers ) ) ) != 0 ) {
        NGHTTP2_DBG( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret );
        return ret;
    }

    NGHTTP2_DBG( " ok\n" );

    /*
     * 0. Initialize certificates
     */

    NGHTTP2_DBG( "  . Loading the CA root certificate ..." );

    if (NULL != verify_source->trusted_ca_crt) {
        if (0 != (ret = mbedtls_x509_crt_parse(&verify_source->cacertl,
                                               (unsigned char *)verify_source->trusted_ca_crt,
                                               strlen(verify_source->trusted_ca_crt) + 1))) {
            NGHTTP2_DBG(" failed ! x509parse_crt returned -0x%04x", -ret);
            return ret;
        }
    }

    NGHTTP2_DBG( " ok (%d skipped)", ret );

    return 0;
}
Beispiel #16
0
static dukf_ssl_context_t *create_dukf_ssl_context(const char *hostname, int fd) {
	char errortext[256];
	dukf_ssl_context_t *dukf_ssl_context;

	dukf_ssl_context = malloc(sizeof(dukf_ssl_context_t));
	mbedtls_ssl_init(&dukf_ssl_context->ssl);
	mbedtls_ssl_config_init(&dukf_ssl_context->conf);
	mbedtls_x509_crt_init(&dukf_ssl_context->cacert);
	mbedtls_ctr_drbg_init(&dukf_ssl_context->ctr_drbg);
	mbedtls_entropy_init(&dukf_ssl_context->entropy);

	mbedtls_ssl_conf_dbg(&dukf_ssl_context->conf, debug_log, NULL);
	dukf_ssl_context->fd = fd;

  int rc = mbedtls_ctr_drbg_seed(
     &dukf_ssl_context->ctr_drbg,
     mbedtls_entropy_func, &dukf_ssl_context->entropy, (const unsigned char *) pers, strlen(pers));
  if (rc != 0) {
     LOGE(" failed\n  ! mbedtls_ctr_drbg_seed returned %d", rc);
     return NULL;
  }

  rc = mbedtls_ssl_config_defaults(
		&dukf_ssl_context->conf,
		MBEDTLS_SSL_IS_CLIENT,
		MBEDTLS_SSL_TRANSPORT_STREAM,
		MBEDTLS_SSL_PRESET_DEFAULT);
	if (rc != 0) {
		 LOGE("mbedtls_ssl_config_defaults returned %d", rc);
		 return NULL;
	}

	mbedtls_ssl_conf_authmode(&dukf_ssl_context->conf, MBEDTLS_SSL_VERIFY_NONE);

	mbedtls_ssl_conf_rng(&dukf_ssl_context->conf, mbedtls_ctr_drbg_random, &dukf_ssl_context->ctr_drbg);

	rc = mbedtls_ssl_setup(&dukf_ssl_context->ssl, &dukf_ssl_context->conf);
	if (rc != 0) {
		 mbedtls_strerror(rc, errortext, sizeof(errortext));
		 LOGE("error from mbedtls_ssl_setup: %d - %x - %s\n", rc, rc, errortext);
		 return NULL;
	}

	rc = mbedtls_ssl_set_hostname(&dukf_ssl_context->ssl, hostname);
	if (rc) {
		 mbedtls_strerror(rc, errortext, sizeof(errortext));
		 LOGE("error from mbedtls_ssl_set_hostname: %s %d - %x - %s", hostname, rc, rc, errortext);
		 return NULL;
	}

	mbedtls_ssl_set_bio(&dukf_ssl_context->ssl, dukf_ssl_context, ssl_send, ssl_recv, NULL);
	return dukf_ssl_context;
} // create_ssl_socket
Beispiel #17
0
static CURLcode Curl_mbedtls_random(struct Curl_easy *data,
                                    unsigned char *entropy, size_t length)
{
#if defined(MBEDTLS_CTR_DRBG_C)
  int ret = -1;
  char errorbuf[128];
  mbedtls_entropy_context ctr_entropy;
  mbedtls_ctr_drbg_context ctr_drbg;
  mbedtls_entropy_init(&ctr_entropy);
  mbedtls_ctr_drbg_init(&ctr_drbg);
  errorbuf[0]=0;

  ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func,
                              &ctr_entropy, NULL, 0);

  if(ret) {
#ifdef MBEDTLS_ERROR_C
    mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
#endif /* MBEDTLS_ERROR_C */
    failf(data, "Failed - mbedTLS: ctr_drbg_seed returned (-0x%04X) %s\n",
          -ret, errorbuf);
  }
  else {
    ret = mbedtls_ctr_drbg_random(&ctr_drbg, entropy, length);

    if(ret) {
#ifdef MBEDTLS_ERROR_C
      mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
#endif /* MBEDTLS_ERROR_C */
      failf(data, "mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n",
            -ret, errorbuf);
    }
  }

  mbedtls_ctr_drbg_free(&ctr_drbg);
  mbedtls_entropy_free(&ctr_entropy);

  return ret == 0 ? CURLE_OK : CURLE_FAILED_INIT;
#elif defined(MBEDTLS_HAVEGE_C)
  mbedtls_havege_state hs;
  mbedtls_havege_init(&hs);
  mbedtls_havege_random(&hs, entropy, length);
  mbedtls_havege_free(&hs);
  return CURLE_OK;
#else
  return CURLE_NOT_BUILT_IN;
#endif
}
void ssl_init(SSLConnection* conn) {
    /*
     * Initialize the RNG and the session data
     */
    mbedtls_net_init(&conn->net_ctx);
    mbedtls_ssl_init(&conn->ssl_ctx);
    mbedtls_ssl_config_init(&conn->ssl_conf);

    mbedtls_x509_crt_init(&conn->ca_cert);
    mbedtls_x509_crt_init(&conn->client_cert);
    mbedtls_pk_init(&conn->client_key);

    mbedtls_ctr_drbg_init(&conn->drbg_ctx);
    mbedtls_entropy_init(&conn->entropy_ctx);

}
Beispiel #19
0
void rand_bytes(byte* pb, size_t cb){
     
     mbedtls_ctr_drbg_context ctx;
    // unsigned char buf[16];
     
     mbedtls_ctr_drbg_init( &ctx );
     
     mbedtls_ctr_drbg_seed_entropy_len( &ctx, ctr_drbg_self_test_entropy, (void *) entropy_source_pr, nonce_pers_pr, 16, 32 );
     
     //mbedtls_ctr_drbg_set_prediction_resistance( &ctx, MBEDTLS_CTR_DRBG_PR_ON );
    
     mbedtls_ctr_drbg_random( &ctx, pb, cb );
     //mbedtls_ctr_drbg_random( &ctx, buf, MBEDTLS_CTR_DRBG_BLOCKSIZE );
     //memcmp( buf, result_pr, MBEDTLS_CTR_DRBG_BLOCKSIZE ) );
     
     mbedtls_ctr_drbg_free( &ctx );
}
Error StreamPeerMbedTLS::connect_to_stream(Ref<StreamPeer> p_base, bool p_validate_certs, const String &p_for_hostname) {

	base = p_base;
	int ret = 0;
	int authmode = p_validate_certs ? MBEDTLS_SSL_VERIFY_REQUIRED : MBEDTLS_SSL_VERIFY_NONE;

	mbedtls_ssl_init(&ssl);
	mbedtls_ssl_config_init(&conf);
	mbedtls_ctr_drbg_init(&ctr_drbg);
	mbedtls_entropy_init(&entropy);

	ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0);
	if (ret != 0) {
		ERR_PRINTS(" failed\n  ! mbedtls_ctr_drbg_seed returned an error" + itos(ret));
		return FAILED;
	}

	mbedtls_ssl_config_defaults(&conf,
			MBEDTLS_SSL_IS_CLIENT,
			MBEDTLS_SSL_TRANSPORT_STREAM,
			MBEDTLS_SSL_PRESET_DEFAULT);

	mbedtls_ssl_conf_authmode(&conf, authmode);
	mbedtls_ssl_conf_ca_chain(&conf, &cacert, NULL);
	mbedtls_ssl_conf_rng(&conf, mbedtls_ctr_drbg_random, &ctr_drbg);
	mbedtls_ssl_conf_dbg(&conf, my_debug, stdout);
	mbedtls_ssl_setup(&ssl, &conf);
	mbedtls_ssl_set_hostname(&ssl, p_for_hostname.utf8().get_data());

	mbedtls_ssl_set_bio(&ssl, this, bio_send, bio_recv, NULL);

	while ((ret = mbedtls_ssl_handshake(&ssl)) != 0) {
		if (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE) {
			ERR_PRINTS("TLS handshake error: " + itos(ret));
			_print_error(ret);
			status = STATUS_ERROR_HOSTNAME_MISMATCH;
			return FAILED;
		}
	}

	connected = true;
	status = STATUS_CONNECTED;

	return OK;
}
Beispiel #21
0
int
rb_init_ssl(void)
{
	int ret;
	mbedtls_entropy_init(&entropy);
	mbedtls_ctr_drbg_init(&ctr_drbg);


	if((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, NULL, 0)) != 0)
	{
		rb_lib_log("rb_init_prng: unable to initialize PRNG, mbedtls_ctr_drbg_seed() returned -0x%x", -ret);
		return 0;
	}
#if 0
	mbedtls_ssl_config_init(&serv_config);

	if ((ret = mbedtls_ssl_config_defaults(&serv_config,
		MBEDTLS_SSL_IS_SERVER,
		MBEDTLS_SSL_TRANSPORT_STREAM,
		MBEDTLS_SSL_PRESET_DEFAULT)) != 0)
	{
		rb_lib_log("rb_init_ssl: unable to initialize default SSL parameters for server context: -0x%x", -ret);
		return 0;
	}
#endif
//	mbedtls_ssl_conf_rng(&serv_config, mbedtls_ctr_drbg_random, &ctr_drbg);

	/***************************************************************************************************************/
#if 0
	mbedtls_ssl_config_init(&client_config);

	if ((ret = mbedtls_ssl_config_defaults(&client_config,
		MBEDTLS_SSL_IS_CLIENT,
		MBEDTLS_SSL_TRANSPORT_STREAM,
		MBEDTLS_SSL_PRESET_DEFAULT)) != 0)
	{
		rb_lib_log("rb_init_ssl: unable to initialize default SSL parameters for client context: -0x%x", -ret);
		return 0;
	}

	mbedtls_ssl_conf_rng(&client_config, mbedtls_ctr_drbg_random, &ctr_drbg);
#endif
	return 1;
}
Beispiel #22
0
static
Socket *dslink_socket_init(uint_fast8_t secure) {
    if (secure) {
        SslSocket *s = malloc(sizeof(SslSocket));
        if (!s) {
            return NULL;
        }
        s->secure = 1;
        s->socket_fd = malloc(sizeof(mbedtls_net_context));
        s->entropy = malloc(sizeof(mbedtls_entropy_context));
        s->drbg = malloc(sizeof(mbedtls_ctr_drbg_context));
        s->ssl = malloc(sizeof(mbedtls_ssl_context));
        s->conf = malloc(sizeof(mbedtls_ssl_config));

        if (!(s->socket_fd && s->entropy && s->drbg && s->ssl && s->conf)) {
            DSLINK_CHECKED_EXEC(free, s->socket_fd);
            DSLINK_CHECKED_EXEC(free, s->entropy);
            DSLINK_CHECKED_EXEC(free, s->drbg);
            DSLINK_CHECKED_EXEC(free, s->ssl);
            DSLINK_CHECKED_EXEC(free, s->conf);
            free(s);
            return NULL;
        }

        mbedtls_net_init(s->socket_fd);
        mbedtls_entropy_init(s->entropy);
        mbedtls_ctr_drbg_init(s->drbg);
        mbedtls_ssl_init(s->ssl);
        mbedtls_ssl_config_init(s->conf);
        return (Socket *) s;
    } else {
        Socket *s = malloc(sizeof(Socket));
        if (!s) {
            return NULL;
        }
        s->secure = 0;
        s->socket_fd = malloc(sizeof(mbedtls_net_context));
        if (!s->socket_fd) {
            free(s);
            return NULL;
        }
        return s;
    }
}
static pmbedtls_msg mbedtls_msg_new(void)
{
	pmbedtls_msg msg = (pmbedtls_msg)os_zalloc( sizeof(mbedtls_msg));
	if (msg) {
		os_bzero(msg, sizeof(mbedtls_msg));
		msg->psession = mbedtls_session_new();
		if (msg->psession){
			mbedtls_net_init(&msg->listen_fd);
			mbedtls_net_init(&msg->fd);
			mbedtls_ssl_init(&msg->ssl);
			mbedtls_ssl_config_init(&msg->conf);		
			mbedtls_ctr_drbg_init(&msg->ctr_drbg);
			mbedtls_entropy_init(&msg->entropy);
		} else{
			os_free(msg);
			msg = NULL;
		}
	}
	return msg;
}
Beispiel #24
0
int init_aes_key(unsigned char *key, size_t bytes)
{
    mbedtls_ctr_drbg_context ctr_drbg;
    mbedtls_entropy_context entropy;

    const uint8_t pers[] = "aes_generate_key";
    int ret;

    mbedtls_entropy_init(&entropy);
    mbedtls_ctr_drbg_init(&ctr_drbg);

    if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
            pers, sizeof(pers) - 1)) == 0) {
        ret = mbedtls_ctr_drbg_random(&ctr_drbg, key, bytes);
    }

    mbedtls_ctr_drbg_free(&ctr_drbg);
    mbedtls_entropy_free(&entropy);

    return ret;
}
Beispiel #25
0
/* Returns an opaque ssl context */
int openssl_connect(struct connection *conn)
{
	if (!initialized) {
		initialized = 1;

		mbedtls_entropy_init(&entropy);
		mbedtls_ctr_drbg_init(&ctr_drbg);

		mbedtls_ssl_config_init(&config);
		if (mbedtls_ssl_config_defaults(&config,
										MBEDTLS_SSL_IS_CLIENT,
										MBEDTLS_SSL_TRANSPORT_STREAM,
										MBEDTLS_SSL_PRESET_DEFAULT)) {
			printf("Unable to initialize ssl defaults\n");
			exit(1);
		}
	}

	mbedtls_ssl_context *ssl = malloc(sizeof(mbedtls_ssl_context));
	if (!ssl) {
		printf("Out of memory");
		return 1;
	}

	mbedtls_ssl_init(ssl);
	if (mbedtls_ssl_setup(ssl, &config)) {
		printf("Unable to set ssl defaults\n");
		exit(1);
	}

	conn->ssl = ssl;


//	mbedtls_ssl_set_rng(ssl, ctr_drbg_random, &ctr_drbg);

	int *fd = &conn->poll->fd;
	mbedtls_ssl_set_bio(ssl, fd, mbedtls_net_send, mbedtls_net_recv, NULL);

	return openssl_check_connect(conn);
}
Beispiel #26
0
kaa_error_t rsa_encrypt(const uint8_t *key, size_t key_size, const uint8_t *input,
        size_t input_len, uint8_t *output)
{
    if (key == NULL || key_size == 0) {
        return KAA_ERR_BADPARAM;
    }

    mbedtls_pk_context pk;
    mbedtls_entropy_context entropy;
    mbedtls_ctr_drbg_context ctr_drbg;
    const uint8_t pers[] = "key_gen";

    mbedtls_pk_init(&pk);

    if (mbedtls_pk_parse_public_key(&pk, key, key_size) != 0) {
        return KAA_ERR_INVALID_PUB_KEY;
    }

    mbedtls_ctr_drbg_init(&ctr_drbg);
    mbedtls_entropy_init(&entropy);

    int ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
            pers, sizeof(pers) - 1);

    if (!ret) {
        ret = mbedtls_rsa_rsaes_pkcs1_v15_encrypt(mbedtls_pk_rsa(pk), mbedtls_ctr_drbg_random, &ctr_drbg,
                MBEDTLS_RSA_PUBLIC, input_len, input, output);
    }

    mbedtls_ctr_drbg_free(&ctr_drbg);
    mbedtls_entropy_free(&entropy);
    mbedtls_pk_free(&pk);

    if (ret) {
        return KAA_ERR_GENERIC;
    }

    return KAA_ERR_NONE;
}
static int coap_security_handler_init(coap_security_t *sec){
    const char *pers = "dtls_client";
#ifdef COAP_SERVICE_PROVIDE_STRONG_ENTROPY_SOURCE
    const int entropy_source_type = MBEDTLS_ENTROPY_SOURCE_STRONG;
#else
    const int entropy_source_type = MBEDTLS_ENTROPY_SOURCE_WEAK;
#endif
    
    mbedtls_ssl_init( &sec->_ssl );
    mbedtls_ssl_config_init( &sec->_conf );
    mbedtls_ctr_drbg_init( &sec->_ctr_drbg );
    mbedtls_entropy_init( &sec->_entropy );

#if defined(MBEDTLS_X509_CRT_PARSE_C)
    mbedtls_x509_crt_init( &sec->_cacert );
    mbedtls_x509_crt_init( &sec->_owncert );
#endif
    mbedtls_pk_init( &sec->_pkey );

    memset(&sec->_cookie, 0, sizeof(simple_cookie_t));
    memset(&sec->_keyblk, 0, sizeof(key_block_t));

    sec->_is_started = false;

    if( mbedtls_entropy_add_source( &sec->_entropy, entropy_poll, NULL,
                                128, entropy_source_type ) < 0 ){
        return -1;
    }

    if( ( mbedtls_ctr_drbg_seed( &sec->_ctr_drbg, mbedtls_entropy_func, &sec->_entropy,
                               (const unsigned char *) pers,
                               strlen( pers ) ) ) != 0 )
    {
        return -1;
    }
    return 0;
}
Beispiel #28
0
int rsa_sign(mbedtls_pk_context *pk, const uint8_t *input,
        size_t input_size, uint8_t *output, size_t *output_size)
{
    // TODO(KAA-982): Use asserts
    if (!input || !input_size || !output || !output_size) {
        return KAA_ERR_BADPARAM;
    }
    int ret = 0;
    uint8_t hash[32];
    mbedtls_entropy_context entropy;
    mbedtls_ctr_drbg_context ctr_drbg;
    const uint8_t pers[] = "mbedtls_pk_sign";

    mbedtls_entropy_init(&entropy);
    mbedtls_ctr_drbg_init(&ctr_drbg);

    if ((ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
            pers,sizeof(pers) - 1)) != 0) {
        goto exit;
    }

    const mbedtls_md_info_t *info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1);

    if ((ret = mbedtls_md(info, input, input_size, hash)) != 0) {
        goto exit;
    }

    ret = mbedtls_pk_sign(pk, MBEDTLS_MD_SHA1, hash, 0, output, output_size,
            mbedtls_ctr_drbg_random, &ctr_drbg);

exit:
    mbedtls_ctr_drbg_free(&ctr_drbg);
    mbedtls_entropy_free(&entropy);

    return ret ? KAA_ERR_BADDATA : KAA_ERR_NONE;
}
Beispiel #29
0
int Server_init_rng(Server *srv)
{
    int rc;
    unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
    void *ctx = NULL;

    mbedtls_entropy_init( &srv->entropy );

    // test the entropy source
    rc = mbedtls_entropy_func(&srv->entropy, buf, MBEDTLS_ENTROPY_BLOCK_SIZE);

    if(rc == 0) {
        ctx = calloc(sizeof(mbedtls_ctr_drbg_context), 1);

        mbedtls_ctr_drbg_init((mbedtls_ctr_drbg_context *)ctx);
        rc = mbedtls_ctr_drbg_seed((mbedtls_ctr_drbg_context *)ctx,
            mbedtls_entropy_func, &srv->entropy, NULL, 0);
        check(rc == 0, "Init rng failed: ctr_drbg_init returned %d\n", rc);

        srv->rng_func = mbedtls_ctr_drbg_random;
        srv->rng_ctx = ctx;
    } else {
        log_warn("entropy source unavailable. falling back to havege rng");

        ctx = calloc(sizeof(mbedtls_havege_state), 1);
        mbedtls_havege_init((mbedtls_havege_state *)ctx);

        srv->rng_func = mbedtls_havege_random;
        srv->rng_ctx = ctx;
    }

    return 0;
error:
    if(ctx != NULL) free(ctx);
    return -1;
}
Beispiel #30
0
static CURLcode
mbed_connect_step1(struct connectdata *conn,
                   int sockindex)
{
  struct SessionHandle *data = conn->data;
  struct ssl_connect_data* connssl = &conn->ssl[sockindex];

  bool sni = TRUE; /* default is SNI enabled */
  int ret = -1;
#ifdef ENABLE_IPV6
  struct in6_addr addr;
#else
  struct in_addr addr;
#endif
  void *old_session = NULL;
  char errorbuf[128];
  errorbuf[0]=0;

  /* mbedTLS only supports SSLv3 and TLSv1 */
  if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) {
    failf(data, "mbedTLS does not support SSLv2");
    return CURLE_SSL_CONNECT_ERROR;
  }
  else if(data->set.ssl.version == CURL_SSLVERSION_SSLv3)
    sni = FALSE; /* SSLv3 has no SNI */

#ifdef THREADING_SUPPORT
  entropy_init_mutex(&entropy);
  mbedtls_ctr_drbg_init(&connssl->ctr_drbg);

  ret = mbedtls_ctr_drbg_seed(&connssl->ctr_drbg, entropy_func_mutex,
                              &entropy, NULL, 0);
  if(ret) {
#ifdef MBEDTLS_ERROR_C
    mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
#endif /* MBEDTLS_ERROR_C */
    failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n",
          -ret, errorbuf);
  }
#else
  mbedtls_entropy_init(&connssl->entropy);
  mbedtls_ctr_drbg_init(&connssl->ctr_drbg);

  ret = mbedtls_ctr_drbg_seed(&connssl->ctr_drbg, mbedtls_entropy_func,
                              &connssl->entropy, NULL, 0);
  if(ret) {
#ifdef MBEDTLS_ERROR_C
    mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
#endif /* MBEDTLS_ERROR_C */
    failf(data, "Failed - mbedTLS: ctr_drbg_init returned (-0x%04X) %s\n",
          -ret, errorbuf);
  }
#endif /* THREADING_SUPPORT */

  /* Load the trusted CA */
  mbedtls_x509_crt_init(&connssl->cacert);

  if(data->set.str[STRING_SSL_CAFILE]) {
    ret = mbedtls_x509_crt_parse_file(&connssl->cacert,
                                      data->set.str[STRING_SSL_CAFILE]);

    if(ret<0) {
#ifdef MBEDTLS_ERROR_C
      mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
#endif /* MBEDTLS_ERROR_C */
      failf(data, "Error reading ca cert file %s - mbedTLS: (-0x%04X) %s",
            data->set.str[STRING_SSL_CAFILE], -ret, errorbuf);

      if(data->set.ssl.verifypeer)
        return CURLE_SSL_CACERT_BADFILE;
    }
  }

  if(data->set.str[STRING_SSL_CAPATH]) {
    ret = mbedtls_x509_crt_parse_path(&connssl->cacert,
                                      data->set.str[STRING_SSL_CAPATH]);

    if(ret<0) {
#ifdef MBEDTLS_ERROR_C
      mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
#endif /* MBEDTLS_ERROR_C */
      failf(data, "Error reading ca cert path %s - mbedTLS: (-0x%04X) %s",
            data->set.str[STRING_SSL_CAPATH], -ret, errorbuf);

      if(data->set.ssl.verifypeer)
        return CURLE_SSL_CACERT_BADFILE;
    }
  }

  /* Load the client certificate */
  mbedtls_x509_crt_init(&connssl->clicert);

  if(data->set.str[STRING_CERT]) {
    ret = mbedtls_x509_crt_parse_file(&connssl->clicert,
                                      data->set.str[STRING_CERT]);

    if(ret) {
#ifdef MBEDTLS_ERROR_C
      mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
#endif /* MBEDTLS_ERROR_C */
      failf(data, "Error reading client cert file %s - mbedTLS: (-0x%04X) %s",
            data->set.str[STRING_CERT], -ret, errorbuf);

      return CURLE_SSL_CERTPROBLEM;
    }
  }

  /* Load the client private key */
  mbedtls_pk_init(&connssl->pk);

  if(data->set.str[STRING_KEY]) {
    ret = mbedtls_pk_parse_keyfile(&connssl->pk, data->set.str[STRING_KEY],
                                   data->set.str[STRING_KEY_PASSWD]);
    if(ret == 0 && !mbedtls_pk_can_do(&connssl->pk, MBEDTLS_PK_RSA))
      ret = MBEDTLS_ERR_PK_TYPE_MISMATCH;

    if(ret) {
#ifdef MBEDTLS_ERROR_C
      mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
#endif /* MBEDTLS_ERROR_C */
      failf(data, "Error reading private key %s - mbedTLS: (-0x%04X) %s",
            data->set.str[STRING_KEY], -ret, errorbuf);

      return CURLE_SSL_CERTPROBLEM;
    }
  }

  /* Load the CRL */
  mbedtls_x509_crl_init(&connssl->crl);

  if(data->set.str[STRING_SSL_CRLFILE]) {
    ret = mbedtls_x509_crl_parse_file(&connssl->crl,
                                      data->set.str[STRING_SSL_CRLFILE]);

    if(ret) {
#ifdef MBEDTLS_ERROR_C
      mbedtls_strerror(ret, errorbuf, sizeof(errorbuf));
#endif /* MBEDTLS_ERROR_C */
      failf(data, "Error reading CRL file %s - mbedTLS: (-0x%04X) %s",
            data->set.str[STRING_SSL_CRLFILE], -ret, errorbuf);

      return CURLE_SSL_CRL_BADFILE;
    }
  }

  infof(data, "mbedTLS: Connecting to %s:%d\n",
        conn->host.name, conn->remote_port);

  mbedtls_ssl_config_init(&connssl->config);

  mbedtls_ssl_init(&connssl->ssl);
  if(mbedtls_ssl_setup(&connssl->ssl, &connssl->config)) {
    failf(data, "mbedTLS: ssl_init failed");
    return CURLE_SSL_CONNECT_ERROR;
  }
  ret = mbedtls_ssl_config_defaults(&connssl->config,
                                    MBEDTLS_SSL_IS_CLIENT,
                                    MBEDTLS_SSL_TRANSPORT_STREAM,
                                    MBEDTLS_SSL_PRESET_DEFAULT);
  if(ret) {
    failf(data, "mbedTLS: ssl_config failed");
    return CURLE_SSL_CONNECT_ERROR;
  }

  /* new profile with RSA min key len = 1024 ... */
  mbedtls_ssl_conf_cert_profile(&connssl->config,
                                &mbedtls_x509_crt_profile_fr);

  switch(data->set.ssl.version) {
  case CURL_SSLVERSION_DEFAULT:
  case CURL_SSLVERSION_TLSv1:
    mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                                 MBEDTLS_SSL_MINOR_VERSION_1);
    infof(data, "mbedTLS: Set min SSL version to TLS 1.0\n");
    break;
  case CURL_SSLVERSION_SSLv3:
    mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                                 MBEDTLS_SSL_MINOR_VERSION_0);
    mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                                 MBEDTLS_SSL_MINOR_VERSION_0);
    infof(data, "mbedTLS: Set SSL version to SSLv3\n");
    break;
  case CURL_SSLVERSION_TLSv1_0:
    mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                                 MBEDTLS_SSL_MINOR_VERSION_1);
    mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                                 MBEDTLS_SSL_MINOR_VERSION_1);
    infof(data, "mbedTLS: Set SSL version to TLS 1.0\n");
    break;
  case CURL_SSLVERSION_TLSv1_1:
    mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                                 MBEDTLS_SSL_MINOR_VERSION_2);
    mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                                 MBEDTLS_SSL_MINOR_VERSION_2);
    infof(data, "mbedTLS: Set SSL version to TLS 1.1\n");
    break;
  case CURL_SSLVERSION_TLSv1_2:
    mbedtls_ssl_conf_min_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                                 MBEDTLS_SSL_MINOR_VERSION_3);
    mbedtls_ssl_conf_max_version(&connssl->config, MBEDTLS_SSL_MAJOR_VERSION_3,
                                 MBEDTLS_SSL_MINOR_VERSION_3);
    infof(data, "mbedTLS: Set SSL version to TLS 1.2\n");
    break;
  default:
    failf(data, "mbedTLS: Unsupported SSL protocol version");
    return CURLE_SSL_CONNECT_ERROR;
  }

  mbedtls_ssl_conf_authmode(&connssl->config, MBEDTLS_SSL_VERIFY_OPTIONAL);

  mbedtls_ssl_conf_rng(&connssl->config, mbedtls_ctr_drbg_random,
                       &connssl->ctr_drbg);
  mbedtls_ssl_set_bio(&connssl->ssl, &conn->sock[sockindex],
                      mbedtls_net_send,
                      mbedtls_net_recv,
                      NULL /*  rev_timeout() */);

  mbedtls_ssl_conf_ciphersuites(&connssl->config,
                                mbedtls_ssl_list_ciphersuites());
  if(!Curl_ssl_getsessionid(conn, &old_session, NULL)) {
    ret = mbedtls_ssl_set_session(&connssl->ssl, old_session);
    if(ret) {
      failf(data, "mbedtls_ssl_set_session returned -0x%x", -ret);
      return CURLE_SSL_CONNECT_ERROR;
    }
    infof(data, "mbedTLS re-using session\n");
  }

  mbedtls_ssl_conf_ca_chain(&connssl->config,
                            &connssl->cacert,
                            &connssl->crl);

  if(data->set.str[STRING_KEY]) {
    mbedtls_ssl_conf_own_cert(&connssl->config,
                              &connssl->clicert, &connssl->pk);
  }
  if(mbedtls_ssl_set_hostname(&connssl->ssl, conn->host.name)) {
    /* mbedtls_ssl_set_hostname() sets the name to use in CN/SAN checks *and*
       the name to set in the SNI extension. So even if curl connects to a
       host specified as an IP address, this function must be used. */
    failf(data, "couldn't set hostname in mbedTLS");
    return CURLE_SSL_CONNECT_ERROR;
  }

#ifdef HAS_ALPN
  if(conn->bits.tls_enable_alpn) {
    const char **p = &connssl->protocols[0];
#ifdef USE_NGHTTP2
    if(data->set.httpversion >= CURL_HTTP_VERSION_2)
      *p++ = NGHTTP2_PROTO_VERSION_ID;
#endif
    *p++ = ALPN_HTTP_1_1;
    *p = NULL;
    /* this function doesn't clone the protocols array, which is why we need
       to keep it around */
    if(mbedtls_ssl_conf_alpn_protocols(&connssl->config,
                                       &connssl->protocols[0])) {
      failf(data, "Failed setting ALPN protocols");
      return CURLE_SSL_CONNECT_ERROR;
    }
    for(p = &connssl->protocols[0]; *p; ++p)
      infof(data, "ALPN, offering %s\n", *p);
  }
#endif

#ifdef MBEDTLS_DEBUG
  mbedtls_ssl_conf_dbg(&connssl->config, mbedtls_debug, data);
#endif

  connssl->connecting_state = ssl_connect_2;

  return CURLE_OK;
}