I've compiled the attached code, and it doesn't decrypt the text
correctly. If anyone could explain why to me, or point out a nice
tutorial about using these routines, it would be much appreciated.
ircd_malloc() is basically malloc() with memset().
Chris Plant
<[EMAIL PROTECTED]>
#ifndef _ENPRESS_H_
#define _ENPRESS_H_
#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
struct _encryption_contexts {
EVP_CIPHER_CTX decrypt;
EVP_CIPHER_CTX encrypt;
};
typedef struct _encryption_contexts * EncryptInfo;
int encrypt_buffer(EncryptInfo,unsigned char *,unsigned char *,int *);
int decrypt_buffer(EncryptInfo,unsigned char *,unsigned char *,int);
EncryptInfo generate_key(unsigned char *);
#endif
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include "enpress.h"
int main(int argc,char **argv)
{
int sockets[2];
char *key="somekeys";
EncryptInfo e_info=NULL;
e_info=generate_key(key);
socketpair(AF_UNIX,SOCK_STREAM,0,sockets);
if(!fork()) {
/* Sending process */
char buffer[512]="NICK Chunky\n\r\0";
char enc_buffer[512];
char out_buffer[512];
int length,enc_length;
encrypt_buffer(e_info,buffer,enc_buffer,&enc_length);
ircd_sprintf(out_buffer,5,"%04d",enc_length);
send(sockets[0],out_buffer,4,0);
send(sockets[0],enc_buffer,enc_length,0);
} else {
/* Reciving process */
char in_buffer[512];
char clean_buffer[512];
char length_buffer[5];
int length,clean_len;
recv(sockets[1],length_buffer,4,0);
length_buffer[4]='\0';
printf("String is %s\n",length_buffer);
length=atoi(length_buffer);
printf("Number is %d\n",length);
recv(sockets[1],in_buffer,length,0);
clean_len=decrypt_buffer(e_info,in_buffer,clean_buffer,length);
clean_buffer[clean_len]='\0';
printf("Cleaned buffer, it is %s\n",clean_buffer);
}
}
/* This file is part of Chunky Monkey IRCD
*
* Chunky Monkey IRCD is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Chunky Monkey IRCD is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Chunky Monkey IRCD; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* $Id: enpress.c,v 1.1 2001/12/31 22:05:14 lloydy Exp $
*
*/
#include "enpress.h"
#include "utility.h"
#include "logger.h"
/*
* Lots of casting in here, until I sus out a better way of dealing with things
*/
/*
* Encrypt buffer using key
*/
int encrypt_buffer(EncryptInfo info,unsigned char *buffer,unsigned char *enc_buffer,int *enc_len)
{
unsigned char enc_tmp_buffer[512];
int enc_tmp_len=0;
*enc_len=0;
EVP_EncryptUpdate(&(info->encrypt),enc_tmp_buffer,&enc_tmp_len,buffer,strlen( (const char *)buffer));
*enc_len+=enc_tmp_len;
strncpy(enc_buffer,enc_tmp_buffer,enc_tmp_len);
EVP_EncryptFinal(&(info->encrypt),enc_tmp_buffer,&enc_tmp_len);
*enc_len+=enc_tmp_len;
strncat(enc_buffer,enc_tmp_buffer,enc_tmp_len);
return (*enc_len);
}
/*
* Decrypt buffer using key
* Assume the buffer is > 512 bytes long
*/
int decrypt_buffer(EncryptInfo info,unsigned char *buffer,unsigned char *clean,int len)
{
char denc_tmp_buffer[512];
int tmp_len=0,out_len=0;
EVP_DecryptUpdate(&(info->decrypt),denc_tmp_buffer,&tmp_len,buffer,len);
out_len+=tmp_len;
strncpy(clean,denc_tmp_buffer,tmp_len);
if(!EVP_DecryptFinal(&(info->decrypt),denc_tmp_buffer,&tmp_len)) {
printf("Failed to decrypt correctly\n");
}
out_len+=tmp_len;
strncat(clean,denc_tmp_buffer,tmp_len);
return out_len;
}
/*
* Generate a blowfish key using the text
*/
EncryptInfo generate_key(unsigned char *key_text)
{
EncryptInfo new=NULL;
unsigned char key[EVP_MAX_KEY_LENGTH];
unsigned char iv[EVP_MAX_IV_LENGTH];
if(!lc_strncmp(key_text,"*",-1)) {
return NULL;
}
new = ircd_malloc(sizeof(struct _encryption_contexts));
EVP_BytesToKey(EVP_bf_cbc(),EVP_md5(),NULL,key_text,strlen(key_text),1,key,iv);
EVP_EncryptInit(&(new->encrypt),EVP_bf_cbc(),key,iv);
EVP_DecryptInit(&(new->decrypt),EVP_bf_cbc(),key,iv);
return new;
}