Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement full TEE with sgx #307

Merged
merged 11 commits into from
Jun 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ services:
- MONGO_HOST=mongo
- IEXEC_IPFS_HOST=ipfs
- IEXEC_SMS_HOST=sms
- IEXEC_SCONE_CAS_HOST=iexec-cas
volumes:
- ./src/main/resources/wallet/encrypted-wallet_scheduler.json:/iexec/wallet/encrypted-wallet.json
ports:
Expand Down Expand Up @@ -68,3 +69,13 @@ services:
- 5000:5000
depends_on:
- chain

iexec-cas:
image: nexus.iex.ec/iexec-cas:${IEXEC_CAS_VERSION}
container_name: iexec-cas
ports:
- 18765:18765
networks:
- iexec-net
devices:
- /dev/isgx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.iexec.core.configuration;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;


/**
* CAS: Configuration and Attestation Service.
* It handles configurations and secret provisioning: a user uploads secrets
* and configuration infos for a specific service to the CAS.
* When a service wants to access those secrets, it sends a quote with its MREnclave.
* The CAS attests the quote through Intel Attestation Service and sends the secrets
* if the MREnclave is as expected.
*
* MREnclave: an enclave identifier, created by hashing all its
* code. It guarantees that a code behaves exactly as expected.
*/
@Component
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class SconeCasConfiguration {

@Value("${scone.cas.host}")
private String host;

@Value("${scone.cas.port}")
private String port;

public String getURL() {
return host + ":" + port;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ Optional<ContributionAuthorization> getAuthOfAvailableReplicate(long workerLastB
}

// skip the task if it needs TEE and the worker doesn't support it
boolean doesTaskNeedTEE = task.isTeeNeeded();
if (doesTaskNeedTEE && !worker.isTeeEnabled()) {
boolean isTeeTask = task.isTeeTask();
if (isTeeTask && !worker.isTeeEnabled()) {
continue;
}

Expand All @@ -144,7 +144,7 @@ Optional<ContributionAuthorization> getAuthOfAvailableReplicate(long workerLastB
if (isFewBlocksAfterInitialization && !hasWorkerAlreadyParticipated
&& consensusService.doesTaskNeedMoreContributionsForConsensus(chainTaskId, task.getTrust(), task.getMaxExecutionTime())) {

String enclaveChallenge = smsService.getEnclaveChallenge(chainTaskId, doesTaskNeedTEE);
String enclaveChallenge = smsService.getEnclaveChallenge(chainTaskId, isTeeTask);
if (enclaveChallenge.isEmpty()) {
taskService.unlockTaskAccessForNewReplicate(chainTaskId);//avoid dead lock
continue;
Expand Down Expand Up @@ -188,8 +188,8 @@ public List<TaskNotification> getMissedTaskNotifications(long blockNumber, Strin
boolean isRecoverable = replicate.isRecoverable();
if (!isRecoverable) continue;

String enclaveChallenge = smsService.getEnclaveChallenge(chainTaskId, task.isTeeNeeded());
if (task.isTeeNeeded() && enclaveChallenge.isEmpty()) continue;
String enclaveChallenge = smsService.getEnclaveChallenge(chainTaskId, task.isTeeTask());
if (task.isTeeTask() && enclaveChallenge.isEmpty()) continue;

Optional<TaskNotificationType> taskNotificationType = getTaskNotificationType(task, replicate, blockNumber);
if (!taskNotificationType.isPresent()) continue;
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/iexec/core/task/Task.java
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public boolean inCompletionPhase() {
return TaskStatus.isInCompletionPhase(getCurrentStatus());
}

public boolean isTeeNeeded() {
return TeeUtils.isTrustedExecutionTag(getTag());
public boolean isTeeTask() {
return TeeUtils.isTeeTag(getTag());
}
}
2 changes: 1 addition & 1 deletion src/main/java/com/iexec/core/task/TaskService.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public boolean isConsensusReached(Task task) {

return isChainTaskRevealing && offChainWinnersGreaterOrEqualsOnChainWinners;
}

private List<Task> getTasksByChainDealIdAndTaskIndex(String chainDealId, int taskIndex) {
return taskRepository.findByChainDealIdAndTaskIndex(chainDealId, taskIndex);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,14 @@ public void onTaskConsensusReached(ConsensusReachedEvent event) {

// winners: please reveal
if (!winners.isEmpty()) {
TaskNotificationExtra notificationExtra = TaskNotificationExtra.builder()
.blockNumber(event.getBlockNumber())
.build();

notificationService.sendTaskNotification(TaskNotification.builder()
.taskNotificationType(TaskNotificationType.PLEASE_REVEAL)
.chainTaskId(chainTaskId)
.taskNotificationExtra(TaskNotificationExtra.builder().blockNumber(event.getBlockNumber()).build())
.taskNotificationExtra(notificationExtra)
.workersAddress(winners).build()
);
}
Expand Down
7 changes: 6 additions & 1 deletion src/main/java/com/iexec/core/worker/WorkerController.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.iexec.core.chain.ChainConfig;
import com.iexec.core.chain.CredentialsService;
import com.iexec.core.configuration.ResultRepositoryConfiguration;
import com.iexec.core.configuration.SconeCasConfiguration;
import com.iexec.core.configuration.SessionService;
import com.iexec.core.configuration.SmsConfiguration;
import com.iexec.core.configuration.WorkerConfiguration;
Expand Down Expand Up @@ -40,6 +41,7 @@ public class WorkerController {
private WorkerConfiguration workerConfiguration;
private ResultRepositoryConfiguration resultRepoConfig;
private SmsConfiguration smsConfiguration;
private SconeCasConfiguration sconeCasConfiguration;

public WorkerController(WorkerService workerService,
ChainConfig chainConfig,
Expand All @@ -48,7 +50,8 @@ public WorkerController(WorkerService workerService,
ChallengeService challengeService,
WorkerConfiguration workerConfiguration,
ResultRepositoryConfiguration resultRepoConfig,
SmsConfiguration smsConfiguration) {
SmsConfiguration smsConfiguration,
SconeCasConfiguration sconeCasConfiguration) {
this.workerService = workerService;
this.chainConfig = chainConfig;
this.credentialsService = credentialsService;
Expand All @@ -57,6 +60,7 @@ public WorkerController(WorkerService workerService,
this.workerConfiguration = workerConfiguration;
this.resultRepoConfig = resultRepoConfig;
this.smsConfiguration = smsConfiguration;
this.sconeCasConfiguration = sconeCasConfiguration;
}

@PostMapping(path = "/workers/ping")
Expand Down Expand Up @@ -130,6 +134,7 @@ public ResponseEntity<PublicConfiguration> getPublicConfiguration() {
.schedulerPublicAddress(credentialsService.getCredentials().getAddress())
.resultRepositoryURL(resultRepoConfig.getResultRepositoryURL())
.smsURL(smsConfiguration.getSmsURL())
.sconeCasURL(sconeCasConfiguration.getURL())
.askForReplicatePeriod(workerConfiguration.getAskForReplicatePeriod())
.requiredWorkerVersion(workerConfiguration.getRequiredWorkerVersion())
.build();
Expand Down
10 changes: 10 additions & 0 deletions src/main/java/com/iexec/core/workflow/ReplicateWorkflow.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ private ReplicateWorkflow() {

addTransition(APP_DOWNLOAD_FAILED, toList(
// DATA_DOWNLOADING,
CANT_CONTRIBUTE_SINCE_DETERMINISM_HASH_NOT_FOUND,
CANT_CONTRIBUTE_SINCE_CHAIN_UNREACHABLE,
CANT_CONTRIBUTE_SINCE_STAKE_TOO_LOW,
CANT_CONTRIBUTE_SINCE_TASK_NOT_ACTIVE,
CANT_CONTRIBUTE_SINCE_AFTER_DEADLINE,
Expand All @@ -39,6 +41,8 @@ private ReplicateWorkflow() {

addTransition(DATA_DOWNLOAD_FAILED, toList(
// COMPUTING,
CANT_CONTRIBUTE_SINCE_DETERMINISM_HASH_NOT_FOUND,
CANT_CONTRIBUTE_SINCE_CHAIN_UNREACHABLE,
CANT_CONTRIBUTE_SINCE_STAKE_TOO_LOW,
CANT_CONTRIBUTE_SINCE_TASK_NOT_ACTIVE,
CANT_CONTRIBUTE_SINCE_AFTER_DEADLINE,
Expand All @@ -52,6 +56,9 @@ private ReplicateWorkflow() {
addTransition(COMPUTING, toList(COMPUTED, COMPUTE_FAILED, RECOVERING));

addTransition(COMPUTED, toList(
CANT_CONTRIBUTE_SINCE_DETERMINISM_HASH_NOT_FOUND,
CANT_CONTRIBUTE_SINCE_TEE_EXECUTION_NOT_VERIFIED,
CANT_CONTRIBUTE_SINCE_CHAIN_UNREACHABLE,
CANT_CONTRIBUTE_SINCE_STAKE_TOO_LOW,
CANT_CONTRIBUTE_SINCE_TASK_NOT_ACTIVE,
CANT_CONTRIBUTE_SINCE_AFTER_DEADLINE,
Expand All @@ -60,6 +67,9 @@ private ReplicateWorkflow() {
RECOVERING));

addTransition(COMPUTE_FAILED, toList(
CANT_CONTRIBUTE_SINCE_DETERMINISM_HASH_NOT_FOUND,
CANT_CONTRIBUTE_SINCE_TEE_EXECUTION_NOT_VERIFIED,
CANT_CONTRIBUTE_SINCE_CHAIN_UNREACHABLE,
CANT_CONTRIBUTE_SINCE_STAKE_TOO_LOW,
CANT_CONTRIBUTE_SINCE_TASK_NOT_ACTIVE,
CANT_CONTRIBUTE_SINCE_AFTER_DEADLINE,
Expand Down
19 changes: 12 additions & 7 deletions src/main/resources/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ detector:
task.initialized.unnotified.period: 30000 # 30 s
task.finalized.unnotified.period: 30000 # 30 s

workers:
askForReplicatePeriod: ${IEXEC_ASK_REPLICATE_PERIOD:5000}
requiredWorkerVersion: ${IEXEC_CORE_REQUIRED_WORKER_VERSION:} #leave empty will allow any worker version

wallet:
encryptedFilePath: ${IEXEC_CORE_WALLET_PATH:./src/main/resources/wallet/encrypted-wallet_scheduler.json}
password: ${IEXEC_CORE_WALLET_PASSWORD:whatever}
Expand All @@ -35,23 +39,24 @@ chain:
gasPriceMultiplier: ${IEXEC_GAS_PRICE_MULTIPLIER:1.0} # txs will be send with networkGasPrice*gasPriceMultiplier, 4.0 means super fast
gasPriceCap: ${IEXEC_GAS_PRICE_CAP:22000000000} #in Wei, will be used for txs if networkGasPrice*gasPriceMultiplier > gasPriceCap

workers:
askForReplicatePeriod: ${IEXEC_ASK_REPLICATE_PERIOD:5000}
requiredWorkerVersion: ${IEXEC_CORE_REQUIRED_WORKER_VERSION:} #leave empty will allow any worker version

resultRepository:
protocol: ${IEXEC_RESULT_REPOSITORY_PROTOCOL:http}
host: ${IEXEC_RESULT_REPOSITORY_HOST:localhost}
port: ${IEXEC_RESULT_REPOSITORY_PORT:18090}

ipfs:
host: ${IEXEC_IPFS_HOST:127.0.0.1}
port: ${IEXEC_IPFS_PORT:5001}

sms:
protocol: ${IEXEC_SMS_PROTOCOL:http}
host: ${IEXEC_SMS_HOST:localhost}
port: ${IEXEC_SMS_PORT:5000}

ipfs:
host: ${IEXEC_IPFS_HOST:127.0.0.1}
port: ${IEXEC_IPFS_PORT:5001}
scone:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it
cas:
scone:
?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No CAS is a scone service. So CAS under scone (we have also LAS under scone in the worker side)

cas:
host: ${IEXEC_SCONE_CAS_HOST:localhost}
port: ${IEXEC_SCONE_CAS_PORT:18765}

management:
endpoints:
Expand Down