0
0
mirror of https://github.com/OpenVPN/openvpn3.git synced 2024-09-20 04:02:15 +02:00

Added CryptoAlgs for managing crypto algorithms independently of

underlying crypto implementation.

Modified proto.hpp to use the new CryptoAlgs types for
cipher/digest selection.

Added initial PolarSSL implementation for cipher/digest
selection using CryptoAlgs types.

Note: this implementation is incomplete, see fixmes.
This commit is contained in:
James Yonan 2014-10-18 10:50:51 -06:00
parent 9145145b64
commit bd04ed3755
7 changed files with 418 additions and 156 deletions

View File

@ -50,9 +50,25 @@ namespace openvpn {
encrypt_.prng = prng;
}
virtual void init_encrypt_cipher(const StaticKey& key, const int mode)
// Encrypt/Decrypt
/* returns true if packet ID is close to wrapping */
virtual bool encrypt(BufferAllocated& buf, const PacketID::time_t now)
{
encrypt_.cipher.init(cipher, key, mode);
encrypt_.encrypt(buf, now);
return encrypt_.pid_send.wrap_warning();
}
virtual Error::Type decrypt(BufferAllocated& buf, const PacketID::time_t now)
{
return decrypt_.decrypt(buf, now);
}
// Initialization
virtual void init_encrypt_cipher(const StaticKey& key)
{
encrypt_.cipher.init(cipher, key, CRYPTO_API::CipherContext::ENCRYPT);
}
virtual void init_encrypt_hmac(const StaticKey& key)
@ -65,9 +81,9 @@ namespace openvpn {
encrypt_.pid_send.init(form);
}
virtual void init_decrypt_cipher(const StaticKey& key, const int mode)
virtual void init_decrypt_cipher(const StaticKey& key)
{
decrypt_.cipher.init(cipher, key, mode);
decrypt_.cipher.init(cipher, key, CRYPTO_API::CipherContext::DECRYPT);
}
virtual void init_decrypt_hmac(const StaticKey& key)
@ -83,18 +99,20 @@ namespace openvpn {
decrypt_.pid_recv.init(mode, form, seq_backtrack, time_backtrack, name, unit, stats_arg);
}
/* returns true if packet ID is close to wrapping */
virtual bool encrypt(BufferAllocated& buf, const PacketID::time_t now)
// Indicate whether or not cipher/digest is defined
virtual bool cipher_defined() const
{
encrypt_.encrypt(buf, now);
return encrypt_.pid_send.wrap_warning();
return cipher.defined();
}
virtual Error::Type decrypt(BufferAllocated& buf, const PacketID::time_t now)
virtual bool digest_defined() const
{
return decrypt_.decrypt(buf, now);
return digest.defined();
}
// Rekeying
virtual void rekey(const typename Base::RekeyType type)
{
}
@ -115,12 +133,12 @@ namespace openvpn {
public:
typedef boost::intrusive_ptr<CryptoContextCHM> Ptr;
CryptoContextCHM(const typename CRYPTO_API::Cipher& cipher_arg,
const typename CRYPTO_API::Digest& digest_arg,
CryptoContextCHM(const CryptoAlgs::Type cipher_arg,
const CryptoAlgs::Type digest_arg,
const Frame::Ptr& frame_arg,
const typename PRNG<CRYPTO_API>::Ptr& prng_arg)
: cipher(cipher_arg),
digest(digest_arg),
: cipher(CryptoAlgs::legal_dc_cipher(cipher_arg)),
digest(CryptoAlgs::legal_dc_digest(digest_arg)),
frame(frame_arg),
prng(prng_arg)
{
@ -131,6 +149,32 @@ namespace openvpn {
return new CryptoCHM<CRYPTO_API>(cipher, digest, frame, prng);
}
// Info for ProtoContext::options_string
virtual std::string cipher_name() const
{
return cipher.defined() ? cipher.name() : "[null-cipher]";
}
virtual std::string digest_name() const
{
return digest.defined() ? digest.name() : "[null-digest]";
}
virtual size_t key_size() const
{
return cipher.defined() ? cipher.key_length_in_bits() : 0;
}
// Info for ProtoContext::link_mtu_adjust
virtual size_t encap_overhead() const
{
return (digest.defined() ? digest.size() : 0) + // HMAC
(cipher.defined() ? cipher.iv_length() : 0) + // Cipher IV
(cipher.defined() ? cipher.block_size() : 0); // worst-case cipher padding expansion
}
private:
typename CRYPTO_API::Cipher cipher;
typename CRYPTO_API::Digest digest;

View File

@ -0,0 +1,147 @@
// OpenVPN -- An application to securely tunnel IP networks
// over a single port, with support for SSL/TLS-based
// session authentication and key exchange,
// packet encryption, packet authentication, and
// packet compression.
//
// Copyright (C) 2013-2014 OpenVPN Technologies, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License Version 3
// as published by the Free Software Foundation.
//
// 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program in the COPYING file.
// If not, see <http://www.gnu.org/licenses/>.
// Crypto algorithms
#ifndef OPENVPN_CRYPTO_CRYPTOALGS_H
#define OPENVPN_CRYPTO_CRYPTOALGS_H
#include <string>
#include <openvpn/common/exception.hpp>
#include <openvpn/common/string.hpp>
namespace openvpn {
namespace CryptoAlgs {
OPENVPN_EXCEPTION(crypto_alg);
OPENVPN_SIMPLE_EXCEPTION(crypto_alg_index);
enum Type {
NONE=0,
// CBC ciphers
AES_128_CBC,
AES_192_CBC,
AES_256_CBC,
DES_CBC,
DES_EDE3_CBC,
BF_CBC,
// AEAD ciphers
AES_128_GCM,
AES_192_GCM,
AES_256_GCM,
// digests
MD4,
MD5,
SHA1,
SHA224,
SHA256,
SHA384,
SHA512,
SIZE,
};
enum Mode {
MODE_UNDEF=0,
CBC_HMAC,
AEAD,
};
enum AlgFlags {
F_CIPHER=(1<<0), // alg is a cipher
F_DIGEST=(1<<1), // alg is a digest
F_ALLOW_DC=(1<<2), // alg may be used in OpenVPN data channel
};
struct Alg
{
const char *name;
unsigned int flags;
Mode mode;
};
const Alg algs[] = { // NOTE: MUST be indexed by CryptoAlgs::Type (CONST GLOBAL)
{ "NONE", F_CIPHER|F_DIGEST|F_ALLOW_DC, CBC_HMAC },
{ "AES-128-CBC", F_CIPHER|F_ALLOW_DC, CBC_HMAC },
{ "AES-192-CBC", F_CIPHER|F_ALLOW_DC, CBC_HMAC },
{ "AES-256-CBC", F_CIPHER|F_ALLOW_DC, CBC_HMAC },
{ "DES-CBC", F_CIPHER|F_ALLOW_DC, CBC_HMAC },
{ "DES-EDE3-CBC", F_CIPHER|F_ALLOW_DC, CBC_HMAC },
{ "BF-CBC", F_CIPHER|F_ALLOW_DC, CBC_HMAC },
{ "AES-128-GCM", F_CIPHER|F_ALLOW_DC, AEAD },
{ "AES-192-GCM", F_CIPHER|F_ALLOW_DC, AEAD },
{ "AES-256-GCM", F_CIPHER|F_ALLOW_DC, AEAD },
{ "MD4", F_DIGEST, MODE_UNDEF },
{ "MD5", F_DIGEST|F_ALLOW_DC, MODE_UNDEF },
{ "SHA1", F_DIGEST|F_ALLOW_DC, MODE_UNDEF },
{ "SHA224", F_DIGEST|F_ALLOW_DC, MODE_UNDEF },
{ "SHA256", F_DIGEST|F_ALLOW_DC, MODE_UNDEF },
{ "SHA384", F_DIGEST|F_ALLOW_DC, MODE_UNDEF },
{ "SHA512", F_DIGEST|F_ALLOW_DC, MODE_UNDEF },
};
inline const Alg& get(const Type type)
{
const size_t i = static_cast<size_t>(type);
if (i >= SIZE)
throw crypto_alg_index();
return algs[i];
}
inline Type lookup(const std::string& name)
{
for (size_t i = 0; i < SIZE; ++i)
{
const Alg& alg = algs[i];
if (string::strcasecmp(name, alg.name) == 0)
return static_cast<Type>(i);
}
OPENVPN_THROW(crypto_alg, name << ": not found");
}
inline const char *name(const Type type)
{
return get(type).name;
}
inline Type legal_dc_cipher(const Type type)
{
const Alg& alg = get(type);
if ((alg.flags & (F_CIPHER|F_ALLOW_DC)) != (F_CIPHER|F_ALLOW_DC))
OPENVPN_THROW(crypto_alg, alg.name << ": bad cipher");
return type;
}
inline Type legal_dc_digest(const Type type)
{
const Alg& alg = get(type);
if ((alg.flags & (F_DIGEST|F_ALLOW_DC)) != (F_DIGEST|F_ALLOW_DC))
OPENVPN_THROW(crypto_alg, alg.name << ": bad digest");
return type;
}
}
}
#endif

View File

@ -31,6 +31,7 @@
#include <openvpn/random/prng.hpp>
#include <openvpn/crypto/static_key.hpp>
#include <openvpn/crypto/packet_id.hpp>
#include <openvpn/crypto/cryptoalgs.hpp>
namespace openvpn {
@ -41,23 +42,6 @@ namespace openvpn {
public:
typedef boost::intrusive_ptr<CryptoDCBase> Ptr;
// Initialization
virtual void init_encrypt_cipher(const StaticKey& key, const int mode) = 0;
virtual void init_encrypt_hmac(const StaticKey& key) = 0;
virtual void init_encrypt_pid_send(const int form) = 0;
virtual void init_decrypt_cipher(const StaticKey& key, const int mode) = 0;
virtual void init_decrypt_hmac(const StaticKey& key) = 0;
virtual void init_decrypt_pid_recv(const int mode, const int form,
const int seq_backtrack, const int time_backtrack,
const char *name, const int unit,
const SessionStats::Ptr& stats_arg) = 0;
// Encrypt/Decrypt
// returns true if packet ID is close to wrapping
@ -65,6 +49,23 @@ namespace openvpn {
virtual Error::Type decrypt(BufferAllocated& buf, const PacketID::time_t now) = 0;
// Initialization
virtual void init_encrypt_cipher(const StaticKey& key) = 0;
virtual void init_encrypt_hmac(const StaticKey& key) = 0;
virtual void init_encrypt_pid_send(const int form) = 0;
virtual void init_decrypt_cipher(const StaticKey& key) = 0;
virtual void init_decrypt_hmac(const StaticKey& key) = 0;
virtual void init_decrypt_pid_recv(const int mode, const int form,
const int seq_backtrack, const int time_backtrack,
const char *name, const int unit,
const SessionStats::Ptr& stats_arg) = 0;
// Indicate whether or not cipher/digest is defined
virtual bool cipher_defined() const = 0;
virtual bool digest_defined() const = 0;
// Rekeying
enum RekeyType {
@ -85,6 +86,16 @@ namespace openvpn {
typedef boost::intrusive_ptr<CryptoDCContext> Ptr;
virtual typename CryptoDCBase<CRYPTO_API>::Ptr new_obj(const unsigned int key_id) = 0;
// Info for ProtoContext::options_string
virtual std::string cipher_name() const = 0;
virtual std::string digest_name() const = 0;
virtual size_t key_size() const = 0;
// Info for ProtoContext::link_mtu_adjust
virtual size_t encap_overhead() const = 0;
};
// Factory for CryptoDCContext objects
@ -94,8 +105,8 @@ namespace openvpn {
public:
typedef boost::intrusive_ptr<CryptoDCFactory> Ptr;
virtual typename CryptoDCContext<CRYPTO_API>::Ptr new_obj(const typename CRYPTO_API::Cipher& cipher,
const typename CRYPTO_API::Digest& digest) = 0;
virtual typename CryptoDCContext<CRYPTO_API>::Ptr new_obj(const CryptoAlgs::Type cipher,
const CryptoAlgs::Type digest) = 0;
};
}

View File

@ -39,14 +39,14 @@ namespace openvpn {
typedef boost::intrusive_ptr<CryptoDCSelect> Ptr;
CryptoDCSelect(const Frame::Ptr& frame_arg,
const typename PRNG<CRYPTO_API>::Ptr& prng_arg)
const typename PRNG<CRYPTO_API>::Ptr& prng_arg)
: frame(frame_arg),
prng(prng_arg)
{
}
virtual typename CryptoDCContext<CRYPTO_API>::Ptr new_obj(const typename CRYPTO_API::Cipher& cipher,
const typename CRYPTO_API::Digest& digest)
virtual typename CryptoDCContext<CRYPTO_API>::Ptr new_obj(const CryptoAlgs::Type cipher,
const CryptoAlgs::Type digest)
{
// fixme -- handle AEAD modes as well
return new CryptoContextCHM<CRYPTO_API>(cipher, digest, frame, prng);

View File

@ -35,6 +35,7 @@
#include <openvpn/common/types.hpp>
#include <openvpn/common/exception.hpp>
#include <openvpn/crypto/static_key.hpp>
#include <openvpn/crypto/cryptoalgs.hpp>
namespace openvpn {
namespace PolarSSLCrypto {
@ -45,23 +46,47 @@ namespace openvpn {
friend class CipherContext;
public:
OPENVPN_EXCEPTION(polarssl_cipher_not_found);
OPENVPN_EXCEPTION(polarssl_cipher);
OPENVPN_SIMPLE_EXCEPTION(polarssl_cipher_undefined);
Cipher() : cipher_(NULL) {}
Cipher(const std::string& name)
Cipher()
{
const std::string translated_name = openvpn_to_cipher_name(name.c_str());
cipher_ = cipher_info_from_string(translated_name.c_str());
if (!cipher_)
throw polarssl_cipher_not_found(translated_name);
reset();
}
Cipher(const CryptoAlgs::Type alg)
{
switch (type_ = alg)
{
case CryptoAlgs::NONE:
reset();
break;
case CryptoAlgs::AES_128_CBC:
cipher_ = cipher_info_from_type(POLARSSL_CIPHER_AES_128_CBC);
break;
case CryptoAlgs::AES_192_CBC:
cipher_ = cipher_info_from_type(POLARSSL_CIPHER_AES_192_CBC);
break;
case CryptoAlgs::AES_256_CBC:
cipher_ = cipher_info_from_type(POLARSSL_CIPHER_AES_256_CBC);
break;
case CryptoAlgs::DES_CBC:
cipher_ = cipher_info_from_type(POLARSSL_CIPHER_DES_CBC);
break;
case CryptoAlgs::DES_EDE3_CBC:
cipher_ = cipher_info_from_type(POLARSSL_CIPHER_DES_EDE3_CBC);
break;
case CryptoAlgs::BF_CBC:
cipher_ = cipher_info_from_type(POLARSSL_CIPHER_BLOWFISH_CBC);
break;
default:
OPENVPN_THROW(polarssl_cipher, CryptoAlgs::name(alg) << ": not usable");
}
}
std::string name() const
{
check_initialized();
return cipher_name_to_openvpn(cipher_->name);
return CryptoAlgs::name(type_);
}
size_t key_length() const
@ -91,6 +116,12 @@ namespace openvpn {
bool defined() const { return cipher_ != NULL; }
private:
void reset()
{
cipher_ = NULL;
type_ = CryptoAlgs::NONE;
}
const cipher_info_t *get() const
{
check_initialized();
@ -105,24 +136,8 @@ namespace openvpn {
#endif
}
static std::string openvpn_to_cipher_name(const std::string& name)
{
const std::string n = boost::algorithm::to_upper_copy(name);
if (boost::algorithm::starts_with(n, "BF-"))
return "BLOWFISH-" + n.substr(3);
else
return n;
}
static std::string cipher_name_to_openvpn(const std::string& name)
{
if (boost::algorithm::starts_with(name, "BLOWFISH-"))
return "BF-" + name.substr(9);
else
return name;
}
const cipher_info_t *cipher_;
CryptoAlgs::Type type_;
};
class CipherContext : boost::noncopyable

View File

@ -45,22 +45,58 @@ namespace openvpn {
friend class HMACContext;
public:
OPENVPN_EXCEPTION(polarssl_digest_not_found);
OPENVPN_EXCEPTION(polarssl_digest_not_found); // fixme
OPENVPN_EXCEPTION(polarssl_digest);
OPENVPN_SIMPLE_EXCEPTION(polarssl_digest_undefined);
Digest() : digest_(NULL) {}
Digest()
{
reset();
}
Digest(const std::string& name)
Digest(const std::string& name) // fixme
{
digest_ = md_info_from_string(name.c_str());
if (!digest_)
throw polarssl_digest_not_found(name);
}
Digest(const CryptoAlgs::Type alg)
{
switch (type_ = alg)
{
case CryptoAlgs::NONE:
reset();
break;
case CryptoAlgs::MD4:
digest_ = md_info_from_type(POLARSSL_MD_MD4);
break;
case CryptoAlgs::MD5:
digest_ = md_info_from_type(POLARSSL_MD_MD5);
break;
case CryptoAlgs::SHA1:
digest_ = md_info_from_type(POLARSSL_MD_SHA1);
break;
case CryptoAlgs::SHA224:
digest_ = md_info_from_type(POLARSSL_MD_SHA224);
break;
case CryptoAlgs::SHA256:
digest_ = md_info_from_type(POLARSSL_MD_SHA256);
break;
case CryptoAlgs::SHA384:
digest_ = md_info_from_type(POLARSSL_MD_SHA384);
break;
case CryptoAlgs::SHA512:
digest_ = md_info_from_type(POLARSSL_MD_SHA512);
break;
default:
OPENVPN_THROW(polarssl_digest, CryptoAlgs::name(alg) << ": not usable");
}
}
std::string name() const
{
check_initialized();
return md_get_name(digest_);
return CryptoAlgs::name(type_);
}
size_t size() const
@ -79,6 +115,12 @@ namespace openvpn {
private:
Digest(const md_info_t *digest) : digest_(digest) {}
void reset()
{
digest_ = NULL;
type_ = CryptoAlgs::NONE;
}
const md_info_t *get() const
{
check_initialized();
@ -94,6 +136,7 @@ namespace openvpn {
}
const md_info_t *digest_;
CryptoAlgs::Type type_;
};
class DigestContext : boost::noncopyable

View File

@ -47,6 +47,7 @@
#include <openvpn/frame/frame.hpp>
#include <openvpn/random/randapi.hpp>
#include <openvpn/random/prng.hpp>
#include <openvpn/crypto/cryptoalgs.hpp>
#include <openvpn/crypto/cryptodc.hpp>
#include <openvpn/crypto/cipher.hpp>
#include <openvpn/crypto/hmac.hpp>
@ -237,8 +238,8 @@ namespace openvpn {
SSLFactoryAPI::Ptr ssl_factory;
// data channel context and factory
typename DCContext::Ptr dc_context; // set with set_cipher_digest
typename DCFactory::Ptr dc_factory;
typename DCContext::Ptr dc_context; // set with set_cipher_digest
// master Frame object
Frame::Ptr frame;
@ -264,10 +265,6 @@ namespace openvpn {
// compressor
CompressContext comp_ctx;
// data channel parms
typename CRYPTO_API::Cipher cipher; // set with set_cipher_digest
typename CRYPTO_API::Digest digest; // set with set_cipher_digest
// tls_auth parms
OpenVPNStaticKey tls_auth_key; // leave this undefined to disable tls_auth
typename CRYPTO_API::Digest tls_auth_digest;
@ -341,36 +338,39 @@ namespace openvpn {
throw proto_option_error("bad dev-type");
}
// cipher
// data channel
{
const Option *o = opt.get_ptr("cipher");
if (o)
{
const std::string& cipher_name = o->get(1, 128);
if (cipher_name != "none")
cipher = typename CRYPTO_API::Cipher(cipher_name);
else
cipher = typename CRYPTO_API::Cipher();
}
else
cipher = typename CRYPTO_API::Cipher("BF-CBC");
}
CryptoAlgs::Type cipher = CryptoAlgs::NONE;
CryptoAlgs::Type digest = CryptoAlgs::NONE;
// digest
{
const Option *o = opt.get_ptr("auth");
if (o)
{
const std::string& auth_name = o->get(1, 128);
if (auth_name != "none")
digest = typename CRYPTO_API::Digest(auth_name);
else
digest = typename CRYPTO_API::Digest();
}
else
digest = typename CRYPTO_API::Digest("SHA1");
// cipher
{
const Option *o = opt.get_ptr("cipher");
if (o)
{
const std::string& cipher_name = o->get(1, 128);
if (cipher_name != "none")
cipher = CryptoAlgs::lookup(cipher_name);
}
else
cipher = CryptoAlgs::lookup("BF-CBC");
}
// digest
{
const Option *o = opt.get_ptr("auth");
if (o)
{
const std::string& auth_name = o->get(1, 128);
if (auth_name != "none")
digest = CryptoAlgs::lookup(auth_name);
}
else
digest = CryptoAlgs::lookup("SHA1");
}
OPENVPN_LOG("************* CRYPTO CONFIG cipher=" << cipher << " digest=" << digest); // fixme
set_cipher_digest(cipher, digest);
}
set_cipher_digest(); // fixme
// tls-auth
{
@ -378,7 +378,7 @@ namespace openvpn {
if (o)
{
tls_auth_key.parse(o->get(1, 0));
tls_auth_digest = digest;
tls_auth_digest = typename CRYPTO_API::Digest("SHA256"); // fixme
}
}
@ -453,42 +453,45 @@ namespace openvpn {
OPENVPN_THROW(process_server_push_error, "Problem accepting server-pushed parameter: " << e.what());
}
// cipher
std::string new_cipher;
try {
const Option *o = opt.get_ptr("cipher");
if (o)
{
new_cipher = o->get(1, 128);
if (new_cipher != "none")
cipher = typename CRYPTO_API::Cipher(new_cipher);
else
cipher = typename CRYPTO_API::Cipher();
}
}
catch (const std::exception& e)
{
OPENVPN_THROW(process_server_push_error, "Problem accepting server-pushed cipher '" << new_cipher << "': " << e.what());
}
// data channel
{
CryptoAlgs::Type cipher = CryptoAlgs::NONE;
CryptoAlgs::Type digest = CryptoAlgs::NONE;
// digest
std::string new_digest;
try {
const Option *o = opt.get_ptr("auth");
if (o)
{
new_digest = o->get(1, 128);
if (new_digest != "none")
digest = typename CRYPTO_API::Digest(new_digest);
else
digest = typename CRYPTO_API::Digest();
}
}
catch (const std::exception& e)
{
OPENVPN_THROW(process_server_push_error, "Problem accepting server-pushed digest '" << new_digest << "': " << e.what());
// cipher
std::string new_cipher;
try {
const Option *o = opt.get_ptr("cipher");
if (o)
{
new_cipher = o->get(1, 128);
if (new_cipher != "none")
cipher = CryptoAlgs::lookup(new_cipher);
}
}
set_cipher_digest(); // fixme
catch (const std::exception& e)
{
OPENVPN_THROW(process_server_push_error, "Problem accepting server-pushed cipher '" << new_cipher << "': " << e.what());
}
// digest
std::string new_digest;
try {
const Option *o = opt.get_ptr("auth");
if (o)
{
new_digest = o->get(1, 128);
if (new_digest != "none")
digest = CryptoAlgs::lookup(new_digest);
}
}
catch (const std::exception& e)
{
OPENVPN_THROW(process_server_push_error, "Problem accepting server-pushed digest '" << new_digest << "': " << e.what());
}
OPENVPN_LOG("************* CRYPTO PULL cipher=" << cipher << " digest=" << digest); // fixme
set_cipher_digest(cipher, digest);
}
// compression
std::string new_comp;
@ -536,7 +539,7 @@ namespace openvpn {
throw proto_option_error("transport protocol undefined");
}
void set_cipher_digest() // fixme
void set_cipher_digest(const CryptoAlgs::Type cipher, const CryptoAlgs::Type digest)
{
dc_context = dc_factory->new_obj(cipher, digest);
}
@ -581,9 +584,12 @@ namespace openvpn {
if (key_direction >= 0)
out << ",keydir " << key_direction;
out << ",cipher " << (cipher.defined() ? cipher.name() : "[null-cipher]");
out << ",auth " << (digest.defined() ? digest.name() : "[null-digest]");
out << ",keysize " << (cipher.defined() ? cipher.key_length_in_bits() : 0);
if (dc_context)
{
out << ",cipher " << dc_context->cipher_name();
out << ",auth " << dc_context->digest_name();
out << ",keysize " << dc_context->key_size();
}
if (tls_auth_key.defined())
out << ",tls-auth";
out << ",key-method 2";
@ -648,9 +654,7 @@ namespace openvpn {
1 + // leading op byte
comp_ctx.extra_payload_bytes() + // compression magic byte
PacketID::size(PacketID::SHORT_FORM) + // sequence number
(digest.defined() ? digest.size() : 0) + // HMAC
(cipher.defined() ? cipher.iv_length() : 0) + // Cipher IV
(cipher.defined() ? cipher.block_size() : 0); // worst-case cipher padding expansion
(dc_context ? dc_context->encap_overhead() : 0); // data channel crypto layer overhead
return (unsigned int)adj;
}
};
@ -1572,26 +1576,24 @@ namespace openvpn {
// OpenVPN data channel protocol
void init_data_channel_crypto_context(const OpenVPNStaticKey& key)
{
// fixme -- this method is being called too early, and is preventing cipher/digest algs from being pushed by server
const Config& c = *proto.config;
const unsigned int key_dir = proto.is_server() ? OpenVPNStaticKey::INVERSE : OpenVPNStaticKey::NORMAL;
// build crypto context for data channel encryption/decryption
OPENVPN_LOG("************* NEW_OBJ KEY_ID=" << key_id_); // fixme
crypto = proto.config->dc_context->new_obj(key_id_);
// initialize CryptoContext encrypt
if (c.cipher.defined())
crypto->init_encrypt_cipher(key.slice(OpenVPNStaticKey::CIPHER | OpenVPNStaticKey::ENCRYPT | key_dir),
CRYPTO_API::CipherContext::ENCRYPT);
if (c.digest.defined())
crypto->init_encrypt_hmac(key.slice(OpenVPNStaticKey::HMAC | OpenVPNStaticKey::ENCRYPT | key_dir));
if (crypto->cipher_defined())
{
crypto->init_encrypt_cipher(key.slice(OpenVPNStaticKey::CIPHER | OpenVPNStaticKey::ENCRYPT | key_dir));
crypto->init_decrypt_cipher(key.slice(OpenVPNStaticKey::CIPHER | OpenVPNStaticKey::DECRYPT | key_dir));
}
if (crypto->digest_defined())
{
crypto->init_encrypt_hmac(key.slice(OpenVPNStaticKey::HMAC | OpenVPNStaticKey::ENCRYPT | key_dir));
crypto->init_decrypt_hmac(key.slice(OpenVPNStaticKey::HMAC | OpenVPNStaticKey::DECRYPT | key_dir));
}
crypto->init_encrypt_pid_send(PacketID::SHORT_FORM);
// initialize CryptoContext decrypt
if (c.cipher.defined())
crypto->init_decrypt_cipher(key.slice(OpenVPNStaticKey::CIPHER | OpenVPNStaticKey::DECRYPT | key_dir),
CRYPTO_API::CipherContext::DECRYPT);
if (c.digest.defined())
crypto->init_decrypt_hmac(key.slice(OpenVPNStaticKey::HMAC | OpenVPNStaticKey::DECRYPT | key_dir));
crypto->init_decrypt_pid_recv(c.pid_mode,
PacketID::SHORT_FORM,
c.pid_seq_backtrack, c.pid_time_backtrack,