Paul Zinselmeyer
ba8e969470
All checks were successful
Latex Build / build-latex (Assignment 4 - Protokollsicherheit (Praxis)) (push) Successful in 1m2s
Latex Build / build-latex (Assignment 5 - Software Security - Teil 1) (push) Successful in 1m3s
Latex Build / build-latex (Assignment 6 - Software Security - Teil 2) (push) Successful in 1m0s
Latex Build / build-latex (Assignment 4 - Protokollsicherheit (Praxis)) (pull_request) Successful in 30s
Latex Build / build-latex (Assignment 5 - Software Security - Teil 1) (pull_request) Successful in 10s
Latex Build / build-latex (Assignment 6 - Software Security - Teil 2) (pull_request) Successful in 8s
403 lines
9.4 KiB
C++
Executable file
403 lines
9.4 KiB
C++
Executable file
#include "enclave_t.h"
|
|
#include "string.h"
|
|
|
|
#include "enclave.h"
|
|
#include "wallet.h"
|
|
|
|
#include "sgx_tseal.h"
|
|
#include "sealing/sealing.h"
|
|
|
|
int ecall_create_wallet(const char* master_password) {
|
|
|
|
//
|
|
// OVERVIEW:
|
|
// 1. check password policy
|
|
// 2. [ocall] abort if wallet already exist
|
|
// 3. create wallet
|
|
// 4. seal wallet
|
|
// 5. [ocall] save wallet
|
|
// 6. exit enclave
|
|
//
|
|
//
|
|
sgx_status_t ocall_status, sealing_status;
|
|
int ocall_ret;
|
|
|
|
|
|
// 1. check passaword policy
|
|
if (strlen(master_password) < 8 || strlen(master_password)+1 > MAX_ITEM_SIZE) {
|
|
return ERR_PASSWORD_OUT_OF_RANGE;
|
|
}
|
|
|
|
|
|
// 2. abort if wallet already exist
|
|
ocall_status = ocall_is_wallet(&ocall_ret);
|
|
if (ocall_ret != 0) {
|
|
return ERR_WALLET_ALREADY_EXISTS;
|
|
}
|
|
|
|
|
|
// 3. create new wallet
|
|
wallet_t* wallet = (wallet_t*)malloc(sizeof(wallet_t));
|
|
wallet->size = 0;
|
|
strncpy(wallet->master_password, master_password, strlen(master_password)+1);
|
|
|
|
|
|
// 4. seal wallet
|
|
size_t sealed_size = sizeof(sgx_sealed_data_t) + sizeof(wallet_t);
|
|
uint8_t* sealed_data = (uint8_t*)malloc(sealed_size);
|
|
sealing_status = seal_wallet(wallet, (sgx_sealed_data_t*)sealed_data, sealed_size);
|
|
free(wallet);
|
|
if (sealing_status != SGX_SUCCESS) {
|
|
free(sealed_data);
|
|
return ERR_FAIL_SEAL;
|
|
}
|
|
|
|
|
|
// 5. save wallet
|
|
ocall_status = ocall_save_wallet(&ocall_ret, sealed_data, sealed_size);
|
|
free(sealed_data);
|
|
if (ocall_ret != 0 || ocall_status != SGX_SUCCESS) {
|
|
return ERR_CANNOT_SAVE_WALLET;
|
|
}
|
|
|
|
|
|
// 6. exit enclave
|
|
return RET_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Provides the wallet content. The sizes/length of
|
|
* pointers need to be specified, otherwise SGX will
|
|
* assume a count of 1 for all pointers.
|
|
*
|
|
*/
|
|
int ecall_show_wallet(const char* master_password, wallet_t* wallet, size_t wallet_size) {
|
|
|
|
//
|
|
// OVERVIEW:
|
|
// 1. [ocall] load wallet
|
|
// 2. unseal wallet
|
|
// 3. verify master-password
|
|
// 4. return wallet to app
|
|
// 5. exit enclave
|
|
//
|
|
//
|
|
sgx_status_t ocall_status, sealing_status;
|
|
int ocall_ret;
|
|
|
|
|
|
|
|
// 1. load wallet
|
|
size_t sealed_size = sizeof(sgx_sealed_data_t) + sizeof(wallet_t);
|
|
uint8_t* sealed_data = (uint8_t*)malloc(sealed_size);
|
|
ocall_status = ocall_load_wallet(&ocall_ret, sealed_data, sealed_size);
|
|
if (ocall_ret != 0 || ocall_status != SGX_SUCCESS) {
|
|
free(sealed_data);
|
|
return ERR_CANNOT_LOAD_WALLET;
|
|
}
|
|
|
|
|
|
// 2. unseal loaded wallet
|
|
uint32_t plaintext_size = sizeof(wallet_t);
|
|
wallet_t* unsealed_wallet = (wallet_t*)malloc(plaintext_size);
|
|
sealing_status = unseal_wallet((sgx_sealed_data_t*)sealed_data, unsealed_wallet, plaintext_size);
|
|
free(sealed_data);
|
|
if (sealing_status != SGX_SUCCESS) {
|
|
free(unsealed_wallet);
|
|
return ERR_FAIL_UNSEAL;
|
|
}
|
|
|
|
|
|
// 3. verify master-password
|
|
if (strcmp(unsealed_wallet->master_password, master_password) != 0) {
|
|
free(unsealed_wallet);
|
|
return ERR_WRONG_MASTER_PASSWORD;
|
|
}
|
|
|
|
|
|
// 4. return wallet to app
|
|
(* wallet) = *unsealed_wallet;
|
|
free(unsealed_wallet);
|
|
|
|
|
|
// 5. exit enclave
|
|
return RET_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Changes the wallet's master-password.
|
|
*
|
|
*/
|
|
int ecall_change_master_password(const char* old_password, const char* new_password) {
|
|
|
|
//
|
|
// OVERVIEW:
|
|
// 1. check password policy
|
|
// 2. [ocall] load wallet
|
|
// 3. unseal wallet
|
|
// 4. verify old password
|
|
// 5. update password
|
|
// 6. seal wallet
|
|
// 7. [ocall] save sealed wallet
|
|
// 8. exit enclave
|
|
//
|
|
//
|
|
sgx_status_t ocall_status, sealing_status;
|
|
int ocall_ret;
|
|
|
|
|
|
|
|
// 1. check passaword policy
|
|
if (strlen(new_password) < 8 || strlen(new_password)+1 > MAX_ITEM_SIZE) {
|
|
return ERR_PASSWORD_OUT_OF_RANGE;
|
|
}
|
|
|
|
|
|
// 2. load wallet
|
|
size_t sealed_size = sizeof(sgx_sealed_data_t) + sizeof(wallet_t);
|
|
uint8_t* sealed_data = (uint8_t*)malloc(sealed_size);
|
|
ocall_status = ocall_load_wallet(&ocall_ret, sealed_data, sealed_size);
|
|
if (ocall_ret != 0 || ocall_status != SGX_SUCCESS) {
|
|
free(sealed_data);
|
|
return ERR_CANNOT_LOAD_WALLET;
|
|
}
|
|
|
|
|
|
// 3. unseal wallet
|
|
uint32_t plaintext_size = sizeof(wallet_t);
|
|
wallet_t* wallet = (wallet_t*)malloc(plaintext_size);
|
|
sealing_status = unseal_wallet((sgx_sealed_data_t*)sealed_data, wallet, plaintext_size);
|
|
free(sealed_data);
|
|
if (sealing_status != SGX_SUCCESS) {
|
|
free(wallet);
|
|
return ERR_FAIL_UNSEAL;
|
|
}
|
|
|
|
|
|
// 4. verify master-password
|
|
if (strcmp(wallet->master_password, old_password) != 0) {
|
|
free(wallet);
|
|
return ERR_WRONG_MASTER_PASSWORD;
|
|
}
|
|
|
|
|
|
// 5. update password
|
|
strncpy(wallet->master_password, new_password, strlen(new_password)+1);
|
|
|
|
|
|
// 6. seal wallet
|
|
sealed_data = (uint8_t*)malloc(sealed_size);
|
|
sealing_status = seal_wallet(wallet, (sgx_sealed_data_t*)sealed_data, sealed_size);
|
|
free(wallet);
|
|
if (sealing_status != SGX_SUCCESS) {
|
|
free(wallet);
|
|
free(sealed_data);
|
|
return ERR_FAIL_SEAL;
|
|
}
|
|
|
|
|
|
// 7. save wallet
|
|
ocall_status = ocall_save_wallet(&ocall_ret, sealed_data, sealed_size);
|
|
free(sealed_data);
|
|
if (ocall_ret != 0 || ocall_status != SGX_SUCCESS) {
|
|
return ERR_CANNOT_SAVE_WALLET;
|
|
}
|
|
|
|
|
|
// 6. exit enclave
|
|
return RET_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Adds an item to the wallet. The sizes/length of
|
|
* pointers need to be specified, otherwise SGX will
|
|
* assume a count of 1 for all pointers.
|
|
*
|
|
*/
|
|
int ecall_add_item(const char* master_password, const item_t* item, const size_t item_size) {
|
|
|
|
//
|
|
// OVERVIEW:
|
|
// 1. [ocall] load wallet
|
|
// 2. unseal wallet
|
|
// 3. verify master-password
|
|
// 4. check input length
|
|
// 5. add item to the wallet
|
|
// 6. seal wallet
|
|
// 7. [ocall] save sealed wallet
|
|
// 8. exit enclave
|
|
//
|
|
//
|
|
sgx_status_t ocall_status, sealing_status;
|
|
int ocall_ret;
|
|
|
|
|
|
|
|
// 2. load wallet
|
|
size_t sealed_size = sizeof(sgx_sealed_data_t) + sizeof(wallet_t);
|
|
uint8_t* sealed_data = (uint8_t*)malloc(sealed_size);
|
|
ocall_status = ocall_load_wallet(&ocall_ret, sealed_data, sealed_size);
|
|
if (ocall_ret != 0 || ocall_status != SGX_SUCCESS) {
|
|
free(sealed_data);
|
|
return ERR_CANNOT_LOAD_WALLET;
|
|
}
|
|
|
|
|
|
// 3. unseal wallet
|
|
uint32_t plaintext_size = sizeof(wallet_t);
|
|
wallet_t* wallet = (wallet_t*)malloc(plaintext_size);
|
|
sealing_status = unseal_wallet((sgx_sealed_data_t*)sealed_data, wallet, plaintext_size);
|
|
free(sealed_data);
|
|
if (sealing_status != SGX_SUCCESS) {
|
|
free(wallet);
|
|
return ERR_FAIL_UNSEAL;
|
|
}
|
|
|
|
|
|
// 3. verify master-password
|
|
if (strcmp(wallet->master_password, master_password) != 0) {
|
|
free(wallet);
|
|
return ERR_WRONG_MASTER_PASSWORD;
|
|
}
|
|
|
|
|
|
// 4. check input length
|
|
if (strlen(item->title)+1 > MAX_ITEM_SIZE ||
|
|
strlen(item->username)+1 > MAX_ITEM_SIZE ||
|
|
strlen(item->password)+1 > MAX_ITEM_SIZE
|
|
) {
|
|
free(wallet);
|
|
return ERR_ITEM_TOO_LONG;
|
|
}
|
|
|
|
|
|
// 5. add item to the wallet
|
|
size_t wallet_size = wallet->size;
|
|
if (wallet_size >= MAX_ITEMS) {
|
|
free(wallet);
|
|
return ERR_WALLET_FULL;
|
|
}
|
|
wallet->items[wallet_size] = *item;
|
|
++wallet->size;
|
|
|
|
|
|
// 6. seal wallet
|
|
sealed_data = (uint8_t*)malloc(sealed_size);
|
|
sealing_status = seal_wallet(wallet, (sgx_sealed_data_t*)sealed_data, sealed_size);
|
|
free(wallet);
|
|
if (sealing_status != SGX_SUCCESS) {
|
|
free(wallet);
|
|
free(sealed_data);
|
|
return ERR_FAIL_SEAL;
|
|
}
|
|
|
|
|
|
// 7. save wallet
|
|
ocall_status = ocall_save_wallet(&ocall_ret, sealed_data, sealed_size);
|
|
free(sealed_data);
|
|
if (ocall_ret != 0 || ocall_status != SGX_SUCCESS) {
|
|
return ERR_CANNOT_SAVE_WALLET;
|
|
}
|
|
|
|
|
|
// 8. exit enclave
|
|
return RET_SUCCESS;
|
|
}
|
|
|
|
|
|
/**
|
|
* @brief Removes an item from the wallet. The sizes/length of
|
|
* pointers need to be specified, otherwise SGX will
|
|
* assume a count of 1 for all pointers.
|
|
*
|
|
*/
|
|
int ecall_remove_item(const char* master_password, const int index) {
|
|
|
|
//
|
|
// OVERVIEW:
|
|
// 1. check index bounds
|
|
// 2. [ocall] load wallet
|
|
// 3. unseal wallet
|
|
// 4. verify master-password
|
|
// 5. remove item from the wallet
|
|
// 6. seal wallet
|
|
// 7. [ocall] save sealed wallet
|
|
// 8. exit enclave
|
|
//
|
|
//
|
|
sgx_status_t ocall_status, sealing_status;
|
|
int ocall_ret;
|
|
|
|
|
|
|
|
// 1. check index bounds
|
|
if (index < 0 || index >= MAX_ITEMS) {
|
|
return ERR_ITEM_DOES_NOT_EXIST;
|
|
}
|
|
|
|
|
|
// 2. load wallet
|
|
size_t sealed_size = sizeof(sgx_sealed_data_t) + sizeof(wallet_t);
|
|
uint8_t* sealed_data = (uint8_t*)malloc(sealed_size);
|
|
ocall_status = ocall_load_wallet(&ocall_ret, sealed_data, sealed_size);
|
|
if (ocall_ret != 0 || ocall_status != SGX_SUCCESS) {
|
|
free(sealed_data);
|
|
return ERR_CANNOT_LOAD_WALLET;
|
|
}
|
|
|
|
|
|
// 3. unseal wallet
|
|
uint32_t plaintext_size = sizeof(wallet_t);
|
|
wallet_t* wallet = (wallet_t*)malloc(plaintext_size);
|
|
sealing_status = unseal_wallet((sgx_sealed_data_t*)sealed_data, wallet, plaintext_size);
|
|
free(sealed_data);
|
|
if (sealing_status != SGX_SUCCESS) {
|
|
free(wallet);
|
|
return ERR_FAIL_UNSEAL;
|
|
}
|
|
|
|
|
|
// 4. verify master-password
|
|
if (strcmp(wallet->master_password, master_password) != 0) {
|
|
free(wallet);
|
|
return ERR_WRONG_MASTER_PASSWORD;
|
|
}
|
|
|
|
|
|
// 5. remove item from the wallet
|
|
size_t wallet_size = wallet->size;
|
|
if (index >= wallet_size) {
|
|
free(wallet);
|
|
return ERR_ITEM_DOES_NOT_EXIST;
|
|
}
|
|
for (int i = index; i < wallet_size-1; ++i) {
|
|
wallet->items[i] = wallet->items[i+1];
|
|
}
|
|
--wallet->size;
|
|
|
|
|
|
// 6. seal wallet
|
|
sealed_data = (uint8_t*)malloc(sealed_size);
|
|
sealing_status = seal_wallet(wallet, (sgx_sealed_data_t*)sealed_data, sealed_size);
|
|
free(wallet);
|
|
if (sealing_status != SGX_SUCCESS) {
|
|
free(sealed_data);
|
|
return ERR_FAIL_SEAL;
|
|
}
|
|
|
|
|
|
// 7. save wallet
|
|
ocall_status = ocall_save_wallet(&ocall_ret, sealed_data, sealed_size);
|
|
free(sealed_data);
|
|
if (ocall_ret != 0 || ocall_status != SGX_SUCCESS) {
|
|
return ERR_CANNOT_SAVE_WALLET;
|
|
}
|
|
|
|
|
|
// 8. exit enclave
|
|
return RET_SUCCESS;
|
|
}
|
|
|