Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include "ibrcommon/ssl/CipherStream.h"
00009
00010 namespace ibrcommon
00011 {
00012 CipherStream::CipherStream(std::ostream &stream, const CipherMode mode, const size_t buffer)
00013 : std::ostream(this), _stream(stream), _mode(mode), data_buf_(new char[buffer]), data_size_(buffer)
00014 {
00015 setp(data_buf_, data_buf_ + data_size_ - 1);
00016 }
00017
00018 CipherStream::~CipherStream()
00019 {
00020 delete[] data_buf_;
00021 }
00022
00023 void CipherStream::encrypt(std::iostream& stream)
00024 {
00025 char buf[4096];
00026 while (!stream.eof())
00027 {
00028 std::ios::pos_type pos = stream.tellg();
00029
00030 stream.read((char*)&buf, 4096);
00031 size_t bytes = stream.gcount();
00032
00033 encrypt(buf, bytes);
00034
00035
00036
00037 if (stream.eof() && (bytes > 0)) stream.clear();
00038
00039 stream.seekp(pos, std::ios::beg);
00040 stream.write((char*)&buf, bytes);
00041 }
00042
00043 stream.flush();
00044 encrypt_final();
00045 }
00046
00047 void CipherStream::decrypt(std::iostream& stream)
00048 {
00049 char buf[4096];
00050 while (!stream.eof())
00051 {
00052 std::ios::pos_type pos = stream.tellg();
00053
00054 stream.read((char*)&buf, 4096);
00055 size_t bytes = stream.gcount();
00056
00057 decrypt(buf, bytes);
00058
00059
00060
00061 if (stream.eof() && (bytes > 0)) stream.clear();
00062
00063 stream.seekp(pos, std::ios::beg);
00064 stream.write((char*)&buf, bytes);
00065 }
00066
00067 stream.flush();
00068 decrypt_final();
00069 }
00070
00071 int CipherStream::sync()
00072 {
00073 int ret = std::char_traits<char>::eq_int_type(this->overflow(
00074 std::char_traits<char>::eof()), std::char_traits<char>::eof()) ? -1
00075 : 0;
00076
00077
00078 switch (_mode)
00079 {
00080 case CIPHER_ENCRYPT:
00081 encrypt_final();
00082 break;
00083
00084 case CIPHER_DECRYPT:
00085 decrypt_final();
00086 break;
00087 }
00088
00089 return ret;
00090 }
00091
00092 int CipherStream::overflow(int c)
00093 {
00094 char *ibegin = data_buf_;
00095 char *iend = pptr();
00096
00097
00098 setp(data_buf_, data_buf_ + data_size_ - 1);
00099
00100 if (!std::char_traits<char>::eq_int_type(c, std::char_traits<char>::eof()))
00101 {
00102 *iend++ = std::char_traits<char>::to_char_type(c);
00103 }
00104
00105
00106 if ((iend - ibegin) == 0)
00107 {
00108 return std::char_traits<char>::not_eof(c);
00109 }
00110
00111
00112 switch (_mode)
00113 {
00114 case CIPHER_ENCRYPT:
00115 encrypt(data_buf_, (iend - ibegin));
00116 break;
00117
00118 case CIPHER_DECRYPT:
00119 decrypt(data_buf_, (iend - ibegin));
00120 break;
00121 }
00122
00123
00124 _stream.write(data_buf_, (iend - ibegin));
00125
00126 return std::char_traits<char>::not_eof(c);
00127 }
00128 }