Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* Implementiert in dieser Datei die Teilaufgabe (b) */
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include "otp_encrypt.h"
- #include "vorgabe.h"
- extern int exitcode; /* diesen Wert gibt die main()-Funktion als Exit-
- Code zurueck (in otp.c definiert) */
- /* praktische Fehlermeldungen fuer eure Fehlerbehandlungen */
- #define ERRMSG_ENCRYPTED_EXISTS "Die verschluesselte Datei existiert " \
- "bereits!"
- #define ERRMSG_PLAINTEXT_MISSING "Die Klartext-Datei existiert nicht!"
- #define ERRMSG_PLAINTEXT_NOT_REG "Die Klartext-Datei ist keine regulaere " \
- "Datei!"
- #define ERRMSG_OTP_MISSING "Die OTP-Datei existiert nicht!"
- #define ERRMSG_OTP_NOT_REG "Die OTP-Datei ist keine regulaere Datei!"
- #define ERRMSG_OTP_TOO_SHORT "Die OTP-Datei ist nicht lang genug!"
- #define ERRMSG_PLAINTEXT_OPEN "Kann die Klartext-Datei nicht oeffnen!"
- #define ERRMSG_OTP_OPEN "Kann die OTP-Datei nicht oeffnen!"
- #define ERRMSG_OTP_READ "Die OTP-Datei laesst sich nicht lesen!"
- #define ERRMSG_MAGIC_OTPENC_USED "Das One-Time Pad wurde bereits zum " \
- "Verschluesseln benutzt!"
- #define ERRMSG_MAGIC_OTPDEC "Das One-Time Pad ist nur zum Entschluesseln " \
- "geeignet!"
- #define ERRMSG_MAGIC_NO_OTP "Die angegebene OTP-Datei enthaelt kein " \
- "One-Time Pad!"
- #define ERRMSG_ENCRYPTED_CREATE "Kann die verschluesselte Datei nicht " \
- "erzeugen!"
- #define ERRMSG_ENCRYPTED_WRITE "Die verschluesselte Datei laesst sich " \
- "nicht schreiben!"
- #define ERRMSG_OTPENC_MARK "Kann die OTP-Datei nicht als benutzt markieren!"
- #define ERRMSG_PLAINTEXT_READ "Die Klartext-Datei laesst sich nicht lesen!"
- #define ERRMSG_PLAINTEXT_CLOSE "Kann die Klartext-Datei nicht schliessen!"
- #define ERRMSG_OTP_CLOSE "Kann die OTP-Datei nicht schliessen!"
- #define ERRMSG_ENCRYPTED_CLOSE "Kann die verschluesselte Datei nicht " \
- "schliessen!"
- void otp_encrypt(char *in, char *otpenc, char *out)
- {
- int val1;
- int val2;
- int val3;
- struct stat fileinfo1 = {0};
- struct stat fileinfo2 = {0};
- struct stat fileinfo3 = {0};
- int val4;
- size_t test;
- int mnr;
- int i;
- int count = 0;
- size_t fill;
- /*
- Hier soll mit Hilfe eines One-Time Pads eine Klartext-Datei
- (eine normale Datei mit vertraulichem Inhalt) verschluesselt werden.
- "in" enthaelt den Namen dieser Klartext-Datei. "otpenc" enthaelt den
- Namen eines unverbrauchten (noch nicht benutzten) One Time Pads.
- "out" ist der Name der zu erzeugenden verschluesselten Datei.
- Wichtig: denkt auch immer an die Fehlerbehandlung.
- */
- FILE *in_file = NULL, *otpenc_file = NULL, *out_file = NULL;
- char inout_buf[BUF_SIZE], otpenc_buf[BUF_SIZE];
- /* Makros zur Erleichterung der Fehlerbehandlung */
- #define cancel2(errmsg) { \
- fprintf(stderr, "%s\n", errmsg); \
- \
- /* Schliesst alle Dateien die erfolgreich \
- geoeffnet wurden (fclose(3)). Man sollte \
- eigentlich auch die unfertige ver- \
- schluesselte Datei loeschen, aber setzt \
- remove(3) sehr umsichtig ein! */ \
- /* HIER MUESST IHR EUREN CODE EINFUEGEN! */ \
- if (otpenc_file != NULL) { \
- fclose(otpenc_file); \
- } \
- if (in_file != NULL) { \
- fclose(in_file); \
- } \
- if (out_file != NULL) { \
- fclose(out_file); \
- remove(out); \
- } \
- exitcode = EXIT_FAILURE; \
- return; \
- } /* cancel2() */
- #define cancel(failedcall, errmsg) { \
- perror(failedcall); \
- cancel2(errmsg); \
- } /* cancel() */
- /* Wenn ihr das parametrisierte Makro cancel2() vervollstaendigt, dann
- koennt ihr euch wieder jede Menge Tipparbeit bei der Fehlerbehandlung
- ersparen. cancel() ist wie in generate_otp() fuer fehlgeschlagene
- Systemaufrufe gedacht, und cancel2() fuer alle anderen Fehler. */
- /* (passt diesen printf() geringfuegig an) */
- printf("Es wird eine Klartext-Datei mit dem Schluessel aus einer "
- "OTP-Datei\n"
- "verschluesselt in eine andere Datei geschrieben.\n\n"
- "Klartext-Datei: %s\n"
- "OTP-Datei: %s\n"
- "verschluesselte Datei: %s\n\n",
- in, otpenc, out);
- /* HINWEIS: Ihr habt schon ein paar Variablen vorgegeben, die ihr
- verwenden koennt:
- in, otpenc und out mit den gegebenen Dateinamen,
- in_file, otpenc_file und out_file fuer die geoeffneten Dateien,
- und inout_buf[BUF_SIZE] und otpenc_buf[BUF_SIZE] fuer die Puffer.*/
- /* Es darf keine existierende Datei ueberschrieben werden ("out" darf
- also nicht bereits existieren). Ueberprueft dies mit stat(2). */
- /* HIER MUESST IHR EUREN CODE EINFUEGEN! */
- val1 = stat(otpenc, &fileinfo1);
- if (val1 == -1) {
- cancel("stat", ERRMSG_OTP_MISSING);
- }
- val2 = stat(in, &fileinfo2);
- if (val2 == -1) {
- cancel("stat", ERRMSG_PLAINTEXT_MISSING);
- }
- val3 = stat(out, &fileinfo3);
- if (val3 != -1) {
- cancel("stat", ERRMSG_ENCRYPTED_EXISTS);
- }
- /* Ueberprueft nun ebenfalls mit stat(2), ob die Klartext-Datei aus "in"
- und die OTP-Datei aus "otpenc" nicht nur existieren, sondern auch
- regulaere Dateien sind (S_ISREG(m)). */
- /* HIER MUESST IHR EUREN CODE EINFUEGEN! */
- if (!(S_ISREG(fileinfo1.st_mode))) {
- cancel("S_ISREG", ERRMSG_OTP_NOT_REG);
- }
- if (!(S_ISREG(fileinfo2.st_mode))) {
- cancel("S_ISREG", ERRMSG_PLAINTEXT_NOT_REG);
- }
- /* Ausserdem muss die OTP-Datei mindestens 4 Bytes laenger als die
- Klartext-Datei sein, damit das One-Time Pad lang genug ist, da es
- vier Bytes kuerzer als die gesamte OTP-Datei ist (aufgrund der magic
- number in der OTP-Datei). */
- /* HIER MUESST IHR EUREN CODE EINFUEGEN! */
- if (fileinfo1.st_size < (fileinfo2.st_size + 4)) {
- cancel("st_size", ERRMSG_OTP_TOO_SHORT);
- }
- /* Oeffnet die Klartext-Datei und die OTP-Datei mit fopen(3). */
- /* HIER MUESST IHR EUREN CODE EINFUEGEN! */
- in_file = fopen(in, "r");
- if (in_file == NULL) {
- cancel("fopen", ERRMSG_PLAINTEXT_OPEN);
- }
- otpenc_file = fopen(otpenc, "r+");
- if (otpenc_file == NULL) {
- cancel("fopen", ERRMSG_OTP_OPEN);
- }
- /* Lest die magic number der OTP-Datei mit fread(3) und ueberprueft sie
- (MAGIC_OTPENC_NEW). Benutzt hier die vorgegebene Funktion
- bigendian(), da die magic number immer im Big-Endian-Format sein
- soll. */
- /* HIER MUESST IHR EUREN CODE EINFUEGEN! */
- test = fread(&val4, sizeof(int), 1, otpenc_file);
- if (test != 1) {
- cancel("fread", ERRMSG_OTP_READ);
- }
- if (val4 != bigendian(MAGIC_OTPENC_NEW)) {
- if (val4 == bigendian(MAGIC_OTPENC_USED)) {
- cancel("validate", ERRMSG_MAGIC_OTPENC_USED);
- }
- else if (val4 == bigendian(MAGIC_OTPDEC)) {
- cancel("validate", ERRMSG_MAGIC_OTPDEC);
- }
- cancel("validate", ERRMSG_MAGIC_NO_OTP)
- }
- /* Erzeugt die verschluesselte Datei indem ihr sie mit fopen(3)
- oeffnet. */
- /* HIER MUESST IHR EUREN CODE EINFUEGEN! */
- out_file = fopen(out, "w");
- if (out_file == NULL) {
- cancel("fopen", ERRMSG_ENCRYPTED_CREATE );
- }
- /* Schreibt auch sofort mit fwrite(3) die magic number in die neue
- verschluesselte Datei (MAGIC_ENCRYPTED_FILE). Benutzt dabei wieder
- bigendian(). */
- /* HIER MUESST IHR EUREN CODE EINFUEGEN! */
- mnr = bigendian(MAGIC_ENCRYPTED_FILE);
- test = fwrite(&mnr, sizeof(int), 1, out_file);
- if (test != 1) {
- cancel("fwrite", ERRMSG_ENCRYPTED_WRITE);
- }
- /* "Entwertet" die OTP-Datei, indem ihr die magic number in
- MAGIC_OTPENC_USED aendert (damit das OTP nicht mehrfach verwendet
- werden kann). Auch hier muss wieder bigendian() benutzt werden.
- Springt dazu mit fseek(3) an den Anfang der Datei zurueck und
- schreibt mit fwrite(3) die neue magic number. */
- /* HIER MUESST IHR EUREN CODE EINFUEGEN! */
- /* Hier keine Fehlerbehandlung, da unnötig: Springen an den Anfang muss immer gehen */
- fseek(otpenc_file, 0, SEEK_SET);
- mnr = bigendian(MAGIC_OTPENC_USED);
- test = fwrite(&mnr, sizeof(int), 1, otpenc_file);
- if (test != 1) {
- cancel("fwrite", ERRMSG_OTPENC_MARK);
- }
- /* Verschluesselt den Inhalt der Klartext-Datei (Inhalt und OTP mit
- fread(3) lesen, Inhalt verschluesseln und mit fwrite(3) schreiben).
- Dazu muesst ihr in einer Schleife blockweise (BUF_SIZE) arbeiten,
- da eine Datei sehr lang sein kann. */
- while ( !(feof(in_file)) ) { /* Ersetzt die 0 durch einen geeigneten feof(3)-Aufruf. */
- /* einen Block aus der Klartext-Datei lesen */
- /* HIER MUESST IHR EUREN CODE EINFUEGEN! */
- if (fileinfo2.st_size-(count*BUF_SIZE+4) < BUF_SIZE) {
- fill = (size_t)(fileinfo2.st_size-(count*BUF_SIZE+4));
- }
- else {
- fill = BUF_SIZE;
- }
- test = fread(&inout_buf, sizeof(char), fill, in_file);
- if (ferror(in_file)) {
- cancel("fread", ERRMSG_PLAINTEXT_READ);
- }
- /* einen genauso grossen Block aus dem OTP lesen */
- /* HIER MUESST IHR EUREN CODE EINFUEGEN! */
- test = fread(&otpenc_buf, sizeof(char), fill, otpenc_file);
- if (ferror(otpenc_file)) {
- cancel("fread", ERRMSG_OTP_READ);
- }
- /* den Block byteweise mit dem XOR-Operator verschluesseln */
- /* HIER MUESST IHR EUREN CODE EINFUEGEN! */
- for (i = 0; i < fill; i++)
- inout_buf[i] = inout_buf[i] ^ otpenc_buf[i];
- /* den verschluesselten Block in die Zieldatei schreiben */
- /* HIER MUESST IHR EUREN CODE EINFUEGEN! */
- test = fwrite(&inout_buf, sizeof(char), fill, out_file);
- if(ferror(out_file)) {
- cancel("fwrite", ERRMSG_ENCRYPTED_WRITE);
- }
- }
- /* Schliesst nun wieder alle Dateien mit fclose(3). */
- /* HIER MUESST IHR EUREN CODE EINFUEGEN! */
- val1 = fclose(otpenc_file);
- if (val1 != 0)
- cancel("fclose", ERRMSG_OTP_CLOSE);
- val2 = fclose(in_file);
- if (val2 != 0)
- cancel("fclose", ERRMSG_ENCRYPTED_CLOSE);
- val3 = fclose(out_file);
- if (val3 != 0)
- cancel("fclose", ERRMSG_PLAINTEXT_CLOSE);
- /* Gebt abschliessend eine Erfolgsmeldung aus. */
- /* HIER MUESST IHR EUREN CODE EINFUEGEN! */
- printf(" Die Datei wurde erfolgreich verschlüsselt, und das OneTimePad entwertet.\n\n");
- #undef cancel
- #undef cancel2
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement