2014-12-04 11:27:38 +00:00
|
|
|
/*
|
|
|
|
* This file Copyright (C) 2007-2014 Mnemosyne LLC
|
|
|
|
*
|
|
|
|
* It may be used under the GNU GPL versions 2 or 3
|
|
|
|
* or any future license endorsed by Mnemosyne LLC.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
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
|
|
|
|
2014-12-04 12:13:59 +00:00
|
|
|
#include <inttypes.h>
|
2014-12-04 11:27:38 +00:00
|
|
|
#include <stddef.h>
|
|
|
|
|
2014-12-04 20:53:56 +00:00
|
|
|
#include "transmission.h" /* SHA_DIGEST_LENGTH */
|
2020-08-11 18:11:55 +00:00
|
|
|
#include "tr-macros.h"
|
2014-12-04 19:58:34 +00:00
|
|
|
#include "utils.h" /* TR_GNUC_MALLOC, TR_GNUC_NULL_TERMINATED */
|
|
|
|
|
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 Generate a SHA1 hash from one or more chunks of memory.
|
|
|
|
*/
|
2017-04-20 16:02:19 +00:00
|
|
|
bool tr_sha1(uint8_t* hash, void const* data1, int data1_length, ...) TR_GNUC_NULL_TERMINATED;
|
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.
|
|
|
|
*/
|
2017-04-19 12:04:45 +00:00
|
|
|
bool tr_sha1_final(tr_sha1_ctx_t handle, uint8_t* hash);
|
2014-12-04 12:37:08 +00:00
|
|
|
|
#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-08-15 09:41:48 +00:00
|
|
|
bool tr_dh_secret_derive(
|
|
|
|
tr_dh_secret_t handle,
|
|
|
|
void const* prepend_data,
|
|
|
|
size_t prepend_data_size,
|
|
|
|
void const* append_data,
|
|
|
|
size_t append_data_size,
|
|
|
|
uint8_t* hash);
|
#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.
|
|
|
|
*/
|
2017-04-20 16:02:19 +00:00
|
|
|
char* tr_ssha1(char const* plain_text) TR_GNUC_MALLOC;
|
2014-12-04 20:45:18 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Validate a test password against the a ssha1 password.
|
|
|
|
*/
|
2017-04-20 16:02:19 +00:00
|
|
|
bool tr_ssha1_matches(char const* ssha1, char const* plain_text);
|
2014-12-04 20:45:18 +00:00
|
|
|
|
2014-12-04 19:58:34 +00:00
|
|
|
/**
|
|
|
|
* @brief Translate a block of bytes into base64.
|
2017-04-21 07:40:57 +00:00
|
|
|
* @return a newly-allocated null-terminated string that can be freed with tr_free()
|
2014-12-04 19:58:34 +00:00
|
|
|
*/
|
2017-04-20 16:02:19 +00:00
|
|
|
void* tr_base64_encode(void const* input, size_t input_length, size_t* output_length) TR_GNUC_MALLOC;
|
2014-12-04 19:58:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Translate null-terminated string into base64.
|
2017-04-21 07:40:57 +00:00
|
|
|
* @return a newly-allocated null-terminated string that can be freed with tr_free()
|
2014-12-04 19:58:34 +00:00
|
|
|
*/
|
2017-04-20 16:02:19 +00:00
|
|
|
void* tr_base64_encode_str(char const* input, size_t* output_length) TR_GNUC_MALLOC;
|
2014-12-04 19:58:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Translate a block of bytes from base64 into raw form.
|
2017-04-21 07:40:57 +00:00
|
|
|
* @return a newly-allocated null-terminated string that can be freed with tr_free()
|
2014-12-04 19:58:34 +00:00
|
|
|
*/
|
2017-04-20 16:02:19 +00:00
|
|
|
void* tr_base64_decode(void const* input, size_t input_length, size_t* output_length) TR_GNUC_MALLOC;
|
2014-12-04 19:58:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Translate null-terminated string from base64 into raw form.
|
2017-04-21 07:40:57 +00:00
|
|
|
* @return a newly-allocated null-terminated string that can be freed with tr_free()
|
2014-12-04 19:58:34 +00:00
|
|
|
*/
|
2017-04-20 16:02:19 +00:00
|
|
|
void* tr_base64_decode_str(char const* input, size_t* output_length) TR_GNUC_MALLOC;
|
2014-12-04 19:58:34 +00:00
|
|
|
|
2014-12-04 20:53:56 +00:00
|
|
|
/**
|
2017-04-21 07:40:57 +00:00
|
|
|
* @brief Wrapper around tr_binary_to_hex() for SHA_DIGEST_LENGTH.
|
2014-12-04 20:53:56 +00:00
|
|
|
*/
|
2020-08-11 18:11:55 +00:00
|
|
|
static inline void tr_sha1_to_hex(void* hex, void const* sha1)
|
2014-12-04 20:53:56 +00:00
|
|
|
{
|
2017-04-19 12:04:45 +00:00
|
|
|
tr_binary_to_hex(sha1, hex, SHA_DIGEST_LENGTH);
|
2014-12-04 20:53:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-04-21 07:40:57 +00:00
|
|
|
* @brief Wrapper around tr_hex_to_binary() for SHA_DIGEST_LENGTH.
|
2014-12-04 20:53:56 +00:00
|
|
|
*/
|
2020-08-11 18:11:55 +00:00
|
|
|
static inline void tr_hex_to_sha1(void* sha1, void const* hex)
|
2014-12-04 20:53:56 +00:00
|
|
|
{
|
2017-04-19 12:04:45 +00:00
|
|
|
tr_hex_to_binary(hex, sha1, SHA_DIGEST_LENGTH);
|
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 */
|