diff --git a/src/InitiatorMSEHandshakeCommand.cc b/src/InitiatorMSEHandshakeCommand.cc index cf82858e..bbeb38dc 100644 --- a/src/InitiatorMSEHandshakeCommand.cc +++ b/src/InitiatorMSEHandshakeCommand.cc @@ -156,11 +156,10 @@ bool InitiatorMSEHandshakeCommand::executeInternal() { peerConnection->enableEncryption(mseHandshake_->getEncryptor(), mseHandshake_->getDecryptor()); size_t buflen = mseHandshake_->getBufferLength(); - array_ptr buffer(new unsigned char[buflen]); - mseHandshake_->getDecryptor()->encrypt(buffer, buflen, + mseHandshake_->getDecryptor()->encrypt(buflen, mseHandshake_->getBuffer(), - buflen); - peerConnection->presetBuffer(buffer, buflen); + mseHandshake_->getBuffer()); + peerConnection->presetBuffer(mseHandshake_->getBuffer(), buflen); } else { peerConnection->presetBuffer(mseHandshake_->getBuffer(), mseHandshake_->getBufferLength()); diff --git a/src/LibgcryptARC4Context.cc b/src/LibgcryptARC4Context.cc deleted file mode 100644 index 39d2b2c2..00000000 --- a/src/LibgcryptARC4Context.cc +++ /dev/null @@ -1,84 +0,0 @@ -/* */ -#include "LibgcryptARC4Context.h" -#include "DlAbortEx.h" -#include "fmt.h" - -namespace aria2 { - -namespace { -void handleError(gcry_error_t err) -{ - throw DL_ABORT_EX - (fmt("Exception in libgcrypt routine(ARC4Context class): %s", - gcry_strerror(err))); -} -} // namespace - -LibgcryptARC4Context::LibgcryptARC4Context():cipherCtx_(0) {} - -LibgcryptARC4Context::~LibgcryptARC4Context() -{ - gcry_cipher_close(cipherCtx_); -} - -void LibgcryptARC4Context::init(const unsigned char* key, size_t keyLength) -{ - gcry_cipher_close(cipherCtx_); - - int algo = GCRY_CIPHER_ARCFOUR; - int mode = GCRY_CIPHER_MODE_STREAM; - unsigned int flags = 0; - { - gcry_error_t r = gcry_cipher_open(&cipherCtx_, algo, mode, flags); - if(r) { - handleError(r); - } - } - { - gcry_error_t r = gcry_cipher_setkey(cipherCtx_, key, keyLength); - if(r) { - handleError(r); - } - } - { - gcry_error_t r = gcry_cipher_setiv(cipherCtx_, 0, 0); - if(r) { - handleError(r); - } - } -} - -} // namespace aria2 diff --git a/src/LibgcryptARC4Context.h b/src/LibgcryptARC4Context.h deleted file mode 100644 index d8e6240d..00000000 --- a/src/LibgcryptARC4Context.h +++ /dev/null @@ -1,62 +0,0 @@ -/* */ -#ifndef D_LIBGCRYPT_ARC4_CONTEXT_H -#define D_LIBGCRYPT_ARC4_CONTEXT_H - -#include "common.h" - -#include - -namespace aria2 { - -class LibgcryptARC4Context { -private: - gcry_cipher_hd_t cipherCtx_; -public: - LibgcryptARC4Context(); - - ~LibgcryptARC4Context(); - - gcry_cipher_hd_t getCipherContext() const - { - return cipherCtx_; - } - - void init(const unsigned char* key, size_t keyLength); -}; - -} // namespace aria2 - -#endif // D_LIBGCRYPT_ARC4_CONTEXT_H diff --git a/src/LibgcryptARC4Encryptor.cc b/src/LibgcryptARC4Encryptor.cc index 92495981..0290e4e6 100644 --- a/src/LibgcryptARC4Encryptor.cc +++ b/src/LibgcryptARC4Encryptor.cc @@ -50,21 +50,47 @@ void handleError(gcry_error_t err) } } // namespace -ARC4Encryptor::ARC4Encryptor() {} +ARC4Encryptor::ARC4Encryptor() + : hdl_(0) +{} -ARC4Encryptor::~ARC4Encryptor() {} +ARC4Encryptor::~ARC4Encryptor() +{ + gcry_cipher_close(hdl_); +} void ARC4Encryptor::init(const unsigned char* key, size_t keyLength) { - ctx_.init(key, keyLength); + int algo = GCRY_CIPHER_ARCFOUR; + int mode = GCRY_CIPHER_MODE_STREAM; + unsigned int flags = 0; + gcry_error_t r; + if((r = gcry_cipher_open(&hdl_, algo, mode, flags))) { + handleError(r); + } + if((r = gcry_cipher_setkey(hdl_, key, keyLength))) { + handleError(r); + } + if((r = gcry_cipher_setiv(hdl_, 0, 0))) { + handleError(r); + } } -void ARC4Encryptor::encrypt(unsigned char* out, size_t outLength, - const unsigned char* in, size_t inLength) +void ARC4Encryptor::encrypt +(size_t len, + unsigned char* out, + const unsigned char* in) { - gcry_error_t r = gcry_cipher_encrypt(ctx_.getCipherContext(), - out, outLength, in, inLength); - if(r) { + size_t inlen; + if(in == out) { + out = const_cast(in); + in = 0; + inlen = 0; + } else { + inlen = len; + } + gcry_error_t r; + if((r = gcry_cipher_encrypt(hdl_, out, len, in, inlen))) { handleError(r); } } diff --git a/src/LibgcryptARC4Encryptor.h b/src/LibgcryptARC4Encryptor.h index c6257989..1a99650d 100644 --- a/src/LibgcryptARC4Encryptor.h +++ b/src/LibgcryptARC4Encryptor.h @@ -39,13 +39,11 @@ #include -#include "LibgcryptARC4Context.h" - namespace aria2 { class ARC4Encryptor { private: - LibgcryptARC4Context ctx_; + gcry_cipher_hd_t hdl_; public: ARC4Encryptor(); @@ -53,8 +51,9 @@ public: void init(const unsigned char* key, size_t keyLength); - void encrypt(unsigned char* out, size_t outLength, - const unsigned char* in, size_t inLength); + // Encrypts data in in buffer to out buffer. in and out can be the + // same buffer. + void encrypt(size_t len, unsigned char* out, const unsigned char* in); }; } // namespace aria2 diff --git a/src/LibnettleARC4Context.cc b/src/LibnettleARC4Context.cc deleted file mode 100644 index 926d708f..00000000 --- a/src/LibnettleARC4Context.cc +++ /dev/null @@ -1,53 +0,0 @@ -/* */ -#include "LibnettleARC4Context.h" - -namespace aria2 { - -LibnettleARC4Context::LibnettleARC4Context() - : cipherCtx_(new arcfour_ctx()) -{} - -LibnettleARC4Context::~LibnettleARC4Context() -{ - delete cipherCtx_; -} - -void LibnettleARC4Context::init(const unsigned char* key, size_t keyLength) -{ - arcfour_set_key(cipherCtx_, keyLength, key); -} - -} // namespace aria2 diff --git a/src/LibnettleARC4Context.h b/src/LibnettleARC4Context.h deleted file mode 100644 index a7cb094f..00000000 --- a/src/LibnettleARC4Context.h +++ /dev/null @@ -1,64 +0,0 @@ -/* */ -#ifndef D_LIBNETTLE_ARC4_CONTEXT_H -#define D_LIBNETTLE_ARC4_CONTEXT_H - -#include "common.h" - -#include - -#include - -namespace aria2 { - -class LibnettleARC4Context { -private: - arcfour_ctx* cipherCtx_; -public: - LibnettleARC4Context(); - - ~LibnettleARC4Context(); - - arcfour_ctx* getCipherContext() const - { - return cipherCtx_; - } - - void init(const unsigned char* key, size_t keyLength); -}; - -} // namespace aria2 - -#endif // D_LIBNETTLE_ARC4_CONTEXT_H diff --git a/src/LibnettleARC4Encryptor.cc b/src/LibnettleARC4Encryptor.cc index fc1dab4e..9bf19c66 100644 --- a/src/LibnettleARC4Encryptor.cc +++ b/src/LibnettleARC4Encryptor.cc @@ -34,8 +34,6 @@ /* copyright --> */ #include "LibnettleARC4Encryptor.h" -#include - namespace aria2 { ARC4Encryptor::ARC4Encryptor() {} @@ -44,14 +42,15 @@ ARC4Encryptor::~ARC4Encryptor() {} void ARC4Encryptor::init(const unsigned char* key, size_t keyLength) { - ctx_.init(key, keyLength); + arcfour_set_key(&ctx_, keyLength, key); } -void ARC4Encryptor::encrypt(unsigned char* out, size_t outLength, - const unsigned char* in, size_t inLength) +void ARC4Encryptor::encrypt +(size_t len, + unsigned char* out, + const unsigned char* in) { - assert(outLength == inLength); - arcfour_crypt(ctx_.getCipherContext(), outLength, out, in); + arcfour_crypt(&ctx_, len, out, in); } } // namespace aria2 diff --git a/src/LibnettleARC4Encryptor.h b/src/LibnettleARC4Encryptor.h index bc71f781..eed03a66 100644 --- a/src/LibnettleARC4Encryptor.h +++ b/src/LibnettleARC4Encryptor.h @@ -36,13 +36,16 @@ #define D_LIBNETTLE_ARC4_ENCRYPTOR_H #include "common.h" -#include "LibnettleARC4Context.h" + +#include + +#include namespace aria2 { class ARC4Encryptor { private: - LibnettleARC4Context ctx_; + arcfour_ctx ctx_; public: ARC4Encryptor(); @@ -50,8 +53,9 @@ public: void init(const unsigned char* key, size_t keyLength); - void encrypt(unsigned char* out, size_t outLength, - const unsigned char* in, size_t inLength); + // Encrypts data in in buffer to out buffer. in and out can be the + // same buffer. + void encrypt(size_t len, unsigned char* out, const unsigned char* in); }; } // namespace aria2 diff --git a/src/LibsslARC4Context.cc b/src/LibsslARC4Context.cc deleted file mode 100644 index 3e73e71c..00000000 --- a/src/LibsslARC4Context.cc +++ /dev/null @@ -1,91 +0,0 @@ -/* */ -#include "LibsslARC4Context.h" - -#include - -#include "DlAbortEx.h" -#include "fmt.h" - -namespace aria2 { - -namespace { -void handleError() -{ - throw DL_ABORT_EX - (fmt("Exception in libssl routine(ARC4Context class): %s", - ERR_error_string(ERR_get_error(), 0))); -} -} // namespace - -LibsslARC4Context::LibsslARC4Context():cipherCtx_(0) {} - -LibsslARC4Context::~LibsslARC4Context() -{ - if(cipherCtx_) { - EVP_CIPHER_CTX_cleanup(cipherCtx_); - } - delete cipherCtx_; -} - -EVP_CIPHER_CTX* LibsslARC4Context::getCipherContext() const -{ - return cipherCtx_; -} - -// enc == 1: encryption -// enc == 0: decryption -void LibsslARC4Context::init -(const unsigned char* key, size_t keyLength, int enc) -{ - if(cipherCtx_) { - EVP_CIPHER_CTX_cleanup(cipherCtx_); - } - delete cipherCtx_; - cipherCtx_ = new EVP_CIPHER_CTX; - EVP_CIPHER_CTX_init(cipherCtx_); - - if(!EVP_CipherInit_ex(cipherCtx_, EVP_rc4(), 0, 0, 0, enc)) { - handleError(); - } - if(!EVP_CIPHER_CTX_set_key_length(cipherCtx_, keyLength)) { - handleError(); - } - if(!EVP_CipherInit_ex(cipherCtx_, 0, 0, key, 0, -1)) { - handleError(); - } -} - -} // namespace aria2 diff --git a/src/LibsslARC4Context.h b/src/LibsslARC4Context.h deleted file mode 100644 index 4f570570..00000000 --- a/src/LibsslARC4Context.h +++ /dev/null @@ -1,61 +0,0 @@ -/* */ -#ifndef D_LIBSSL_ARC4_CONTEXT_H -#define D_LIBSSL_ARC4_CONTEXT_H - -#include "common.h" - -#include - -namespace aria2 { - -class LibsslARC4Context { -private: - EVP_CIPHER_CTX* cipherCtx_; -public: - LibsslARC4Context(); - - ~LibsslARC4Context(); - - EVP_CIPHER_CTX* getCipherContext() const; - - // enc == 1: encryption - // enc == 0: decryption - void init(const unsigned char* key, size_t keyLength, int enc); -}; - -} // namespace aria2 - -#endif // D_LIBSSL_ARC4_CONTEXT_H diff --git a/src/LibsslARC4Encryptor.cc b/src/LibsslARC4Encryptor.cc index f128fe5a..fcbf29dc 100644 --- a/src/LibsslARC4Encryptor.cc +++ b/src/LibsslARC4Encryptor.cc @@ -34,39 +34,23 @@ /* copyright --> */ #include "LibsslARC4Encryptor.h" -#include - -#include "DlAbortEx.h" -#include "fmt.h" - namespace aria2 { -namespace { -void handleError() -{ - throw DL_ABORT_EX - (fmt("Exception in libssl routine(ARC4Encryptor class): %s", - ERR_error_string(ERR_get_error(), 0))); -} -} // namespace - ARC4Encryptor::ARC4Encryptor() {} ARC4Encryptor::~ARC4Encryptor() {} void ARC4Encryptor::init(const unsigned char* key, size_t keyLength) { - ctx_.init(key, keyLength, 1); + RC4_set_key(&key_, keyLength, key); } -void ARC4Encryptor::encrypt(unsigned char* out, size_t outLength, - const unsigned char* in, size_t inLength) +void ARC4Encryptor::encrypt +(size_t len, + unsigned char* out, + const unsigned char* in) { - int soutLength = outLength; - if(!EVP_CipherUpdate(ctx_.getCipherContext(), out, &soutLength, - in, inLength)) { - handleError(); - } + RC4(&key_, len, in, out); } } // namespace aria2 diff --git a/src/LibsslARC4Encryptor.h b/src/LibsslARC4Encryptor.h index 29a87492..e726e1d7 100644 --- a/src/LibsslARC4Encryptor.h +++ b/src/LibsslARC4Encryptor.h @@ -37,15 +37,13 @@ #include "common.h" -#include - -#include "LibsslARC4Context.h" +#include namespace aria2 { class ARC4Encryptor { private: - LibsslARC4Context ctx_; + RC4_KEY key_; public: ARC4Encryptor(); @@ -53,8 +51,9 @@ public: void init(const unsigned char* key, size_t keyLength); - void encrypt(unsigned char* out, size_t outLength, - const unsigned char* in, size_t inLength); + // Encrypts data in in buffer to out buffer. in and out can be the + // same buffer. + void encrypt(size_t len, unsigned char* out, const unsigned char* in); }; } // namespace aria2 diff --git a/src/MSEHandshake.cc b/src/MSEHandshake.cc index 74080feb..3ab2d197 100644 --- a/src/MSEHandshake.cc +++ b/src/MSEHandshake.cc @@ -207,27 +207,25 @@ void MSEHandshake::initCipher(const unsigned char* infoHash) decryptor_->init(peerCipherKey, sizeof(peerCipherKey)); // discard first 1024 bytes ARC4 output. - unsigned char from[1024]; - unsigned char to[1024]; - encryptor_->encrypt(to, 1024, from, 1024); - decryptor_->encrypt(to, 1024, from, 1024); + unsigned char garbage[1024]; + encryptor_->encrypt(1024, garbage, garbage); + decryptor_->encrypt(1024, garbage, garbage); if(initiator_) { ARC4Encryptor enc; enc.init(peerCipherKey, sizeof(peerCipherKey)); // discard first 1024 bytes ARC4 output. - enc.encrypt(to, 1024, from, 1024); - enc.encrypt(initiatorVCMarker_, sizeof(initiatorVCMarker_), VC, sizeof(VC)); + enc.encrypt(1024, garbage, garbage); + enc.encrypt(VC_LENGTH, initiatorVCMarker_, VC); } } -void MSEHandshake::encryptAndSendData(const unsigned char* data, size_t length) +// Given data is pushed to socketBuffer_ and data will be deleted by +// socketBuffer_. +void MSEHandshake::encryptAndSendData(unsigned char* data, size_t length) { - unsigned char* buf = new unsigned char[length]; - array_ptr bufp(buf); - encryptor_->encrypt(buf, length, data, length); - socketBuffer_.pushBytes(buf, length); - bufp.reset(0); + encryptor_->encrypt(length, data, data); + socketBuffer_.pushBytes(data, length); } void MSEHandshake::createReq1Hash(unsigned char* md) const @@ -263,9 +261,9 @@ void MSEHandshake::createReq23Hash(unsigned char* md, const unsigned char* infoH uint16_t MSEHandshake::decodeLength16(const unsigned char* buffer) { uint16_t be; - decryptor_->encrypt(reinterpret_cast(&be), - sizeof(be), - buffer, sizeof(be)); + decryptor_->encrypt(sizeof(be), + reinterpret_cast(&be), + buffer); return ntohs(be); } @@ -286,7 +284,9 @@ void MSEHandshake::sendInitiatorStep2() // len(padC)(2 bytes), // padC(len(padC) bytes <= MAX_PAD_LENGTH), // len(IA)(2 bytes) - unsigned char buffer[40+VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2+MAX_PAD_LENGTH+2]; + unsigned char* buffer = new unsigned char + [40+VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2+MAX_PAD_LENGTH+2]; + array_ptr bufp(buffer); unsigned char* ptr = buffer; // VC memcpy(ptr, VC, sizeof(VC)); @@ -318,6 +318,7 @@ void MSEHandshake::sendInitiatorStep2() } ptr += 2; encryptAndSendData(buffer, ptr-buffer); + bufp.reset(0); } // This function reads exactly until the end of VC marker is reached. @@ -352,26 +353,22 @@ bool MSEHandshake::receiveInitiatorCryptoSelectAndPadDLength() } //verifyCryptoSelect unsigned char* rbufptr = rbuf_; - { - unsigned char cryptoSelect[CRYPTO_BITFIELD_LENGTH]; - decryptor_->encrypt(cryptoSelect, sizeof(cryptoSelect), - rbufptr, sizeof(cryptoSelect)); - if(cryptoSelect[3]&CRYPTO_PLAIN_TEXT && - option_->get(PREF_BT_MIN_CRYPTO_LEVEL) == V_PLAIN) { - A2_LOG_DEBUG(fmt("CUID#%lld - peer prefers plaintext.", - cuid_)); - negotiatedCryptoType_ = CRYPTO_PLAIN_TEXT; - } - if(cryptoSelect[3]&CRYPTO_ARC4) { - A2_LOG_DEBUG(fmt("CUID#%lld - peer prefers ARC4", - cuid_)); - negotiatedCryptoType_ = CRYPTO_ARC4; - } - if(negotiatedCryptoType_ == CRYPTO_NONE) { - throw DL_ABORT_EX - (fmt("CUID#%lld - No supported crypto type selected.", - cuid_)); - } + decryptor_->encrypt(CRYPTO_BITFIELD_LENGTH, rbufptr, rbufptr); + if(rbufptr[3]&CRYPTO_PLAIN_TEXT && + option_->get(PREF_BT_MIN_CRYPTO_LEVEL) == V_PLAIN) { + A2_LOG_DEBUG(fmt("CUID#%lld - peer prefers plaintext.", + cuid_)); + negotiatedCryptoType_ = CRYPTO_PLAIN_TEXT; + } + if(rbufptr[3]&CRYPTO_ARC4) { + A2_LOG_DEBUG(fmt("CUID#%lld - peer prefers ARC4", + cuid_)); + negotiatedCryptoType_ = CRYPTO_ARC4; + } + if(negotiatedCryptoType_ == CRYPTO_NONE) { + throw DL_ABORT_EX + (fmt("CUID#%lld - No supported crypto type selected.", + cuid_)); } // padD length rbufptr += CRYPTO_BITFIELD_LENGTH; @@ -390,8 +387,7 @@ bool MSEHandshake::receivePad() if(padLength_ == 0) { return true; } - unsigned char temp[MAX_PAD_LENGTH]; - decryptor_->encrypt(temp, padLength_, rbuf_, padLength_); + decryptor_->encrypt(padLength_, rbuf_, rbuf_); // shift rbuf_ shiftBuffer(padLength_); return true; @@ -456,27 +452,23 @@ bool MSEHandshake::receiveReceiverHashAndPadCLength verifyVC(rbufptr); // decrypt crypto_provide rbufptr += VC_LENGTH; - { - unsigned char cryptoProvide[CRYPTO_BITFIELD_LENGTH]; - decryptor_->encrypt(cryptoProvide, sizeof(cryptoProvide), - rbufptr, sizeof(cryptoProvide)); - // TODO choose the crypto type based on the preference. - // For now, choose ARC4. - if(cryptoProvide[3]&CRYPTO_PLAIN_TEXT && - option_->get(PREF_BT_MIN_CRYPTO_LEVEL) == V_PLAIN) { - A2_LOG_DEBUG(fmt("CUID#%lld - peer provides plaintext.", - cuid_)); - negotiatedCryptoType_ = CRYPTO_PLAIN_TEXT; - } else if(cryptoProvide[3]&CRYPTO_ARC4) { - A2_LOG_DEBUG(fmt("CUID#%lld - peer provides ARC4.", - cuid_)); - negotiatedCryptoType_ = CRYPTO_ARC4; - } - if(negotiatedCryptoType_ == CRYPTO_NONE) { - throw DL_ABORT_EX - (fmt("CUID#%lld - No supported crypto type provided.", - cuid_)); - } + decryptor_->encrypt(CRYPTO_BITFIELD_LENGTH, rbufptr, rbufptr); + // TODO choose the crypto type based on the preference. + // For now, choose ARC4. + if(rbufptr[3]&CRYPTO_PLAIN_TEXT && + option_->get(PREF_BT_MIN_CRYPTO_LEVEL) == V_PLAIN) { + A2_LOG_DEBUG(fmt("CUID#%lld - peer provides plaintext.", + cuid_)); + negotiatedCryptoType_ = CRYPTO_PLAIN_TEXT; + } else if(rbufptr[3]&CRYPTO_ARC4) { + A2_LOG_DEBUG(fmt("CUID#%lld - peer provides ARC4.", + cuid_)); + negotiatedCryptoType_ = CRYPTO_ARC4; + } + if(negotiatedCryptoType_ == CRYPTO_NONE) { + throw DL_ABORT_EX + (fmt("CUID#%lld - No supported crypto type provided.", + cuid_)); } // decrypt PadC length rbufptr += CRYPTO_BITFIELD_LENGTH; @@ -513,7 +505,7 @@ bool MSEHandshake::receiveReceiverIA() } delete [] ia_; ia_ = new unsigned char[iaLength_]; - decryptor_->encrypt(ia_, iaLength_, rbuf_, iaLength_); + decryptor_->encrypt(iaLength_, ia_, rbuf_); A2_LOG_DEBUG(fmt("CUID#%lld - IA received.", cuid_)); // shift rbuf_ shiftBuffer(iaLength_); @@ -527,24 +519,28 @@ void MSEHandshake::sendReceiverStep2() // cryptoSelect(CRYPTO_BITFIELD_LENGTH bytes), // len(padD)(2bytes), // padD(len(padD)bytes <= MAX_PAD_LENGTH) - unsigned char buffer[VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2+MAX_PAD_LENGTH]; + unsigned char* buffer = new unsigned char + [VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2+MAX_PAD_LENGTH]; + array_ptr bufp(buffer); + unsigned char* ptr = buffer; // VC - memcpy(buffer, VC, sizeof(VC)); + memcpy(ptr, VC, sizeof(VC)); + ptr += sizeof(VC); // crypto_select - unsigned char cryptoSelect[CRYPTO_BITFIELD_LENGTH]; - memset(cryptoSelect, 0, sizeof(cryptoSelect)); - cryptoSelect[3] = negotiatedCryptoType_; - memcpy(buffer+VC_LENGTH, cryptoSelect, sizeof(cryptoSelect)); + memset(ptr, 0, CRYPTO_BITFIELD_LENGTH); + ptr[3] = negotiatedCryptoType_; + ptr += CRYPTO_BITFIELD_LENGTH; // len(padD) - uint16_t padDLength = SimpleRandomizer::getInstance()->getRandomNumber(MAX_PAD_LENGTH+1); - { - uint16_t padDLengthBE = htons(padDLength); - memcpy(buffer+VC_LENGTH+CRYPTO_BITFIELD_LENGTH, &padDLengthBE, - sizeof(padDLengthBE)); - } + uint16_t padDLength = + SimpleRandomizer::getInstance()->getRandomNumber(MAX_PAD_LENGTH+1); + uint16_t padDLengthBE = htons(padDLength); + memcpy(ptr, &padDLengthBE, sizeof(padDLengthBE)); + ptr += sizeof(padDLengthBE); // padD, all zeroed - memset(buffer+VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2, 0, padDLength); - encryptAndSendData(buffer, VC_LENGTH+CRYPTO_BITFIELD_LENGTH+2+padDLength); + memset(ptr, 0, padDLength); + ptr += padDLength; + encryptAndSendData(buffer, ptr-buffer); + bufp.reset(0); } uint16_t MSEHandshake::verifyPadLength(const unsigned char* padlenbuf, const char* padName) @@ -561,14 +557,13 @@ uint16_t MSEHandshake::verifyPadLength(const unsigned char* padlenbuf, const cha return padLength; } -void MSEHandshake::verifyVC(const unsigned char* vcbuf) +void MSEHandshake::verifyVC(unsigned char* vcbuf) { A2_LOG_DEBUG(fmt("CUID#%lld - Verifying VC.", cuid_)); - unsigned char vc[VC_LENGTH]; - decryptor_->encrypt(vc, sizeof(vc), vcbuf, sizeof(vc)); - if(memcmp(VC, vc, sizeof(VC)) != 0) { + decryptor_->encrypt(VC_LENGTH, vcbuf, vcbuf); + if(memcmp(VC, vcbuf, VC_LENGTH) != 0) { throw DL_ABORT_EX - (fmt("Invalid VC: %s", util::toHex(vc, VC_LENGTH).c_str())); + (fmt("Invalid VC: %s", util::toHex(vcbuf, VC_LENGTH).c_str())); } } diff --git a/src/MSEHandshake.h b/src/MSEHandshake.h index 94e57b80..2d3ea0d1 100644 --- a/src/MSEHandshake.h +++ b/src/MSEHandshake.h @@ -100,7 +100,7 @@ private: unsigned char* ia_; SharedHandle sha1_; - void encryptAndSendData(const unsigned char* data, size_t length); + void encryptAndSendData(unsigned char* data, size_t length); void createReq1Hash(unsigned char* md) const; @@ -116,7 +116,7 @@ private: uint16_t verifyPadLength(const unsigned char* padlenbuf, const char* padName); - void verifyVC(const unsigned char* vcbuf); + void verifyVC(unsigned char* vcbuf); void verifyReq1Hash(const unsigned char* req1buf); @@ -212,6 +212,11 @@ public: return rbuf_; } + unsigned char* getBuffer() + { + return rbuf_; + } + size_t getBufferLength() const { return rbufLength_; diff --git a/src/Makefile.am b/src/Makefile.am index 85dc6f05..c3670dca 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -264,14 +264,12 @@ endif # HAVE_LIBGNUTLS if HAVE_LIBGCRYPT SRCS += LibgcryptMessageDigestImpl.cc LibgcryptMessageDigestImpl.h\ - LibgcryptARC4Context.cc LibgcryptARC4Context.h\ LibgcryptARC4Encryptor.cc LibgcryptARC4Encryptor.h\ LibgcryptDHKeyExchange.cc LibgcryptDHKeyExchange.h endif # HAVE_LIBGCRYPT if HAVE_LIBNETTLE SRCS += LibnettleMessageDigestImpl.cc LibnettleMessageDigestImpl.h\ - LibnettleARC4Context.cc LibnettleARC4Context.h\ LibnettleARC4Encryptor.cc LibnettleARC4Encryptor.h endif # HAVE_LIBNETTLE @@ -283,7 +281,6 @@ endif # HAVE_LIBGMP if HAVE_OPENSSL SRCS += LibsslTLSContext.cc LibsslTLSContext.h\ LibsslMessageDigestImpl.cc LibsslMessageDigestImpl.h\ - LibsslARC4Context.cc LibsslARC4Context.h\ LibsslARC4Encryptor.cc LibsslARC4Encryptor.h\ LibsslDHKeyExchange.cc LibsslDHKeyExchange.h endif # HAVE_OPENSSL diff --git a/src/PeerConnection.cc b/src/PeerConnection.cc index 6a3320fb..2af5383b 100644 --- a/src/PeerConnection.cc +++ b/src/PeerConnection.cc @@ -71,40 +71,12 @@ PeerConnection::~PeerConnection() delete [] resbuf_; } -void PeerConnection::pushStr(const std::string& data) -{ - if(encryptionEnabled_) { - const size_t len = data.size(); - unsigned char* chunk = new unsigned char[len]; - try { - encryptor_->encrypt - (chunk, len, reinterpret_cast(data.data()), len); - } catch(RecoverableException& e) { - delete [] chunk; - throw; - } - socketBuffer_.pushBytes(chunk, len); - } else { - socketBuffer_.pushStr(data); - } -} - void PeerConnection::pushBytes(unsigned char* data, size_t len) { if(encryptionEnabled_) { - unsigned char* chunk = new unsigned char[len]; - try { - encryptor_->encrypt(chunk, len, data, len); - } catch(RecoverableException& e) { - delete [] data; - delete [] chunk; - throw; - } - delete [] data; - socketBuffer_.pushBytes(chunk, len); - } else { - socketBuffer_.pushBytes(data, len); + encryptor_->encrypt(len, data, data); } + socketBuffer_.pushBytes(data, len); } bool PeerConnection::receiveMessage(unsigned char* data, size_t& dataLength) { @@ -211,13 +183,9 @@ bool PeerConnection::receiveHandshake(unsigned char* data, size_t& dataLength, void PeerConnection::readData (unsigned char* data, size_t& length, bool encryption) { + socket_->readData(data, length); if(encryption) { - unsigned char temp[MAX_PAYLOAD_LEN]; - assert(MAX_PAYLOAD_LEN >= length); - socket_->readData(temp, length); - decryptor_->encrypt(data, length, temp, length); - } else { - socket_->readData(data, length); + decryptor_->encrypt(length, data, data); } } diff --git a/test/ARC4Test.cc b/test/ARC4Test.cc index 9275fa49..7666728a 100644 --- a/test/ARC4Test.cc +++ b/test/ARC4Test.cc @@ -37,13 +37,13 @@ void ARC4Test::testEncrypt() unsigned char encrypted[LEN]; unsigned char decrypted[LEN]; - enc.encrypt(encrypted, LEN, key, LEN); - dec.encrypt(decrypted, LEN, encrypted, LEN); + enc.encrypt(LEN, encrypted, key); + dec.encrypt(LEN, decrypted, encrypted); CPPUNIT_ASSERT(memcmp(key, decrypted, LEN) == 0); // once more - enc.encrypt(encrypted, LEN, key, LEN); - dec.encrypt(decrypted, LEN, encrypted, LEN); + enc.encrypt(LEN, encrypted, key); + dec.encrypt(LEN, decrypted, encrypted); CPPUNIT_ASSERT(memcmp(key, decrypted, LEN) == 0); }