1

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

4

0 回答 0