I am doing serialization of a structure in C but I am having a problem which I can figure it out:s The code is a bit long but I think it is ok to understand.
This is the top level structure I am trying to serialize:
typedef struct
{
uint8_t protocol_version;
ContentType signed_content_type;
signedDATA signed_data;
}data1609Dot2SignData;
Contentype and signedDATA are other structures as defined bellow:
typedef enum
{
UNSECURED,
SIGNED,
ENCRYPTED,
CERTIFICATE_REQUEST,
CERTIFICATE_RESPONSE,
ANONYMOUS_CERTIFICATE_RESPONSE,
CERTIFICATE_REQUEST_ERROR,
CRL_REQUEST,
CRL,
SIGNED_PARTIAL_PAYLOAD,
SIGNED_EXTERNAL_PAYLOAD,
SIGNED_WSA,
CERTIFICATE_RESPONSE_ACKNOWLEDGMENT
}ContentType;
typedef struct
{
ToBeSignedDATA unsigned_data;
Signature signature;
}signedDATA;
typedef struct
{
Psid psid;
octet_string data;
}ToBeSignedDATA;
typedef uint32_t Psid;
typedef struct {
uint32_t length;
char* content;
} octet_string;
typedef struct
{
PKAlgorithm algorithm;
ECDSA_SIG* sig;
}Signature;
typedef enum
{
ECDSA_NISTP224_WITH_SHA224,
ECDSA_NISTP256_WITH_SHA256,
ECIES_NISTP256
}PKAlgorithm;
I created 2 functions one to serialize and another to deserialize:
int serialize1609Dot2DATA(data1609Dot2SignData x,char** buffer)
{
//printf(" Serialize: (sig->r, sig->s): (%s,%s)\n", BN_bn2hex(x.signed_data.signature.sig->r), BN_bn2hex(x.signed_data.signature.sig->s));
// load of text file to buffer. //
char* cert_buffer = 0;
cert_buffer = NULL;
int certificate_length = 0;
FILE* f = fopen("ecdsa256.crt", "r");
if(f)
{
fseek(f,0,SEEK_END);
certificate_length = ftell(f);
fseek(f,0,SEEK_SET);
cert_buffer = calloc(1, certificate_length);
if(cert_buffer)
{
fread(cert_buffer, 1, certificate_length, f);
}
fclose(f);
}
// end.
uint32_t msg_data_len = x.signed_data.unsigned_data.data.length; // size of data.
char* sig_big_num_r;
char* sig_big_num_s;
int size_sig_r, size_sig_s = 0;
sig_big_num_r = BN_bn2hex(x.signed_data.signature.sig->r);
sig_big_num_s = BN_bn2hex(x.signed_data.signature.sig->s);
size_sig_r = strlen(sig_big_num_r);
size_sig_s = strlen(sig_big_num_s);
int serialize_size = 0;
serialize_size = certificate_length + sizeof(x.protocol_version) + sizeof(x.signed_content_type) + size_sig_r + size_sig_s + sizeof(x.signed_data.signature.algorithm) + sizeof(x.signed_data.unsigned_data.psid) + msg_data_len + sizeof(uint32_t);
*buffer = 0;
*buffer = calloc(1, sizeof(char)*serialize_size);
if(*buffer)
{
size_t offset = 0;
memcpy(*buffer+offset, &x.signed_data.unsigned_data.data.length, sizeof(uint32_t)); // size of the data field.
offset += sizeof(uint32_t);
memcpy(*buffer+offset, &x.protocol_version, sizeof(x.protocol_version)); // protocol version
offset += sizeof(x.protocol_version);
memcpy(*buffer+offset, &x.signed_content_type, sizeof(x.signed_content_type)); // signed content type
offset += sizeof(x.signed_content_type);
strcpy(*buffer+offset, sig_big_num_r); // Sig r
offset += size_sig_r;
strcpy(*buffer+offset, sig_big_num_s); // Sig s
offset += size_sig_s;
memcpy(*buffer+offset, &x.signed_data.signature.algorithm, sizeof(x.signed_data.signature.algorithm)); // algorithm
offset += sizeof(x.signed_data.signature.algorithm);
memcpy(*buffer+offset, &x.signed_data.unsigned_data.psid, sizeof(x.signed_data.unsigned_data.psid)); // PSID
offset += sizeof(x.signed_data.unsigned_data.psid);
memcpy(*buffer+offset, cert_buffer, certificate_length); // certificate buffer(buffer of the text file) is set here.
offset += certificate_length;
memcpy(*buffer+offset, x.signed_data.unsigned_data.data.content, x.signed_data.unsigned_data.data.length); // data.
offset += msg_data_len;
}
OPENSSL_free(sig_big_num_r);
OPENSSL_free(sig_big_num_s);
return serialize_size;
}
and:
data1609Dot2SignData* deserialize1609Dot2DATA(char* serialdata)
{
data1609Dot2SignData* y = 0;
y = malloc(sizeof(data1609Dot2SignData));
if(y)
{
size_t offset = 0;
memcpy(&y->signed_data.unsigned_data.data.length, (serialdata + offset), sizeof(uint32_t));
offset += sizeof(uint32_t);
uint32_t data_len = y->signed_data.unsigned_data.data.length;
// printf("DATA LEN in DESERIALIZED 1609dot2 function: %d\n", data_len);
memcpy(&y->protocol_version, (serialdata + offset), sizeof(y->protocol_version));
offset += sizeof(y->protocol_version);
//printf("Protocol_version in DESERIALIZED 1609dot2 function: %d\n", y->protocol_version);
memcpy(&y->signed_content_type, (serialdata + offset), sizeof(y->signed_content_type));
offset += sizeof(y->signed_content_type);
// printf("Signed content type in DESERIALIZED 1609dot2 function: %d\n", y->signed_content_type);
//y->signed_data.signature.sig->r = malloc(32);
char* tmp_sig_r = calloc(1, 64);
char* tmp_sig_s = calloc(1, 64);
ECDSA_SIG* sig = calloc(1, 128);
BIGNUM* big_r = calloc(1, 64);
BIGNUM* big_s = calloc(1, 64);
memcpy(tmp_sig_r, (serialdata + offset), 64);
offset += 64; //
BN_hex2bn(&big_r, tmp_sig_r);
// y->signed_data.signature.sig->r= big_r;
// printf("SIZE R: %d\n", r);
sig->r = big_r;
memcpy(tmp_sig_s, (serialdata + offset), 64);
offset += 64;
BN_hex2bn(&big_s, tmp_sig_s);
// printf("SIZE S: %d\n", s);
sig->s = big_s;
y->signed_data.signature.sig = sig;
// printf(" Deserialize: (sig->r, sig->s): (%s,%s)\n",tmp_sig_r ,tmp_sig_s);
memcpy(&y->signed_data.signature.algorithm, (serialdata + offset), sizeof(y->signed_data.signature.algorithm));
offset += sizeof(y->signed_data.signature.algorithm);
// printf("Algorithm in DESERIALIZED 1609dot2 function: %d\n", y->signed_data.signature.algorithm);
memcpy(&y->signed_data.unsigned_data.psid, (serialdata + offset), sizeof(y->signed_data.unsigned_data.psid));
offset += sizeof(y->signed_data.unsigned_data.psid);
// printf("PSID in DESERIALIZED 1609dot2 function: %d\n", y->signed_data.unsigned_data.psid);
char* certificate_buffer = calloc(1, 956);
memcpy(certificate_buffer, (serialdata + offset), 956);
offset += 956;
// write the buffer with the data back to a text file:
size_t size_cert = 956;
FILE* out = fopen("output.crt", "w");
fwrite(certificate_buffer, 1, size_cert, out);
y->signed_data.unsigned_data.data.content = malloc(y->signed_data.unsigned_data.data.length);
memcpy(y->signed_data.unsigned_data.data.content, (serialdata + offset), y->signed_data.unsigned_data.data.length); // msg data.
offset += y->signed_data.unsigned_data.data.length;
fclose(out);
free(certificate_buffer);
free(tmp_sig_r);
free(tmp_sig_s);
}
return y;
}
I'm having problems when I had the serialization and de-serialization of the file I am trying to serialize. If I take it out everything works ok, otherwise I get bad de-serialized values:s In the Des-serialization I assigning the size of the buffer to 956, because I know this size will always be fixed and the file will have always the same amount of data and it is always the same file.
I have been over hours looking over this and I can't find out the mistake:s
Thanks Best Regards