Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

zackriggle

A Handler for FStream I/O

This topic is 5650 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have just finished outlining the wrapper class that allows me to write encrypyed data using 'fstream' objects. I beleive that it will work just fine [no compiler probs]... but that is hardly ever right. I was wondering if anyone could, should they have the time to do so, look over all of this, especially the operator overriding and getline() functions [right below this, at the top].
        
//===========================================================

// LHS File.CPP

//===========================================================

#ifndef __LHSFILE_CPP___
#define __LHSFILE_CPP___

#ifndef LHSFILE_DLL
#define LHSFILE_DLL __declspec(dllexport)
#endif

#include <fstream.h>
#include <windows.h>
#include <vector>
#include "lhs crypto.h"
#include "lhs file.h"

void LHSFILE_DLL LHSFile::operator<< (const signed char* data)
{
	if(fstr.is_open())
		fstr.close();

	if(flags |= _BINARY_)
		fstr.open(filename,ios::out|ios::binary);
	else
		fstr.open(filename,ios::out);

	BYTE* copydat;
	copydat = new unsigned char[strlen((const char*)data)+1];
	strcpy((char*)copydat,(char*)data);
	if(flags |= _ENCRYPT_)
	{
		CBlowFish cbf;
		cbf.Initialize(Global_Key, Global_Keysize);
		cbf.Encode(copydat,copydat,strlen((char*)copydat));
	}

	fstr << copydat;
	fstr.flush();
	fstr.close();
};
void LHSFILE_DLL LHSFile::operator<< (const unsigned char* data)
{
	operator<<((const signed char*)data);
};





void LHSFILE_DLL LHSFile::operator<< (const ULONG dat)
{
	if(fstr.is_open())
		fstr.close();
	if(flags |= _BINARY_)
		fstr.open(filename,ios::out|ios::binary);
	else
		fstr.open(filename,ios::out);

	BYTE *copydat;

	copydat = new BYTE[sizeof(ULONG)];
	itoa(dat,(char*)copydat,256);

	if(flags |= _ENCRYPT_)
	{
		CBlowFish cbf;
		cbf.Initialize(Global_Key, Global_Keysize);
		cbf.Encode(copydat,copydat,strlen((char*)copydat));
	};

	fstr << copydat;
	fstr.flush();
	fstr.close();
}
void LHSFILE_DLL LHSFile::operator<< (const signed long dat)
{
	operator<<((const ULONG) dat);
}





void LHSFILE_DLL LHSFile::operator<<(const UINT dat)
{
	if(fstr.is_open())
		fstr.close();
	if(flags |= _BINARY_)
		fstr.open(filename,ios::out|ios::binary);
	else
		fstr.open(filename,ios::out);
	
	BYTE *copydat;
	copydat = new BYTE[sizeof(UINT)];
	itoa(dat,(char*)copydat,256);	

	if(flags |= _ENCRYPT_)
	{
		CBlowFish cbf;
		cbf.Initialize(Global_Key, Global_Keysize);
		cbf.Encode(copydat,copydat,strlen((char*)copydat));
	};

	fstr << copydat;
	fstr.flush();
	fstr.close();
};
void LHSFILE_DLL LHSFile::operator<<(const signed int dat)
{
	operator<<((const unsigned int)dat);
};








void LHSFILE_DLL LHSFile::operator>> (char* dat)
{
	char* buffer;
	buffer = new char[1024];
	getline(buffer,1023,' ');
	delete[] dat;
	dat = buffer;
};
void LHSFILE_DLL LHSFile::operator>> (unsigned char* dat)
{
	operator>>((char*)dat);
};
void LHSFILE_DLL LHSFile::operator>> (signed char* dat)
{
	operator>>((char*)dat);
};


void LHSFILE_DLL LHSFile::operator>> (signed int &dat)
{
	char* buffer;
	buffer = new char[16];
	getline(buffer,15,' ');
	dat = atoi(buffer);
	delete[] buffer;
};
void LHSFILE_DLL LHSFile::operator>> (unsigned int &dat)
{
	operator>>((signed int&)dat);
};


void LHSFILE_DLL LHSFile::operator>> (unsigned long &dat)
{
	char* buffer;
	buffer = new unsigned char[32];
	getline(buffer,31,' ');
	dat = atoi(buffer);
	delete[] buffer;
};
void LHSFILE_DLL LHSFile::operator>> (signed long &dat)
{
	operator>>((unsigned int&)dat);
};


void LHSFILE_DLL LHSFile::getline(signed char* userbuf,int len, char delim)
{
	getline((char*)userbuf,len,delim);
};
void LHSFILE_DLL LHSFile::getline(unsigned char* userbuf,int len, char delim)
{
	getline((char*)userbuf,len,delim);
};
void LHSFILE_DLL LHSFile::getline(char* userbuf,int len, char delim)
{
	if(fstr.is_open())
		fstr.close();

	if(flags |= _BINARY_)
		fstr.open(filename,ios::in|ios::binary);
	else
		fstr.open(filename,ios::in);

	char* nbuf;
	nbuf = new char[len];
	
	fstr.read(nbuf,len);
	
	// Search the string for the first occurence of the delimeter

	signed int first = -1;
	for(int x = 0; x != len; x++)
	{
		if(delim == nbuf[x])
			first=x;
	}

	if(delim != -1)
	{
		delete[] userbuf;
		userbuf = new char[len];
		// Copy the data _up to_ the delimeter into nbuf2

		for(x=0; x != first; x++)
		{
			userbuf[x] = nbuf[x];
		}
	}
	else
		strcpy(userbuf,nbuf);

	delete[] nbuf;	
};
#endif



//===========================================================

// BlowFish.H

//===========================================================

// This is the outline for the CBlowFish class.

// It wraps the BlowFish algorithm, and does so quite

// simply.  I did not include the implementation of the

// functions, they should be relatively self-explanatory.

// The only ones you ever need to use are Initialize(),

// Encode() and Decode().

#ifndef BLOWFISH_DLL
#define BLOWFISH_DLL __declspec(dllimport)
#endif

#define MAXKEYBYTES 	56		// 448 bits max
#define NPASS           16		// SBox passes
#include <windows.h>


class CBlowFish
{
private:
	DWORD 		* PArray ;
	DWORD		(* SBoxes)[256];
	bool		init;
	BLOWFISH_DLL void 		Blowfish_encipher (DWORD *xl, DWORD *xr) ;
	BLOWFISH_DLL void 		Blowfish_decipher (DWORD *xl, DWORD *xr) ;

public:
	BLOWFISH_DLL CBlowFish () ;
	BLOWFISH_DLL ~CBlowFish () ;
	BLOWFISH_DLL void 		Initialize (BYTE key[], int keybytes) ;
	BLOWFISH_DLL DWORD		GetOutputLength (DWORD lInputLong) ;
	BLOWFISH_DLL DWORD		Encode (BYTE * pInput, BYTE * pOutput, DWORD lSize) ;
	BLOWFISH_DLL void		Decode (BYTE * pInput, BYTE * pOutput, DWORD lSize) ;

} ;

// choose a byte order for your hardware

#define ORDER_DCBA	// choosing Intel in this case


#ifdef ORDER_DCBA  	// DCBA - little endian - intel
	union aword {

	  DWORD dword;
	  BYTE byte [4];
	  struct {
	    unsigned int byte3:8;
	    unsigned int byte2:8;
	    unsigned int byte1:8;
	    unsigned int byte0:8;
	  } w;
	};
#endif


//===========================================================

// LHS Crypto.H

//===========================================================

// The LhsCipher [LHS = LakeShore High] struct creates a

// small struct for the CBlowFish class, because I did

// not want to modify the CBlowFish code, since I did not

// write it.  The only difference between the two is that\

// it keeps a real copy of the key and keylength in memory

// that can be changed (but you have to call Initialize()

// if you want to change the key used with the cipher)....

#ifndef LHSCRYTP_DLL
#define LHSCRYTP_DLL __declspec(dllimport)
#endif

#include "blowfish.h"

struct LhsCipher
{
	CBlowFish cipher;
	BYTE *key;
	UINT keysize;
};

     // Global_Key and Global_Keysize are two values

     // that are used to encrypt non user-specific files

     // [ex. config files].

     // They are assumed to be set up at the beginning of

     // the program, and not covered here....

static BYTE		*Global_Key;
static UINT		Global_Keysize;

//===========================================================

// LHS File.H

//===========================================================

#ifndef LHSFILE_DLL
#define LHSFILE_DLL __declspec(dllimport)
#endif

#include <fstream.h>
#include <windows.h>
#include <vector>
#include "lhs crypto.h"

#define _ENCRYPT_	1
#define _BINARY_	2
class LHSFile
{
	char* filename;
	fstream fstr;
	DWORD flags;

	LHSFILE_DLL void operator<< (const char*)
	LHSFILE_DLL void operator<< (const unsigned char*);
	LHSFILE_DLL void operator<< (const signed char*);
	LHSFILE_DLL void operator<< (const unsigned int);
	LHSFILE_DLL void operator<< (const signed int);
	LHSFILE_DLL void operator<< (const unsigned long);
	LHSFILE_DLL void operator<< (const signed long);

	LHSFILE_DLL void operator>> (unsigned char*);
	LHSFILE_DLL void operator>> (signed char*);
	LHSFILE_DLL void operator>> (unsigned int&);
	LHSFILE_DLL void operator>> (signed int&);
	LHSFILE_DLL void operator>> (unsigned long&);
	LHSFILE_DLL void operator>> (signed long&);

	LHSFILE_DLL void getline(unsigned char*,int, char delim='\n');
	LHSFILE_DLL void getline(signed char*,int, char delim='\n');
	LHSFILE_DLL void getline(char*,int,char delim='\n');
};

        
Thanks, [XtaC] The Next Name in Low-End of the "Never-Heard-of-It" applications [edited by - zackriggle on March 31, 2003 6:45:23 PM] [edited by - zackriggle on April 1, 2003 11:56:39 PM]

Share this post


Link to post
Share on other sites
Advertisement
A problem with this approach is that LHSFile doesn''t behave entirely like a stream. If someone overloads operator << (ostream&, const Foo&), they won''t be able to use it with LHSFile. LHSFile also doesn''t have the same functions and operators that the language''s streams do. You might want to derive from the c++ stream classes.

Share this post


Link to post
Share on other sites
If I inherit from it, then I will have to know how the actual ''fstream'' class works -- something I am not willing to spend the time to do -- in order to overload any virtual functions. I could add my own functions (ex readTo(), instead of operator>>, as well as write() instead of operator>> [the write would have nothing to do with iostream::write() ] )...

Share this post


Link to post
Share on other sites
Really if you want to be compatible with iostream functionality you should derive from a streambuf or filebuf and use those rather than duplicating an fstream.

Create a LHSfilebuf (or whatever you want to call it), then it can be used in any iostream and it''s actually a lot less work than doing it your way (the time taken learning how to do it will be more than paid off when it comes to maintaining the implementation).

Share this post


Link to post
Share on other sites
A note on another matter: BlowFish is a 64 bit block cipher algorithm, if the length of the string (or size of the type) you pass to the Encode isn''t an even 8 bytes you will get into trouble (in other words: if strlen(data) % 8 != 0 then you''ll get into trouble), unless if your implementation of the BlowFish algorithm takes care of this.

And instead of creating a local BlowFish object and initialize it for each call to operator<<, you could have a BlowFish member in LHSFile.



Update GameDev.net system time campaign - success at last

Share this post


Link to post
Share on other sites
The BlowFish implementation I use takes any length of string, but the output value is always (strlen(out) mod 8 == 0).... hence, there is no need for me to do any shaping or padding. Thx for the idea, though.

Also, might there be any tutorials or documentations anywhere on the web that describe how the hell the iostream libraries work, so that I don't have to go blindfolded into a bunch of sourcecode....

==================
My (soon-to-be) Cherished Cookie of Appreciation:

-- MattB - for WinSock advice --

[edited by - zackriggle on April 2, 2003 11:11:58 AM]

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!