I have three binary files: cipher01.bin, cipher02.bin and cipher03.bin.
Additionally I have a sign.bin and a pubkey.pem file. The task is to hash all three ciphers and compare it to the signature. Therefore I used RSA to decrypt the sign.bin with the public key from pubkey.pem.
The result looks good but none of the cipher-hashes belongs to the signature. But I know, that there is at least one cipher which belongs to the signature because it is a task from our university. Maybe I forgot something but I can't figure out what.
Here is my code so far:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <openssl/sha.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/rsa.h>
#include <openssl/bio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/** converts unsigned character to readble string*/
char *pt(unsigned char *md) {
int i;
char *buf = (char*)malloc(sizeof(char)*80);
for(int i = 0; i < SHA_DIGEST_LENGTH;i++) {
sprintf(&(buf[i*2]),"%02x",md[i]);
}
return (buf);
}
/** returns error */
void err_exit(void) {
printf("%s\n",ERR_error_string(ERR_get_error(),NULL));
ERR_free_strings();
exit(EXIT_FAILURE);
}
/** reads a file */
char * readFile(char * filename,long int * filesize) {
FILE *fin;
char *buf;
if((fin=fopen(filename,"r"))==NULL) {
printf("Error opening %s.\n",filename);
exit(EXIT_FAILURE);
}
fseek(fin,0L,SEEK_END);
*filesize = ftell(fin);
rewind(fin);
if(!(buf=malloc(*filesize))) {
printf("Memory exhausted. Stop.\n");
exit(EXIT_FAILURE);
}
fread(buf,*filesize,1,fin);
fclose(fin);
return buf;
}
/** hash a file with sha1 */
char * hashBinaryFile(char * filename) {
long int filesize = 0;
EVP_MD_CTX c;
unsigned char md[SHA_DIGEST_LENGTH];
ERR_load_crypto_strings();
EVP_MD_CTX_init(&c);
/** reads files into buf */
char * buf = readFile(filename,&filesize);
if((EVP_DigestInit(&c,EVP_sha1()))==0) {
err_exit();
}
if((EVP_DigestUpdate(&c,buf,filesize))==0) {
err_exit();
}
if((EVP_DigestFinal(&c,md,NULL))==0) {
err_exit();
}
//printf("%s\n",pt(md));
EVP_MD_CTX_cleanup(&c);
free(buf);
ERR_free_strings();
return pt(md);
}
int padding = RSA_PKCS1_PADDING;
/** loads public key and creates rsa */
RSA * createRSAWithFilename(char * filename,int public) {
FILE * fp = fopen(filename,"rb");
if(fp == NULL) {
printf("Unable to open file %s \n",filename);
return NULL;
}
RSA *rsa= RSA_new() ;
if(public) {
rsa = PEM_read_RSA_PUBKEY(fp, &rsa,NULL, NULL);
} else {
rsa = PEM_read_RSAPrivateKey(fp, &rsa,NULL, NULL);
}
return rsa;
}
/** decrypt signature */
char * public_decrypt(unsigned char * enc_data,int data_len, unsigned char *decrypted) {
RSA * rsa = createRSAWithFilename("archieve/pubkey.pem",1);
int result = RSA_public_decrypt(data_len,enc_data,decrypted,rsa,padding);
return pt(decrypted);
}
int main(int argc,char *argv[]) {
/** decrypt signature */
long int encrypted_length;
long int decrypted_length;
unsigned char decrypted[4098]={};
char * encrypted = readFile("archieve/s72897-sig.bin",&encrypted_length);
char * sign = public_decrypt(encrypted,encrypted_length, decrypted);
char * cipher01 = hashBinaryFile("archieve/s72897-cipher01.bin");
char * cipher02 = hashBinaryFile("archieve/s72897-cipher02.bin");
char * cipher03 = hashBinaryFile("archieve/s72897-cipher03.bin");
if(strcmp(sign,cipher01)==0) {
printf("cipher01\n");
} else if(strcmp(sign,cipher02)==0) {
printf("cipher02\n");
} else if(strcmp(sign,cipher03)==0) {
printf("cipher03\n");
} else {
printf("No cipher matches the signature\n");
}
return 0;
}
Thanks for any kind of help.
Edit: fixed some code
Edit2: link to the *.zip https://ufile.io/tqwoh
You transform your files in human readable format twice:
char * public_decrypt(...)
{
return pt(decrypted);
// ^
}
int main(int argc,char *argv[])
{
char * sign = pt(public_decrypt(encrypted,encrypted_length, decrypted));
// ^
Additionally, you actually have some memory leaks: You do not free the rsa instance in public_decrypt neither do you free the strings returned (encrypted, sign, cypher0x)...
Further recommendation in for pt:
char *buf = (char*)malloc(sizeof(char) * 2 * SHA_DIGEST_LENGTH);
If you have an appropriate constant already, use it... sizeof(char) always is 1 by definition, so you could drop it...
Related
I am creating a struct called Job and I want to create an array of struct Job. The name of my array is jobQueue I populate the array using commandline args. The instructor has it set up to where **args is being used. After the user inputs the name of the job and the execution time it gets added to the array. However, when I try to print jobQueue[0].name using the list() funct I have written, the name does not get printed. I'm trying to get my code set up to where I can print the name. I have provided a minimal version of my overall project that just focuses on the specific problem I am encountering and should compile and run fine.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdbool.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <assert.h>
#include <sys/wait.h>
#include <stdint.h>
#define EINVAL 1
#define E2BIG 2
#define MAXMENUARGS 7
//structure job initialize
struct Job {
//initializing name variable
char *name;
int executionTime;
};
//init the array
struct Job jobQueue[5] = {0};
//cmd function provided by intructor
int cmd_run(int nargs, char **args) {
int execT;
sscanf(args[2], "%d", &execT);
run(args[1], execT);
return 0;
}
//cmd function provided by intructor
void cmd_list() {
list();
}
//cmd function provided by intructor
static struct {
const char *name;
int (*func)(int nargs, char **args);
} cmdtable[] = {
/* commands: single command must end with \n */
{ "r", cmd_run},
{ "run", cmd_run},
{ "list\n", cmd_list}
};
//cmd function provided by intructor
//this is the function that handles the arguments entered by the user
//provided it just in case someone needs to see how arguments are being
//processed
int cmd_dispatch(char *cmd) {
time_t beforesecs, aftersecs, secs;
u_int32_t beforensecs, afternsecs, nsecs;
char *args[MAXMENUARGS];
int nargs = 0;
char *word;
char *context;
int i, result;
void *Dispatcher(void *arg);
for (word = strtok_r(cmd, " ", &context);
word != NULL;
word = strtok_r(NULL, " ", &context)) {
if (nargs >= MAXMENUARGS) {
printf("Command line has too many words\n");
return E2BIG;
}
args[nargs++] = word;
}
if (nargs == 0) {
return 0;
}
for (i = 0; cmdtable[i].name; i++) {
if (*cmdtable[i].name && !strcmp(args[0], cmdtable[i].name)) {
assert(cmdtable[i].func != NULL);
/* Call function through the cmd_table */
result = cmdtable[i].func(nargs, args);
return result;
}
}
printf("%s: Command not found\n", args[0]);
return EINVAL;
}
//adds job to the array using user arguments
void run(char name[], int executionTime) {
//creates a job using the arguments specified by user
struct Job job = {name, executionTime};
jobQueue[0] = job;
printf("\nJob added to queue now please type 'list'\n");
}
//name will not print here
void list() {
printf("\nSee how the name will not print below?\n");
char executionTimeStr[5];
for (int c = 0; c < sizeof (jobQueue) / sizeof (jobQueue[0]); c++) {
//prints job info formatted
if (jobQueue[c].name != NULL) {
sprintf(executionTimeStr, "%d", jobQueue[c].executionTime);
//job name will not print here, output is just left blank
printf("%s %20.8s", "Name", "ExecTime");
printf("%-10.15s %11.3s\n",
jobQueue[c].name,
executionTimeStr
);
}
}
}
int main(int argc, char *argv[]) {
printf("Welcome to our batch job scheduler\n");
printf("Please enter the following exactly: 'run job1 10' \n");
//ignore this, it handles my commandline parser
char *buffer;
size_t bufsize = 64;
buffer = (char*) malloc(bufsize * sizeof (char));
if (buffer == NULL) {
perror("Unable to malloc buffer");
exit(1);
}
while (1) {
printf("User Input: ");
getline(&buffer, &bufsize, stdin);
cmd_dispatch(buffer);
}
//ignore this, it handles my commandline parser
return 0;
}
I'm trying to implement reading the BMP file in c.
I came across basic bmp reading module from google as the below.
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#include <io.h>
#include <fcntl.h>
#include "ReadBMP.h"
char ReadBMPFile(const char *file_name, BMPDATA *ret_bmp_data)
{
int fh;
long file_length;
void *bmp_file_data;
fh = _open(file_name, _O_RDONLY, _O_BINARY);
if (fh == -1)
{
return -1;
}
_lseek(fh, 0, SEEK_END);
file_length = _tell(fh);
_lseek(fh, 0, SEEK_SET);
bmp_file_data = malloc(file_length);
_read(fh, bmp_file_data, file_length);
_close(fh);
ReadBMPData(bmp_file_data, ret_bmp_data);
free(bmp_file_data);
return 0;
}
But I feel hard to use above function in my code.
#include <windows.h>
#include "ReadBMP.h"
#define WIDTHBYTES(bits) (((bits)+31)/32*4)
#define BYTE unsigned char
int main(int argc, char *argv[])
{
FILE *fp;
int i, j, k,n;
int width = 16;
int height = 16;
int bpp = 24;
FILE *fp_new;
char *filename_new;
char ch;
BMPDATA *ret_bmp_data;
int val[1000];
char filename[100];
//char *filename = "test.bmp";
// Check if a filename has been specified in the command
if (argc < 2)
{
printf("Missing Filename\n");
return(1);
}
else
{
filename_new = argv[1];
printf("Filename : %s\n", filename_new);
}
ReadBMPFile(filename_new, ret_bmp_data);
When I do implement like this I've got a error message as the below
error C4700: uninitialized local variable 'ret_bmp_data' used
How do I initialize the local variable?
update
I've updated ReadBMP.c file at all.
#include <stdio.h>
#include <malloc.h>
#include <memory.h>
#include <io.h>
#include <fcntl.h>
#include "ReadBMP.h"
void DecodeData(const char *byte_data, int offset, BMPDATA *ret_bmp_data);
void DecodeInfomation(const char *byte_data, int offset, BMPDATA *ret_bmp_data);
char ReadBMPFile(const char *file_name, BMPDATA *ret_bmp_data)
{
int fh;
long file_length;
void *bmp_file_data;
fh = _open(file_name, _O_RDONLY, _O_BINARY);
if (fh == -1)
{
return -1;
}
_lseek(fh, 0, SEEK_END);
file_length = _tell(fh);
_lseek(fh, 0, SEEK_SET);
bmp_file_data = malloc(file_length);
_read(fh, bmp_file_data, file_length);
_close(fh);
ReadBMPData(bmp_file_data, ret_bmp_data);
free(bmp_file_data);
return 0;
}
char ReadBMPData(const void *bmp_file_data, BMPDATA *ret_bmp_data)
{
char *byte_data;
int offset;
byte_data = (char *)bmp_file_data;
if ((byte_data[0] != 'B') || (byte_data[1] != 'M'))
{
return -1;
}
memcpy(&offset, &byte_data[10], 4);
DecodeInfomation(byte_data, offset, ret_bmp_data);
DecodeData(byte_data, offset, ret_bmp_data);
return 0;
}
void DecodeInfomation(const char *byte_data, int offset, BMPDATA *ret_bmp_data)
{
if (offset == 26)
{
memcpy(&ret_bmp_data->width, &byte_data[18], 2);
memcpy(&ret_bmp_data->height, &byte_data[20], 2);
memcpy(&ret_bmp_data->bits_per_pixel, &byte_data[24], 2);
}
else
{
memcpy(&ret_bmp_data->width, &byte_data[18], 4);
memcpy(&ret_bmp_data->height, &byte_data[22], 4);
memcpy(&ret_bmp_data->bits_per_pixel, &byte_data[28], 2);
}
}
void DecodeData(const char *byte_data, int offset, BMPDATA *ret_bmp_data)
{
int data_size;
if (ret_bmp_data->bits_per_pixel == 24)
{
data_size = ret_bmp_data->width * ret_bmp_data->height * 3;
ret_bmp_data->data = malloc(data_size);
memcpy(ret_bmp_data->data, &byte_data[offset], data_size);
}
}
this is ReadBMP.h
#ifndef READBMP_H
#define READBMP_H
typedef struct BMPDATA
{
short bits_per_pixel;
int width;
int height;
unsigned char *data;
}BMPDATA;
#ifdef __cplusplus
extern "C"
{
#endif
char ReadBMPFile(const char *file_name, BMPDATA *ret_bmp_data);
char ReadBMPData(const void *bmp_file_data, BMPDATA *ret_bmp_data);
#ifdef __cplusplus
}
#endif
#endif
and
this is Source.cpp
#include <stdio.h>
#include <stdlib.h> /* system, NULL, EXIT_FAILURE */
#include <windows.h>
#include "ReadBMP.h"
#define WIDTHBYTES(bits) (((bits)+31)/32*4)
#define BYTE unsigned char
int main(int argc, char *argv[])
{
FILE *fp;
int i, j, k,n;
int width = 16;
int height = 16;
int bpp = 24;
////////////////// add BMP read 2018-03-20 ///////////////
FILE *fp_new;
char *filename_new;
char ch;
BMPDATA *ret_bmp_data;
int val[1000];
char filename[100];
//char *filename = "test.bmp";
// Check if a filename has been specified in the command
if (argc < 2)
{
printf("Missing Filename\n");
return(1);
}
else
{
filename_new = argv[1];
printf("Filename : %s\n", filename_new);
}
ReadBMPFile(filename_new, ret_bmp_data);
fclose(fp);
fclose(fp_new);
}
Due to the error message, it seems that the BMPDATA variable in main isn't supposed to be a BMPDATA pointer but a BMPDATA object.
Like:
int main(int argc, char *argv[])
{
....
BMPDATA ret_bmp_data;
....
ReadBMPFile(filename_new, &ret_bmp_data);
....
}
Can someone explain to me how this retarget.c works?
I am trying to send integers to and from the uart of a microcontroller, i have been successful with using fgets to get a char (16 bits) and returning an integer using the atoi function in the Uart Interupt service routine but I am trying to get an integer using scanf, i am thinking i need to change the retarget file outlined below?
#include <stdio.h>
#include <time.h>
#include <rt_misc.h>
#define AHB_LED_BASE 0x50000000
#define AHB_UART_BASE 0x51000000
#pragma import(__use_no_semihosting)
struct __FILE {
unsigned char * ptr;
};
FILE __stdout = {(unsigned char *) AHB_UART_BASE};
FILE __stdin = {(unsigned char *) AHB_UART_BASE};
int fputc(int ch, FILE *f)
{
return(uart_out(ch));
}
int fgetc(FILE *f)
{
return(uart_in());
}
int ferror(FILE *f)
{
return 0;
}
int uart_out(int ch)
{
int* UARTPtr;
UARTPtr = (int*)AHB_UART_BASE;
*UARTPtr = (int)ch;
return(ch);
}
int uart_in()
{
int ch;
int* UARTPtr;
UARTPtr = (int*)AHB_UART_BASE;
ch = *UARTPtr;
uart_out(ch);
return((int)ch);
}
void _ttywrch(int ch)
{
fputc(ch,&__stdout);
}
void _sys_exit(void) {
while(1);
}
//------------------------------------------------------------------------------
// Cortex-M0
//------------------------------------------------------------------------------
#include <stdio.h>
#include <time.h>
#include <rt_misc.h>
#include <stdlib.h>
#define AHB_LED_BASE 0x50000000
#define AHB_UART_BASE 0x51000000
void UART_ISR(void)
{
int sample;
printf("the value entered is %d\n", sample);
}
//////////////////////////////////////////////////////////////////
// Main Function
//////////////////////////////////////////////////////////////////
int main() {
{
int sample;
scanf ("%d",&sample);
}
}
The scanf function will need ungetc because it must scan ahead in the buffer to see when fields end. E.g., when looking for a number, it needs to pull one character after the number to see where the number ends. When it sees the non-number character, it needs to put it back into the stream so the next call to getc will get it.
Something like this:
struct __FILE
{
unsigned char * ptr;
int unchar; /* place to keep the character put back in the stream */
};
FILE __stdout = {(unsigned char *) AHB_UART_BASE, -1};
FILE __stdin = {(unsigned char *) AHB_UART_BASE, -1};
int fgetc(FILE *f)
{
int c;
if (f->unchar == -1)
{
c = uart_in(); /* just read a character */
}
else
{
c = f->unchar; /* reuse the character put back by ungetc */
f->unchar = -1; /* mark it as used */
}
return c;
}
int fungetc(int c, FILE *f)
{
unsigned char uc = c; /* POSIX says that it is converted first to unsigned char */
f->unchar = (int )uc; /* put back the character */
return (int )uc;
}
am trying to implement an application that uses an MD5 hash underneath, i have acquired the MD5 hash program from the internet, but i don't know how to pass the string from my program ( my program written in C) to the program that calculate the MD5 hash.
this is the main of the program that calculate the MD5 hash..
//
// MD5 Hashing Example - Using Windows Crypto API
//
// by Napalm # NetCore2K
//
#include <stdio.h>
#include <string.h>
#include "winmd5.h"
HCRYPTPROV hCryptProv;
int main(int argc, char *argv[])
{
int i;
CryptStartup();
if(argc > 1){
MD5Context ctx;
MD5Init(&ctx);
MD5Update(&ctx, (unsigned char *)argv[1], strlen(argv[1]));
MD5Final(&ctx);
for(i = 0; i < 16; i++)
printf("%02x", ctx.digest[i]);
printf("\n");
}else
printf("Usage: %s <string>\n", argv[0]);
CryptCleanup();
return 0;
}
this is the header file content..
//
// MD5 Hashing Example - Using Windows Crypto API
//
// by Napalm # NetCore2K
//
#include <windows.h>
#include <wincrypt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern HCRYPTPROV hCryptProv;
void PrintMD5(const char *);
typedef struct {
unsigned char digest[16];
unsigned long hHash;
} MD5Context;
BOOL CryptStartup()
{
if(CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET) == 0){
if(GetLastError() == NTE_EXISTS){
if(CryptAcquireContext(&hCryptProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, 0) == 0){
return FALSE;
}
}
else return FALSE;
}
return TRUE;
}
void CryptCleanup()
{
if(hCryptProv) CryptReleaseContext(hCryptProv, 0);
hCryptProv = NULL;
}
void inline MD5Init(MD5Context *ctx)
{
CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, &ctx->hHash);
}
void inline MD5Update(MD5Context *ctx, unsigned char const *buf, unsigned len)
{
CryptHashData(ctx->hHash, buf, len, 0);
}
void inline MD5Final(MD5Context *ctx)
{
DWORD dwCount = 16;
CryptGetHashParam(ctx->hHash, HP_HASHVAL, ctx->digest, &dwCount, 0);
if(ctx->hHash) CryptDestroyHash(ctx->hHash);
ctx->hHash = 0;
}
void PrintMD5(const char *s)
{
MD5Context ctx;
MD5Init(&ctx);
MD5Update(&ctx, (const unsigned char *)s, strlen(s));
MD5Final(&ctx);
int i;
for (i = 0; i < 16; i++) {
printf("%02x", ctx.hHash[i]);
}
printf("\n");
}
how should i call this Main(), and how to pass the String to it and get the result.?
thanks in advance.
Regards
You don't call main() again. You rather use this program as an example to write a separate function, like this:
void PrintMD5(const char *s)
{
MD5Context ctx;
MD5Init(&ctx);
MD5Update(&ctx, (const unsigned char *)s, strlen(s));
MD5Final(&ctx);
int i;
for (i = 0; i < 16; i++) {
printf("%02x", ctx.digest[i]);
}
printf("\n");
}
Then you can call this from your own program like:
PrintMD5("FooBarHelloWorld42");
Below is my code:
I cant seem to use qsort effectively... It turns my array into 0's after they are populated with names and start times... Is it a problem with my qsort call? or the qsort itself.
The header with the structures is as follows:
/**
* Simulation of a process scheduler
*/
//#ifndef SCHEDULER_H_
#define SCHEDULER_H_
#include <stddef.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
/* types */
/** units of time */
typedef long time;
/** process identifier */
typedef int pid;
/** Information about a job of interest to the task scheduler */
struct job_data {
/* pid of this process */
pid pid;
/* time process starts */
time start;
/* time needed to finish */
time finish;
/* time spent processing so far */
time scheduled;
/* Number of lines */
int lines;
};
struct job {
/* Various parameters used by the scheduler */
char job_id[20];
struct job_data parameters;
char *lines[20];
};
/* I/O Files */
//static char *inputFile;
char * in;
static FILE *input;
static FILE *cur;
/*Scheduled jobs indexed by PID*/
struct job list[20];
/* the next job to schedule */
//static struct job *job_next = NULL;
/* Time */
time clock;
/*Comparison for qsort*/
int compare_start(const void *x, const void *y)
{
const struct job *a = x;
const struct job *b = y;
printf("%ld, %ld\n", a->parameters.start, b->parameters.start);
if (a->parameters.start < b->parameters.start)
{
return -1;
}
if (a->parameters.start > b->parameters.start)
{
return 1;
}
return 0;
}
/*Order Jobs*/
static void order_jobs(void)
{
qsort(list, (sizeof list) / (sizeof list[0]), sizeof list[0], compare_start);
}
/** Read and parse input from input file */
static void parse_input(void)
{
char buffer[BUFSIZ];
char lines[BUFSIZ];
int jobs = 0;
struct job *current;
while( fgets(buffer, sizeof(buffer), input) )
{
time start;
char buf[BUFSIZ];
sscanf(buffer,"./%s/", buf);
cur = fopen(buf, "r" );
int n_lines = 0;
while( fgets(lines, sizeof(lines), cur) )
{
if( n_lines == 0 )
{
current = &list[jobs];
strcpy(current->job_id, buf);
sscanf(lines,"%ld", &start);
current->parameters.start = start;
}
n_lines++;
}
current->parameters.lines = n_lines;
jobs++;
fclose(cur);
}
order_jobs();
for (int i = 0; i < jobs; i++)
{
printf("%s %ld %d\n", list[i].job_id, list[i].parameters.start, list[i].parameters.lines);
}
}
int main(int argc, char **argv)
{
in = argv[1];
if ( (input = fopen(in, "r")) == NULL ) {
fprintf(stderr, "cannot open %s\n", argv[1]);
}
parse_input();
fclose(input);
return EXIT_SUCCESS;
}
You only load jobs entries into the array, but you tell qsort() to sort the entire array (20 elements). This probably puts non-initialized elements at the front, which you then print.