Click here to Skip to main content
15,886,513 members
Articles / Desktop Programming / MFC

MFC CFile Implementation for Crypto++

Rate me:
Please Sign up or sign in to vote.
3.77/5 (4 votes)
10 Mar 2009CPOL4 min read 35.7K   517   25   2
Implementation of a file store/source/sink using MFC CFile.

Introduction

Target Audience

This article is targeted for MFC developers with understanding of the Crypto++ code library.
For the sake of clarity and introducing Crypto++ to those who are not familiar with it, I added the following paragraph.

Crypto++ Intro

From the Crypto++ website: "Crypto++ Library is a free C++ class library of cryptographic schemes".
Written and maintained by Wei Dai, this is a powerful library that contains modern cryptography algorithms.

To understand Crypto++, you should have (at least) basic understanding of cryptography concepts.
The World-Wide-Web offers a lot of information, and so does CodeProject (e.g.: See Jeffery Walton's valuable articles in this field).
For an in-depth reading, I found the book Applied Cryptography to be very enlightening. Beyond being very informative, it is written almost like an espionage/conspiracy novel, which makes reading it a lot more fun.

Back to Crypto++, the website contains valuable information and you may also want to visit the Crypto++ Wiki pages to get started.
I should point out that, to me, the learning curve was kinda slower than, oh, let's say, the time it took Trinity to learn how to fly that Bell 212 helicopter... (Note: I am not the geek you might think I am at this point in the article!)
Anyway, it will take a while to get used to the concepts and design patterns of the library (on a personal note, I really enjoyed reading Crypto++'s source code).
So, if you're going for it - don't get discouraged - once you get the hang of things, everything will fall into place and it'll all become clear.

The Problem

While integrating cryptography abilities into an MFC application I'm working on, I needed to use CFile(s) with Crypto++'s code instead of its built-in fstream file handling implementation.
Not being able to find such an implementation, I decided to write one.

The Code

This implementation will enable you to use an MFC CFile as a Source / Sink element in conjunction with Crypto++'s data transport design pattern. It is pretty straightforward - I used Crypto++'s files.h/.cpp as a baseline, and made the necessary modifications for the code to work with a CFile.
The code is based on Crypto++ v5.5.2 (but I believe it may work with earlier versions) and was tested on Visual C++ 6.0 and Visual Studio 2005.

Code Integration

The source code won't run on its own. You will have to integrate it into a working Crypto++ environment.
Crypto++ source code may be downloaded from Crypto++'s download section.
You'll probably want to review the Compiling and Integrating Crypto++ into the Microsoft Visual C++ Environment page, which will help you get started with Crypto++ on your version of Microsoft Visual Studio.
You may also have a look at the Crypto++ FAQ and the Crypto++ Wiki for a user reference, some useful examples and more information.

Using the Code

I'll use a simple file-copy operation to demonstrate the code.

C++
void CopyFile( CFile* fin, CFile* fout )
{
    MfcCFileSource( fin, true, new MfcCFileSink( fout ) );
}

This code will create an MfcCFileSource wrapper for the input file, create a MfcCFileSink wrapper for the output file, and pump all bytes from the input file to the output file.

Preserving the Output File Pointer

In the above example, MfcCFileSink will be deleted somewhere during MfcCFileSource's destruction sequence. Effectively, this means that MfcCFileSink, in its turn, will delete the fout file pointer (this will be done implicitly by a smart pointer that wraps fout).

In order to overcome this hurdle, I added a boolean parameter to MfcCFileSink's constructor:

C++
MfcCFileSink( CFile* out, bool bAutoDelete = true );

The default value of bAutoDelete will be to auto-delete the out file pointer, which is the default behavior of having fout wrapped in a smart pointer. In order to keep out alive and unharmed, you should pass false as the second parameter to MfcCFileSink's constructor.

Here's the revised file-copy example:

C++
void CopyFile( CFile* fin, CFile* fout, bool bAutoDeleteFOut )
{
    MfcCFileSource( fin, true, new MfcCFileSink( fout, bAutoDeleteFOut ) );
}

Using this version of CopyFile, it is possible to pass false to bAutoDeleteFOut and thus preserve fout for consecutive operations (e.g., appending several files one after the other into a single output file).

No Auto-delete Option for a Filename Constructor

While we're on the subject, I'll just add the filename related constructor:

C++
MfcCFileSink(LPCTSTR filename, bool binary=true);

Since the CFile pointer in this case is maintained internally in this case, I'd like to keep it that way. That is why there is no bAutoDeleteFOut parameter here. If you really need the CFile* - open a file in advance and pass it to the appropriate constructor.

A Real-Life Example

Of course, any transformation filter may be applied before MfcCFileSink in order to manipulate the bytes on their way from the source to the sink.

In order to see the code in action, here's a real-life example of compressing and encrypting an input file:

C++
void EncryptFileDemo( CFile* fin, CFile* fout, const char* sPassPhrase )
{
    MfcCFileSource( fin, true, 
            new Gzip(
                new DefaultEncryptorWithMAC( sPassPhrase,
                    new MfcCFileSink( fout )
                )
            )
        );
}

In the example, we pass the input file bytes through a compression filter and an encryption (with password) filter all the way out to the output file.

  • Filter is a Crypto++ data manipulation mechanism.
  • Explaining filters is beyond the scope of this article.

The client code may look like this:

C++
EncryptFileDemo(
        new CFile(File, CFile::modeRead),
        new CFile(sOutFile, CFile::modeWrite | CFile::modeCreate),
        "Geronimo"
    );

That's It

Hope you'll find this helpful.
Comments / suggestions are most welcome.

History

  • 3rd March, 2009
    • Initial post
  • 7th March, 2009
    • Added Crypto++ Background and Code Integration info (thanks to Hans Dietrich)
    • Fixed a minor compatibility issue with VC7 version and above

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Israel Israel
Developing software since 1994 (or so Smile | :) )

Comments and Discussions

 
GeneralProblem in Release Mode Pin
rubel00122-Sep-10 1:34
rubel00122-Sep-10 1:34 
GeneralRe: Problem in Release Mode Pin
AVIDeveloper2-Oct-10 17:07
AVIDeveloper2-Oct-10 17:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.