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