OpenSSLのEVP_EncodeBlock()→EVP_DecodeBlock()をやったらハマった話
まぁ四の五の言わずにやってみるといいと思う。
// ----------------
// メイン処理
// ----------------
int main (void)
{
int src_len = 32;
int encode_result = 0;
int decode_result = 0;
int memcmp_result = 0;
unsigned char src_data[64];
unsigned char encoded_data[256];
unsigned char decoded_data[256];
// 元データを'S'で埋める
memset(src_data, 'S', sizeof(src_data));
// エンコードしたデータを格納する領域を'E'で埋める
memset(encoded_data, 'E', sizeof(src_data));
// デコードしたデータを格納する領域を'D'で埋める
memset(decoded_data, 'D', sizeof(decoded_data));
// 元データをBASE64でエンコードした文字列を取得
encode_result = EVP_EncodeBlock(encoded_data, src_data, src_len);
printf("src_data(%d bytes) -> BASE64 ENCODE -> encode_result=%d, encoded_data=%s\n", src_len, encode_result, encoded_data);
// エンコードした文字列を、エンコードした文字列長でデコードしたデータを取得
decode_result = EVP_DecodeBlock(decoded_data, encoded_data, encode_result);
printf("encoded_data(%d bytes) -> BASE64 DECODE -> decode_result=%d\n", encode_result, decode_result);
// 元データとデコードしたデータを、デコード結果の長さで取得
memcmp_result = memcmp(src_data, decoded_data, decode_result);
printf("memcmp(src_data, decoded_data, decode_result) = memcmp_result=%d\n", memcmp_result);
// https://www.openssl.org/docs/manmaster/man3/EVP_EncodeBlock.html
// "EVP_DecodeBlock() returns the length of the data decoded or -1 on error." <- Doubt!
}
上記に必要なヘッダーファイルを#includeしてコンパイルして実行すると、元データとデコードしたデータの長さが合致しない。(0x00が最後に1バイトだけ着くとかいう話でもなく、場合によって追加される長さが変わるので厄介)
これってバグなのか仕様なのか…(OpenSSLのドキュメントをそのまま受け取るならバグのような!?)
詳しい人教えてー。
2021.03.17 追記
再始動するためにググってたら
https://commondatastorage.googleapis.com/chromium-boringssl-docs/base64.h.html
というのも見つかったりして、まぁOpenSSLの方のBASE64はガッチガチで扱いにくいから、みんなあれこれラッピングしたり別の関数を用意したりしているんだな、っていうのはなんとなく理解した。