-
Notifications
You must be signed in to change notification settings - Fork 0
/
menu.c
359 lines (347 loc) · 14.3 KB
/
menu.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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
#include <stdio.h>
#include <stdlib.h>
#include "pointeurs.h"
#include "menu.h"
#ifndef WIN32
#include <sys/types.h>
#endif
#include <dirent.h>
#include <string.h>
/** \file menu.c
*
* \brief Contient des fonctions et permettant de générer et afficher les menus.
* \author I. Laruelle / A. Masciulli - UTT NF05 A18
*
*/
/** \fn void menuprincipal()
*
* \brief Affiche le menu principal dans la console.
*/
void menuprincipal()
{
int choix;
do
{
printf("-------------------------------------------------\n");
printf("----------------- Logiciel RSA ------------------\n");
printf("-------------------------------------------------\n");
printf(" Concepteurs : Ivann LARUELLE / Adriana MASCIULLI\n");
printf(" Dans le cadre d'un cours sur le C (NF05) a l'UTT\n");
printf("---------- https://github.com/larueli/ ----------\n");
printf("\n");
printf("Menu principal\n\n");
printf("\t\t1. Generation d'une paire de clef\n");
printf("\t\t2. Envoi d'un message\n");
printf("\t\t3. Reception d'un message\n");
printf("\n");
printf("\t\t0. Quitter\n\n");
choix = saisieInt("\tVotre choix : ");
switch(choix)
{
case 1:
menugeneration();
break;
case 2:
menuchiffrement();
break;
case 3:
menudechiffrement();
break;
}
}while(choix!=0);
}
/** \fn void menugeneration()
*
* \brief Affiche le menu de génération de clef dans la console, et enregistre les clefs dans leurs dossiers repectifs.
* \warning La fonction srand() doit avoir été appellée auparavant.
* \note Les clefs seront écrites sous la forme "n exposant" sur la même ligne d'un fichier en base 2.
*
* Les clefs seront enregistrées dans les dossiers public_keys et private_keys du répertoire d'exécution.
*/
void menugeneration()
{
RSA newClef;
printf("\n-----------------------\nGeneration de la clef\n\n");
printf("\t\t1. Generation automatique\n");
printf("\t\t2. Generation manuelle\n");
printf("\n\t\t0. Revenir au menu\n\n");
int choix = saisieInt("\tVotre choix : ");
switch(choix)
{
case 1:
printf("\n\nRecherche de p...");
newClef.p = rabinmillerdeux();
printf("\n\nRecherche de q...");
newClef.q = rabinmillerdeux();
printf("\n");
break;
case 2:
printf("\n");
int base;
do
{
base = saisieInt("Dans quelle base allez-vous saisir p et q ? (10 ou 2) : ");
}while(base != 10 && base != 2);
newClef.p = saisieGRDNB("Veuillez saisir p premier : ");
newClef.q = saisieGRDNB("Veuillez saisir q premier : ");
if(base == 10)
{
affectation(&(newClef.p),b10Tob2(newClef.p,0));
affectation(&(newClef.q),b10Tob2(newClef.q,0));
}
break;
default:
printf("\n");
menuprincipal();
break;
}
newClef.n = mulnaive(newClef.p,newClef.q,2);
printf("\nLongueur de la clef : %d bits\n\n",(newClef.n).indicemax);
newClef.phi = mulnaive(sous(newClef.p,un(),2),sous(newClef.q,un(),2),2);
newClef.e = calcul_e(b2Tob10(newClef.phi),&(newClef.d));
char *fichier = (char*)malloc(19*sizeof(char));
verifErreurAlloc(fichier);
strcpy(fichier,"private_keys\\");
printf("Vos clefs seront enregistrees sous la forme nom.key dans des dossiers :\n\n\tpublic_keys\\ pour la clef publique\n\tprivate_keys\\ pour la clef privee\n\nVeuillez rentrer le nom de la clef privee : ");
char *fichierclef = saisieBrute();
fichier = realloc(fichier,strlen(fichierclef)+19);
verifErreurAlloc(fichier);
strcat(fichier,fichierclef);
strcat(fichier,".key");
fichierClef(&(newClef.n),&(newClef.d),1,fichier);
printf("Veuillez rentrer le nom de la clef publique : ");
free(fichier);
fichier = (char*)malloc(19*sizeof(char));
verifErreurAlloc(fichier);
strcpy(fichier,"public_keys\\");
free(fichierclef);
fichierclef = saisieBrute();
fichier = realloc(fichier,strlen(fichierclef)+19);
verifErreurAlloc(fichier);
strcat(fichier,fichierclef);
strcat(fichier,".key");
fichierClef(&(newClef.n),&(newClef.e),1,fichier);
free(fichier);
}
/** \fn int fichierClef(GRDNB *a, GRDNB *b, int mode, char *fichier)
*
* \brief Ecrit/Lit sur une ligne deux grands nombres séparés par un espace.
* \param[in,out] a Pointeur sur un GRDNB
* \param[in,out] b Pointeur sur un GRDNB
* \param[in] mode Si mode = 1, écriture de a et b.\n Si mode = 0, lecture dans a et b.
* \param[in] fichier Chemin d'accès relatif ou absolu du fichier accessible en lecture ou écriture le cas échéant.
* \warning En lecture, les clefs doivent être écrites dans le fichier en base 2.
* \return 0 si l'opération s'est bien déroulée\n 1 sinon.
*
* En mode écriture, on convertit les GRDNB en chaine et on écrit sur une seule ligne les chaines séparées par un espace.
*
* En mode lecture, on essaye de récupérer les deux chaines, et on les convertit en GRDNB si tout se passe bien.
*/
int fichierClef(GRDNB *a, GRDNB *b, int mode, char *fichier)
{
if(fichier == NULL)
return 1;
if(mode)
{
FILE *fich = fopen(fichier,"w");
if(fich!=NULL)
{
fputs(GRDNBtoSTR(*a),fich);
fputc(' ',fich);
fputs(GRDNBtoSTR(*b),fich);
fclose(fich);
return 0;
}
}
else
{
FILE *fich = fopen(fichier,"r");
if(fich!=NULL)
{
int retour = 0,test;
fseek(fich,0,SEEK_END);
int taille = ftell(fich);
fseek(fich,0,SEEK_SET);
char *achar = (char*)malloc(taille*sizeof(char));
verifErreurAlloc(achar);
char *bchar = (char*)malloc(taille*sizeof(char));
verifErreurAlloc(bchar);
test = fscanf(fich,"%s %s",achar,bchar);
if(test != 2)
{
printf("\nErreur de lecture, verifiez le format de vos clefs.\n");
retour = 1;
}
else
{
*a = str2grdnb(achar);
*b = str2grdnb(bchar);
if(a->signe == -1 || b->signe == -1 || !isBase2(*a) || !isBase2(*b) || a->indicemax < 9 || b->indicemax == 0)
{
printf("n n'est pas bien ecrit : %d\nL'exposant n'est pas bien ecrit : %d\nn n'est pas en base 2 : %d\nL'exposant n'est pas en base 2 : %d\nn a moins de 8 bits %d\nL'exposant est nul : %d\n",a->signe == -1, b->signe == -1, !isBase2(*a), !isBase2(*b), a->indicemax < 9, b->indicemax == 0);
printf("\nErreur de lecture, verifiez le format de vos clefs.\n");
retour = 1;
}
}
free(achar);
free(bchar);
fclose(fich);
return retour;
}
else
{
printf("\nErreur lors de l'acces au fichier\n");
}
}
return 1;
}
/** \fn char *listeClefs(char *nomduDossier)
* \brief Affiche un menu ergonomique pour sélectionner une clef dans un répertoire donné.
* \param[in] Chaine de caractère contenant le chemin d'accès relatif ou absolu du répertoire, accessible en lecture
* \return La chaine de caractère comprenant le chemin d'accès relatif ou absolu à la clef selectionnée par l'utilisateur, ou NULL s'il n'y pas de clef.
*
* \warning Les clefs doivent avoir l'extension .key pour être affichées dans le menu.
*
* On ouvre le dossier, on ajoute le nom des fichiers finissant par .key dans un tableau, puis l'utilisateur choisit la clef voulue.
*
*/
char *listeClefs(char *nomduDossier)
{
struct dirent *contenu;
int nbfichiers = 0;
DIR *rep;
rep = opendir(nomduDossier);
char **listedefichiers = calloc(1,sizeof(char*));
verifErreurAlloc(listedefichiers);
while ((contenu = readdir(rep)))
{
if(strlen(contenu->d_name) > 4 && !strcmp((contenu->d_name)+strlen(contenu->d_name)-4,".key"))
{
nbfichiers++;
listedefichiers = (char**)realloc(listedefichiers,nbfichiers*sizeof(char*));
verifErreurAlloc(listedefichiers);
listedefichiers[nbfichiers-1] = (char*)malloc((strlen(contenu->d_name) + strlen(nomduDossier) + 3)*sizeof(char));
verifErreurAlloc(listedefichiers[nbfichiers-1]);
strcpy(listedefichiers[nbfichiers-1],nomduDossier);
strcat(listedefichiers[nbfichiers-1],"/");
strcat(listedefichiers[nbfichiers-1],contenu->d_name);
}
}
closedir(rep);
int i = 0;
int choixcorrect = 0, choix;
if(nbfichiers > 0)
printf("\n\nVeuillez selectionner une clef :\n\n");
else
{
printf("\n\n! Vous n'avez pas de clef, generez-en ou importez-en !\n");
return NULL;
}
while(!choixcorrect)
{
for(i=1;i<nbfichiers+1;i++)
{
printf("\t\t%d. %s\n",i,listedefichiers[i-1]);
}
printf("\n");
choix = saisieInt("\tVotre choix : ");
choixcorrect = choix >= 1 && choix <= nbfichiers;
}
return listedefichiers[choix-1];
}
/** \fn void menuchiffrement()
* \brief Permet de chiffrer, signer ou de signer puis chiffrer un document.
*
* \warning Dans le cadre de la signature couplée au chiffrement, le fichier "tmp.tmp" du répertoire d'exécution sera créé ou écrasé puis effacé.
*
* Affiche le menu de chiffrement et lance les fonctions correspondantes.
*/
void menuchiffrement()
{
printf("\n-----------------------\nChiffrement\n\n");
printf("\t\t1. Chiffrement\n");
printf("\t\t2. Signature\n");
printf("\t\t3. Signature et chiffrement\n");
printf("\n\t\t0. Revenir au menu\n\n");
int choix = saisieInt("\tVotre choix : ");
if(choix != 1 && choix != 2 && choix !=3)
menuprincipal();
printf("\nVeuillez saisir le nom du fichier a chiffrer : ");
char *fichier = saisieBrute();
printf("Veuillez saisir le nom du fichier chiffre : ");
char *fichierdest = saisieBrute();
RSA clefprivee,clefpublique;
switch(choix)
{
case 1:
printf("\nVous allez chiffrer ce message avec la clef publique du destinataire, importee au prealable dans le dossier public_keys\\\n");
if(!fichierClef(&(clefpublique.n),&(clefpublique.e),0,listeClefs("public_keys")))
chiffrer(fichier,fichierdest,clefpublique.n,clefpublique.e);
break;
case 2:
printf("\nVous allez chiffrer ce message avec votre clef, importee au prealable dans le dossier private_keys\\ ou generee via le logiciel\n");
if(!fichierClef(&(clefprivee.n),&(clefprivee.d),0,listeClefs("private_keys")))
chiffrer(fichier,fichierdest,clefprivee.n,clefprivee.d);
break;
case 3:
printf("\nVous allez chiffrer ce message avec votre clef privee, puis avec la clef publique du destinataire. \nVotre clef privee doit etre generee avec le logiciel ou importee dans le dossier private_keys\\\nLa clef publique du destinataire doit etre importee au prealable dans le dossier public_keys\\\n");
if(!(fichierClef(&(clefprivee.n),&(clefprivee.d),0,listeClefs("private_keys")) || fichierClef(&(clefpublique.n),&(clefpublique.e),0,listeClefs("public_keys"))));
{
chiffrer(fichier,"tmp.tmp",clefprivee.n,clefprivee.d);
printf("\nSecond passage");
chiffrer("tmp.tmp",fichierdest,clefpublique.n,clefpublique.e);
remove("tmp.tmp");
}
break;
}
free(fichier);
free(fichierdest);
}
/** \fn void menudechiffrement()
* \brief Permet de dechiffrer, vérifier la signature ou de dechiffrer puis verifier la signature d'un document.
*
* \warning Dans le cadre du double déchiffrement, le fichier "tmp.tmp" du répertoire d'exécution sera créé ou écrasé puis effacé.
*
* Affiche le menu de déchiffrement et lance les fonctions correspondantes.
*/
void menudechiffrement()
{
printf("\n-----------------------\nDechiffrement\n\n");
printf("\t\t1. Dechiffrement\n");
printf("\t\t2. Verification de signature\n");
printf("\t\t3. Dechiffrement puis verification de signature\n");
printf("\n\t\t0. Revenir au menu\n\n");
int choix = saisieInt("\tVotre choix : ");
if(choix != 1 && choix != 2 && choix != 3)
menuprincipal();
printf("Veuillez saisir le nom du fichier a dechiffrer : ");
char *fichier = saisieBrute();
printf("Veuillez saisir le nom du fichier dechiffre : ");
char *fichierdest = saisieBrute();
RSA clefprivee,clefpublique;
switch(choix)
{
case 1:
printf("\nVous allez dechiffrer ce message avec votre clef, importee au prealable dans le dossier private_keys\\ ou generee via le logiciel\n");
if(!fichierClef(&(clefprivee.n),&(clefprivee.d),0,listeClefs("private_keys")))
dechiffrer(fichier,fichierdest,clefprivee.n,clefprivee.d);
break;
case 2:
printf("\nVous allez dechiffrer ce message avec la clef publique de l'emetteur, importee au prealable dans le dossier public_keys\\\n");
if(!fichierClef(&(clefpublique.n),&(clefpublique.e),0,listeClefs("public_keys")))
dechiffrer(fichier,fichierdest,clefpublique.n,clefpublique.e);
break;
case 3:
printf("\nVous allez dechiffrer ce message avec votre clef privee, puis avec la clef publique de l'emetteur.\nVotre clef privee doit etre generee avec le logiciel ou importee dans le dossier private_keys\\\nLa clef publique de l'emetteur doit etre importee au prealable dans le dossier public_keys\\\n");
if(!(fichierClef(&(clefprivee.n),&(clefprivee.d),0,listeClefs("private_keys")) || fichierClef(&(clefpublique.n),&(clefpublique.e),0,listeClefs("public_keys"))));
{
dechiffrer(fichier,"tmp.tmp",clefprivee.n,clefprivee.d);
printf("\nSecond passage");
dechiffrer("tmp.tmp",fichierdest,clefpublique.n,clefpublique.e);
remove("tmp.tmp");
}
break;
}
free(fichier);
free(fichierdest);
}