Teh function below causes a segmentation fault when it gets to the RSA_verify() part. I'm a c-beginner so it's hard for me to find the reason for the problem. Maybe someone can point out what I'm doing wrong. It would be very helpful, thanks in advance.
Here's the Code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <openssl/sha.h>
#include <openssl/dsa.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/bio.h>
#define BUF 20000
#define DSS 20
int matchCipherToSign(unsigned char *signPath, char *cipherPath) {
unsigned char *bufCipher = malloc(BUF);
unsigned char *sha = malloc(SHA_DIGEST_LENGTH);
unsigned char *bufSign = malloc(BUF);
unsigned int retSign;
int ret=0;
int retCipher;
FILE *key;
RSA *rsa = RSA_new();
EVP_MD_CTX ctx;
key = fopen("key.bin", "rb");
if (key == NULL){
printf("Couldn't open file key.bin.\n");
exit(EXIT_FAILURE);
}
retSign = readFile(signPath, bufSign);
if (retSign == 0){
printf("Couldn't read file %s.\n", signPath);
exit(EXIT_FAILURE);
}
retCipher = readFile(cipherPath, bufCipher);
if (retCipher == 0){
printf("Couldn't open file %s.\n", cipherPath);
exit(EXIT_FAILURE);
}
rsa = PEM_read_RSA_PUBKEY(key, &rsa, NULL, NULL);
fclose(key);
if (1!=EVP_DigestInit(&ctx, EVP_sha1())) {
printf("EVP_DigestInit Error.\n");
exit(EXIT_FAILURE);
}
if (1!=EVP_DigestUpdate(&ctx, bufCipher, retCipher)) {
printf("VP_DigestUpdate Error.\n");
exit(EXIT_FAILURE);
}
if (1!=EVP_DigestFinal(&ctx, sha, NULL)) {
printf("EVP_DigestFinal Error.\n");
exit(EXIT_FAILURE);
}
ret = RSA_verify(NID_sha1, sha, SHA_DIGEST_LENGTH, bufSign, sizeof(bufSign), rsa);
RSA_free(rsa);
free(bufCipher);
free(bufSign);
free(sha);
return ret;
}
Thanks for your help!
Related
I have some code whose goal is to open/create a file, read in messages, and then write those messages to the opened/created file. Everything up to the writing to the file seems to work just fine. Here is my code.
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include "message-lib.h"
int usage( char name[] );
void * recv_log_msgs( void * arg );
sem_t mutex;
int log_fd;
void * recv_log_msgs( void * arg ){
sleep(1);
sem_wait(&mutex);
char buffer[1024];
int number_bytes_read;
FILE *fp = log_fd;
do{
number_bytes_read = read_msg(arg, buffer, 1024);
printf("in recv\n");
printf(buffer);
fwrite(&buffer, 1, sizeof(buffer)/sizeof(buffer[0]), fp);
}while(number_bytes_read > 0);
if(number_bytes_read == 0){
close_connection(arg);
}
sem_post(&mutex);
return NULL;
}
int usage( char name[] ){
printf( "Usage:\n" );
printf( "\t%s <log-file-name> <UDS path>\n", name );
return 1;
}
int main( int argc, char * argv[] )
{
int connection;
pthread_t tid;
if ( argc != 3 )
return usage( argv[0] );
log_fd = creat(argv[1], S_IRUSR | S_IWUSR);
if(log_fd == -1){
perror(argv[1]);
return 1;
}
int listener = permit_connections(argv[2]);
if(listener == -1){
return -1;
}
sem_init(&mutex, 0, 1);
do{
connection = accept_next_connection(listener);
if(connection == -1){
return -1;
}
pthread_create(&tid, NULL, recv_log_msgs, connection);
}while(connection != -1);
close_connection(connection);
close_listener(listener);
fclose(log_fd);
return 0;
}
permit_connections, accept_next_connection, and read_msg are all from a library that was provided to me. I'm guessing my problem is in recv_log_msgs, but I'm not sure what it would be.
Here's the root of your problem:
FILE *fp = log_fd;
log_fd is a file descriptor, fp is a FILE pointer.
The two are not interchangeable, and what you need to do is use the write(...) system call for writing to the log file, or create the log file in some other fashion to get a hold of a FILEpointer to it.
FILE *fp = fopen(argv[1], "w"), might do the trick.
EDIT: As #DarrenSmith pointed out to me in the comments, you can also use
fp = fdopen(log_fd, "w")
and keep the rest of the code as is.
I'm trying to read the GPS data from a serial port, at the moment i can read the data. But im trying to get only the data from "$GPRMC" line only.
I have this code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <sys/ioctl.h>
int main(int argc, char** argv) {
int sfd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY);
if (sfd == -1) {
printf("Error no is : %d\n", errno);
printf("Error description is : %s\n", strerror(errno));
return (-1);
};
struct termios options;
tcgetattr(sfd, &options);
cfsetspeed(&options, B9600);
cfmakeraw(&options);
//options.c_cc[VTIME]=1;
//options.c_cc[VMIN]=100;
//tcflush(sfd, TCIFLUSH);
tcsetattr(sfd, TCSANOW, &options);
usleep(100000);
char serialBuffer[500];
int bytes;
int count;
ioctl(sfd, FIONREAD, &bytes);
int i =0;
char *ret;
char *sepa;
char sepa2[500];
int compare;
for(;;){
if(bytes!=0){
count = read(sfd, serialBuffer, sizeof(serialBuffer));
}
if (count == -1){
printf("ERROR");
break;
}
else if(count == 0){
printf("NODATA");
break;
}
else{
serialBuffer[count] = '\0';
//strcpy(serialBuffer2, serialBuffer);
//printf("%s,", serialBuffer);
sepa = strtok(serialBuffer, "\n");
while(sepa != NULL){
//printf("%s", sepa);
//strcpy(serialBuffer2, sepa);
sepa = strtok(NULL, "\n");
ret = strstr(sepa, "$GPRMC");
if (NULL != ret) {
printf("The substring is: %s\n", ret);
}
}
}
}
close(sfd);
return (EXIT_SUCCESS);
}
This script is always returning me "Segmentation Faul(Core Dumped)", and i dont know why. Im new at c, can any one help me on this?
Thanks
I'm new with PulseAudio. I'm trying to make simple programs. One would record the sound and save it in baniry file, and the other one should open it and play. Here is my code for recording:
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <pulse/simple.h>
#include <pulse/error.h>
#define BUFSIZE 32
int main(int argc, char*argv[])
{
/* The Sample format to use */
static const pa_sample_spec ss = {
.format = PA_SAMPLE_S16LE, //16bit iqneba agwerili tito sample
.rate = 44100, //number of samples played in each second
.channels = 2
};
pa_simple *s_in = NULL;
int ret = 1;
int error;
int siri =0;
//file info
FILE* pFile;
char* yourFilePath = "xma.bin";
pFile = fopen(yourFilePath,"wb");
if (!(s_in = pa_simple_new(NULL, argv[0], PA_STREAM_RECORD, NULL, "record", &ss, NULL, NULL, &error)))
{
fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));
goto finish;
}
for (;siri<10000;siri+=1)
{
uint8_t buf[BUFSIZE];
ssize_t r;
int yorBufferSize = strlen(buf) + 1;
/* Write your buffer to disk. */
if (pa_simple_read(s_in, buf, sizeof(buf), &error) < 0)
{
fprintf(stderr, __FILE__": read() failed: %s\n", strerror(errno));
goto finish;
}
if (pFile)
{
fwrite(buf, yorBufferSize, 1, pFile);
puts("Wrote to file!");
}
else
{
puts("Something wrong writing to File.");
}
}
ret = 0;
finish:
if (s_in)
pa_simple_free(s_in);
return ret;
fclose(pFile);
}
And here is my recording program:
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <pulse/simple.h>
#include <pulse/error.h>
#define BUFSIZE 32
int main(int argc, char*argv[])
{
/* The Sample format to use */
static const pa_sample_spec ss = {
.format = PA_SAMPLE_S16LE, //16bit iqneba agwerili tito sample
.rate = 44100, //number of samples played in each second
.channels = 2
};
pa_simple *s_out = NULL;
int ret = 1;
int error;
//file info
FILE* pFile;
char* yourFilePath = "xma.bin";
pFile = fopen(yourFilePath, "rb");
/* Create a new playback stream */
if (!(s_out = pa_simple_new(NULL, argv[0], PA_STREAM_PLAYBACK, NULL, "playback", &ss, NULL, NULL, &error)))
{
fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error));
goto finish;
}
for (;;)
{
uint8_t buf[BUFSIZE];
fread(buf, sizeof(buf), 1, pFile);
ssize_t r;
if(feof(pFile))
{
break;
}
printf("%x", buf);
/* ... and play it */
if (pa_simple_write(s_out, buf, sizeof(buf), &error) < 0)
{
fprintf(stderr, __FILE__": pa_simple_write() failed: %s\n", pa_strerror(error));
goto finish;
}
}
/* Make sure that every single sample was played */
if (pa_simple_drain(s_out, &error) < 0)
{
fprintf(stderr, __FILE__": pa_simple_drain() failed: %s\n", pa_strerror(error));
goto finish;
}
ret = 0;
finish:
if (s_out)
pa_simple_free(s_out);
return ret;
fclose(pFile);
}
For loop in record program is just for time to record something(could not figure out how to set a timer) and I know that I should not use gotos but its for educational purposes(example provided on PulseAudio website). I tried hexdump of xma.bin and it gave me totally different ouput
than printf("%x", buf); Basically printf only gives back bf9fe15c repeatedly and it make annoying sound. Hope you can help. thanks.
I deleted pa_simple_drain() (it was my mistake that i used this function in recording program)function from record program and now it works. But in printf("%x", buf) it still gives me back same hex value over and over again. But programs work great. Can someone exmplain why does it print same value?
I am in the middle of writing a user level C program, that reads a SPI device and translate the results to a keyboard event.
I am now trying to pass emulate key event to /dev/uinput. A weird thing is happening, file operation is failing.
my_kbd.c
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <signal.h>
#include <unistd.h>
#include <errno.h>
#include <linux/input.h>
#include <linux/uinput.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <fcntl.h>
#define PROG_NAME "c2h2_spi_kbd"
int fire_key(__u16);
int setup_uinputfd(const char *);
int close_uinputfd();
void write_uinput(__u16, __u16, __s32);
/*fd for uinput, we do need kernel to support uinput */
static int uinputfd = -1;
int main(int argc, char **argv){
puts("Welcome to use SPI keyboard program v0.1!");
uinputfd = setup_uinputfd(PROG_NAME);
if(uinputfd != -1){
fire_key(KEY_A);
}else{
puts("where is uinput ? do you have permission?\n");
}
close_uinputfd();
exit(0);
}
int fire_key(__u16 key){
write_uinput(EV_KEY, key, 1);
return 0;
}
void write_uinput(__u16 type, __u16 code, __s32 value){
struct input_event ie;
sleep(1);
memset(&ie, 0, sizeof(ie));
ie.type = type;
ie.code = code;
ie.value = value;
if(write(uinputfd, &ie, sizeof(ie)) != sizeof(ie)) puts("ERR1");
memset(&ie, 0, sizeof(ie));
ie.type = EV_SYN;
ie.code = SYN_REPORT;
ie.value = 0;
if(write(uinputfd, &ie, sizeof(ie)) != sizeof(ie)) puts("ERR2");
}
int close_uinputfd(){
close(uinputfd);
return 0;
}
int setup_uinputfd(const char *name){
int fd;
int key;
struct uinput_user_dev dev;
fd = open("/dev/input/uinput", O_RDWR);
if (fd == -1) {
fd = open("/dev/uinput", O_RDWR);
if (fd == -1) {
fd = open("/dev/misc/uinput", O_RDWR);
if (fd == -1) {
fprintf(stderr, "could not open %s\n", "uinput");
perror(NULL);
return -1;
}
}
}
memset(&dev, 0, sizeof(dev));
strncpy(dev.name, name, sizeof(dev.name));
dev.name[sizeof(dev.name) - 1] = 0;
if (write(fd, &dev, sizeof(dev)) != sizeof(dev) ||
ioctl(fd, UI_SET_EVBIT, EV_KEY) != 0
|| ioctl(fd, UI_SET_EVBIT, EV_REP) != 0) {
goto setup_error;
}
for (key = KEY_RESERVED; key <= KEY_UNKNOWN; key++) {
if (ioctl(fd, UI_SET_KEYBIT, key) != 0) {
goto setup_error;
}
}
if (ioctl(fd, UI_DEV_CREATE) != 0) {
goto setup_error;
}
return fd;
setup_error:
fprintf(stderr, "could not setup %s\n", "uinput");
perror(NULL);
close(fd);
return -1;
}
gcc -Wall my_kbd.c && sudo ./a.out
without sleep(1); I never have uinput event happen. with sleep(1);, this works perfect. (emulate keys output to focused program)
I do suspect this could be a cache problem, but fsync(fd); did not help. Please help.
I use openssl. First off I created private/public keys, then I encrypt a string and keep the result in a file. When I try to decrypt the file my program fails. What's more, the encrypted file is different each time(I use md5sum checked). What have I missed to deal with?
/*
gcc -lssl queation.c -o test_ssl
#openssl genrsa -out test_private.key 1024
#openssl rsa -in test_private.key -pubout -out test_public.key
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<openssl/rsa.h>
#include<openssl/pem.h>
#include<openssl/err.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <linux/netdevice.h>
#include <linux/sockios.h>
#include <linux/if.h>
#include <asm/types.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <net/if_arp.h>
#include <netinet/if_ether.h>
#include <netinet/ether.h>
#include <fcntl.h>
#include <sys/socket.h>
#define OPENSSLKEY "test_private.key"
#define PUBLICKEY "test_public.key"
#define BUFFSIZE 1024
#define SIZE 1024
#define LIC_FILE "lic.rn"
#define PRTFL printf("fun = %s, line = %d\n", __FUNCTION__,__LINE__)
static char *ptr_en;
static char *p_en;
static RSA *p_rsa_public;
static FILE *fp_public;
static int flen_public, rsa_public_len;
static char *ptr_de;
static char *p_de;
static RSA *p_rsa_private;
static FILE *fp_private;
static int flen_private, rsa_private_len;
void usage( unsigned char * prog_name)
{
printf("usage: %s\n",
prog_name);
exit(1);
}
int main(int argc , char ** argv)
{
int i, ret , len;
unsigned char buf_plain[32];
unsigned char *buf_en;
unsigned char *raw_buffer;
FILE * pf_tmp;
if( argc != 1)
{
usage(argv[0]);
}
snprintf(buf_plain,sizeof(buf_plain),"this is a test line.\n");
if((fp_public=fopen(PUBLICKEY,"r"))==NULL)
{
perror("open public key file error");
ret = -1;
goto error;
}
if((p_rsa_public = PEM_read_RSA_PUBKEY(fp_public,NULL,NULL,NULL))==NULL)
{
ERR_print_errors_fp(stdout);
ret = -1;
goto error;
}
rsa_public_len=RSA_size(p_rsa_public);
p_en=(unsigned char *)malloc(rsa_public_len+1);
memset(p_en,0,rsa_public_len+1);
//printf("%s(%d)p_en = %p,rsa_public_len = %d\n", __FUNCTION__,__LINE__,p_en,rsa_public_len);
len = RSA_public_encrypt(rsa_public_len,buf_plain,p_en,p_rsa_public,RSA_NO_PADDING);
if (len !=rsa_public_len)
{
fprintf(stderr,"Error: len =%d, rsa_public_len = %d,ciphertext should match length of key\n", len,rsa_public_len);
ret = -1;
goto error;
}
pf_tmp = fopen(LIC_FILE,"w");
if( NULL == pf_tmp )
{
printf("open %s failed\n",LIC_FILE);
ret = -1;
goto error;
}
fwrite(p_en,1,128,pf_tmp);
fclose(pf_tmp);
if((fp_private=fopen(OPENSSLKEY,"r"))==NULL)
{
perror("open private key file error");
ret = -1;
goto error;
}
if((p_rsa_private=PEM_read_RSAPrivateKey(fp_private,NULL,NULL,NULL))==NULL)
{
ERR_print_errors_fp(stdout);
ret = -1;
goto error;
}
rsa_private_len = RSA_size(p_rsa_private);
pf_tmp = fopen(LIC_FILE,"r");
if( NULL == pf_tmp )
{
printf("open %s failed\n",LIC_FILE);
ret = -1;
goto error2;
}
raw_buffer = calloc(rsa_private_len,sizeof(char));
if( NULL == raw_buffer )
{
ret = -1;
goto error;
}
len = fread(raw_buffer, sizeof(char),sizeof(raw_buffer), pf_tmp);
if( len <=0 )
{
ret = -1;
goto error;
}
p_de=(unsigned char *)malloc(rsa_private_len+1);
memset(p_de,0,rsa_private_len+1);
//printf("%s(%d)p_en = %p,rsa_public_len = %d\n", __FUNCTION__,__LINE__,p_en,rsa_public_len);
len =RSA_private_decrypt (rsa_private_len,raw_buffer,p_de,p_rsa_private,RSA_NO_PADDING);
printf("%s(%d) p_de = %s\n",__FUNCTION__,__LINE__,p_de);
if ( len != rsa_private_len )
{
fprintf(stderr,"Error: ciphertext should match length of key\n");
exit(1);
}
error2:
fclose(pf_tmp);
error:
free(ptr_en);
free(ptr_de);
fclose(fp_public);
fclose(fp_private);
RSA_free(p_rsa_public);
RSA_free(p_rsa_private);
return ret;
}
It looks like you are not reading the whole file:
len = fread(raw_buffer, sizeof(char),sizeof(raw_buffer), pf_tmp);
Note that sizeof(raw_buffer) is the size of a pointer, but you wrote 128 bytes into the file (1024 bits). So you're only reading back 4 or 8 bytes and trying to decrypt that.
Try reading 128 bytes back.