mirror of https://github.com/aria2/aria2
				
				
				
			Rewritten *ARC4Encryptor. Removed *ARC4Context.
Now *ARC4Encryptor supports in-place encryption.pull/2/head
							parent
							
								
									f6f053cae1
								
							
						
					
					
						commit
						72a1847ba8
					
				| 
						 | 
				
			
			@ -156,11 +156,10 @@ bool InitiatorMSEHandshakeCommand::executeInternal() {
 | 
			
		|||
          peerConnection->enableEncryption(mseHandshake_->getEncryptor(),
 | 
			
		||||
                                           mseHandshake_->getDecryptor());
 | 
			
		||||
          size_t buflen = mseHandshake_->getBufferLength();
 | 
			
		||||
          array_ptr<unsigned char> 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());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,84 +0,0 @@
 | 
			
		|||
/* <!-- copyright */
 | 
			
		||||
/*
 | 
			
		||||
 * aria2 - The high speed download utility
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2010 Tatsuhiro Tsujikawa
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | 
			
		||||
 *
 | 
			
		||||
 * In addition, as a special exception, the copyright holders give
 | 
			
		||||
 * permission to link the code of portions of this program with the
 | 
			
		||||
 * OpenSSL library under certain conditions as described in each
 | 
			
		||||
 * individual source file, and distribute linked combinations
 | 
			
		||||
 * including the two.
 | 
			
		||||
 * You must obey the GNU General Public License in all respects
 | 
			
		||||
 * for all of the code used other than OpenSSL.  If you modify
 | 
			
		||||
 * file(s) with this exception, you may extend this exception to your
 | 
			
		||||
 * version of the file(s), but you are not obligated to do so.  If you
 | 
			
		||||
 * do not wish to do so, delete this exception statement from your
 | 
			
		||||
 * version.  If you delete this exception statement from all source
 | 
			
		||||
 * files in the program, then also delete it here.
 | 
			
		||||
 */
 | 
			
		||||
/* copyright --> */
 | 
			
		||||
#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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,62 +0,0 @@
 | 
			
		|||
/* <!-- copyright */
 | 
			
		||||
/*
 | 
			
		||||
 * aria2 - The high speed download utility
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2006 Tatsuhiro Tsujikawa
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | 
			
		||||
 *
 | 
			
		||||
 * In addition, as a special exception, the copyright holders give
 | 
			
		||||
 * permission to link the code of portions of this program with the
 | 
			
		||||
 * OpenSSL library under certain conditions as described in each
 | 
			
		||||
 * individual source file, and distribute linked combinations
 | 
			
		||||
 * including the two.
 | 
			
		||||
 * You must obey the GNU General Public License in all respects
 | 
			
		||||
 * for all of the code used other than OpenSSL.  If you modify
 | 
			
		||||
 * file(s) with this exception, you may extend this exception to your
 | 
			
		||||
 * version of the file(s), but you are not obligated to do so.  If you
 | 
			
		||||
 * do not wish to do so, delete this exception statement from your
 | 
			
		||||
 * version.  If you delete this exception statement from all source
 | 
			
		||||
 * files in the program, then also delete it here.
 | 
			
		||||
 */
 | 
			
		||||
/* copyright --> */
 | 
			
		||||
#ifndef D_LIBGCRYPT_ARC4_CONTEXT_H
 | 
			
		||||
#define D_LIBGCRYPT_ARC4_CONTEXT_H
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
#include <gcrypt.h>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
| 
						 | 
				
			
			@ -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<unsigned char*>(in);
 | 
			
		||||
    in = 0;
 | 
			
		||||
    inlen = 0;
 | 
			
		||||
  } else {
 | 
			
		||||
    inlen = len;
 | 
			
		||||
  }
 | 
			
		||||
  gcry_error_t r;
 | 
			
		||||
  if((r = gcry_cipher_encrypt(hdl_, out, len, in, inlen))) {
 | 
			
		||||
    handleError(r);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -39,13 +39,11 @@
 | 
			
		|||
 | 
			
		||||
#include <gcrypt.h>
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,53 +0,0 @@
 | 
			
		|||
/* <!-- copyright */
 | 
			
		||||
/*
 | 
			
		||||
 * aria2 - The high speed download utility
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2011 Tatsuhiro Tsujikawa
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | 
			
		||||
 *
 | 
			
		||||
 * In addition, as a special exception, the copyright holders give
 | 
			
		||||
 * permission to link the code of portions of this program with the
 | 
			
		||||
 * OpenSSL library under certain conditions as described in each
 | 
			
		||||
 * individual source file, and distribute linked combinations
 | 
			
		||||
 * including the two.
 | 
			
		||||
 * You must obey the GNU General Public License in all respects
 | 
			
		||||
 * for all of the code used other than OpenSSL.  If you modify
 | 
			
		||||
 * file(s) with this exception, you may extend this exception to your
 | 
			
		||||
 * version of the file(s), but you are not obligated to do so.  If you
 | 
			
		||||
 * do not wish to do so, delete this exception statement from your
 | 
			
		||||
 * version.  If you delete this exception statement from all source
 | 
			
		||||
 * files in the program, then also delete it here.
 | 
			
		||||
 */
 | 
			
		||||
/* copyright --> */
 | 
			
		||||
#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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,64 +0,0 @@
 | 
			
		|||
/* <!-- copyright */
 | 
			
		||||
/*
 | 
			
		||||
 * aria2 - The high speed download utility
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2011 Tatsuhiro Tsujikawa
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | 
			
		||||
 *
 | 
			
		||||
 * In addition, as a special exception, the copyright holders give
 | 
			
		||||
 * permission to link the code of portions of this program with the
 | 
			
		||||
 * OpenSSL library under certain conditions as described in each
 | 
			
		||||
 * individual source file, and distribute linked combinations
 | 
			
		||||
 * including the two.
 | 
			
		||||
 * You must obey the GNU General Public License in all respects
 | 
			
		||||
 * for all of the code used other than OpenSSL.  If you modify
 | 
			
		||||
 * file(s) with this exception, you may extend this exception to your
 | 
			
		||||
 * version of the file(s), but you are not obligated to do so.  If you
 | 
			
		||||
 * do not wish to do so, delete this exception statement from your
 | 
			
		||||
 * version.  If you delete this exception statement from all source
 | 
			
		||||
 * files in the program, then also delete it here.
 | 
			
		||||
 */
 | 
			
		||||
/* copyright --> */
 | 
			
		||||
#ifndef D_LIBNETTLE_ARC4_CONTEXT_H
 | 
			
		||||
#define D_LIBNETTLE_ARC4_CONTEXT_H
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
 | 
			
		||||
#include <nettle/arcfour.h>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
| 
						 | 
				
			
			@ -34,8 +34,6 @@
 | 
			
		|||
/* copyright --> */
 | 
			
		||||
#include "LibnettleARC4Encryptor.h"
 | 
			
		||||
 | 
			
		||||
#include <cassert>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,13 +36,16 @@
 | 
			
		|||
#define D_LIBNETTLE_ARC4_ENCRYPTOR_H
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
#include "LibnettleARC4Context.h"
 | 
			
		||||
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
 | 
			
		||||
#include <nettle/arcfour.h>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,91 +0,0 @@
 | 
			
		|||
/* <!-- copyright */
 | 
			
		||||
/*
 | 
			
		||||
 * aria2 - The high speed download utility
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2010 Tatsuhiro Tsujikawa
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | 
			
		||||
 *
 | 
			
		||||
 * In addition, as a special exception, the copyright holders give
 | 
			
		||||
 * permission to link the code of portions of this program with the
 | 
			
		||||
 * OpenSSL library under certain conditions as described in each
 | 
			
		||||
 * individual source file, and distribute linked combinations
 | 
			
		||||
 * including the two.
 | 
			
		||||
 * You must obey the GNU General Public License in all respects
 | 
			
		||||
 * for all of the code used other than OpenSSL.  If you modify
 | 
			
		||||
 * file(s) with this exception, you may extend this exception to your
 | 
			
		||||
 * version of the file(s), but you are not obligated to do so.  If you
 | 
			
		||||
 * do not wish to do so, delete this exception statement from your
 | 
			
		||||
 * version.  If you delete this exception statement from all source
 | 
			
		||||
 * files in the program, then also delete it here.
 | 
			
		||||
 */
 | 
			
		||||
/* copyright --> */
 | 
			
		||||
#include "LibsslARC4Context.h"
 | 
			
		||||
 | 
			
		||||
#include <openssl/err.h>
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
| 
						 | 
				
			
			@ -1,61 +0,0 @@
 | 
			
		|||
/* <!-- copyright */
 | 
			
		||||
/*
 | 
			
		||||
 * aria2 - The high speed download utility
 | 
			
		||||
 *
 | 
			
		||||
 * Copyright (C) 2006 Tatsuhiro Tsujikawa
 | 
			
		||||
 *
 | 
			
		||||
 * This program is free software; you can redistribute it and/or modify
 | 
			
		||||
 * it under the terms of the GNU General Public License as published by
 | 
			
		||||
 * the Free Software Foundation; either version 2 of the License, or
 | 
			
		||||
 * (at your option) any later version.
 | 
			
		||||
 *
 | 
			
		||||
 * This program is distributed in the hope that it will be useful,
 | 
			
		||||
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
			
		||||
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
			
		||||
 * GNU General Public License for more details.
 | 
			
		||||
 *
 | 
			
		||||
 * You should have received a copy of the GNU General Public License
 | 
			
		||||
 * along with this program; if not, write to the Free Software
 | 
			
		||||
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 | 
			
		||||
 *
 | 
			
		||||
 * In addition, as a special exception, the copyright holders give
 | 
			
		||||
 * permission to link the code of portions of this program with the
 | 
			
		||||
 * OpenSSL library under certain conditions as described in each
 | 
			
		||||
 * individual source file, and distribute linked combinations
 | 
			
		||||
 * including the two.
 | 
			
		||||
 * You must obey the GNU General Public License in all respects
 | 
			
		||||
 * for all of the code used other than OpenSSL.  If you modify
 | 
			
		||||
 * file(s) with this exception, you may extend this exception to your
 | 
			
		||||
 * version of the file(s), but you are not obligated to do so.  If you
 | 
			
		||||
 * do not wish to do so, delete this exception statement from your
 | 
			
		||||
 * version.  If you delete this exception statement from all source
 | 
			
		||||
 * files in the program, then also delete it here.
 | 
			
		||||
 */
 | 
			
		||||
/* copyright --> */
 | 
			
		||||
#ifndef D_LIBSSL_ARC4_CONTEXT_H
 | 
			
		||||
#define D_LIBSSL_ARC4_CONTEXT_H
 | 
			
		||||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
#include <openssl/evp.h>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
| 
						 | 
				
			
			@ -34,39 +34,23 @@
 | 
			
		|||
/* copyright --> */
 | 
			
		||||
#include "LibsslARC4Encryptor.h"
 | 
			
		||||
 | 
			
		||||
#include <openssl/err.h>
 | 
			
		||||
 | 
			
		||||
#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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,15 +37,13 @@
 | 
			
		|||
 | 
			
		||||
#include "common.h"
 | 
			
		||||
 | 
			
		||||
#include <openssl/evp.h>
 | 
			
		||||
 | 
			
		||||
#include "LibsslARC4Context.h"
 | 
			
		||||
#include <openssl/rc4.h>
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<unsigned char> 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<unsigned char*>(&be),
 | 
			
		||||
                      sizeof(be),
 | 
			
		||||
                      buffer, sizeof(be));
 | 
			
		||||
  decryptor_->encrypt(sizeof(be),
 | 
			
		||||
                      reinterpret_cast<unsigned char*>(&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<unsigned char> 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<unsigned char> 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()));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -100,7 +100,7 @@ private:
 | 
			
		|||
  unsigned char* ia_;
 | 
			
		||||
  SharedHandle<MessageDigest> 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_;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<const unsigned char*>(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);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue