0
我正在做一個C語言結構的序列化,但我遇到了一個問題,我可以弄明白:s代碼有點長,但我認爲理解是可以的。帶有OPENSSL簽名的結構序列化
這是我試圖序列頂層結構:
typedef struct
{
uint8_t protocol_version;
ContentType signed_content_type;
signedDATA signed_data;
}data1609Dot2SignData;
Contentype和簽名數據是如波紋管所形成的其它結構:
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種功能的一個到另一個序列化和反序列化:
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;
}
我在desserialize函數中的函數BN_hex2_bn上發生了Segmentation錯誤。我已經對代碼進行了評論。我不明白爲什麼我只在分配sig-> s而不是在sig-> r中得到這個錯誤。我已經堅持了幾個星期:希望有人能幫助我。
我已經嘗試過了,但它是不是也工作:■我用gdb,我得到BN_set_word(),我認爲它是從BN_hex2bn()函數調用的一個錯誤。 – mmm 2013-05-07 12:58:06
嘗試在sig結構中使用memset或在調用BN_hex2bn之前直接將NULL指定給r和s。 – Lucas 2013-05-07 14:18:16
問題出在你說的,與內存分配有關,在分配之後,代碼編譯正確。非常感謝。 – mmm 2013-05-08 13:39:51