Boost logo

Boost Users :

From: Pfligersdorffer, Christian (Christian.Pfligersdorffer_at_[hidden])
Date: 2006-09-22 10:41:44


Dear community,

I'm on my way to learn writing filters for the iostreams library and find it very hard. I want to compress and encrypt data, so I use the gzip-filters (that are already provided) and some self-tailored crypto-filter. Using a symmetric block cipher should be just fine with the framework, since data from a stream is usually fed in portions to the filter (128 Bytes by default).

Of course not when you use an aggregate_filter, which was my first attempt because it is so simple. Implementing a multichar_dual_use_filter seemed simple too but I am experiencing weird behaviour. Such as having runtime errors when reading an encrypted compressed file but not when reading compressed encrypted files. Also I am not entirely sure that I understood the documentation...

Here is what I do, perhaps you gurus instantly see what I'm doing wrong:

_________________________________________________________________________

class block_crypter : public boost::iostreams::multichar_dual_use_filter
{
        const std::string pw;

        char* buffer;
        int length;

        void reallocate_buffer(std::size_t n)
        {
                if (length < n) {
                        if (buffer) free(buffer);
                        buffer = (char*) malloc(n);
                        length = n;
                }
        }
        
public:
        block_crypter(const char* password) : pw(password), buffer(NULL), length(0) {}
        ~block_crypter() { if (buffer) free(buffer); }

    template<typename Source>
    std::streamsize read(Source& src, char* s, std::streamsize n)
    {
        // Read up to n filtered characters into the buffer s,
        // returning the number of characters read or -1 for EOF.
        // Use src to access the unfiltered character sequence

                reallocate_buffer(n);

                std::streamsize count = boost::iostreams::read(src, buffer, n);
                assert(count <= n);
                if (count <= 0) return -1;

                decrypt(pw, buffer, count, s);
                return count;
        }

        template<typename Sink>
        std::streamsize write(Sink& dest, const char* s, std::streamsize n)
        {
        // Consume up to n filtered characters from the buffer s,
        // writing filtered characters to dest. Return the number
        // of characters consumed.

                reallocate_buffer(n);

                encrypt(pw, s, n, buffer);

                std::streamsize count = boost::iostreams::write(dest, buffer, n);
                assert(count <= n);
                
                return count;
        }
};

BOOST_IOSTREAMS_PIPABLE(block_crypter, 0)
_________________________________________________________________________

The encrypt() and decrypt() functions produce a character sequence of the exact same length as the input sequence. All char values can occur which might be a problem but I don't know.

Runtime errors always occur at the end of the stream, i.e. on the last run of the filter. Perhaps I did not understand the EOF mechanics or am mixing up something. But then, it compiles and seems to behave properly if used alone. Only in read-mode preceding gzip-deflation there is an error.

I hope someone can help me there.

BTW: I did not even try to implement my filter as symmetric_filter. I cannot see how anyone would be able to do this given the present documentation or existing "examples".

Another thing that clearly arises is the block size issue n which has to be the same for writing and reading in order to produce the correct plain text again. Maybe the optimally_buffered_tag should be used instead of trusting in always the same default filter buffer size?

Thanks for your suggestions,

--
Christian Pfligersdorffer
Dipl.-Ing. Bakk.rer.nat.
Software Engineering
EOS GmbH - Electro Optical Systems
Robert-Stirling-Ring 1
D-82152 Krailling / Munich
Phone +49 89 893 36-229
Fax +49 89 893 36-287
 
christian.pfligersdorffer_at_[hidden]
http://www.eos.info 

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net