aboutsummaryrefslogtreecommitdiff
path: root/main.c
blob: 0d8c426d079c6799f351b8028ff475d930bf2a53 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include <openssl/aes.h>

#define MAX_PASSWORD_LENGTH 128
#define AES_KEY_SIZE 256 / 8

struct Password {
    char website[128];
    char username[128];
    char password[MAX_PASSWORD_LENGTH];
    char notes[256];
};

void generate_password(char *password, int length) {
    // Generate a random password of the specified length
    // using a combination of upper and lowercase letters, digits, and special characters
    char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()_+-=[]{}\\|;:'\",.<>/?";
    int charset_size = strlen(charset);

    for (int i = 0; i < length; i++) {
        int index = rand() % charset_size;
        password[i] = charset[index];
    }

    password[length] = '\0';
}

void encrypt_password(struct Password *password, unsigned char *key) {
    AES_KEY aes_key;
    unsigned char iv[AES_BLOCK_SIZE];
    unsigned char encrypted_password[AES_BLOCK_SIZE];

    // Generate a random initialization vector
    RAND_bytes(iv, AES_BLOCK_SIZE);

    // Initialize the encryption key
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    EVP_EncryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);

    // Encrypt the password using AES-256 encryption
    int outlen, tmplen;
    EVP_EncryptUpdate(ctx, encrypted_password, &outlen, (unsigned char*)password->password, AES_BLOCK_SIZE);
    EVP_EncryptFinal_ex(ctx, encrypted_password + outlen, &tmplen);

    // Copy the encrypted password and IV back into the password struct
    memcpy(password->password, encrypted_password, AES_BLOCK_SIZE);
    memcpy(password->notes, iv, AES_BLOCK_SIZE);

    // Clean up
    EVP_CIPHER_CTX_free(ctx);
}

void decrypt_password(struct Password *password, unsigned char *key) {
    EVP_CIPHER_CTX *ctx;
    unsigned char iv[AES_BLOCK_SIZE];
    unsigned char decrypted_password[AES_BLOCK_SIZE];

    // Read the initialization vector from the password struct
    memcpy(iv, password->notes, AES_BLOCK_SIZE);

    // Initialize the decryption context
    ctx = EVP_CIPHER_CTX_new();
    EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);

    // Decrypt the password using AES-256 decryption
    int outlen, tmplen;
    EVP_DecryptUpdate(ctx, decrypted_password, &outlen, (unsigned char*)password->password, AES_BLOCK_SIZE);
    EVP_DecryptFinal_ex(ctx, decrypted_password + outlen, &tmplen);

    // Copy the decrypted password back into the password struct
    memcpy(password->password, decrypted_password, MAX_PASSWORD_LENGTH);

    // Clean up
    EVP_CIPHER_CTX_free(ctx);
}

void save_password(struct Password *password, char *filename, unsigned char *key) {
    // Save the password information to a file in an encrypted format using AES-256 encryption
    FILE *fp = fopen(filename, "wb");
    if (fp == NULL) {
        printf("Error: could not open file %s for writing.\n", filename);
        return;
    }

    // Encrypt the password information
    encrypt_password(password, key);

    // Write the encrypted password information to the file
    fwrite(password, sizeof(struct Password), 1, fp);

    fclose(fp);
}

void load_password(struct Password *password, char *filename, unsigned char *key) {
    // Load the password information from a file and decrypt it using AES-256 decryption
    // Open the file for reading
    FILE *file = fopen(filename, "rb");
    if (file == NULL) {
        printf("Error: Could not open file %s\n", filename);
        return;
    }

    // Read the encrypted password information from the file
    unsigned char iv[AES_BLOCK_SIZE];
    fread(iv, 1, AES_BLOCK_SIZE, file);
    unsigned char encrypted[sizeof(struct Password)];
    fread(encrypted, 1, sizeof(struct Password), file);

    // Decrypt the password information
    AES_KEY aes_key;
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), NULL, key, iv);
    int outlen, finallen;
    EVP_DecryptUpdate(ctx, (unsigned char*)password, &outlen, encrypted, sizeof(struct Password));
    EVP_DecryptFinal_ex(ctx, ((unsigned char*)password) + outlen, &finallen);
    EVP_CIPHER_CTX_free(ctx);

    // Close the file
    fclose(file);
}

int main() {
    int choice;
    char filename[256];
    struct Password password;
    unsigned char key[AES_BLOCK_SIZE];

    // Get the encryption key from the user
    printf("Enter the encryption key: ");
    char key_str[AES_BLOCK_SIZE];
    printf("Enter the encryption key: ");
    fgets(key_str, AES_BLOCK_SIZE, stdin);
    for (int i = 0; i < AES_BLOCK_SIZE; i++) {
        key[i] = (unsigned char) key_str[i];
    }

    // Loop until the user chooses to exit the program
    do {
        // Display the menu of options to the user
        printf("\n1. Generate new password\n");
        printf("2. Save password information to file\n");
        printf("3. Load password information from file\n");
        printf("4. Exit program\n\n");
        printf("Enter your choice: ");
        scanf("%d", &choice);

        switch (choice) {
            case 1:
                // Generate a new password and display it to the user
                generate_password(password.password, MAX_PASSWORD_LENGTH);
                printf("New password: %s\n", password.password);
                break;
            case 2:
                // Get the filename from the user and save the password information to a file
                printf("Enter the filename to save to: ");
                scanf("%s", filename);
                save_password(&password, filename, key);
                printf("Password information saved to %s\n", filename);
                break;
            case 3:
                // Get the filename from the user and load the password information from a file
                printf("Enter the filename to load from:");
                scanf("%s", filename);
                load_password(&password, filename, key);
                printf("Password information loaded from %s\n", filename);
                // Display the password information to the user
                printf("Website: %s\n", password.website);
                printf("Username: %s\n", password.username);
                printf("Password: %s\n", password.password);
                printf("Notes: %s\n", password.notes);
                break;
            case 4:
                // Exit the program
                printf("Exiting program...\n");
                break;
            default:
                // Invalid choice
                printf("Invalid choice. Please enter a number between 1 and 4.\n");
                break;
        }
    } while (choice != 4);

    return 0;
}