Opensslを使用して、リモートサーバーとのTLS接続を確立しています。
コードスニペットは次のとおりです。
if ((ret = SSL_connect(c->ssl)) <= 0) {
ret = SSL_get_error(c->ssl, ret);
if((err = ERR_get_error())) {
SSL_load_error_strings();
ERR_load_crypto_strings();
CRERROR(LOGSSLUTILS, "SSL connect err code:[%lu](%s)\n", err, ERR_error_string(err, NULL));
CRERROR(LOGSSLUTILS, "Error is %s \n",ERR_reason_error_string(err));
}
}
不明な理由でssl_connectが失敗し、ERR_error_stringを使用して理由を特定したい場合、出力は次のとおりです。
SSL connect err code:[336077172] (error:14082174:lib(20):func(130):reason(372))
Error: cmrSSLlInit:174 Error is (null)
ご覧のとおり、エラーコードしか取得できませんが、読み取り可能なエラー文字列は取得できません。
読み取り可能なエラー文字列を取得するにはどうすればよいですか?
不明な理由でssl_connectが失敗し、ERR_error_stringを使用して理由を特定したい場合、出力は次のとおりです。
SSL connect err code:[336077172] (error:14082174:lib(20):func(130):reason(372))
$ openssl errstr 0x14082174
error:14082174:SSL routines:ssl3_check_cert_and_algorithm:dh key too small
DH key too small
の場合、チェックアウト SSL操作がコード1で失敗しました:dhキーが小さすぎます スタックオーバーフロー。つまり、OpenSSLの以前のバージョンは512ビットのDHグループを使用していました。小さすぎるため、2048ビットグループを使用する必要があります。
読み取り可能なエラー文字列を取得するにはどうすればよいですか?
error:14082174:SSL routines:ssl3_check_cert_and_algorithm:dh key too small
のような文字列を記録するには、err_print_errors
およびERR_print_errors_fp
を呼び出すことができると思います。関数はエラースタック全体を出力します。 ERR_print_errors
manページ も参照してください。
すべてのキューに入れられたスレッドのローカルエラーを取得する1つの方法は、提案された以下のスニペットを使用することです here :
string getOpenSSLError()
{
BIO *bio = BIO_new(BIO_s_mem());
ERR_print_errors(bio);
char *buf;
size_t len = BIO_get_mem_data(bio, &buf);
string ret(buf, len);
BIO_free(bio);
return ret;
}
サンプルコードでSSL_load_error_strings()
およびERR_load_crypto_strings()
を呼び出すのが遅すぎます。これらは、プログラムの開始時に直接呼び出す必要があります。その後、OpenSSLから読み取り可能なエラー文字列を取得する必要があります。 @jwwは、DHグループが小さすぎるという点で正しいです。理想的には、サーバーをより大きなグループで再構成する必要があります。それが不可能な場合は、DHE以外の暗号スイートで接続してみてください(代わりにECDHEベースの暗号スイートを使用してください)。
これは、opensslのコンパイル時に「no-err」オプションを含めるためです。したがって、Err_error_stringはNULLを返します