ProtocolError DTLSMessageChannel::init( const uint8_t* core_private, size_t core_private_len, const uint8_t* core_public, size_t core_public_len, const uint8_t* server_public, size_t server_public_len, const uint8_t* device_id, Callbacks& callbacks, message_id_t* coap_state) { init(); this->coap_state = coap_state; int ret; this->callbacks = callbacks; this->device_id = device_id; keys_checksum = compute_checksum(callbacks.calculate_crc, server_public, server_public_len, core_private, core_private_len); ret = mbedtls_ssl_config_defaults(&conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT); EXIT_ERROR(ret, "unable to configure defaults"); mbedtls_ssl_conf_handshake_timeout(&conf, 3000, 6000); mbedtls_ssl_conf_rng(&conf, dtls_rng, this); mbedtls_ssl_conf_dbg(&conf, my_debug, nullptr); mbedtls_ssl_conf_min_version(&conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); ret = mbedtls_pk_parse_public_key(&pkey, core_public, core_public_len); EXIT_ERROR(ret, "unable to parse device public key"); ret = mbedtls_pk_parse_key(&pkey, core_private, core_private_len, NULL, 0); EXIT_ERROR(ret, "unable to parse device private key"); ret = mbedtls_ssl_conf_own_cert(&conf, &clicert, &pkey); EXIT_ERROR(ret, "unable to configure own certificate"); mbedtls_ssl_conf_authmode(&conf, MBEDTLS_SSL_VERIFY_OPTIONAL); static int ssl_cert_types[] = { MBEDTLS_TLS_CERT_TYPE_RAW_PUBLIC_KEY, MBEDTLS_TLS_CERT_TYPE_NONE }; mbedtls_ssl_conf_client_certificate_types(&conf, ssl_cert_types); mbedtls_ssl_conf_server_certificate_types(&conf, ssl_cert_types); mbedtls_ssl_conf_certificate_receive(&conf, MBEDTLS_SSL_RECEIVE_CERTIFICATE_DISABLED); this->server_public = new uint8_t[server_public_len]; memcpy(this->server_public, server_public, server_public_len); this->server_public_len = server_public_len; return NO_ERROR; }
DTLSContext *HAL_DTLSSession_create(coap_dtls_options_t *p_options) { char port[6] = {0}; int result = 0; dtls_session_t *p_dtls_session = NULL; p_dtls_session = _DTLSSession_init(); if (NULL != p_dtls_session) { mbedtls_ssl_config_init(&p_dtls_session->conf); result = mbedtls_ctr_drbg_seed(&p_dtls_session->ctr_drbg, mbedtls_entropy_func, &p_dtls_session->entropy, (const unsigned char *)"IoTx", strlen("IoTx")); if (0 != result) { DTLS_ERR("mbedtls_ctr_drbg_seed result 0x%04x\r\n", result); goto error; } result = mbedtls_ssl_config_defaults(&p_dtls_session->conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT); if (0 != result) { DTLS_ERR("mbedtls_ssl_config_defaults result 0x%04x\r\n", result); goto error; } mbedtls_ssl_conf_rng(&p_dtls_session->conf, mbedtls_ctr_drbg_random, &p_dtls_session->ctr_drbg); mbedtls_ssl_conf_dbg(&p_dtls_session->conf, _DTLSLog_wrapper, NULL); result = mbedtls_ssl_cookie_setup(&p_dtls_session->cookie_ctx, mbedtls_ctr_drbg_random, &p_dtls_session->ctr_drbg); if (0 != result) { DTLS_ERR("mbedtls_ssl_cookie_setup result 0x%04x\r\n", result); goto error; } #if defined(MBEDTLS_SSL_DTLS_HELLO_VERIFY) && defined(MBEDTLS_SSL_SRV_C) mbedtls_ssl_conf_dtls_cookies(&p_dtls_session->conf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check, &p_dtls_session->cookie_ctx); #endif result = _DTLSVerifyOptions_set(p_dtls_session, p_options->p_ca_cert_pem); if (DTLS_SUCCESS != result) { DTLS_ERR("DTLSVerifyOptions_set result 0x%04x\r\n", result); goto error; } sprintf(port, "%u", p_options->port); result = mbedtls_net_connect(&p_dtls_session->fd, p_options->p_host, port, MBEDTLS_NET_PROTO_UDP); if (0 != result) { DTLS_ERR("mbedtls_net_connect result 0x%04x\r\n", result); goto error; } #ifdef MBEDTLS_SSL_PROTO_DTLS if (p_dtls_session->conf.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM) { mbedtls_ssl_conf_min_version(&p_dtls_session->conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); mbedtls_ssl_conf_max_version(&p_dtls_session->conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); mbedtls_ssl_conf_handshake_timeout(&p_dtls_session->conf, (MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN * 2), (MBEDTLS_SSL_DTLS_TIMEOUT_DFL_MIN * 2 * 4)); } #endif result = _DTLSContext_setup(p_dtls_session, p_options); if (DTLS_SUCCESS != result) { DTLS_ERR("DTLSVerifyOptions_set result 0x%04x\r\n", result); goto error; } return (DTLSContext *)p_dtls_session; } error: if (NULL != p_dtls_session) { _DTLSSession_deinit(p_dtls_session); } return NULL; }
int coap_security_handler_connect_non_blocking(coap_security_t *sec, bool is_server, SecureSocketMode sock_mode, coap_security_keys_t keys, uint32_t timeout_min, uint32_t timeout_max) { if( !sec ){ return -1; } sec->_is_blocking = false; int endpoint = MBEDTLS_SSL_IS_CLIENT; if( is_server ){ endpoint = MBEDTLS_SSL_IS_SERVER; } int mode = MBEDTLS_SSL_TRANSPORT_DATAGRAM; if( sock_mode == TLS ){ mode = MBEDTLS_SSL_TRANSPORT_STREAM; } if( ( mbedtls_ssl_config_defaults( &sec->_conf, endpoint, mode, 0 ) ) != 0 ) { return -1; } if(!timeout_max && !timeout_min){ mbedtls_ssl_conf_handshake_timeout( &sec->_conf, DTLS_HANDSHAKE_TIMEOUT_MIN, DTLS_HANDSHAKE_TIMEOUT_MAX ); } else{ mbedtls_ssl_conf_handshake_timeout( &sec->_conf, timeout_min, timeout_max ); } mbedtls_ssl_conf_rng( &sec->_conf, mbedtls_ctr_drbg_random, &sec->_ctr_drbg ); if( ( mbedtls_ssl_setup( &sec->_ssl, &sec->_conf ) ) != 0 ) { return -1; } mbedtls_ssl_set_bio( &sec->_ssl, sec, f_send, f_recv, NULL ); mbedtls_ssl_set_timer_cb( &sec->_ssl, sec, set_timer, get_timer ); #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) //TODO: Figure out better way!!! //Password should never be stored in multiple places!!! if( is_server && keys._priv_len > 0){ memcpy(sec->_pw, keys._priv, keys._priv_len); sec->_pw_len = keys._priv_len; } #endif if( coap_security_handler_configure_keys( sec, keys ) != 0 ){ return -1; } #ifdef MBEDTLS_SSL_SRV_C mbedtls_ssl_conf_dtls_cookies(&sec->_conf, simple_cookie_write, simple_cookie_check, &sec->_cookie); #endif mbedtls_ssl_conf_min_version(&sec->_conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MAJOR_VERSION_3); mbedtls_ssl_conf_max_version(&sec->_conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MAJOR_VERSION_3); sec->_is_started = true; int ret = mbedtls_ssl_handshake_step( &sec->_ssl ); if( ret == 0 ){ ret = mbedtls_ssl_handshake_step( &sec->_ssl ); if( is_server && 0 == ret){ ret = coap_security_handler_continue_connecting( sec ); } } if( ret >= 0){ ret = 1; }else{ ret = -1; } return ret; }
otError Dtls::Setup(bool aClient) { int rval; // do not handle new connection before guard time expired VerifyOrExit(mState == kStateOpen, rval = MBEDTLS_ERR_SSL_TIMEOUT); mState = kStateInitializing; mbedtls_ssl_init(&mSsl); mbedtls_ssl_config_init(&mConf); mbedtls_ctr_drbg_init(&mCtrDrbg); mbedtls_entropy_init(&mEntropy); #if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE #ifdef MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED mbedtls_x509_crt_init(&mCaChain); mbedtls_x509_crt_init(&mOwnCert); mbedtls_pk_init(&mPrivateKey); #endif // MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED #endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE rval = mbedtls_entropy_add_source(&mEntropy, &Dtls::HandleMbedtlsEntropyPoll, NULL, MBEDTLS_ENTROPY_MIN_PLATFORM, MBEDTLS_ENTROPY_SOURCE_STRONG); VerifyOrExit(rval == 0); { otExtAddress eui64; otPlatRadioGetIeeeEui64(&GetInstance(), eui64.m8); rval = mbedtls_ctr_drbg_seed(&mCtrDrbg, mbedtls_entropy_func, &mEntropy, eui64.m8, sizeof(eui64)); VerifyOrExit(rval == 0); } rval = mbedtls_ssl_config_defaults(&mConf, aClient ? MBEDTLS_SSL_IS_CLIENT : MBEDTLS_SSL_IS_SERVER, MBEDTLS_SSL_TRANSPORT_DATAGRAM, MBEDTLS_SSL_PRESET_DEFAULT); VerifyOrExit(rval == 0); #if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE if (mVerifyPeerCertificate && mCipherSuites[0] == MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8) { mbedtls_ssl_conf_authmode(&mConf, MBEDTLS_SSL_VERIFY_REQUIRED); } else { mbedtls_ssl_conf_authmode(&mConf, MBEDTLS_SSL_VERIFY_NONE); } #else OT_UNUSED_VARIABLE(mVerifyPeerCertificate); #endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE mbedtls_ssl_conf_rng(&mConf, mbedtls_ctr_drbg_random, &mCtrDrbg); mbedtls_ssl_conf_min_version(&mConf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); mbedtls_ssl_conf_max_version(&mConf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MINOR_VERSION_3); mbedtls_ssl_conf_ciphersuites(&mConf, mCipherSuites); mbedtls_ssl_conf_export_keys_cb(&mConf, HandleMbedtlsExportKeys, this); mbedtls_ssl_conf_handshake_timeout(&mConf, 8000, 60000); mbedtls_ssl_conf_dbg(&mConf, HandleMbedtlsDebug, this); #if OPENTHREAD_ENABLE_BORDER_AGENT || OPENTHREAD_ENABLE_COMMISSIONER || OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE if (!aClient) { mbedtls_ssl_cookie_init(&mCookieCtx); rval = mbedtls_ssl_cookie_setup(&mCookieCtx, mbedtls_ctr_drbg_random, &mCtrDrbg); VerifyOrExit(rval == 0); mbedtls_ssl_conf_dtls_cookies(&mConf, mbedtls_ssl_cookie_write, mbedtls_ssl_cookie_check, &mCookieCtx); } #endif // OPENTHREAD_ENABLE_BORDER_AGENT || OPENTHREAD_ENABLE_COMMISSIONER || OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE rval = mbedtls_ssl_setup(&mSsl, &mConf); VerifyOrExit(rval == 0); mbedtls_ssl_set_bio(&mSsl, this, &Dtls::HandleMbedtlsTransmit, HandleMbedtlsReceive, NULL); mbedtls_ssl_set_timer_cb(&mSsl, this, &Dtls::HandleMbedtlsSetTimer, HandleMbedtlsGetTimer); if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8) { rval = mbedtls_ssl_set_hs_ecjpake_password(&mSsl, mPsk, mPskLength); } #if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE else { rval = SetApplicationCoapSecureKeys(); } #endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE VerifyOrExit(rval == 0); mReceiveMessage = NULL; mMessageSubType = Message::kSubTypeNone; mState = kStateConnecting; if (mCipherSuites[0] == MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8) { otLogInfoMeshCoP("DTLS started"); } #if OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE else { otLogInfoCoap("Application Coap Secure DTLS started"); } #endif // OPENTHREAD_ENABLE_APPLICATION_COAP_SECURE mState = kStateConnecting; Process(); exit: if ((mState == kStateInitializing) && (rval != 0)) { mState = kStateOpen; FreeMbedtls(); } return MapError(rval); }