24#ifndef OPENVPN_CRYPTO_TLS_CRYPT_V2_H
25#define OPENVPN_CRYPTO_TLS_CRYPT_V2_H
58 std::string text(
reinterpret_cast<const char *
>(pem.
c_data()), pem.
size());
59 while (!text.empty() && text.back() ==
'\0')
85 throw tls_crypt_v2_server_key_parse_error();
88 throw tls_crypt_v2_server_key_bad_size();
117 throw tls_crypt_v2_server_key_encode_error();
159 throw tls_crypt_v2_client_key_parse_error();
162 throw tls_crypt_v2_client_key_bad_size();
180 throw tls_crypt_v2_client_key_encode_error();
212 const std::string &metadata,
213 const int metadata_type,
214 const std::optional<std::uint32_t> key_id,
258 const unsigned char *kc,
259 const size_t kc_size,
260 const std::string &metadata,
261 const int metadata_type,
262 const std::optional<std::uint32_t> key_id,
272 wrapper->
init(libctx,
278 inner.
write(kc, kc_size);
279 if (!metadata.empty())
281 inner.
push_back(
static_cast<unsigned char>(metadata_type));
282 inner.
write(metadata.c_str(), metadata.size());
285 const std::uint32_t k_id_be = htonl(key_id.value_or(0));
286 const size_t k_id_size = key_id ?
sizeof(k_id_be) : 0;
289 const size_t wkc_size =
sizeof(std::uint16_t) + hmac_size + inner.
size() + k_id_size;
291 throw tls_crypt_v2_client_key_bad_size();
293 const std::uint16_t wkc_len =
static_cast<std::uint16_t
>(wkc_size);
294 const std::uint16_t wkc_len_be = htons(wkc_len);
299 hmac_input.
write(&wkc_len_be,
sizeof(wkc_len_be));
301 hmac_input.
write(&k_id_be,
sizeof(k_id_be));
305 unsigned char *tag =
out.write_alloc(hmac_size);
309 const size_t ciphertext_bytes = wrapper->
encrypt(tag,
310 out.data() + hmac_size,
311 out.max_size() - hmac_size,
314 out.inc_size(ciphertext_bytes);
316 out.write(&k_id_be,
sizeof(k_id_be));
317 out.write(&wkc_len_be,
sizeof(wkc_len_be));
void init(const size_t capacity, const BufferFlags flags=BufAllocFlags::NO_FLAGS)
Initializes the buffer with the specified capacity and flags.
bool defined() const
Returns true if the buffer is not empty.
const T * c_data() const
Returns a const pointer to the start of the buffer.
void append(const B &other)
Append data from another buffer to this buffer.
void push_back(const T &value)
Append a T object to the end of the array, resizing the array if necessary.
const T * c_str() const
Returns a const pointer to the null-terminated string representation of the buffer.
T * write_alloc(const size_t size)
Allocate space for writing data to the buffer.
size_t size() const
Returns the size of the buffer in T objects.
void write(const T *data, const size_t size)
Write data to the buffer.
unsigned char * raw_alloc()
StaticKey slice(unsigned int key_specifier) const
Reference count base class for objects tracked by RCPtr. Disallows copying and assignment.
virtual void rand_bytes(unsigned char *buf, size_t size)=0
Fill a buffer with random bytes.
Abstract base class for cryptographically strong random number generators.
virtual TLSCryptInstance::Ptr new_obj_send()=0
virtual size_t digest_size() const =0
virtual bool hmac_gen(unsigned char *header, const size_t header_len, const unsigned char *payload, const size_t payload_len)=0
virtual size_t encrypt(const unsigned char *iv, unsigned char *out, const size_t olen, const unsigned char *in, const size_t ilen)=0
virtual void init(SSLLib::Ctx libctx, const StaticKey &key_hmac, const StaticKey &key_crypt)=0
void parse(const std::string &key_text)
TLSCryptV2ClientKey(TLSCryptContext::Ptr context)
void extract_wkc(BufferAllocated &wkc_out) const
static BufferAllocated wrap(TLSCryptContext &context, const TLSCryptV2ServerKey &server_key, const unsigned char *kc, const size_t kc_size, const std::string &metadata, const int metadata_type, const std::optional< std::uint32_t > key_id, SSLLib::Ctx libctx=nullptr)
Wrap client key material and metadata into a WKc.
OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_client_key_bad_size)
void generate(StrongRandomAPI &rng, const TLSCryptV2ServerKey &server_key, const std::string &metadata, const int metadata_type, const std::optional< std::uint32_t > key_id, SSLLib::Ctx libctx=nullptr)
Mint a fresh client key Kc and the WKc that carries it to a server.
std::string render() const
void extract_key(OpenVPNStaticKey &tls_key)
TLSCryptContext::Ptr context_
The digest/cipher pair generate() wraps with.
TLSCryptV2ClientKey()=delete
OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_client_key_parse_error)
OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_client_key_encode_error)
OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_server_key_bad_size)
void generate(StrongRandomAPI &rng)
Mint a fresh server key, replacing any key already held.
OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_server_key_parse_error)
void parse(const std::string &key_text)
std::string render() const
void extract_key(OpenVPNStaticKey &tls_key) const
OPENVPN_SIMPLE_EXCEPTION(tls_crypt_v2_server_key_encode_error)
constexpr BufferFlags GROW(1U<< 2)
if enabled, buffer will grow (otherwise buffer_full exception will be thrown)
constexpr BufferFlags DESTRUCT_ZERO(1U<< 1)
if enabled, destructor will zero data before deletion
static constexpr const char * tls_crypt_v2_client_key_name
std::string tls_crypt_v2_pem_to_string(const BufferAllocated &pem)
Convert a pem_encode() output buffer into a std::string.
static constexpr const char * tls_crypt_v2_server_key_name
Implementation of the base classes for random number generators.
static std::stringstream out