OpenSSL APIメモ(handshake failure)
OpenSSL APIを使うクライアントプログラムを書いて、あるサイトにアクセスした時にエラーが出た。
ハマったのでメモしておく。
error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure
TLSを指定している(↓)のに何故SSLv3?
ctx = SSL_CTX_new(TLSv1_client_method());
SSLv3に変えてみると、
ctx = SSL_CTX_new(SSLv23_client_method()); SSL_CTX_set_options(ssl->ctx, SSL_OP_NO_SSLv2); /* SSLv2を無効にする */
エラーメッセージが変わった。
error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure
結果的に原因はプロトコル(SSLv3やTLS1.0)ではなく、「Client Hello」時に、サーバへ渡す情報の不足。
SSL接続時にHandshakeに失敗する場合はSNIが原因かもしれない - TODESKING
SSL/TLS(SSL3.0~TLS1.2)のハンドシェイクを復習する - Qiita
TLS 1.3 Encrypted SNI拡張の議論 - 株式会社レピダム
もう少し違ったメッセージを出せないものだろうか。。。
以下を追加したら正常に接続できた。
SSL_set_tlsext_host_name(ssl, "<アクセス先サーバのHOSTNAME>");
SNIについて、wikiに以下の記載有り。
SSL_set_tlsext_host_name uses the TLS SNI extension to set the hostname.
If you are connecting to a Server Name Indication-aware server (such as Apache with name-based virtual hosts or IIS 8.0), then you will receive the proper certificate during the handshake.