openSSL C ++のピア(クライアント)証明書を検証する
-
27-09-2019 - |
質問
サーバーへのSSL接続を確立する作業アプリケーションがあります。サーバーは自己署名の証明書を使用し、クライアントは証明書局のチェーンをロードして、サーバーが信頼しても問題ないことを伝えます。私はクライアントでこのようなコードでそれをしました:
SSL_METHOD* method = TLSv1_client_method();
_ctx = SSL_CTX_new(method);
if ( SSL_CTX_load_verify_locations(_ctx, "ca-all.crt", NULL) != 1 )
{
return false;
}
_ssl = SSL_new(_ctx);
int val = SSL_set_fd(_ssl, _socket->GetFD());
if ( val != SSL_SUCCESS )
{
int err = SSL_get_error(_ssl, val);
return false;
}
val = SSL_connect(_ssl);
サーバー上:
if ( SSL_CTX_use_certificate_chain_file( g_ctx, "ca-chain1.crt" ) <= 0 ) {
return 1;
}
ppem_file = getenv( "PEM_FILE" );
if ( ppem_file == NULL ) {
ppem_file = pem_file;
}
if ( SSL_CTX_use_certificate_file( g_ctx, ppem_file,
SSL_FILETYPE_PEM ) <= 0 ) {
return 1;
}
if ( SSL_CTX_use_PrivateKey_file( g_ctx, ppem_file,
SSL_FILETYPE_PEM ) <= 0 ) {
return 2;
}
サーバーがクライアントのピア証明書(サーバーと同じ発行者を使用して自己署名)を検証し、少し問題を抱えているように、このコードを変更しようとしています。私はどこでも良い「概念的概要」ドキュメントを見つけていませんが、それはOpenSSLライブラリの典型的なハードルのようです。
クライアントでは、SSL_CTX_LOAD_VERIFY_LOCATIONS()CALL:CALL:後にこれを追加しました。
if ( SSL_CTX_use_certificate_file(_ctx, "generic_client.pem", SSL_FILETYPE_PEM ) != 1 )
{
return false;
}
サーバーで、SSL_CTX_USE_PRIVATEKEY_FILE()CALL:CALL:後にこれを追加しました。
STACK_OF(X509_NAME) *list;
list = SSL_load_client_CA_file( "ca_chain2.crt" );
if( list == NULL ) {
return 4;
}
SSL_CTX_set_client_CA_list( g_ctx, list );
SSL_CTX_set_verify( g_ctx, SSL_VERIFY_PEER, NULL );
証明書が検証されないため、接続は失敗します。クライアントは証明書を正常にロードしているようで、ssl_ctx_set_verify行にコメントした場合、クライアントは問題なく接続します(証明書が検証されないため)。
サーバーは、クライアントの認証局のチェーンが良いとは思わないようです。ここに何が欠けていますか?
私が実行できるコマンドラインから:opensSl検証-cafile ca -chain2.crt generic_client.pemを渡すので、適切な証明書データが利用可能です。
解決
サーバーでは、呼び出す必要があります SSL_CTX_load_verify_locations()
. 。この関数は、証明書の確認に使用する証明書をサーバーに伝えます。 SSL_CTX_set_client_CA_list()
関数は、握手でクライアントに送信される許可されたCAのリストを設定します。どちらも必要です。
(aも必要です SSL_CTX_use_PrivateKey_file()
後にクライアントに電話してください use_certificate_file
電話しますが、私はあなたがそれをしていると思いますが、それを除外しました)。
他のヒント
ssl_ctx_set_client_ca_listを設定します ca リスト。定義上、CA証明書は、ユーザー証明書とは異なります(たとえば、CAビットセットがあります)。そのため、適切なCA(CA証明書が自己署名されている)を作成し、それを使用してクライアントとサーバー証明書の両方に署名することをお勧めします。 OpenSSLは、クライアントが実際に通信にCA証明書を実際に使用することを期待していないと思います。