From 39052451400dd9beb12c350d87c2d48ff476210e Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Wed, 14 Oct 2015 16:32:17 -0400 Subject: Move DataSource to utils and rewrite PEM encoding to avoid filters Removes filters as as an internal dependency pretty much entirely (outside of some dusty corners in misc). --- src/lib/asn1/info.txt | 1 - src/lib/ffi/info.txt | 1 - src/lib/filters/data_src.cpp | 212 ------------------------------------------- src/lib/filters/data_src.h | 180 ------------------------------------ src/lib/filters/info.txt | 2 - src/lib/misc/pem/info.txt | 2 +- src/lib/misc/pem/pem.cpp | 41 ++++++--- src/lib/pubkey/x509_key.h | 2 +- src/lib/utils/data_src.cpp | 212 +++++++++++++++++++++++++++++++++++++++++++ src/lib/utils/data_src.h | 180 ++++++++++++++++++++++++++++++++++++ src/lib/utils/info.txt | 1 + 11 files changed, 425 insertions(+), 409 deletions(-) delete mode 100644 src/lib/filters/data_src.cpp delete mode 100644 src/lib/filters/data_src.h create mode 100644 src/lib/utils/data_src.cpp create mode 100644 src/lib/utils/data_src.h (limited to 'src/lib') diff --git a/src/lib/asn1/info.txt b/src/lib/asn1/info.txt index c6c3db537..a067168e4 100644 --- a/src/lib/asn1/info.txt +++ b/src/lib/asn1/info.txt @@ -3,7 +3,6 @@ define ASN1 20131128 load_on auto -filters bigint oid_lookup diff --git a/src/lib/ffi/info.txt b/src/lib/ffi/info.txt index 8d6c5237e..4018e4064 100644 --- a/src/lib/ffi/info.txt +++ b/src/lib/ffi/info.txt @@ -2,7 +2,6 @@ define FFI 20151001 aead -filters kdf pbkdf pubkey diff --git a/src/lib/filters/data_src.cpp b/src/lib/filters/data_src.cpp deleted file mode 100644 index 4e0725943..000000000 --- a/src/lib/filters/data_src.cpp +++ /dev/null @@ -1,212 +0,0 @@ -/* -* DataSource -* (C) 1999-2007 Jack Lloyd -* 2005 Matthew Gregan -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#include -#include -#include -#include - -namespace Botan { - -/* -* Read a single byte from the DataSource -*/ -size_t DataSource::read_byte(byte& out) - { - return read(&out, 1); - } - -/* -* Peek a single byte from the DataSource -*/ -size_t DataSource::peek_byte(byte& out) const - { - return peek(&out, 1, 0); - } - -/* -* Discard the next N bytes of the data -*/ -size_t DataSource::discard_next(size_t n) - { - byte buf[64] = { 0 }; - size_t discarded = 0; - - while(n) - { - const size_t got = this->read(buf, std::min(n, sizeof(buf))); - discarded += got; - - if(got == 0) - break; - } - - return discarded; - } - -/* -* Read from a memory buffer -*/ -size_t DataSource_Memory::read(byte out[], size_t length) - { - size_t got = std::min(source.size() - offset, length); - copy_mem(out, source.data() + offset, got); - offset += got; - return got; - } - -bool DataSource_Memory::check_available(size_t n) - { - return (n <= (source.size() - offset)); - } - -/* -* Peek into a memory buffer -*/ -size_t DataSource_Memory::peek(byte out[], size_t length, - size_t peek_offset) const - { - const size_t bytes_left = source.size() - offset; - if(peek_offset >= bytes_left) return 0; - - size_t got = std::min(bytes_left - peek_offset, length); - copy_mem(out, &source[offset + peek_offset], got); - return got; - } - -/* -* Check if the memory buffer is empty -*/ -bool DataSource_Memory::end_of_data() const - { - return (offset == source.size()); - } - -/* -* DataSource_Memory Constructor -*/ -DataSource_Memory::DataSource_Memory(const std::string& in) : - source(reinterpret_cast(in.data()), - reinterpret_cast(in.data()) + in.length()), - offset(0) - { - offset = 0; - } - -/* -* Read from a stream -*/ -size_t DataSource_Stream::read(byte out[], size_t length) - { - source.read(reinterpret_cast(out), length); - if(source.bad()) - throw Stream_IO_Error("DataSource_Stream::read: Source failure"); - - size_t got = source.gcount(); - total_read += got; - return got; - } - -bool DataSource_Stream::check_available(size_t n) - { - const std::streampos orig_pos = source.tellg(); - source.seekg(0, std::ios::end); - const size_t avail = source.tellg() - orig_pos; - source.seekg(orig_pos); - return (avail >= n); - } - -/* -* Peek into a stream -*/ -size_t DataSource_Stream::peek(byte out[], size_t length, size_t offset) const - { - if(end_of_data()) - throw Invalid_State("DataSource_Stream: Cannot peek when out of data"); - - size_t got = 0; - - if(offset) - { - secure_vector buf(offset); - source.read(reinterpret_cast(buf.data()), buf.size()); - if(source.bad()) - throw Stream_IO_Error("DataSource_Stream::peek: Source failure"); - got = source.gcount(); - } - - if(got == offset) - { - source.read(reinterpret_cast(out), length); - if(source.bad()) - throw Stream_IO_Error("DataSource_Stream::peek: Source failure"); - got = source.gcount(); - } - - if(source.eof()) - source.clear(); - source.seekg(total_read, std::ios::beg); - - return got; - } - -/* -* Check if the stream is empty or in error -*/ -bool DataSource_Stream::end_of_data() const - { - return (!source.good()); - } - -/* -* Return a human-readable ID for this stream -*/ -std::string DataSource_Stream::id() const - { - return identifier; - } - -/* -* DataSource_Stream Constructor -*/ -DataSource_Stream::DataSource_Stream(const std::string& path, - bool use_binary) : - identifier(path), - source_p(new std::ifstream(path, - use_binary ? std::ios::binary : std::ios::in)), - source(*source_p), - total_read(0) - { - if(!source.good()) - { - delete source_p; - throw Stream_IO_Error("DataSource: Failure opening file " + path); - } - } - -/* -* DataSource_Stream Constructor -*/ -DataSource_Stream::DataSource_Stream(std::istream& in, - const std::string& name) : - identifier(name), - source_p(nullptr), - source(in), - total_read(0) - { - } - -/* -* DataSource_Stream Destructor -*/ -DataSource_Stream::~DataSource_Stream() - { - delete source_p; - } - -} diff --git a/src/lib/filters/data_src.h b/src/lib/filters/data_src.h deleted file mode 100644 index 2b6998448..000000000 --- a/src/lib/filters/data_src.h +++ /dev/null @@ -1,180 +0,0 @@ -/* -* DataSource -* (C) 1999-2007 Jack Lloyd -* 2012 Markus Wanner -* -* Botan is released under the Simplified BSD License (see license.txt) -*/ - -#ifndef BOTAN_DATA_SRC_H__ -#define BOTAN_DATA_SRC_H__ - -#include -#include -#include - -namespace Botan { - -/** -* This class represents an abstract data source object. -*/ -class BOTAN_DLL DataSource - { - public: - /** - * Read from the source. Moves the internal offset so that every - * call to read will return a new portion of the source. - * - * @param out the byte array to write the result to - * @param length the length of the byte array out - * @return length in bytes that was actually read and put - * into out - */ - virtual size_t read(byte out[], size_t length) = 0; - - virtual bool check_available(size_t n) = 0; - - /** - * Read from the source but do not modify the internal - * offset. Consecutive calls to peek() will return portions of - * the source starting at the same position. - * - * @param out the byte array to write the output to - * @param length the length of the byte array out - * @param peek_offset the offset into the stream to read at - * @return length in bytes that was actually read and put - * into out - */ - virtual size_t peek(byte out[], size_t length, - size_t peek_offset) const = 0; - - /** - * Test whether the source still has data that can be read. - * @return true if there is still data to read, false otherwise - */ - virtual bool end_of_data() const = 0; - /** - * return the id of this data source - * @return std::string representing the id of this data source - */ - virtual std::string id() const { return ""; } - - /** - * Read one byte. - * @param out the byte to read to - * @return length in bytes that was actually read and put - * into out - */ - size_t read_byte(byte& out); - - /** - * Peek at one byte. - * @param out an output byte - * @return length in bytes that was actually read and put - * into out - */ - size_t peek_byte(byte& out) const; - - /** - * Discard the next N bytes of the data - * @param N the number of bytes to discard - * @return number of bytes actually discarded - */ - size_t discard_next(size_t N); - - /** - * @return number of bytes read so far. - */ - virtual size_t get_bytes_read() const = 0; - - DataSource() {} - virtual ~DataSource() {} - DataSource& operator=(const DataSource&) = delete; - DataSource(const DataSource&) = delete; - }; - -/** -* This class represents a Memory-Based DataSource -*/ -class BOTAN_DLL DataSource_Memory : public DataSource - { - public: - size_t read(byte[], size_t) override; - size_t peek(byte[], size_t, size_t) const override; - bool check_available(size_t n) override; - bool end_of_data() const override; - - /** - * Construct a memory source that reads from a string - * @param in the string to read from - */ - DataSource_Memory(const std::string& in); - - /** - * Construct a memory source that reads from a byte array - * @param in the byte array to read from - * @param length the length of the byte array - */ - DataSource_Memory(const byte in[], size_t length) : - source(in, in + length), offset(0) {} - - /** - * Construct a memory source that reads from a secure_vector - * @param in the MemoryRegion to read from - */ - DataSource_Memory(const secure_vector& in) : - source(in), offset(0) {} - - /** - * Construct a memory source that reads from a std::vector - * @param in the MemoryRegion to read from - */ - DataSource_Memory(const std::vector& in) : - source(in.begin(), in.end()), offset(0) {} - - size_t get_bytes_read() const override { return offset; } - private: - secure_vector source; - size_t offset; - }; - -/** -* This class represents a Stream-Based DataSource. -*/ -class BOTAN_DLL DataSource_Stream : public DataSource - { - public: - size_t read(byte[], size_t) override; - size_t peek(byte[], size_t, size_t) const override; - bool check_available(size_t n) override; - bool end_of_data() const override; - std::string id() const override; - - DataSource_Stream(std::istream&, - const std::string& id = ""); - - /** - * Construct a Stream-Based DataSource from file - * @param file the name of the file - * @param use_binary whether to treat the file as binary or not - */ - DataSource_Stream(const std::string& file, bool use_binary = false); - - DataSource_Stream(const DataSource_Stream&) = delete; - - DataSource_Stream& operator=(const DataSource_Stream&) = delete; - - ~DataSource_Stream(); - - size_t get_bytes_read() const override { return total_read; } - private: - const std::string identifier; - - std::istream* source_p; - std::istream& source; - size_t total_read; - }; - -} - -#endif diff --git a/src/lib/filters/info.txt b/src/lib/filters/info.txt index da6827833..fbecd9c87 100644 --- a/src/lib/filters/info.txt +++ b/src/lib/filters/info.txt @@ -6,7 +6,6 @@ basefilt.cpp buf_filt.cpp comp_filter.cpp data_snk.cpp -data_src.cpp filter.cpp key_filt.cpp out_buf.cpp @@ -23,7 +22,6 @@ basefilt.h buf_filt.h data_snk.h comp_filter.h -data_src.h filter.h filters.h key_filt.h diff --git a/src/lib/misc/pem/info.txt b/src/lib/misc/pem/info.txt index c614b5ca7..9340a7cef 100644 --- a/src/lib/misc/pem/info.txt +++ b/src/lib/misc/pem/info.txt @@ -1,5 +1,5 @@ define PEM_CODEC 20131128 -codec_filt +base64 diff --git a/src/lib/misc/pem/pem.cpp b/src/lib/misc/pem/pem.cpp index f33016c70..1279b665e 100644 --- a/src/lib/misc/pem/pem.cpp +++ b/src/lib/misc/pem/pem.cpp @@ -6,25 +6,45 @@ */ #include -#include +#include #include namespace Botan { namespace PEM_Code { +namespace { + +std::string linewrap(size_t width, const std::string& in) + { + std::string out; + for(size_t i = 0; i != in.size(); ++i) + { + if(i > 0 && i % width == 0) + { + out.push_back('\n'); + } + out.push_back(in[i]); + } + if(out.size() > 0 && out[out.size()-1] != '\n') + { + out.push_back('\n'); + } + + return out; + } + +} + /* * PEM encode BER/DER-encoded objects */ -std::string encode(const byte der[], size_t length, const std::string& label, - size_t width) +std::string encode(const byte der[], size_t length, const std::string& label, size_t width) { const std::string PEM_HEADER = "-----BEGIN " + label + "-----\n"; const std::string PEM_TRAILER = "-----END " + label + "-----\n"; - Pipe pipe(new Base64_Encoder(true, width)); - pipe.process_msg(der, length); - return (PEM_HEADER + pipe.read_all_as_string() + PEM_TRAILER); + return (PEM_HEADER + linewrap(width, base64_encode(der, length)) + PEM_TRAILER); } /* @@ -79,8 +99,7 @@ secure_vector decode(DataSource& source, std::string& label) label += static_cast(b); } - Pipe base64(new Base64_Decoder); - base64.start_msg(); + std::vector b64; const std::string PEM_TRAILER = "-----END " + label + "-----"; position = 0; @@ -95,10 +114,10 @@ secure_vector decode(DataSource& source, std::string& label) throw Decoding_Error("PEM: Malformed PEM trailer"); if(position == 0) - base64.write(b); + b64.push_back(b); } - base64.end_msg(); - return base64.read_all(); + + return base64_decode(b64.data(), b64.size()); } secure_vector decode_check_label(const std::string& pem, diff --git a/src/lib/pubkey/x509_key.h b/src/lib/pubkey/x509_key.h index 1bfa248ff..cbb0412d2 100644 --- a/src/lib/pubkey/x509_key.h +++ b/src/lib/pubkey/x509_key.h @@ -10,7 +10,7 @@ #include #include -#include +#include #include namespace Botan { diff --git a/src/lib/utils/data_src.cpp b/src/lib/utils/data_src.cpp new file mode 100644 index 000000000..4e0725943 --- /dev/null +++ b/src/lib/utils/data_src.cpp @@ -0,0 +1,212 @@ +/* +* DataSource +* (C) 1999-2007 Jack Lloyd +* 2005 Matthew Gregan +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include +#include +#include +#include + +namespace Botan { + +/* +* Read a single byte from the DataSource +*/ +size_t DataSource::read_byte(byte& out) + { + return read(&out, 1); + } + +/* +* Peek a single byte from the DataSource +*/ +size_t DataSource::peek_byte(byte& out) const + { + return peek(&out, 1, 0); + } + +/* +* Discard the next N bytes of the data +*/ +size_t DataSource::discard_next(size_t n) + { + byte buf[64] = { 0 }; + size_t discarded = 0; + + while(n) + { + const size_t got = this->read(buf, std::min(n, sizeof(buf))); + discarded += got; + + if(got == 0) + break; + } + + return discarded; + } + +/* +* Read from a memory buffer +*/ +size_t DataSource_Memory::read(byte out[], size_t length) + { + size_t got = std::min(source.size() - offset, length); + copy_mem(out, source.data() + offset, got); + offset += got; + return got; + } + +bool DataSource_Memory::check_available(size_t n) + { + return (n <= (source.size() - offset)); + } + +/* +* Peek into a memory buffer +*/ +size_t DataSource_Memory::peek(byte out[], size_t length, + size_t peek_offset) const + { + const size_t bytes_left = source.size() - offset; + if(peek_offset >= bytes_left) return 0; + + size_t got = std::min(bytes_left - peek_offset, length); + copy_mem(out, &source[offset + peek_offset], got); + return got; + } + +/* +* Check if the memory buffer is empty +*/ +bool DataSource_Memory::end_of_data() const + { + return (offset == source.size()); + } + +/* +* DataSource_Memory Constructor +*/ +DataSource_Memory::DataSource_Memory(const std::string& in) : + source(reinterpret_cast(in.data()), + reinterpret_cast(in.data()) + in.length()), + offset(0) + { + offset = 0; + } + +/* +* Read from a stream +*/ +size_t DataSource_Stream::read(byte out[], size_t length) + { + source.read(reinterpret_cast(out), length); + if(source.bad()) + throw Stream_IO_Error("DataSource_Stream::read: Source failure"); + + size_t got = source.gcount(); + total_read += got; + return got; + } + +bool DataSource_Stream::check_available(size_t n) + { + const std::streampos orig_pos = source.tellg(); + source.seekg(0, std::ios::end); + const size_t avail = source.tellg() - orig_pos; + source.seekg(orig_pos); + return (avail >= n); + } + +/* +* Peek into a stream +*/ +size_t DataSource_Stream::peek(byte out[], size_t length, size_t offset) const + { + if(end_of_data()) + throw Invalid_State("DataSource_Stream: Cannot peek when out of data"); + + size_t got = 0; + + if(offset) + { + secure_vector buf(offset); + source.read(reinterpret_cast(buf.data()), buf.size()); + if(source.bad()) + throw Stream_IO_Error("DataSource_Stream::peek: Source failure"); + got = source.gcount(); + } + + if(got == offset) + { + source.read(reinterpret_cast(out), length); + if(source.bad()) + throw Stream_IO_Error("DataSource_Stream::peek: Source failure"); + got = source.gcount(); + } + + if(source.eof()) + source.clear(); + source.seekg(total_read, std::ios::beg); + + return got; + } + +/* +* Check if the stream is empty or in error +*/ +bool DataSource_Stream::end_of_data() const + { + return (!source.good()); + } + +/* +* Return a human-readable ID for this stream +*/ +std::string DataSource_Stream::id() const + { + return identifier; + } + +/* +* DataSource_Stream Constructor +*/ +DataSource_Stream::DataSource_Stream(const std::string& path, + bool use_binary) : + identifier(path), + source_p(new std::ifstream(path, + use_binary ? std::ios::binary : std::ios::in)), + source(*source_p), + total_read(0) + { + if(!source.good()) + { + delete source_p; + throw Stream_IO_Error("DataSource: Failure opening file " + path); + } + } + +/* +* DataSource_Stream Constructor +*/ +DataSource_Stream::DataSource_Stream(std::istream& in, + const std::string& name) : + identifier(name), + source_p(nullptr), + source(in), + total_read(0) + { + } + +/* +* DataSource_Stream Destructor +*/ +DataSource_Stream::~DataSource_Stream() + { + delete source_p; + } + +} diff --git a/src/lib/utils/data_src.h b/src/lib/utils/data_src.h new file mode 100644 index 000000000..2b6998448 --- /dev/null +++ b/src/lib/utils/data_src.h @@ -0,0 +1,180 @@ +/* +* DataSource +* (C) 1999-2007 Jack Lloyd +* 2012 Markus Wanner +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_DATA_SRC_H__ +#define BOTAN_DATA_SRC_H__ + +#include +#include +#include + +namespace Botan { + +/** +* This class represents an abstract data source object. +*/ +class BOTAN_DLL DataSource + { + public: + /** + * Read from the source. Moves the internal offset so that every + * call to read will return a new portion of the source. + * + * @param out the byte array to write the result to + * @param length the length of the byte array out + * @return length in bytes that was actually read and put + * into out + */ + virtual size_t read(byte out[], size_t length) = 0; + + virtual bool check_available(size_t n) = 0; + + /** + * Read from the source but do not modify the internal + * offset. Consecutive calls to peek() will return portions of + * the source starting at the same position. + * + * @param out the byte array to write the output to + * @param length the length of the byte array out + * @param peek_offset the offset into the stream to read at + * @return length in bytes that was actually read and put + * into out + */ + virtual size_t peek(byte out[], size_t length, + size_t peek_offset) const = 0; + + /** + * Test whether the source still has data that can be read. + * @return true if there is still data to read, false otherwise + */ + virtual bool end_of_data() const = 0; + /** + * return the id of this data source + * @return std::string representing the id of this data source + */ + virtual std::string id() const { return ""; } + + /** + * Read one byte. + * @param out the byte to read to + * @return length in bytes that was actually read and put + * into out + */ + size_t read_byte(byte& out); + + /** + * Peek at one byte. + * @param out an output byte + * @return length in bytes that was actually read and put + * into out + */ + size_t peek_byte(byte& out) const; + + /** + * Discard the next N bytes of the data + * @param N the number of bytes to discard + * @return number of bytes actually discarded + */ + size_t discard_next(size_t N); + + /** + * @return number of bytes read so far. + */ + virtual size_t get_bytes_read() const = 0; + + DataSource() {} + virtual ~DataSource() {} + DataSource& operator=(const DataSource&) = delete; + DataSource(const DataSource&) = delete; + }; + +/** +* This class represents a Memory-Based DataSource +*/ +class BOTAN_DLL DataSource_Memory : public DataSource + { + public: + size_t read(byte[], size_t) override; + size_t peek(byte[], size_t, size_t) const override; + bool check_available(size_t n) override; + bool end_of_data() const override; + + /** + * Construct a memory source that reads from a string + * @param in the string to read from + */ + DataSource_Memory(const std::string& in); + + /** + * Construct a memory source that reads from a byte array + * @param in the byte array to read from + * @param length the length of the byte array + */ + DataSource_Memory(const byte in[], size_t length) : + source(in, in + length), offset(0) {} + + /** + * Construct a memory source that reads from a secure_vector + * @param in the MemoryRegion to read from + */ + DataSource_Memory(const secure_vector& in) : + source(in), offset(0) {} + + /** + * Construct a memory source that reads from a std::vector + * @param in the MemoryRegion to read from + */ + DataSource_Memory(const std::vector& in) : + source(in.begin(), in.end()), offset(0) {} + + size_t get_bytes_read() const override { return offset; } + private: + secure_vector source; + size_t offset; + }; + +/** +* This class represents a Stream-Based DataSource. +*/ +class BOTAN_DLL DataSource_Stream : public DataSource + { + public: + size_t read(byte[], size_t) override; + size_t peek(byte[], size_t, size_t) const override; + bool check_available(size_t n) override; + bool end_of_data() const override; + std::string id() const override; + + DataSource_Stream(std::istream&, + const std::string& id = ""); + + /** + * Construct a Stream-Based DataSource from file + * @param file the name of the file + * @param use_binary whether to treat the file as binary or not + */ + DataSource_Stream(const std::string& file, bool use_binary = false); + + DataSource_Stream(const DataSource_Stream&) = delete; + + DataSource_Stream& operator=(const DataSource_Stream&) = delete; + + ~DataSource_Stream(); + + size_t get_bytes_read() const override { return total_read; } + private: + const std::string identifier; + + std::istream* source_p; + std::istream& source; + size_t total_read; + }; + +} + +#endif diff --git a/src/lib/utils/info.txt b/src/lib/utils/info.txt index 7d3216b1c..79026d7a9 100644 --- a/src/lib/utils/info.txt +++ b/src/lib/utils/info.txt @@ -9,6 +9,7 @@ calendar.h charset.h cpuid.h database.h +data_src.h exceptn.h loadstor.h mem_ops.h -- cgit v1.2.3