2016-04-26 15 views
1

OpenSSLを使用するCサーバーアプリケーションがあり、同じポート上のすべてのトラフィックを受信します。受信データがSSL接続かどうかを確認する安全な方法はありますか?接続がSSLであるかどうかをチェックする方法は?

+1

単一のポートを使用してサーバー内のすべての接続を受け入れることを意味しますか?その後、接続を受け入れたらSSLネゴシエーションを実行しますか?ライブラリ関数を使用して接続を処理していませんか? –

+0

あります。私はトラフィックの種類を決定する必要がありますし、それがSSLであればSSLネゴシエーションを行い、そうでなければ別の方法でそれを処理します。 – Marco

答えて

2

TLS接続で最初に起こることは、クライアントがClientHelloを送信することです。 ClientHelloは、それをハンドシェイクメッセージとして識別するバイト値22'\x16')で始まります。

アプリケーションプロトコルがテキストベースの場合は、22バイト(印刷可能な文字ではありません)が含まれないため、最初のバイトでyour-protocol-over-TCPとyour-protocol-overを区別できます。 -TLS-over-TCP。

アプリケーションプロトコルがテキストベースでなく、クライアントが22バイトを送信してから非TLS接続を開始する可能性がある場合は、さらに深く掘り下げなければなりません。次の2バイトは、TLSのメジャーバージョン番号とマイナーバージョン番号です。現在、メジャーバージョンのバイトは3、マイナーバージョンのバイトは1から3の範囲のどこかにあると期待できます。時代遅れのバージョンのSSLを使用しているクライアントがあれば、より低い数字が可能になり、TLSの将来のアップデートでより高い数字が可能になるので、柔軟にする必要があります。

22を、プロトコルの非TLSバージョンの最初のバイトとして除外することをお勧めします。

recvMSG_PEEKを使用すると、最初のバイトを消費せずに検査することができます。したがって、決定が終わっても、TLSライブラリまたはアプリケーションプロトコルが読み取れるようになります。

もう1つの複雑な問題:アプリケーションプロトコルでサーバーがクライアントの前に話す必要がある場合は、問題があります。クライアントが接続すると、TLS以外の挨拶を待っているか、ClientHelloを送信している可能性があります。この問題は、タイムアウトによってのみ解決できます。クライアントが何らかのタイムフレーム内に何も送信しない場合は、ClientHelloを送信せず、TLS以外のバージョンのプロトコルを使用しないと想定します。これにより、非TLSクライアントに対して接続の開始が遅れることがありますが、これを避ける方法はありません。

+1

...古い破損したバージョンを参照していないときは、プロトコルの名前として「SSL」の使用をやめてみましょう。 TLSはすでにここにあります! –

+0

ありがとう、それはまさに私が探していた答えです! – Marco

0

自分で接続を受け入れ、接続を受け入れた後でSSLハンドシェイクに移行する場合は、自分で追跡する必要があります。

単純な解決策は、受け入れられたソケット記述子を含む構造体と、SSL接続の場合はブール型フラグを持ち、それらの構造体のリストを持つことです。

関連する問題