2013-05-07 7 views
0

Я делаю сериализацию структуры в C, но у меня есть проблема, которую я могу понять: s Код немного длинный, но я думаю, что это нормально понимать.Сериализация структуры с помощью подписей OPENSSL

Это структура высшего уровня Я пытаюсь сериализации:

typedef struct 
{ 
    uint8_t protocol_version; 
    ContentType signed_content_type; 
    signedDATA signed_data; 
}data1609Dot2SignData; 

Contentype и SignedData другие структуры, как определено ниже:

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; 

Я создал 2 функции один сериализовать и другое 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)); 

    const size_t msg_data_len = x.signed_data.unsigned_data.data.length; // size of data. 

    char* sig_big_num_r; 
    char* sig_big_num_s; 

    unsigned char* to_r; 
    unsigned char* to_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); 

    printf("Size of converted signature r: %d\n", size_sig_r); 
    printf("Size of converted signature s: %d\n", size_sig_s); 

    printf("Data sig r: %s\n", sig_big_num_r); 
    printf("Data sig s: %s\n", sig_big_num_s); 
    int serialize_size = 0; 
    serialize_size = 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); 
// an adicional sizeof(uint32_t) is added to store the size of the data. 
    *buffer = malloc(sizeof(char)*serialize_size); 

    if(*buffer) 
    { 
     size_t offset = 0; 

     memcpy(*buffer+offset, &msg_data_len, sizeof(size_t));  // size of the data field is stored here. 
     offset += sizeof(size_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, &x.signed_data.unsigned_data.data.content, msg_data_len);  // data. 
     offset += msg_data_len;  
    } 
    return serialize_size; 
} 

, и это моя функциональность desserialize n:

data1609Dot2SignData* deserialize1609Dot2DATA(char* serialdata) 
{ 
    data1609Dot2SignData* y = 0; 

    y = malloc(sizeof(data1609Dot2SignData)); // must be the size of thebuffer? 

    if(y) 
    { 
     size_t offset = 0; 

     memcpy(&y->signed_data.unsigned_data.data.length, (serialdata + offset), sizeof(y->signed_data.unsigned_data.data.length)); 
     offset += sizeof(y->signed_data.unsigned_data.data.length); 

     int 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 = malloc(64); 
     char* tmp_sig_s = malloc(64); 
     ECDSA_SIG* sig; 

     memcpy(tmp_sig_r, (serialdata + offset), 64); 
     offset += 64; // 
     BN_hex2bn(&sig->r, tmp_sig_r); 

     memcpy(tmp_sig_s, (serialdata + offset), 64); 
     offset += 64; 
     BN_hex2bn(&sig->s, tmp_sig_s);  // SEGMENTATION FAULT HERE. 

     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); 

     y->signed_data.unsigned_data.data.content = malloc(data_len); 
     memcpy(y->signed_data.unsigned_data.data.content, (serialdata + offset), data_len); 
     offset += data_len; 

// printf(" Deserialize: (sig->r, sig->s): (%s,%s)\n", BN_bn2hex(y->signed_data.signature.sig->r), BN_bn2hex(y->signed_data.signature.sig->s)); 
    printf("FINAL\n"); 
    } 
    return y; 
} 

Я получаю ошибку сегментации функции BN_hex2_bn в функции десериализации. Я прокомментировал код. Я не могу понять, почему я получаю эту ошибку только при назначении sig-> s, а не в sig-> r. Я придерживался этого в течение нескольких недель: надеюсь, кто-то может мне помочь.

ответ

1

Не следует использовать ECDSA_SIG sig; вместо ECDSA_SIG * sig; ? Поскольку вы не используете malloc для этого указателя.

Описание функции BN_hex2bn: BN_hex2bn() преобразует строку str, содержащую шестнадцатеричное число, в BIGNUM и сохраняет ее в ** bn. Если * bn равно NULL, создается новый BIGNUM.

Поэтому перед тем, как использовать его, вам необходимо убедиться, что судьба NULL или выделена. попробуйте это:

ECDSA_SIG sig; 

    memset(&sig,0,sizeof(ECDSA_SIG)); 

    memcpy(tmp_sig_r, (serialdata + offset), 64); 
    offset += 64; // 
    BN_hex2bn(&sig.r, tmp_sig_r); 

    memcpy(tmp_sig_s, (serialdata + offset), 64); 
    offset += 64; 
    BN_hex2bn(&sig.s, tmp_sig_s); 
+0

Я пробовал, но он не работает также: s Я использовал GDB, и я получаю сообщение об ошибке на BN_set_word(), который я предположил, что это вызывается из функции BN_hex2bn(). – mmm

+1

попробуйте использовать memset в структуре sig или назначить NULL непосредственно r и s, прежде чем вызывать BN_hex2bn. – Lucas

+0

Проблема была, как вы сказали, связанной с распределением памяти, после того, как она была выделена, код скомпилирован правильно. Огромное спасибо. – mmm

 Смежные вопросы

  • Нет связанных вопросов^_^