Go to the documentation of this file.00001 #include "ibrcommon/ssl/RSASHA256Stream.h"
00002 #include "ibrcommon/Logger.h"
00003 #include <openssl/err.h>
00004
00005 namespace ibrcommon
00006 {
00007 RSASHA256Stream::RSASHA256Stream(EVP_PKEY * const pkey, bool verify)
00008 : ostream(this), out_buf_(new char[BUFF_SIZE]), _pkey(pkey), _verify(verify), _sign_valid(false)
00009 {
00010
00011 setp(out_buf_, out_buf_ + BUFF_SIZE - 1);
00012 EVP_MD_CTX_init(&_ctx);
00013
00014 if (!_verify)
00015 {
00016 if (!EVP_SignInit_ex(&_ctx, EVP_sha256(), NULL))
00017 {
00018 IBRCOMMON_LOGGER(critical) << "failed to initialize the signature function" << IBRCOMMON_LOGGER_ENDL;
00019 ERR_print_errors_fp(stderr);
00020 }
00021 }
00022 else
00023 {
00024 if (!EVP_VerifyInit_ex(&_ctx, EVP_sha256(), NULL))
00025 {
00026 IBRCOMMON_LOGGER(critical) << "failed to initialize the verfication function" << IBRCOMMON_LOGGER_ENDL;
00027 ERR_print_errors_fp(stderr);
00028 }
00029 }
00030 }
00031
00032 RSASHA256Stream::~RSASHA256Stream()
00033 {
00034 EVP_MD_CTX_cleanup(&_ctx);
00035 delete[] out_buf_;
00036 }
00037
00038 void RSASHA256Stream::reset()
00039 {
00040 EVP_MD_CTX_cleanup(&_ctx);
00041
00042 EVP_MD_CTX_init(&_ctx);
00043
00044 if (!_verify)
00045 {
00046 if (!EVP_SignInit_ex(&_ctx, EVP_sha256(), NULL))
00047 {
00048 IBRCOMMON_LOGGER(critical) << "failed to initialize the signature function" << IBRCOMMON_LOGGER_ENDL;
00049 ERR_print_errors_fp(stderr);
00050 }
00051 }
00052 else
00053 {
00054 if (!EVP_VerifyInit_ex(&_ctx, EVP_sha256(), NULL))
00055 {
00056 IBRCOMMON_LOGGER(critical) << "failed to initialize the verfication function" << IBRCOMMON_LOGGER_ENDL;
00057 ERR_print_errors_fp(stderr);
00058 }
00059 }
00060
00061 _sign_valid = false;
00062 }
00063
00064 const std::pair< const int, const std::string > RSASHA256Stream::getSign()
00065 {
00066
00067
00068 if (!_sign_valid)
00069 {
00070 sync();
00071 unsigned char * sign = new unsigned char[EVP_PKEY_size(_pkey)];
00072 unsigned int size;
00073
00074 _return_code = EVP_SignFinal(&_ctx, sign, &size, _pkey);
00075
00076 _sign = std::string(reinterpret_cast<const char * const>(sign), size);
00077 delete [] sign;
00078 _sign_valid = true;
00079 }
00080 return std::pair<const int, const std::string>(_return_code, _sign);
00081 }
00082
00083 int RSASHA256Stream::getVerification(const std::string& their_sign)
00084 {
00085
00086
00087 if (!_sign_valid)
00088 {
00089 sync();
00090 _return_code = EVP_VerifyFinal(&_ctx, reinterpret_cast<const unsigned char *>(their_sign.c_str()), their_sign.size(), _pkey);
00091 _sign_valid = true;
00092 }
00093 return _return_code;
00094 }
00095
00096 int RSASHA256Stream::sync()
00097 {
00098 int ret = std::char_traits<char>::eq_int_type(this->overflow(
00099 std::char_traits<char>::eof()), std::char_traits<char>::eof()) ? -1
00100 : 0;
00101
00102 return ret;
00103 }
00104
00105 int RSASHA256Stream:: overflow(int c)
00106 {
00107 char *ibegin = out_buf_;
00108 char *iend = pptr();
00109
00110
00111 setp(out_buf_, out_buf_ + BUFF_SIZE - 1);
00112
00113 if (!std::char_traits<char>::eq_int_type(c, std::char_traits<char>::eof()))
00114 {
00115
00116 *iend++ = std::char_traits<char>::to_char_type(c);
00117 }
00118
00119
00120 if ((iend - ibegin) == 0)
00121 {
00122 return std::char_traits<char>::not_eof(c);
00123 }
00124
00125 if (!_verify)
00126
00127 {
00128 if (!EVP_SignUpdate(&_ctx, reinterpret_cast<unsigned char*>(out_buf_), iend - ibegin))
00129 {
00130 IBRCOMMON_LOGGER(critical) << "failed to feed data into the signature function" << IBRCOMMON_LOGGER_ENDL;
00131 ERR_print_errors_fp(stderr);
00132 }
00133 }
00134 else
00135 {
00136 if (!EVP_VerifyUpdate(&_ctx, reinterpret_cast<unsigned char*>(out_buf_), iend - ibegin))
00137 {
00138 IBRCOMMON_LOGGER(critical) << "failed to feed data into the verfication function" << IBRCOMMON_LOGGER_ENDL;
00139 ERR_print_errors_fp(stderr);
00140 }
00141 }
00142
00143 return std::char_traits<char>::not_eof(c);
00144 }
00145 }