2022-01-20 18:27:56 +00:00
|
|
|
// This file Copyright © 2007-2022 Mnemosyne LLC.
|
|
|
|
// It may be used under GPLv2 (SPDX: GPL-2.0), GPLv3 (SPDX: GPL-3.0),
|
|
|
|
// or any future license endorsed by Mnemosyne LLC.
|
|
|
|
// License text can be found in the licenses/ folder.
|
2014-12-04 11:27:38 +00:00
|
|
|
|
2016-03-29 19:02:26 +00:00
|
|
|
#ifndef TR_CRYPTO_UTILS_H
|
|
|
|
#define TR_CRYPTO_UTILS_H
|
2014-12-04 11:27:38 +00:00
|
|
|
|
2021-12-17 04:51:53 +00:00
|
|
|
#include <cinttypes> // intX_t
|
|
|
|
#include <cstddef> // size_t
|
2021-11-04 00:55:04 +00:00
|
|
|
#include <optional>
|
2021-11-14 02:03:01 +00:00
|
|
|
#include <string>
|
|
|
|
#include <string_view>
|
2014-12-04 11:27:38 +00:00
|
|
|
|
2021-12-21 22:14:15 +00:00
|
|
|
#include "transmission.h" // tr_sha1_digest_t
|
2014-12-04 19:58:34 +00:00
|
|
|
|
2014-12-04 11:27:38 +00:00
|
|
|
/**
|
|
|
|
*** @addtogroup utils Utilities
|
|
|
|
*** @{
|
|
|
|
**/
|
|
|
|
|
2017-04-19 12:04:45 +00:00
|
|
|
/** @brief Opaque SHA1 context type. */
|
2021-10-06 14:26:07 +00:00
|
|
|
using tr_sha1_ctx_t = void*;
|
2017-04-19 12:04:45 +00:00
|
|
|
/** @brief Opaque DH context type. */
|
2021-10-06 14:26:07 +00:00
|
|
|
using tr_dh_ctx_t = void*;
|
2017-04-19 12:04:45 +00:00
|
|
|
/** @brief Opaque DH secret key type. */
|
2021-10-06 14:26:07 +00:00
|
|
|
using tr_dh_secret_t = void*;
|
2019-06-22 13:02:17 +00:00
|
|
|
/** @brief Opaque SSL context type. */
|
2021-10-06 14:26:07 +00:00
|
|
|
using tr_ssl_ctx_t = void*;
|
2019-06-22 13:02:17 +00:00
|
|
|
/** @brief Opaque X509 certificate store type. */
|
2021-10-06 14:26:07 +00:00
|
|
|
using tr_x509_store_t = void*;
|
2019-06-22 13:02:17 +00:00
|
|
|
/** @brief Opaque X509 certificate type. */
|
2021-10-06 14:26:07 +00:00
|
|
|
using tr_x509_cert_t = void*;
|
2014-12-04 12:13:59 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Allocate and initialize new SHA1 hasher context.
|
|
|
|
*/
|
2017-04-19 12:04:45 +00:00
|
|
|
tr_sha1_ctx_t tr_sha1_init(void);
|
2014-12-04 12:13:59 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Update SHA1 hash.
|
|
|
|
*/
|
2017-04-20 16:02:19 +00:00
|
|
|
bool tr_sha1_update(tr_sha1_ctx_t handle, void const* data, size_t data_length);
|
2014-12-04 12:13:59 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Finalize and export SHA1 hash, free hasher context.
|
|
|
|
*/
|
2021-11-04 00:55:04 +00:00
|
|
|
std::optional<tr_sha1_digest_t> tr_sha1_final(tr_sha1_ctx_t handle);
|
2014-12-04 12:37:08 +00:00
|
|
|
|
2021-12-21 22:14:15 +00:00
|
|
|
/**
|
|
|
|
* @brief Generate a SHA1 hash from one or more chunks of memory.
|
|
|
|
*/
|
|
|
|
template<typename... T>
|
|
|
|
std::optional<tr_sha1_digest_t> tr_sha1(T... args)
|
|
|
|
{
|
|
|
|
auto ctx = tr_sha1_init();
|
|
|
|
if (ctx == nullptr)
|
|
|
|
{
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((tr_sha1_update(ctx, std::data(args), std::size(args)) && ...))
|
|
|
|
{
|
|
|
|
return tr_sha1_final(ctx);
|
|
|
|
}
|
|
|
|
|
|
|
|
// one of the update() calls failed so we will return nullopt,
|
|
|
|
// but we need to call final() first to ensure ctx is released
|
|
|
|
tr_sha1_final(ctx);
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
#4400, #5462: Move DH helpers to crypto-utils
On a way to factoring out OpenSSL support to a standalone file to ease
addition of other crypto libraries support in the future, move helpers
providing DH key exchange to crypto-utils.{c,h}. OpenSSL-related
functionality (DH context management) is moved to crypto-utils-openssl.c.
Since we know in advance that DH secret key management code will be the
same for most of backends, implement common functionality in separate
crypto-utils-fallback.c.
Add new tr_dh_ctx_t and tr_dh_secret_t types and functions to be
implemented by crypto backends:
* tr_dh_new - allocate DH context,
* tr_dh_free - free the context,
* tr_dh_make_key - generate private/public keypair,
* tr_dh_agree - perform DH key exchange and generate secret key,
* tr_dh_secret_derive - calculate secret key hash,
* tr_dh_secret_free - free the secret key,
* tr_dh_align_key - align some DH key in the buffer allocated for it.
Make DH secret key not accessible in plain form outside the crypto
backend. This allows for implementations where the key is managed by
the underlying library and is not even exposed to our backend.
2014-12-04 19:18:08 +00:00
|
|
|
/**
|
|
|
|
* @brief Allocate and initialize new Diffie-Hellman (DH) key exchange context.
|
|
|
|
*/
|
2021-08-15 09:41:48 +00:00
|
|
|
tr_dh_ctx_t tr_dh_new(
|
|
|
|
uint8_t const* prime_num,
|
|
|
|
size_t prime_num_length,
|
|
|
|
uint8_t const* generator_num,
|
2017-04-19 12:04:45 +00:00
|
|
|
size_t generator_num_length);
|
#4400, #5462: Move DH helpers to crypto-utils
On a way to factoring out OpenSSL support to a standalone file to ease
addition of other crypto libraries support in the future, move helpers
providing DH key exchange to crypto-utils.{c,h}. OpenSSL-related
functionality (DH context management) is moved to crypto-utils-openssl.c.
Since we know in advance that DH secret key management code will be the
same for most of backends, implement common functionality in separate
crypto-utils-fallback.c.
Add new tr_dh_ctx_t and tr_dh_secret_t types and functions to be
implemented by crypto backends:
* tr_dh_new - allocate DH context,
* tr_dh_free - free the context,
* tr_dh_make_key - generate private/public keypair,
* tr_dh_agree - perform DH key exchange and generate secret key,
* tr_dh_secret_derive - calculate secret key hash,
* tr_dh_secret_free - free the secret key,
* tr_dh_align_key - align some DH key in the buffer allocated for it.
Make DH secret key not accessible in plain form outside the crypto
backend. This allows for implementations where the key is managed by
the underlying library and is not even exposed to our backend.
2014-12-04 19:18:08 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Free DH key exchange context.
|
|
|
|
*/
|
2017-04-19 12:04:45 +00:00
|
|
|
void tr_dh_free(tr_dh_ctx_t handle);
|
#4400, #5462: Move DH helpers to crypto-utils
On a way to factoring out OpenSSL support to a standalone file to ease
addition of other crypto libraries support in the future, move helpers
providing DH key exchange to crypto-utils.{c,h}. OpenSSL-related
functionality (DH context management) is moved to crypto-utils-openssl.c.
Since we know in advance that DH secret key management code will be the
same for most of backends, implement common functionality in separate
crypto-utils-fallback.c.
Add new tr_dh_ctx_t and tr_dh_secret_t types and functions to be
implemented by crypto backends:
* tr_dh_new - allocate DH context,
* tr_dh_free - free the context,
* tr_dh_make_key - generate private/public keypair,
* tr_dh_agree - perform DH key exchange and generate secret key,
* tr_dh_secret_derive - calculate secret key hash,
* tr_dh_secret_free - free the secret key,
* tr_dh_align_key - align some DH key in the buffer allocated for it.
Make DH secret key not accessible in plain form outside the crypto
backend. This allows for implementations where the key is managed by
the underlying library and is not even exposed to our backend.
2014-12-04 19:18:08 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Generate private and public DH keys, export public key.
|
|
|
|
*/
|
2017-04-19 12:04:45 +00:00
|
|
|
bool tr_dh_make_key(tr_dh_ctx_t handle, size_t private_key_length, uint8_t* public_key, size_t* public_key_length);
|
#4400, #5462: Move DH helpers to crypto-utils
On a way to factoring out OpenSSL support to a standalone file to ease
addition of other crypto libraries support in the future, move helpers
providing DH key exchange to crypto-utils.{c,h}. OpenSSL-related
functionality (DH context management) is moved to crypto-utils-openssl.c.
Since we know in advance that DH secret key management code will be the
same for most of backends, implement common functionality in separate
crypto-utils-fallback.c.
Add new tr_dh_ctx_t and tr_dh_secret_t types and functions to be
implemented by crypto backends:
* tr_dh_new - allocate DH context,
* tr_dh_free - free the context,
* tr_dh_make_key - generate private/public keypair,
* tr_dh_agree - perform DH key exchange and generate secret key,
* tr_dh_secret_derive - calculate secret key hash,
* tr_dh_secret_free - free the secret key,
* tr_dh_align_key - align some DH key in the buffer allocated for it.
Make DH secret key not accessible in plain form outside the crypto
backend. This allows for implementations where the key is managed by
the underlying library and is not even exposed to our backend.
2014-12-04 19:18:08 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Perform DH key exchange, generate secret key.
|
|
|
|
*/
|
2017-04-20 16:02:19 +00:00
|
|
|
tr_dh_secret_t tr_dh_agree(tr_dh_ctx_t handle, uint8_t const* other_public_key, size_t other_public_key_length);
|
#4400, #5462: Move DH helpers to crypto-utils
On a way to factoring out OpenSSL support to a standalone file to ease
addition of other crypto libraries support in the future, move helpers
providing DH key exchange to crypto-utils.{c,h}. OpenSSL-related
functionality (DH context management) is moved to crypto-utils-openssl.c.
Since we know in advance that DH secret key management code will be the
same for most of backends, implement common functionality in separate
crypto-utils-fallback.c.
Add new tr_dh_ctx_t and tr_dh_secret_t types and functions to be
implemented by crypto backends:
* tr_dh_new - allocate DH context,
* tr_dh_free - free the context,
* tr_dh_make_key - generate private/public keypair,
* tr_dh_agree - perform DH key exchange and generate secret key,
* tr_dh_secret_derive - calculate secret key hash,
* tr_dh_secret_free - free the secret key,
* tr_dh_align_key - align some DH key in the buffer allocated for it.
Make DH secret key not accessible in plain form outside the crypto
backend. This allows for implementations where the key is managed by
the underlying library and is not even exposed to our backend.
2014-12-04 19:18:08 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Calculate SHA1 hash of DH secret key, prepending and/or appending
|
|
|
|
* given data to the key during calculation.
|
|
|
|
*/
|
2021-12-21 22:14:15 +00:00
|
|
|
std::optional<tr_sha1_digest_t> tr_dh_secret_derive(
|
2021-08-15 09:41:48 +00:00
|
|
|
tr_dh_secret_t handle,
|
|
|
|
void const* prepend_data,
|
|
|
|
size_t prepend_data_size,
|
|
|
|
void const* append_data,
|
2021-12-21 22:14:15 +00:00
|
|
|
size_t append_data_size);
|
#4400, #5462: Move DH helpers to crypto-utils
On a way to factoring out OpenSSL support to a standalone file to ease
addition of other crypto libraries support in the future, move helpers
providing DH key exchange to crypto-utils.{c,h}. OpenSSL-related
functionality (DH context management) is moved to crypto-utils-openssl.c.
Since we know in advance that DH secret key management code will be the
same for most of backends, implement common functionality in separate
crypto-utils-fallback.c.
Add new tr_dh_ctx_t and tr_dh_secret_t types and functions to be
implemented by crypto backends:
* tr_dh_new - allocate DH context,
* tr_dh_free - free the context,
* tr_dh_make_key - generate private/public keypair,
* tr_dh_agree - perform DH key exchange and generate secret key,
* tr_dh_secret_derive - calculate secret key hash,
* tr_dh_secret_free - free the secret key,
* tr_dh_align_key - align some DH key in the buffer allocated for it.
Make DH secret key not accessible in plain form outside the crypto
backend. This allows for implementations where the key is managed by
the underlying library and is not even exposed to our backend.
2014-12-04 19:18:08 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Free DH secret key returned by @ref tr_dh_agree.
|
|
|
|
*/
|
2017-04-19 12:04:45 +00:00
|
|
|
void tr_dh_secret_free(tr_dh_secret_t handle);
|
#4400, #5462: Move DH helpers to crypto-utils
On a way to factoring out OpenSSL support to a standalone file to ease
addition of other crypto libraries support in the future, move helpers
providing DH key exchange to crypto-utils.{c,h}. OpenSSL-related
functionality (DH context management) is moved to crypto-utils-openssl.c.
Since we know in advance that DH secret key management code will be the
same for most of backends, implement common functionality in separate
crypto-utils-fallback.c.
Add new tr_dh_ctx_t and tr_dh_secret_t types and functions to be
implemented by crypto backends:
* tr_dh_new - allocate DH context,
* tr_dh_free - free the context,
* tr_dh_make_key - generate private/public keypair,
* tr_dh_agree - perform DH key exchange and generate secret key,
* tr_dh_secret_derive - calculate secret key hash,
* tr_dh_secret_free - free the secret key,
* tr_dh_align_key - align some DH key in the buffer allocated for it.
Make DH secret key not accessible in plain form outside the crypto
backend. This allows for implementations where the key is managed by
the underlying library and is not even exposed to our backend.
2014-12-04 19:18:08 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Align DH key (big-endian number) to required length (internal, do not use).
|
|
|
|
*/
|
2017-04-19 12:04:45 +00:00
|
|
|
void tr_dh_align_key(uint8_t* key_buffer, size_t key_size, size_t buffer_size);
|
#4400, #5462: Move DH helpers to crypto-utils
On a way to factoring out OpenSSL support to a standalone file to ease
addition of other crypto libraries support in the future, move helpers
providing DH key exchange to crypto-utils.{c,h}. OpenSSL-related
functionality (DH context management) is moved to crypto-utils-openssl.c.
Since we know in advance that DH secret key management code will be the
same for most of backends, implement common functionality in separate
crypto-utils-fallback.c.
Add new tr_dh_ctx_t and tr_dh_secret_t types and functions to be
implemented by crypto backends:
* tr_dh_new - allocate DH context,
* tr_dh_free - free the context,
* tr_dh_make_key - generate private/public keypair,
* tr_dh_agree - perform DH key exchange and generate secret key,
* tr_dh_secret_derive - calculate secret key hash,
* tr_dh_secret_free - free the secret key,
* tr_dh_align_key - align some DH key in the buffer allocated for it.
Make DH secret key not accessible in plain form outside the crypto
backend. This allows for implementations where the key is managed by
the underlying library and is not even exposed to our backend.
2014-12-04 19:18:08 +00:00
|
|
|
|
2019-06-22 13:02:17 +00:00
|
|
|
/**
|
|
|
|
* @brief Get X509 certificate store from SSL context.
|
|
|
|
*/
|
|
|
|
tr_x509_store_t tr_ssl_get_x509_store(tr_ssl_ctx_t handle);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Add certificate to X509 certificate store.
|
|
|
|
*/
|
|
|
|
bool tr_x509_store_add(tr_x509_store_t handle, tr_x509_cert_t cert);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Allocate and initialize new X509 certificate from DER-encoded buffer.
|
|
|
|
*/
|
|
|
|
tr_x509_cert_t tr_x509_cert_new(void const* der_data, size_t der_data_size);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Free X509 certificate returned by @ref tr_x509_cert_new.
|
|
|
|
*/
|
|
|
|
void tr_x509_cert_free(tr_x509_cert_t handle);
|
|
|
|
|
2014-12-04 11:27:38 +00:00
|
|
|
/**
|
|
|
|
* @brief Returns a random number in the range of [0...upper_bound).
|
|
|
|
*/
|
2017-04-19 12:04:45 +00:00
|
|
|
int tr_rand_int(int upper_bound);
|
2014-12-04 11:27:38 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Returns a pseudorandom number in the range of [0...upper_bound).
|
|
|
|
*
|
2017-04-21 07:40:57 +00:00
|
|
|
* This is faster, BUT WEAKER, than tr_rand_int() and never be used in sensitive cases.
|
|
|
|
* @see tr_rand_int()
|
2014-12-04 11:27:38 +00:00
|
|
|
*/
|
2017-04-19 12:04:45 +00:00
|
|
|
int tr_rand_int_weak(int upper_bound);
|
2014-12-04 11:27:38 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Fill a buffer with random bytes.
|
|
|
|
*/
|
2017-04-19 12:04:45 +00:00
|
|
|
bool tr_rand_buffer(void* buffer, size_t length);
|
2014-12-04 11:27:38 +00:00
|
|
|
|
2014-12-04 20:45:18 +00:00
|
|
|
/**
|
|
|
|
* @brief Generate a SSHA password from its plaintext source.
|
|
|
|
*/
|
2021-11-14 02:03:01 +00:00
|
|
|
std::string tr_ssha1(std::string_view plain_text);
|
2014-12-04 20:45:18 +00:00
|
|
|
|
2021-12-21 22:14:15 +00:00
|
|
|
/**
|
|
|
|
* @brief Return true if this is salted text, false otherwise
|
|
|
|
*/
|
|
|
|
bool tr_ssha1_test(std::string_view text);
|
|
|
|
|
2014-12-04 20:45:18 +00:00
|
|
|
/**
|
|
|
|
* @brief Validate a test password against the a ssha1 password.
|
|
|
|
*/
|
2021-11-14 02:03:01 +00:00
|
|
|
bool tr_ssha1_matches(std::string_view ssha1, std::string_view plain_text);
|
2014-12-04 20:45:18 +00:00
|
|
|
|
2014-12-04 19:58:34 +00:00
|
|
|
/**
|
|
|
|
* @brief Translate null-terminated string into base64.
|
2022-01-08 12:46:25 +00:00
|
|
|
* @return a new std::string with the encoded contents
|
2014-12-04 19:58:34 +00:00
|
|
|
*/
|
2022-01-08 12:46:25 +00:00
|
|
|
std::string tr_base64_encode(std::string_view input);
|
2014-12-04 19:58:34 +00:00
|
|
|
|
2021-11-15 03:54:48 +00:00
|
|
|
/**
|
|
|
|
* @brief Translate a character range from base64 into raw form.
|
|
|
|
* @return a new std::string with the decoded contents.
|
|
|
|
*/
|
2022-01-08 12:46:25 +00:00
|
|
|
std::string tr_base64_decode(std::string_view input);
|
2021-11-15 03:54:48 +00:00
|
|
|
|
2014-12-04 20:53:56 +00:00
|
|
|
/**
|
2021-12-21 22:14:15 +00:00
|
|
|
* @brief Generate an ascii hex string for a sha1 digest.
|
|
|
|
* @return address pointing past the last element written.
|
|
|
|
*/
|
|
|
|
char* tr_sha1_to_string(tr_sha1_digest_t const& digest, char* strbuf);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Generate an ascii hex string for a sha1 digest.
|
2014-12-04 20:53:56 +00:00
|
|
|
*/
|
2021-12-21 22:14:15 +00:00
|
|
|
std::string tr_sha1_to_string(tr_sha1_digest_t const&);
|
2014-12-04 20:53:56 +00:00
|
|
|
|
|
|
|
/**
|
2021-12-21 22:14:15 +00:00
|
|
|
* @brief Generate a sha1 digest from a hex string.
|
2014-12-04 20:53:56 +00:00
|
|
|
*/
|
2021-12-21 22:14:15 +00:00
|
|
|
tr_sha1_digest_t tr_sha1_from_string(std::string_view hex);
|
2014-12-04 20:53:56 +00:00
|
|
|
|
2014-12-04 11:27:38 +00:00
|
|
|
/** @} */
|
|
|
|
|
2016-03-29 19:02:26 +00:00
|
|
|
#endif /* TR_CRYPTO_UTILS_H */
|