sha384 アルゴリズムを使用して、スマート カードによって未加工の形式で作成された 96 バイト長の ecdsa 署名があります。これは、2 つの 48 バイト長の整数 r と s で構成されています。ecdsa 署名は、sign_ptr が指すバッファーにあります。この関数 (C) を使用して、生の形式の署名を ASN1 形式の buf_out に変換しています。
int convert_ecdsa_sha384_sign(char **buf_out, char *sign_ptr)
{
buf_out[0]=0x30; /* Type = Sequence of */
buf_out[2]=0x02; /* Type = Integer */
/* Verify if negative bit is set */
if (!(sign_ptr[0] & 0x80))
{
buf_out[3]=0x30; /* Length */
memcpy(&(buf_out[4]), sign_ptr, 48); /* Copy first integer */
}
else
{
/* Negative bit is set. Add one padding byte */
buf_out[3]=0x31; /* Length */
buf_out[4]=0x00; /* Padding */
memcpy(&(buf_out[5]), sign_ptr, 48); /* Copy first integer */
sign_offset += 1;
}
buf_out[52+sign_offset]=0x02; /* Type = Integer */
/* Verify if negative bit is set */
if (!(sign_ptr[48] & 0x80))
{
buf_out[53+sign_offset]=0x30; /* Length */
memcpy(((&(buf_out[54]))+ sign_offset), sign_ptr + 48, 48); /* Copy second integer */
}
else
{
/* Negative bit is set. Add one padding byte */
buf_out[53+sign_offset]=0x31; /* Length */
buf_out[54+sign_offset]=0x00; /* Padding */
memcpy(((&(buf_out[55]))+ sign_offset), sign_ptr + 48, 48); /* Copy second integer */
sign_offset += 1;
}
buf_out[1]= 100 + sign_offset; /* Total signature length */
return 1;
}
よりエレガントな方法でこれを行うのに役立つ同等のopenssl関数があるかどうか疑問に思っていますか? 多くの d2i 関数 (d2i_ASN1_xxxx、ASN1_item_d2i、ASN_d2i_func など) を調べましたが、どれが適しているかは明確ではありません。