1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
|
// 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) 2012-2022 OpenVPN 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/>.
// OpenVPN 3 wrapper for kovpn crypto
#ifndef OPENVPN_KOVPN_KOREKEY_H
#define OPENVPN_KOVPN_KOREKEY_H
#include <openvpn/dco/kocrypto.hpp>
namespace openvpn {
namespace KoRekey {
class Receiver : public virtual RC<thread_unsafe_refcount>
{
public:
typedef RCPtr<Receiver> Ptr;
virtual void rekey(const CryptoDCInstance::RekeyType type,
const Info &info)
= 0;
virtual void explicit_exit_notify()
{
}
};
class Instance : public CryptoDCInstance
{
public:
Instance(const Receiver::Ptr &rcv_arg,
const CryptoDCContext::Ptr &dc_context_delegate,
const unsigned int key_id,
const Frame::Ptr &frame)
: rcv(rcv_arg),
info(dc_context_delegate, key_id, frame)
{
}
// Initialization
virtual unsigned int defined() const override
{
return CIPHER_DEFINED | HMAC_DEFINED | EXPLICIT_EXIT_NOTIFY_DEFINED;
}
virtual void init_cipher(StaticKey &&encrypt_key,
StaticKey &&decrypt_key) override
{
info.encrypt_cipher = std::move(encrypt_key);
info.decrypt_cipher = std::move(decrypt_key);
}
virtual void init_hmac(StaticKey &&encrypt_key,
StaticKey &&decrypt_key) override
{
info.encrypt_hmac = std::move(encrypt_key);
info.decrypt_hmac = std::move(decrypt_key);
}
virtual void init_pid(const int send_form,
const int recv_mode,
const int recv_form,
const char *recv_name,
const int recv_unit,
const SessionStats::Ptr &recv_stats_arg) override
{
info.tcp_linear = (recv_mode == PacketIDReceive::TCP_MODE);
}
virtual void init_remote_peer_id(const int remote_peer_id) override
{
info.remote_peer_id = remote_peer_id;
}
virtual bool consider_compression(const CompressContext &comp_ctx) override
{
info.comp_ctx = comp_ctx;
return false;
}
// Rekeying
virtual void rekey(const RekeyType type) override
{
rcv->rekey(type, info);
}
virtual void explicit_exit_notify() override
{
rcv->explicit_exit_notify();
}
// Encrypt/Decrypt -- data channel handled by kernel, so these methods
// should never be reached.
// returns true if packet ID is close to wrapping
virtual bool encrypt(BufferAllocated &buf, const PacketID::time_t now, const unsigned char *op32) override
{
throw korekey_error("encrypt");
}
virtual Error::Type decrypt(BufferAllocated &buf, const PacketID::time_t now, const unsigned char *op32) override
{
throw korekey_error("decrypt");
}
private:
Receiver::Ptr rcv;
Info info;
};
class Context : public CryptoDCContext
{
public:
Context(const CryptoAlgs::Type cipher,
const CryptoAlgs::Type digest,
const CryptoAlgs::KeyDerivation key_method,
CryptoDCFactory &dc_factory_delegate,
const Receiver::Ptr &rcv_arg,
const Frame::Ptr &frame_arg)
: CryptoDCContext(key_method),
rcv(rcv_arg),
dc_context_delegate(dc_factory_delegate.new_obj(cipher, digest, key_method)),
frame(frame_arg)
{
Key::validate(cipher, digest);
}
virtual CryptoDCInstance::Ptr new_obj(const unsigned int key_id) override
{
return new Instance(rcv, dc_context_delegate, key_id, frame);
}
// Info for ProtoContext::options_string
virtual Info crypto_info() override
{
return dc_context_delegate->crypto_info();
}
// Info for ProtoContext::link_mtu_adjust
virtual size_t encap_overhead() const override
{
return dc_context_delegate->encap_overhead();
}
private:
Receiver::Ptr rcv;
CryptoDCContext::Ptr dc_context_delegate;
Frame::Ptr frame;
};
class Factory : public CryptoDCFactory
{
public:
Factory(const CryptoDCFactory::Ptr &dc_factory_delegate_arg,
const Receiver::Ptr &rcv_arg,
const Frame::Ptr &frame_arg)
: dc_factory_delegate(dc_factory_delegate_arg),
rcv(rcv_arg),
frame(frame_arg)
{
}
virtual CryptoDCContext::Ptr new_obj(const CryptoAlgs::Type cipher,
const CryptoAlgs::Type digest,
const CryptoAlgs::KeyDerivation key_method) override
{
return new Context(cipher, digest, key_method, *dc_factory_delegate, rcv, frame);
}
private:
CryptoDCFactory::Ptr dc_factory_delegate;
Receiver::Ptr rcv;
Frame::Ptr frame;
};
} // namespace KoRekey
} // namespace openvpn
#endif
|