IBR-DTNSuite
0.8
|
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 // Initialize get pointer. This should be zero so that underflow is called upon first read. 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 // check if data was feed into the stream and the sign needs to be 00067 // recalculated 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 // check if data was feed into the stream and the sign needs to be 00086 // recalculated 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 RSASHA256Stream::traits::int_type RSASHA256Stream::overflow(RSASHA256Stream::traits::int_type c) 00106 { 00107 char *ibegin = out_buf_; 00108 char *iend = pptr(); 00109 00110 // mark the buffer as free 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 //TODO writing one byte after the buffer? 00116 *iend++ = std::char_traits<char>::to_char_type(c); 00117 } 00118 00119 // if there is nothing to send, just return 00120 if ((iend - ibegin) == 0) 00121 { 00122 return std::char_traits<char>::not_eof(c); 00123 } 00124 00125 if (!_verify) 00126 // hashing 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 }