+static int CASslExportKeysHandler(void *p_expkey,
+ const unsigned char *ms,
+ const unsigned char *kb,
+ size_t maclen,
+ size_t keylen,
+ size_t ivlen)
+{
+ OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
+
+ if (NULL == g_caSslContext)
+ {
+ OIC_LOG(ERROR, NET_SSL_TAG, "SSL Context is not initialized.");
+ return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+ }
+ if (NULL == p_expkey)
+ {
+ OIC_LOG(ERROR, NET_SSL_TAG, "Can not find the protocol information from 'p_expkey'.");
+ return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+ }
+
+ CASslEkcbProtocol_t* protocol = (CASslEkcbProtocol_t*)p_expkey;
+
+ if (gTlsExportKeysCallback && CA_SSL_EKCB_TLS == (*protocol))
+ {
+ OIC_LOG(DEBUG, NET_SSL_TAG, "Invoking TLS export key callback.");
+ gTlsExportKeysCallback(ms, kb, maclen, keylen, ivlen);
+ }
+ else if (gDtlsExportKeysCallback && CA_SSL_EKCB_DTLS == (*protocol))
+ {
+ OIC_LOG(DEBUG, NET_SSL_TAG, "Invoking DTLS export key callback.");
+ gDtlsExportKeysCallback(ms, kb, maclen, keylen, ivlen);
+ }
+ else
+ {
+ OIC_LOG(ERROR, NET_SSL_TAG, "Failed to Invoke (D)TLS export key callback.");
+ return MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE;
+ }
+
+ OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
+ return 0;
+}
+
+CAResult_t CASetSslExportKeysCallback(SslExportKeysCallback_t exportKeysCb,
+ CASslEkcbProtocol_t protocol, CASslEkcbRole_t role)
+{
+ OIC_LOG_V(DEBUG, NET_SSL_TAG, "In %s", __func__);
+ mbedtls_ssl_config* sslConf = NULL;
+ static CASslEkcbProtocol_t protocolCtx = CA_SSL_EKCB_TLS;
+
+ if (CA_SSL_EKCB_TLS != protocol && CA_SSL_EKCB_DTLS != protocol)
+ {
+ OIC_LOG(ERROR, NET_SSL_TAG, "Invaild protocol.");
+ return CA_STATUS_INVALID_PARAM;
+ }
+ if (CA_SSL_EKCB_CLIENT != role && CA_SSL_EKCB_SERVER != role)
+ {
+ OIC_LOG(ERROR, NET_SSL_TAG, "Invaild role.");
+ return CA_STATUS_INVALID_PARAM;
+ }
+
+ OIC_LOG_V(DEBUG, NET_SSL_TAG, "TLS Export Key Callback Type : [%s] [%s]",
+ (CA_SSL_EKCB_TLS == protocol ? "TLS" : "DTLS"),
+ (CA_SSL_EKCB_CLIENT == role ? "Client" : "Server"));
+
+ oc_mutex_lock(g_sslContextMutex);
+ if (NULL == g_caSslContext)
+ {
+ OIC_LOG(ERROR, NET_SSL_TAG, "SSL Context is not initialized.");
+ oc_mutex_unlock(g_sslContextMutex);
+ return CA_STATUS_NOT_INITIALIZED;
+ }
+
+ if (CA_SSL_EKCB_TLS == protocol)
+ {
+ gTlsExportKeysCallback = exportKeysCb;
+ if (CA_SSL_EKCB_CLIENT == role)
+ {
+ sslConf = &g_caSslContext->clientTlsConf;
+ }
+ else
+ {
+ sslConf = &g_caSslContext->serverTlsConf;
+ }
+ }
+ else
+ {
+ gDtlsExportKeysCallback = exportKeysCb;
+ if (CA_SSL_EKCB_CLIENT == role)
+ {
+ sslConf = &g_caSslContext->clientDtlsConf;
+ }
+ else
+ {
+ sslConf = &g_caSslContext->serverDtlsConf;
+ }
+ }
+ protocolCtx = protocol;
+
+ if (NULL == exportKeysCb)
+ {
+ mbedtls_ssl_conf_export_keys_cb(sslConf, NULL, NULL);
+ OIC_LOG(DEBUG, NET_SSL_TAG, "Export key callback unregistered.");
+ }
+ else
+ {
+ mbedtls_ssl_conf_export_keys_cb(sslConf, CASslExportKeysHandler, (void*)(&protocolCtx));
+ OIC_LOG(DEBUG, NET_SSL_TAG, "Export key callback registered.");
+ }
+ oc_mutex_unlock(g_sslContextMutex);
+
+ OIC_LOG_V(DEBUG, NET_SSL_TAG, "Out %s", __func__);
+
+ return CA_STATUS_OK;
+}
+