#c
#c
Вопрос:
Имея этот код:
typedef struct {
struct {
uint64_t key;
uint64_t mac;
uint64_t orig;
uint64_t body;
} length;
} secure_head_t;
typedef char *secure_t;
secure_t *secure_alloc(uint64_t key, uint64_t mac, uint64_t orig, uint64_t body) {
secure_t *cryptex = (secure_t*)malloc(sizeof(secure_head_t) key mac body);
secure_head_t *head = (secure_head_t *)cryptex;
head->length.key = key;
head->length.mac = mac;
head->length.orig = orig;
head->length.body = body;
return cryptex;
}
Я хочу преобразовать secure_t
в char *
,
что-то вроде: char *str = secure_t *text;
Я пробовал это:
secure_head_t *head = (secure_head_t *)securetext;
char frame[sizeof(secure_head_t)];
memcpy(frame, amp;head, sizeof(secure_head_t));
Но это работает не каждый раз, и иногда это не может быть скопировано. Пожалуйста, покажите, как я должен ее правильно скопировать. Все, что я хочу, это преобразовать secure_t*
в char*
и обратно из char*
в secure_t*
.
Обновить:
Я хочу превратить блок (ы) данных, зашифрованных с помощью ECDHA с использованием OpenSSL 1.0.2, в двоичный буфер для последующего дешифрования. Минимальное значение блока данных составляет 1 КБ, а максимальный — 1 МБ. Я могу контролировать весь процесс, я использую его для изучения асимметричного и симметричного шифрования.
Вот подробный код:
void Encryption(UnicodeString PlainText)
{
srand(time(NULL));
int tlen;
size_t olen;
EC_KEY *key = NULL;
secure_t *ciphered = NULL;
char *hex_pub = NULL, *hex_priv = NULL;
char *text = NULL;
tlen = PlainText.Length();
text = new char [tlen];
WideCharToMultiByte(CP_ACP, 0, PlainText.c_str(), wcslen(PlainText.c_str()) 1, text , sizeof(char)*tlen, NULL, NULL);
// Generate a key for our theoretical user.
if (!(key = ecies_key_create()))
{
printf("Key creation failed.n");
}
// Since we'll store the keys as hex values in reali life, extract the appropriate hex values and release the original key structure.
if (!(hex_pub = ecies_key_public_get_hex(key)) || !(hex_priv = ecies_key_private_get_hex(key)))
{
printf("Serialization of the key to a pair of hex strings failed.n");
}
//saving keys
KeyPriv = AnsiString(hex_priv);
KeyPub = AnsiString(hex_pub);
if (!(ciphered = ecies_encrypt(hex_pub, text, tlen)))
{
printf("The encryption process failed!n");
}
secure_head_t *head = (secure_head_t *)ciphered;
char frame[sizeof(secure_head_t )];
memcpy(frame, amp;head, sizeof(secure_head_t *));
CipherText = frame;
}
void Decrypt(AnsiString CipherText)
{
size_t olen;
EC_KEY *key = NULL;
secure_t *ciphered = NULL;
char *hex_pub = NULL, *hex_priv = NULL;
unsigned char *text = NULL, *copy = NULL, *original = NULL;
secure_head_t *head = new secure_head_t;
memcpy(amp;head, CipherText.c_str(), sizeof(char)*CipherText.Length());
secure_t *cryptex = (secure_t*)head;
hex_priv = KeyPriv.c_str();
if(!(original = ecies_decrypt(hex_priv, cryptex, amp;olen)))
{
printf("The decryption process failed!n");
}
PlainText = AnsiString((char*)original);
}
Приведенный выше код работает, но иногда нет, и я не отправляю строки длиной < 25.
Другой код можно увидеть ниже, кроме кода OpenSSL
ecies.h
------------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//#include <inttypes.h>
#include<stdint.h>
#include <openssl/ssl.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/stack.h>
#define ECIES_CURVE NID_secp521r1
#define ECIES_CIPHER EVP_aes_256_cbc()
#define ECIES_HASHER EVP_sha512()
//EC_GROUP *eliptic = NULL;
typedef struct {
struct {
uint64_t key;
uint64_t mac;
uint64_t orig;
uint64_t body;
} length;
} secure_head_t;
typedef char* secure_t;
void secure_free(secure_t *cryptex);
void * secure_key_data(secure_t *cryptex);
void * secure_mac_data(secure_t *cryptex);
void * secure_body_data(secure_t *cryptex);
uint64_t secure_key_length(secure_t *cryptex);
uint64_t secure_mac_length(secure_t *cryptex);
uint64_t secure_body_length(secure_t *cryptex);
uint64_t secure_orig_length(secure_t *cryptex);
uint64_t secure_total_length(secure_t *cryptex);
secure_t * secure_alloc(uint64_t key, uint64_t mac, uint64_t orig, uint64_t body);
void ecies_group_init(void);
void ecies_group_free(void);
EC_GROUP * ecies_group(void);
void ecies_key_free(EC_KEY *key);
EC_KEY * ecies_key_create(void);
EC_KEY * ecies_key_create_public_hex(char *hex);
EC_KEY * ecies_key_create_private_hex(char *hex);
EC_KEY * ecies_key_create_public_octets(unsigned char *octets, size_t length);
char * ecies_key_public_get_hex(EC_KEY *key);
char * ecies_key_private_get_hex(EC_KEY *key);
secure_t * ecies_encrypt(char *key, unsigned char *data, size_t length);
unsigned char * ecies_decrypt(char *key, secure_t *cryptex, size_t *length);
------------------------------------------------------------------------------
**secure.c**
------------------------------------------------------------------------------
#include "ecies.h"
uint64_t secure_key_length(secure_t *cryptex) {
secure_head_t *head = (secure_head_t *)cryptex;
return head->length.key;
}
uint64_t secure_mac_length(secure_t *cryptex) {
secure_head_t *head = (secure_head_t *)cryptex;
return head->length.mac;
}
uint64_t secure_body_length(secure_t *cryptex) {
secure_head_t *head = (secure_head_t *)cryptex;
return head->length.body;
}
uint64_t secure_orig_length(secure_t *cryptex) {
secure_head_t *head = (secure_head_t *)cryptex;
return head->length.orig;
}
uint64_t secure_total_length(secure_t *cryptex) {
secure_head_t *head = (secure_head_t *)cryptex;
return sizeof(secure_head_t) (head->length.key head->length.mac
head->length.body);
}
void * secure_key_data(secure_t *cryptex) {
return (char *)cryptex sizeof(secure_head_t);
}
void * secure_mac_data(secure_t *cryptex) {
secure_head_t *head = (secure_head_t *)cryptex;
return (char *)cryptex (sizeof(secure_head_t) head->length.key);
}
void * secure_body_data(secure_t *cryptex) {
secure_head_t *head = (secure_head_t *)cryptex;
return (char *)cryptex (sizeof(secure_head_t) head->length.key
head->length.mac);
}
secure_t * secure_alloc(uint64_t key, uint64_t mac, uint64_t orig, uint64_t body) {
secure_t *cryptex = (secure_t*)malloc(sizeof(secure_head_t) key mac body);
secure_head_t *head = (secure_head_t *)cryptex;
head->length.key = key;
head->length.mac = mac;
head->length.orig = orig;
head->length.body = body;
return cryptex;
}
void secure_free(secure_t *cryptex) {
free(cryptex);
return;
}
------------------------------------------------------------------------------
ecies.c
-------------------------------------------------------------------------------
#include "ecies.h"
#include <openssl/keys.c>
#include <openssl/secure.c>
/*
void ecies_group_free(void) {
EC_GROUP *group = eliptic;
eliptic = NULL;
if (group) {
EC_GROUP_free(group);
}
return;
} */
void * ecies_key_derivation(const void *input, size_t ilen, void *output,
size_t *olen) {
if (*olen < SHA512_DIGEST_LENGTH) {
return NULL;
}
*olen = SHA512_DIGEST_LENGTH;
return SHA512((unsigned char*)input, ilen, (unsigned char*)output);
}
secure_t * ecies_encrypt(char *key, unsigned char *data, size_t length) {
unsigned char *body;
HMAC_CTX hmac;
int body_length;
secure_t *cryptex;
EVP_CIPHER_CTX cipher;
unsigned int mac_length;
EC_KEY *user, *ephemeral;
size_t envelope_length, block_length, key_length;
unsigned char envelope_key[SHA512_DIGEST_LENGTH], iv[EVP_MAX_IV_LENGTH], block[EVP_MAX_BLOCK_LENGTH];
// Simple sanity check.
if (!key || !data || !length) {
//printf("Invalid parameters passed in.n");
MessageBox ( NULL,L"Invalid parameters passed in.n" ,L"Error", MB_OK );
return NULL;
}
// Make sure we are generating enough key material for the symmetric ciphers.
if ((key_length = EVP_CIPHER_key_length(ECIES_CIPHER)) * 2 > SHA512_DIGEST_LENGTH) {
//printf("The key derivation method will not produce enough envelope key material for the chosen ciphers. {envelope = %i / required = %zu}", SHA512_DIGEST_LENGTH / 8,(key_length * 2) / 8);
MessageBox ( NULL,L"The key derivation method will not produce enough envelope key material for the chosen ciphers. " ,L"Error", MB_OK );
return NULL;
}
// Convert the user's public key from hex into a full EC_KEY structure.
if (!(user = ecies_key_create_public_hex(key))) {
//printf("Invalid public key provided.n");
MessageBox ( NULL,L"Invalid public key provided" ,L"Error", MB_OK );
return NULL;
}
// Create the ephemeral key used specifically for this block of data.
else if (!(ephemeral = ecies_key_create())) {
//printf("An error occurred while trying to generate the ephemeral key.n");
MessageBox ( NULL,L"An error occurred while trying to generate the ephemeral key" ,L"Error", MB_OK );
EC_KEY_free(user);
return NULL;
}
// Use the intersection of the provided keys to generate the envelope data used by the ciphers below. The ecies_key_derivation() function uses
// SHA 512 to ensure we have a sufficient amount of envelope key material and that the material created is sufficiently secure.
else if (ECDH_compute_key(envelope_key, SHA512_DIGEST_LENGTH, EC_KEY_get0_public_key(user), ephemeral, ecies_key_derivation) !=
SHA512_DIGEST_LENGTH) {
//printf("An error occurred while trying to compute the envelope key. {error = %s}n", ERR_error_string(ERR_get_error(), NULL));
MessageBox ( NULL,L"An error occurred while trying to compute the envelope key" ,L"Error", MB_OK );
EC_KEY_free(ephemeral);
EC_KEY_free(user);
return NULL;
}
// Determine the envelope and block lengths so we can allocate a buffer for the result.
else if ((block_length = EVP_CIPHER_block_size(ECIES_CIPHER)) == 0 || block_length > EVP_MAX_BLOCK_LENGTH ||
(envelope_length = EC_POINT_point2oct(EC_KEY_get0_group(ephemeral), EC_KEY_get0_public_key(ephemeral),
POINT_CONVERSION_COMPRESSED, NULL, 0, NULL)) == 0) {
//printf("Invalid block or envelope length. {block = %zu /envelope = %zu}n", block_length, envelope_length);
MessageBox ( NULL,L"Invalid block or envelope length" ,L"Error", MB_OK );
EC_KEY_free(ephemeral);
EC_KEY_free(user);
return NULL;
}
// We use a conditional to pad the length if the input buffer is notevenly divisible by the block size.
else if (!(cryptex = secure_alloc(envelope_length, EVP_MD_size(ECIES_HASHER), length, length (length % block_length ? (block_length - (length % block_length)) : 0)))) {
//printf("Unable to allocate a secure_t buffer to hold the encrypted result.n");
MessageBox ( NULL,L"Unable to allocate a secure_t buffer to hold the encrypted result" ,L"Error", MB_OK );
EC_KEY_free(ephemeral);
EC_KEY_free(user);
return NULL;
}
// Store the public key portion of the ephemeral key.
else if (EC_POINT_point2oct(EC_KEY_get0_group(ephemeral), EC_KEY_get0_public_key(ephemeral), POINT_CONVERSION_COMPRESSED, (unsigned char*)secure_key_data(cryptex), envelope_length, NULL) != envelope_length) {
//printf("An error occurred while trying to record the public portion of the envelope key. {error = %s}n", ERR_error_string(ERR_get_error(), NULL));
MessageBox ( NULL,L"An error occurred while trying to record the public portion of the envelope key" ,L"Error", MB_OK );
EC_KEY_free(ephemeral);
EC_KEY_free(user);
secure_free(cryptex);
return NULL;
}
// The envelope key has been stored so we no longer need to keep the keys around.
EC_KEY_free(ephemeral);
EC_KEY_free(user);
// For now we use an empty initialization vector.
memset(iv, 0, EVP_MAX_IV_LENGTH);
// Setup the cipher context, the body length, and store a pointer to the body buffer location.
EVP_CIPHER_CTX_init(amp;cipher);
body = (unsigned char*)secure_body_data(cryptex);
body_length = secure_body_length(cryptex);
// Initialize the cipher with the envelope key.
if (EVP_EncryptInit_ex(amp;cipher, ECIES_CIPHER, NULL, envelope_key, iv) != 1 || EVP_CIPHER_CTX_set_padding(amp;cipher, 0) != 1 || EVP_EncryptUpdate(amp;cipher, (unsigned char*)body, amp;body_length, data, length - (length % block_length)) != 1) {
//printf("An error occurred while trying to secure the data using the chosen symmetric cipher. {error = %s}n", ERR_error_string(ERR_get_error(), NULL));
MessageBox ( NULL,L"An error occurred while trying to secure the data using the chosen symmetric cipher." ,L"Error", MB_OK );
EVP_CIPHER_CTX_cleanup(amp;cipher);
secure_free(cryptex);
return NULL;
}
// Check whether all of the data was encrypted. If they don't match up, we either have a partial block remaining, or an error occurred.
else if (body_length != length) {
// Make sure all that remains is a partial block, and their wasn't an error.
if (length - body_length >= block_length) {
//printf("Unable to secure the data using the chosen symmetric cipher. {error = %s}n", ERR_error_string(ERR_get_error(), NULL));
MessageBox ( NULL,L"Unable to secure the data using the chosen symmetric cipher.." ,L"Error", MB_OK );
EVP_CIPHER_CTX_cleanup(amp;cipher);
secure_free(cryptex);
return NULL;
}
// Copy the remaining data into our partial block buffer. The memset() call ensures any extra bytes will be zero'ed out.
memset(block, 0, EVP_MAX_BLOCK_LENGTH);
memcpy(block, data body_length, length - body_length);
// Advance the body pointer to the location of the remaining space, and calculate just how much room is still available.
body = body_length;
if ((body_length = secure_body_length(cryptex) - body_length) < 0) {
//printf("The symmetric cipher overflowed!n");
MessageBox ( NULL,L"The symmetric cipher overflowed!" ,L"Error", MB_OK );
EVP_CIPHER_CTX_cleanup(amp;cipher);
secure_free(cryptex);
return NULL;
}
// Pass the final partially filled data block into the cipher as a complete block. The padding will be removed during the decryption process.
else if (EVP_EncryptUpdate(amp;cipher, body, amp;body_length, block, block_length) != 1) {
//printf("Unable to secure the data using the chosen symmetric cipher. {error = %s}n", ERR_error_string(ERR_get_error(), NULL));
MessageBox ( NULL,L"Unable to secure the data using the chosen symmetric cipher." ,L"Error", MB_OK );
EVP_CIPHER_CTX_cleanup(amp;cipher);
secure_free(cryptex);
return NULL;
}
}
// Advance the pointer, then use pointer arithmetic to calculate how much of the body buffer has been used. The complex logic is needed so that we get
// the correct status regardless of whether there was a partial data block.
body = body_length;
if ((body_length = secure_body_length(cryptex) - (body - (unsigned char*)secure_body_data(cryptex))) < 0) {
//printf("The symmetric cipher overflowed!n");
MessageBox ( NULL,L"The symmetric cipher overflowed!" ,L"Error", MB_OK );
EVP_CIPHER_CTX_cleanup(amp;cipher);
secure_free(cryptex);
return NULL;
}
else if (EVP_EncryptFinal_ex(amp;cipher, body, amp;body_length) != 1) {
//printf("Unable to secure the data using the chosen symmetric cipher. {error = %s}n", ERR_error_string(ERR_get_error(), NULL));
MessageBox ( NULL,L"Unable to secure the data using the chosen symmetric cipher" ,L"Error", MB_OK );
EVP_CIPHER_CTX_cleanup(amp;cipher);
secure_free(cryptex);
return NULL;
}
EVP_CIPHER_CTX_cleanup(amp;cipher);
// Generate an authenticated hash which can be used to validate the data during decryption.
HMAC_CTX_init(amp;hmac);
mac_length = secure_mac_length(cryptex);
// At the moment we are generating the hash using encrypted data. At some point we may want to validate the original text instead.
if (HMAC_Init_ex(amp;hmac, envelope_key key_length, key_length, ECIES_HASHER, NULL) != 1 || HMAC_Update(amp;hmac, (unsigned char*)secure_body_data(cryptex), secure_body_length(cryptex))
!= 1 || HMAC_Final(amp;hmac, (unsigned char*)secure_mac_data(cryptex), amp;mac_length) != 1) {
//printf("Unable to generate a data authentication code. {error = %s}n", ERR_error_string(ERR_get_error(), NULL));
MessageBox ( NULL,L"Unable to generate a data authentication code." ,L"Error", MB_OK );
HMAC_CTX_cleanup(amp;hmac);
secure_free(cryptex);
return NULL;
}
HMAC_CTX_cleanup(amp;hmac);
return cryptex;
}
unsigned char * ecies_decrypt(char *key, secure_t *cryptex, size_t *length) {
HMAC_CTX hmac;
size_t key_length;
int output_length;
EVP_CIPHER_CTX cipher;
EC_KEY *user, *ephemeral;
unsigned int mac_length = EVP_MAX_MD_SIZE;
unsigned char envelope_key[SHA512_DIGEST_LENGTH], iv[EVP_MAX_IV_LENGTH], md[EVP_MAX_MD_SIZE], *block, *output;
// Simple sanity check.
if (!key || !cryptex || !length) {
//printf("Invalid parameters passed in.n");
MessageBox ( NULL,L"Invalid parameters passed in." ,L"Error", MB_OK );
return NULL;
}
// Make sure we are generating enough key material for the symmetric ciphers.
else if ((key_length = EVP_CIPHER_key_length(ECIES_CIPHER)) * 2 > SHA512_DIGEST_LENGTH) {
//printf("The key derivation method will not produce enough envelope key material for the chosen ciphers. {envelope = %i / required = %zu}", SHA512_DIGEST_LENGTH / 8, (key_length * 2) / 8);
MessageBox ( NULL,L"The key derivation method will not produce enough envelope key material for the chosen ciphers" ,L"Error", MB_OK );
return NULL;
}
// Convert the user's public key from hex into a full EC_KEY structure.
else if (!(user = ecies_key_create_private_hex(key))) {
//printf("Invalid private key provided.n");
MessageBox ( NULL,L"Invalid private key provided" ,L"Error", MB_OK );
return NULL;
}
// Create the ephemeral key used specifically for this block of data.
else if (!(ephemeral =
ecies_key_create_public_octets((unsigned char*)secure_key_data(cryptex), secure_key_length(cryptex)))) {
//printf("An error occurred while trying to recreate the ephemeral key.n");
MessageBox ( NULL,L"An ssssserror occurred while trying to recreate the ephemeral key" ,L"Error", MB_OK );
EC_KEY_free(user);
return NULL;
}
// Use the intersection of the provided keys to generate the envelope data used by the ciphers below. The ecies_key_derivation() function uses
// SHA 512 to ensure we have a sufficient amount of envelope key material and that the material created is sufficiently secure.
else if (ECDH_compute_key(envelope_key, SHA512_DIGEST_LENGTH, EC_KEY_get0_public_key(ephemeral), user, ecies_key_derivation) != SHA512_DIGEST_LENGTH) {
//printf("An error occurred while trying to compute the envelope key. {error = %s}n", ERR_error_string(ERR_get_error(), NULL));
MessageBox ( NULL,L"An error occurred while trying to compute the envelope key." ,L"Error", MB_OK );
EC_KEY_free(ephemeral);
EC_KEY_free(user);
return NULL;
}
// The envelope key material has been extracted, so we no longer need the user and ephemeral keys.
EC_KEY_free(ephemeral);
EC_KEY_free(user);
// Use the authenticated hash of the ciphered data to ensure it was not modified after being encrypted.
HMAC_CTX_init(amp;hmac);
// At the moment we are generating the hash using encrypted data. At some point we may want to validate the original text instead.
if (HMAC_Init_ex(amp;hmac, envelope_key key_length, key_length, ECIES_HASHER, NULL) != 1 || HMAC_Update(amp;hmac, (unsigned char*)secure_body_data(cryptex),
secure_body_length(cryptex))
!= 1 || HMAC_Final(amp;hmac, md, amp;mac_length) != 1) {
//printf("Unable to generate the authentication code needed for validation. {error = %s}n", ERR_error_string(ERR_get_error(), NULL));
MessageBox ( NULL,L"Unable to generate the authentication code needed for validation." ,L"Error", MB_OK );
HMAC_CTX_cleanup(amp;hmac);
return NULL;
}
HMAC_CTX_cleanup(amp;hmac);
// We can use the generated hash to ensure the encrypted data was not altered after being encrypted.
if (mac_length != secure_mac_length(cryptex) || memcmp(md,
secure_mac_data(cryptex), mac_length)) {
//printf("The authentication code was invalid! The ciphered data has been corrupted!n");
MessageBox ( NULL,L"The authentication code was invalid! The ciphered data has been corrupted" ,L"Error", MB_OK );
return NULL;
}
// Create a buffer to hold the result.
output_length = secure_body_length(cryptex);
if (!(block = output = (unsigned char*)malloc(output_length 1))) {
//printf("An error occurred while trying to allocate memory for the decrypted data.n");
MessageBox ( NULL,L"An error occurred while trying to allocate memory for the decrypted data" ,L"Error", MB_OK );
return NULL;
}
// For now we use an empty initialization vector. We also clear out the result buffer just to be on the safe side.
memset(iv, 0, EVP_MAX_IV_LENGTH);
memset(output, 0, output_length 1);
EVP_CIPHER_CTX_init(amp;cipher);
// Decrypt the data using the chosen symmetric cipher.
if (EVP_DecryptInit_ex(amp;cipher, ECIES_CIPHER, NULL, envelope_key, iv)
!= 1 || EVP_CIPHER_CTX_set_padding(amp;cipher, 0) != 1 ||
EVP_DecryptUpdate(amp;cipher, block,
amp;output_length, (unsigned char*)secure_body_data(cryptex),
secure_body_length(cryptex)) != 1) {
//printf("Unable to decrypt the data using the chosen symmetric cipher. {error = %s}n", ERR_error_string(ERR_get_error(), NULL));
MessageBox ( NULL,L"Unable to decrypt the data using the chosen symmetric cipher." ,L"Error", MB_OK );
EVP_CIPHER_CTX_cleanup(amp;cipher);
free(output);
return NULL;
}
block = output_length;
if ((output_length = secure_body_length(cryptex) - output_length) != 0)
{
//printf("The symmetric cipher failed to properly decrypt the correct amount of data!n");
MessageBox ( NULL,L"The symmetric cipher failed to properly decrypt the correct amount of data" ,L"Error", MB_OK );
EVP_CIPHER_CTX_cleanup(amp;cipher);
free(output);
return NULL;
}
if (EVP_DecryptFinal_ex(amp;cipher, block, amp;output_length) != 1) {
//printf("Unable to decrypt the data using the chosen symmetric cipher. {error = %s}n", ERR_error_string(ERR_get_error(), NULL));
MessageBox ( NULL,L"Unable to decrypt the data using the chosen symmetric cipher." ,L"Error", MB_OK );
EVP_CIPHER_CTX_cleanup(amp;cipher);
free(output);
return NULL;
}
EVP_CIPHER_CTX_cleanup(amp;cipher);
*length = secure_orig_length(cryptex);
return output;
}
Комментарии:
1. Это похоже на код на языке Си. Разыменование указателя
head
является неопределенным поведением в C , когда чтение изamp;head
будет пытаться прочитатьsizeof(secure_head_t)
байты, в то время как указатель указывает на буфер изsizeof(secure_head_t *)
байтов.2. @VTT Хорошо, но почему проголосовали против ?
3. вам нужно написать свои собственные процедуры сортировки / разархивирования, чтобы переходить туда и обратно из
secure_head_t
иchar *
4. ваше использование двойного указателя неверно, и ваш malloc выделяет неправильный размер блока, если
key mac orig
значение 0 не равно, см. Мой ответ.5. Вам нужно уточнить несколько вещей: каков именно формат символьного или двоичного буфера, который вы пытаетесь создать? Вы контролируете ее формат? Кто будет потреблять / использовать этот буфер? (Также: похоже, что вы создаете заголовок плюс двоичный фрагмент данных в одном буфере, это то, что происходит?)
Ответ №1:
Структура secure_head_t
содержит только целые числа, без указателей, поэтому при условии, что вы остаетесь на том же компьютере / компиляторе опции, вы можете рассматривать (приводить) указатель на secure_head_t
как указатель на sizeof(secure_head_t)
символы и наоборот без каких-либо проблем. В противном случае сохраните / упорядочьте 4 целых числа в качестве их внешних форм с помощью sprintf или эквивалента и прочитайте / разархивируйте их с помощью scanf или эквивалента.
Я призываю вас никогда не скрывать указатель через typedef, поэтому не определяйте, typedef char* secure_t;
но используйте char*
.
Ваш код выделяет и инициализирует, а затем возвращает a secure_head_t
поэтому использование secure_t *
значения a char **
не имеет смысла, потому что это не указатель на указатель. Возможно, вы вообразили это, потому что структура содержит struct, но struct не содержит указателя на struct, поэтому нет двух уровней указателя.
Здесь у вас тоже есть проблема :
malloc(sizeof(secure_head_t) key mac body);
поскольку вы просите выделить часть памяти, выбранный размер зависит от значения ключа и mac и body, и это не то, что вы хотите, потому что вы выделите большой блок памяти даром и, возможно, не сможете выполнить выделение, потому что требуется огромный размер, просто сделайте
secure_head_t * head = malloc(sizeof(secure_head_t));
head->length.key = key;
head->length.mac = mac;
head->length.orig = orig;
head->length.body = body;
return (char *) head;
даже странно говорить, что вы возвращаете char *
, а не a secure_head_t *
, потому что потеря реального типа никогда не бывает хорошей вещью