Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "stateManager.h"
- //#define JC_DEBUG
- #define SAVE_FILE_LENGTH (crypto_secretbox_NONCEBYTES+crypto_secretbox_ZEROBYTES+crypto_hash_BYTES*2+sizeof(unsigned char) * 2 - crypto_secretbox_BOXZEROBYTES)
- // input -> password(text), target, secret(or empty), empty, empty, empty
- // output -> password(binary), target, outKey, inKey, count, waitingOnAsync
- int manageLoginStateCheck(char **manageLoginStateArgs) {
- int temp;
- // default 0 messages until async ratchet for new keys
- manageLoginStateArgs[3] = 0; // default if function fails
- manageLoginStateArgs[4] = malloc(sizeof(unsigned char));
- *manageLoginStateArgs[4] = 0;
- manageLoginStateArgs[5] = malloc(sizeof(unsigned char));
- *manageLoginStateArgs[5] = 0;
- // Check which input fields are full
- int inputsFull[3];
- for (int i = 0; i < 3; ++i) {
- if (strcmp(manageLoginStateArgs[i], "")) {
- inputsFull[i] = 1;
- }
- else {
- inputsFull[i] = 0;
- }
- }
- if (!inputsFull[0] || !inputsFull[1]) {
- return FIRST_TWO_FIELDS_MUST_BE_FULL;
- }
- // Hash password and shared secret
- if (inputsFull[0]) {
- temp = replaceWithHash(manageLoginStateArgs + 0, strlen(manageLoginStateArgs[0]));
- if (temp) {
- return LOGIN_FUNCTION_ERROR;
- }
- }
- if (inputsFull[2]) {
- temp = replaceWithHash(manageLoginStateArgs + 2, strlen(manageLoginStateArgs[2]));
- if (temp) {
- return LOGIN_FUNCTION_ERROR;
- }
- }
- #ifdef JC_DEBUG
- //printf("Sate manager - Target Name: %s\n", manageLoginStateArgs[1]);
- #endif
- // Read in save file if it exists
- int basePathLength = strlen(SAVE_FILE_PATH), extraPathLength = strlen(manageLoginStateArgs[1]);
- char saveFilePath[basePathLength + extraPathLength + 1];
- memcpy(saveFilePath, SAVE_FILE_PATH, basePathLength);
- memcpy(saveFilePath + basePathLength, manageLoginStateArgs[1], extraPathLength);
- saveFilePath[sizeof(saveFilePath) - 1] = 0;
- char *saveFileBuffer;
- temp = readFileIfExists(&saveFileBuffer, saveFilePath);
- if (temp < 0) {
- free(saveFileBuffer);
- #ifdef JC_DEBUG
- //printf("Sate manager - entered no save file block %s\n", saveFilePath);
- #endif
- // Save file doesn't exist or it's length can't be determined or it can't be read
- if (inputsFull[0] + inputsFull[1] + inputsFull[2] == 3) {
- #ifdef JC_DEBUG
- //printf("Sate manager - entered all inputs ready block\n");
- #endif
- // Ready to scene transition
- manageLoginStateArgs[3] = malloc(crypto_hash_BYTES);
- memcpy(manageLoginStateArgs[3], manageLoginStateArgs[2], crypto_hash_BYTES);
- #ifdef JC_DEBUG
- //printf("Sate manager - entered all inputs ready block - memcpys fine\n");
- #endif
- return GOOD_TO_GO;
- }
- else {
- #ifdef JC_DEBUG
- //printf("Sate manager - saveFilePath: %s\n", saveFilePath);
- #endif
- // All 3 fields must be filled out if no save exists
- return NO_SAVE_NEED_ALL_FIELDS;
- }
- }
- #ifdef JC_DEBUG
- //printf("Sate manager - pre parse/deccrypt save file\n");
- #endif
- // Parse and decrypt save file
- int cryptedSaveFileLength = temp;
- int decryptSaveFile(const char *password, char **fileBuffer, int *length);
- temp = decryptSaveFile(manageLoginStateArgs[0], &saveFileBuffer, &cryptedSaveFileLength);
- #ifdef JC_DEBUG
- //printf("Sate manager - returned from decryptSaveFile()\n");
- #endif
- if (temp < 0) {
- // Failed to decrypt save state
- memset(saveFileBuffer, 0, temp); // UNTESTED
- free(saveFileBuffer);
- #ifdef JC_DEBUG
- //printf("Sate manager - post free(saveFileBuffer)\n");
- #endif
- return PASSWORD_DID_NOT_MATCH_OR_SAVE_CORRUPT;
- }
- #ifdef JC_DEBUG
- //printf("Sate manager - post parse/decrypt save file\n");
- #endif
- // File buffer now contains saved state
- if (!inputsFull[2]) {
- // No new shared secret have to place loaded data into shared secret
- free(manageLoginStateArgs[2]);
- // Parsing decrypted save file
- manageLoginStateArgs[2] = malloc(crypto_hash_BYTES);
- manageLoginStateArgs[3] = malloc(crypto_hash_BYTES);
- memcpy(manageLoginStateArgs[2], saveFileBuffer, crypto_hash_BYTES);
- memcpy(manageLoginStateArgs[3], saveFileBuffer + crypto_hash_BYTES, crypto_hash_BYTES);
- memcpy(manageLoginStateArgs[4], saveFileBuffer + crypto_hash_BYTES * 2, sizeof(unsigned char));
- memcpy(manageLoginStateArgs[5], saveFileBuffer + crypto_hash_BYTES * 2 + sizeof(unsigned char), sizeof(unsigned char));
- #ifdef JC_DEBUG
- //printf("\n\nSate manager - incomingKey loaded from save file: %s\n\n", manageLoginStateArgs[3]);
- #endif
- }
- else {
- #ifdef JC_DEBUG
- //printf("\n\nState manager - reached right place at least\n");
- //printf("\n\nInputsFull[2]: %x\n\n", inputsFull[2]);
- #endif
- // new secret duplicated into both incoming and outgoing keys
- manageLoginStateArgs[3] = malloc(crypto_hash_BYTES);
- memcpy(manageLoginStateArgs[3], manageLoginStateArgs[2], crypto_hash_BYTES);
- }
- memset(saveFileBuffer, 0, cryptedSaveFileLength);
- free(saveFileBuffer);
- #ifdef JC_DEBUG
- //printf("Sate manager - post argument setting\n");
- #endif
- // Ready to scene transition
- return GOOD_TO_GO;
- return -1;
- }
- int readFileIfExists(char **fileBuffer, const char *filePath) {
- *fileBuffer = 0;
- // Attempt to open file
- int saveFile = open(filePath, O_RDONLY);
- if (saveFile < 0) {
- #ifdef JC_DEBUG
- //printf("readFileIfExists - could not open file\n");
- //perror("Reason");
- #endif
- return -1;
- }
- // Get file length
- int getFileSize(const char *fileName);
- int saveFileLength = getFileSize(filePath);
- if (saveFileLength < 0) return -1;
- // Read file into buffer
- *fileBuffer = malloc(saveFileLength);
- int temp = read(saveFile, *fileBuffer, saveFileLength);
- if (temp < 0) {
- g_print("Error reading file into buffer.\nPath: %s", filePath);
- perror("Reason");
- return -1;
- }
- return saveFileLength;
- }
- int getFileSize(const char *fileName) {
- int temp;
- struct stat st;
- temp = stat(fileName, &st);
- if (temp) {
- return -1;
- }
- return st.st_size;
- }
- int decryptSaveFile(const char *password, char **fileBuffer, int *saveFileLength) {
- // Verify save file has enough size to be used as a save file
- if (*saveFileLength < SAVE_FILE_LENGTH) {
- g_print("The save file is not the apropriate size.\n");
- return -1;
- }
- #ifdef JC_DEBUG
- if (crypto_secretbox_KEYBYTES > crypto_hash_BYTES) {
- g_print("Keys are bigger than hashes, need something fancier.\n");
- return -1;
- }
- #endif
- #ifdef JC_DEBUG
- //printf("save file byte size pre decryption: %d\n", *saveFileLength);
- #endif
- unsigned char *pt;
- int result = secretKeyDecrypt(&pt, *fileBuffer, saveFileLength, password);
- if (result < 0) {
- free(pt);
- g_print("Decrypting save file verification failed.\n");
- return -1;
- }
- #ifdef JC_DEBUG
- //printf("save file byte size post decryption: %d\n", *saveFileLength);
- //printf("\n\nSAVE_DATA ON LOAD: %s\n\n", pt);
- #endif
- free(*fileBuffer);
- *fileBuffer = pt;
- return 0;
- }
- int stateManagerSaveState(const char *password, const char *properTarget, const char *outgoingKey, const char *incomingKey, const char *countTillRatchet, const char *waitingOnAsync) {
- // open save file
- int properTargetLength = strlen(properTarget), saveFilePathLength = strlen(SAVE_FILE_PATH);
- char filePath[properTargetLength + saveFilePathLength + 1];
- memcpy(filePath, SAVE_FILE_PATH, saveFilePathLength);
- memcpy(filePath + saveFilePathLength, properTarget, properTargetLength);
- filePath[sizeof(filePath) - 1] = 0;
- int saveFile = open(filePath, O_RDWR | O_CREAT, 0666);
- if (saveFile < 0) {
- printf("Save filed could not be opened.\n");
- return -1;
- }
- // load save data into a buffer
- unsigned char saveData[crypto_hash_BYTES * 2 + sizeof(unsigned char) * 2];
- memcpy(saveData, outgoingKey, crypto_hash_BYTES);
- int offset = crypto_hash_BYTES;
- memcpy(saveData + offset, incomingKey, crypto_hash_BYTES);
- offset += crypto_hash_BYTES;
- memcpy(saveData + offset, countTillRatchet, sizeof(unsigned char));
- offset += sizeof(unsigned char);
- memcpy(saveData + offset, waitingOnAsync, sizeof(unsigned char));
- unsigned char *encryptedSaveData;
- int length = sizeof(saveData);
- #ifdef JC_DEBUG
- //memset(saveData, 65, sizeof(saveData));
- //printf("\n\nSAVE_DATA ON SAVE (unencrypted): %s\n\n", saveData);
- #endif
- // encrypt the save data
- secretKeyEncrypt(&encryptedSaveData, saveData, &length, password);
- #ifdef JC_DEBUG
- //printf("save file byte size post encryption: %d\n", length);
- #endif
- // save state to disk
- if (write(saveFile, encryptedSaveData, length) < 0) {
- #ifdef JC_DEBUG
- printf("write() on save failed.\n");
- perror("Reason");
- #endif
- return -1;
- };
- if (close(saveFile) < 0) {
- printf("close() on save file failed.\n");
- return -1;
- };
- // clean and free memory
- memset(saveData, 0, sizeof(saveData));
- memset(encryptedSaveData, 0, length);
- free(encryptedSaveData);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement