Search code examples
c++stdvectorcrypto++

Saving Crypto++ objects to std::vector


I want to save Crypto++ keys to std::vector<uint8_t>. Unfortunately there is only CryptoPP::StringSink, that takes std::string reference but no CryptoPP::VectorSink that would take a reference to std::vector.

Following code works fine

std::string spki;
CryptoPP::StringSink ss(spki);

CryptoPP::RSA::PublicKey publicKey(...);
publicKey.Save(ss);

But I want this

std::vector<uint8_t> spki;
CryptoPP::VectorSink vs(spki);

CryptoPP::RSA::PublicKey publicKey(...);
publicKey.Save(vs);

The problem

VectorSink can not be created just by using a typedef because of traits_type::char_type inside StringSinkTemplate:

using CryptoPP::StringSinkTemplate;
typedef StringSinkTemplate< std::vector<byte> > VectorSink;

In file included from cryptopp-test.cpp:65:
In file included from /usr/local/include/cryptopp/files.h:5:
/usr/local/include/cryptopp/filters.h:590:22: error: no member named
      'traits_type' in 'std::vector<unsigned char, std::allocator<unsigned char>
      >'
        typedef typename T::traits_type::char_type char_type;
                         ~~~^
cryptopp-test.cpp:243:20: note: in instantiation of template class
      'CryptoPP::StringSinkTemplate<std::vector<unsigned char,
      std::allocator<unsigned char> > >' requested here
        VectorSink vs(spki);

How can I create a VectorSink?


Solution

  • Working implementation of VectorSink

    // Written and placed in the public domain by rrmmnn
    // Copyright assigned to the Crypto++ project.
    
    namespace CryptoPP {
    
    class VectorSink : public Bufferless<Sink> {
    public:
    
      VectorSink(std::vector<uint8_t>& out)
        : _out(&out) {
      }
    
      size_t Put2(const byte *inString, size_t length, int /*messageEnd*/, bool /*blocking*/) {
        _out->insert(_out->end(), inString, inString + length);
        return 0;
      }
    
    private:  
      std::vector<uint8_t>* _out;
    };
    
    }