-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathrsa_main.c
177 lines (162 loc) · 4.96 KB
/
rsa_main.c
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
#include <unistd.h>
#include <getopt.h>
#include "rsa_util.h"
#include "rsa_enc.h"
#include "rsa_dec.h"
#include "rsa.h"
static opt_t options_master[] = {
{RSA_OPT_FILE, 'f', "file", required_argument, ARG " is the input file "
"to encrypt/decrypt"},
{RSA_OPT_ENCRYPT, 'e', "encrypt", no_argument, "encrypt the data file "
"stated by --file"},
{RSA_OPT_LEVEL, 'l', "level", required_argument, "set encryption level "
"to 128(default), 256, 512 or 1024. this switch implies "
"encryption"},
{RSA_OPT_RSAENC, 'r', "rsa", no_argument, "full RSA encryption. if "
"this flag is not set, encryption will be done by xoring the "
"plaintext with a sequence generated by a pseudo random number "
"generator (RNG). the seed of the sequence will be randomly "
"generated and only it will be RSA encrypted. this switch "
"implies encryption"},
{RSA_OPT_CBC, 'c', "cbc", no_argument, "full RSA encryption using "
"Cipher Block Chaining (CBC) cipher mode. by default "
"Electronic Codebook (ECB) is used"},
{RSA_OPT_KEY_SET_DYNAMIC, 'k', "key", required_argument, "set the RSA "
"key to be used for the current encryption. this options "
"overrides the default key if it has been set. this switch "
"implies encryption"},
{RSA_OPT_DECRYPT, 'd', "decrypt", no_argument, "decrypt the encrypted "
"file stated by --file"},
{RSA_OPT_ORIG_FILE, 'o', "original", no_argument, "keep the original "
"file. if this option is not set the file will be deleted "
"after it has been encrypted/decrypted"},
{RSA_OPT_KEYGEN, 'g', "generate", required_argument, "generate an RSA "
"public/private key pair. " ARG " is its name"},
{RSA_OPT_ENC_INFO_ONLY, 'i', "info", no_argument, "get info regarding "
"an encrypted file. this depends on possessing the required "
"private key"},
{ RSA_OPT_MAX }
};
/* either encryption or decryption task are to be performed */
static int parse_args_finalize_master(unsigned int *flags, int actions)
{
/* RSA_OPT_CBC implies RSA_OPT_RSAENC */
if (*flags & (OPT_FLAG(RSA_OPT_CBC)))
*flags |= OPT_FLAG(RSA_OPT_RSAENC);
/* RSA_OPT_LEVEL, RSA_OPT_RSAENC and RSA_OPT_KEY_SET_DYNAMIC imply
* RSA_OPT_ENCRYPT */
if (*flags & (OPT_FLAG(RSA_OPT_LEVEL) | OPT_FLAG(RSA_OPT_RSAENC) |
OPT_FLAG(RSA_OPT_KEY_SET_DYNAMIC))) {
*flags |= OPT_FLAG(RSA_OPT_ENCRYPT);
}
if (*flags & (OPT_FLAG(RSA_OPT_ENC_INFO_ONLY)))
*flags |= OPT_FLAG(RSA_OPT_DECRYPT);
if (*flags & OPT_FLAG(RSA_OPT_ENCRYPT))
actions++;
if (*flags & OPT_FLAG(RSA_OPT_DECRYPT))
actions++;
if (*flags & OPT_FLAG(RSA_OPT_KEYGEN))
actions++;
/* test for a single action option */
if (actions != 1) {
rsa_error_message(actions ?
RSA_ERR_MULTIACTION : RSA_ERR_NOACTION);
return -1;
}
/* test for non compatible options with encrypt/decrypt */
else if ((*flags & (OPT_FLAG(RSA_OPT_ENCRYPT) |
OPT_FLAG(RSA_OPT_DECRYPT))) &&
!(*flags & OPT_FLAG(RSA_OPT_FILE))) {
rsa_error_message(RSA_ERR_NOFILE);
return -1;
}
return 0;
}
static int parse_args_master(int opt, unsigned int *flags)
{
switch (opt_short2code(options_master, opt))
{
case RSA_OPT_FILE:
OPT_ADD(flags, RSA_OPT_FILE);
if (rsa_set_file_name(optarg))
return -1;
break;
case RSA_OPT_ENCRYPT:
OPT_ADD(flags, RSA_OPT_ENCRYPT);
break;
case RSA_OPT_LEVEL:
OPT_ADD(flags, RSA_OPT_LEVEL);
if (rsa_encryption_level_set(optarg))
return -1;
break;
case RSA_OPT_RSAENC:
OPT_ADD(flags, RSA_OPT_RSAENC);
break;
case RSA_OPT_CBC:
OPT_ADD(flags, RSA_OPT_CBC);
cipher_mode = CIPHER_MODE_CBC;
break;
case RSA_OPT_KEY_SET_DYNAMIC:
OPT_ADD(flags, RSA_OPT_KEY_SET_DYNAMIC);
if (optarg && rsa_set_key_name(optarg))
return -1;
break;
case RSA_OPT_DECRYPT:
OPT_ADD(flags, RSA_OPT_DECRYPT);
break;
case RSA_OPT_ORIG_FILE:
OPT_ADD(flags, RSA_OPT_ORIG_FILE);
keep_orig_file = 1;
break;
case RSA_OPT_KEYGEN:
OPT_ADD(flags, RSA_OPT_KEYGEN);
if (rsa_set_key_data(optarg))
return -1;
break;
case RSA_OPT_ENC_INFO_ONLY:
OPT_ADD(flags, RSA_OPT_ENC_INFO_ONLY);
is_encryption_info_only = 1;
break;
default:
rsa_error_message(RSA_ERR_OPTARG);
return -1;
}
return 0;
}
int main(int argc, char *argv[])
{
int ret, action;
unsigned int flags = 0;
rsa_handler_t master_handler = {
.keytype = RSA_KEY_TYPE_PUBLIC | RSA_KEY_TYPE_PRIVATE,
.options = options_master,
.ops_handler = parse_args_master,
.ops_handler_finalize = parse_args_finalize_master,
};
if (parse_args(argc, argv, &flags, &master_handler))
return rsa_error(argv[0]);
action = rsa_action_get(flags, RSA_OPT_ENCRYPT, RSA_OPT_DECRYPT,
RSA_OPT_KEYGEN, NULL);
switch (action)
{
case OPT_FLAG(RSA_OPT_ENCRYPT):
{
if (!(flags & OPT_FLAG(RSA_OPT_LEVEL)))
rsa_encryption_level_set(NULL);
ret = flags & OPT_FLAG(RSA_OPT_RSAENC) ?
rsa_encrypt_full() : rsa_encrypt_quick();
break;
}
case OPT_FLAG(RSA_OPT_KEYGEN):
ret = rsa_keygen();
break;
case OPT_FLAG(RSA_OPT_DECRYPT):
ret = rsa_decrypt();
break;
default:
ret = rsa_action_handle_common(action, argv[0],
&master_handler);
break;
}
return ret;
}