Fehlerbeseitigung bei C Programm



  • Für die Uni muss ich ein C Programm erstellen, welches einen Klartext entschlüsseln soll, eine Signatur mit dem privaten Schlüssel (mit sha1) erzeugen soll und am Ende soll der Klartext wieder verschlüsselt werden. Das Programm soweit steht, jedoch gibt es noch einige Fehler aus, könntet ihr mir da vielleicht weiter helfen? Bin echt total verzweifelt. 😞
    Ausführbar soll es in Linux sein.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <fcntl.h>
    #include <openssl/evp.h>
    
    #define BSIZE 0x10000
    #define TYPEDECIPHER EVP_des_ecb() 
    #define TYPEHASH EVP_ripemd160() //todo
    #define TYPECIPHER EVP_cast5_cfb()
    
    unsigned char cipher[BSIZE];
    unsigned char srcKey[BSIZE];
    unsigned char priKey[BSIZE];
    unsigned char output[BSIZE];
    unsigned char key[16]={0x00};
    unsigned char initVector[16]={0x00};
    
    unsigned char *fileNameSignature 		= "s66884-sig.bin";
    unsigned char *fileNameDecrypt 			= "s66884-plaintext";
    unsigned char *fileNameDestCipher		= "s66884-dest-cipher.bin";
    
    unsigned char *fileNameDestKey 			= "s66884-dest-key.bin";
    unsigned char *fileNamePrivKey			= "s66884-privkey.pem";
    unsigned char *fileNameSrcCipher 		= "s66884-src-cipher.bin";
    unsigned char *fileNameSrcKey 			= "s66884-src-key.bin";
    
    void setKeyAndVector(unsigned char *keyToUse, unsigned char *initVectorToUse, 
    		unsigned char *ressource, long lengthKey, long lengthInitVector) {
    
    	int i;
    	for(i = 0; i < lengthKey; i++) {
    		keyToUse[i] = ressource[i];
    	}
    	keyToUse[i] = '\0';
    	int j;
    	for(j=0; i < lengthKey+lengthInitVector;j++, i++) {
    		initVectorToUse[j] = ressource[i];
    	}
    	initVectorToUse[i] = '\0';
    }
    
    int hashIt(unsigned char *toHash, int length, unsigned char *hash) {
    	EVP_MD_CTX hashContext;
    	EVP_CIPHER_CTX signContext;
    	EVP_MD_CTX_init(&hashContext);
    
    	int tmplen = length;
    
    	EVP_DigestInit(&hashContext, TYPEHASH);
    	EVP_DigestUpdate(&hashContext, toHash, length);
    	EVP_DigestFinal(&hashContext, hash, &tmplen);
    
    	EVP_CIPHER_CTX_cleanup(&signContext);
    	return tmplen;
    }
    
    void writeToFile(unsigned char *fileName, unsigned char *toWrite, int length) {
    	int descriptor = open(fileName, O_CREAT | O_RDWR);	
    	write(descriptor, toWrite, length);		
    }
    
    int readFile(unsigned char *fileName, unsigned char *content){
    	int discriptor = open(fileName, O_RDONLY);
    	if(discriptor < 0){
    		exit(-1);
    	}
    
    	int length = read(fileName, content, BSIZE);
    	if(length < 0 ) {
    		exit(-2);
    	}
    
    	return length;
    }
    
    void signIt(unsigned char *toSign, int length, unsigned char *privKey) {
    	EVP_MD_CTX *signContext = EVP_MD_CTX_create();
    	const EVP_MD *md = EVP_get_digestbyname("SHA1");
    	unsigned char signedContent[BSIZE];
    
    	EVP_DigestSignInit(signContext, NULL, md, NULL, privKey);
    	EVP_DigestSignUpdate(signContext, toSign, length);
    
    	int lengthSign;
    	int EVP_DigestSignFinal(signContext, signedContent, &lengthSign);
    	writeToFile(fileNameSignature, signedContent, lengthSign);
    
    	EVP_CIPHER_CTX_cleanup(signContext);
    }
    
    void encryptIt(unsigned char *toEncrypt, unsigned char *keyToEncrypt){
    	EVP_CIPHER_CTX context;
    	EVP_CIPHER_CTX_init(&context);
    
    	unsigned char encryptOutput[BSIZE];
    	unsigned char key[BSIZE];
    	unsigned char initVector[BSIZE];
    
    	setKeyAndVector(key, initVector, keyToEncrypt, EVP_CIPHER_key_length(TYPECIPHER), EVP_CIPHER_iv_length(TYPECIPHER));
    
    	EVP_EncryptInit(&context, TYPEDECIPHER, key, initVector);		
    
    	int lengthOutput = 0;
    	int lengthInput = 0;
    	EVP_EncryptUpdate(&context, toEncrypt, &lengthOutput, keyToEncrypt, &lengthInput);
    
    	int tmp;	
    	EVP_EncryptFinal(&context, encryptOutput, &tmp);
    
    	writeToFile(fileNameDestCipher, encryptOutput, lengthOutput);
    }
    
    int main(int argc, char **args) {
    	int lengthCipher = readFile(fileNameSrcCipher, cipher);
    	int lengthKey = readFile(fileNameSrcKey, srcKey);
    	int lengthPriKey = readFile(fileNamePrivKey, priKey);
    
    	EVP_CIPHER_CTX context;
    	EVP_CIPHER_CTX_init(&context);
    
    	setKeyAndVector(key, initVector, srcKey, EVP_CIPHER_key_length(TYPECIPHER), EVP_CIPHER_iv_length(TYPECIPHER));
    	EVP_DecryptInit(&context, TYPECIPHER, key, initVector);
    
    	int lengthOutput = 0;
    	EVP_DecryptUpdate(&context, output, &lengthOutput, cipher, lengthCipher);
    
    	int tmp2;	
    	EVP_DecryptFinal(&context, output, &tmp2);
    
    	writeToFile(fileNameDecrypt, output, lengthOutput);
    
    	//unsigned char hash[BSIZE];
    	//int lengthHash = hashIt(output, lengthOutput, hash);
    
    	signIt(output, lengthOutput, priKey);
    
    	printf("%s, %d", output, lengthOutput);	
    
    	EVP_CIPHER_CTX_cleanup(&context);
    	return 0;
    }
    

    Fehlerausgabe:

    s66884_1.c: In function ‘readFile’:
    s66884_1.c:70:20: warning: passing argument 1 of ‘read’ makes integer from pointer without a cast
      int length = read(fileName, content, BSIZE);
                        ^
    In file included from s66884_1.c:4:0:
    /usr/include/unistd.h:360:16: note: expected ‘int’ but argument is of type ‘unsigned char *’
     extern ssize_t read (int __fd, void *__buf, size_t __nbytes) __wur;
                    ^
    s66884_1.c: In function ‘signIt’:
    s66884_1.c:83:2: error: too few arguments to function ‘EVP_DigestSignInit’
      EVP_DigestSignInit(signContext);
      ^
    In file included from s66884_1.c:6:0:
    /usr/include/openssl/evp.h:615:5: note: declared here
     int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
         ^
    s66884_1.c:87:54: error: expected ‘)’ before ‘&’ token
      int EVP_DigestSignFinal(signContext, signedContent, &lengthSign);
                                                          ^
    s66884_1.c:90:25: warning: passing argument 1 of ‘EVP_CIPHER_CTX_cleanup’ from incompatible pointer type
      EVP_CIPHER_CTX_cleanup(signContext);
                             ^
    In file included from s66884_1.c:6:0:
    /usr/include/openssl/evp.h:649:5: note: expected ‘struct EVP_CIPHER_CTX *’ but argument is of type ‘struct EVP_MD_CTX *’
     int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a);
         ^
    s66884_1.c: In function ‘encryptIt’:
    s66884_1.c:106:2: error: too few arguments to function ‘EVP_EncryptUpdate’
      EVP_EncryptUpdate(&context, toEncrypt, &lengthOutput);
      ^
    In file included from s66884_1.c:6:0:
    /usr/include/openssl/evp.h:584:5: note: declared here
     int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out,
         ^
    


  • Zeile 6+7 der Compiler-Ausschrift sind doch wohl eindeutig?
    - nutze POSIX (z.B. read,open,...) nur wenn Standard C nichts anbietet (fread,fopen,...)
    - verwende keine exit()-Calls, schon gar nicht mit negativem Argument
    - nur Deppen benutzen globale Variablen
    - deine defines sind auch Müll
    - Kommentare fehlen



  • Wäre es für mich eindeutig, hätte ich mich nicht ans Forum gewendet. ^^
    Der Quellcode muss nur einmal ausgeführt werden, daher sind keine Kommentare notwendig. Das schaut sich eh keine Sau an. 😃



  • verzweifelt_ich_bin schrieb:

    Das schaut sich eh keine Sau an. 😃

    Aber wir sollen?
    Danke für den Titel.

    Zu read : Schau mal an, wie du write benutzt.

    Wenn du die Fehlermeldungen nicht vertehst, dann übersetz die mal ins deutsche.



  • So war das doch jetzt auch nicht gemeint. 😕
    Bin halt nicht so der Programmierer und hab dabei nicht daran gedacht, wollt das Ding halt nur schnell fertig machen.



  • Danke DirkB für den Hinweis, Fehler in der read behoben. 🙂


Anmelden zum Antworten