2017-11-07 13 views
1

私はデータを読み書きするソケットアプリケーションを持っています。私はOpenSSLを使って暗号化/復号化を行っています。私の質問は、 "BIO_write"メソッドがデータを内部的にバッファリングできるかどうか、またはソケットから多くを読み込む際に成長するバッファに追加する必要があるかどうかです。ここに私がやっていることがあります。SSLに部分パケットを書き込むBIO

私はソケットから読んで、私はBIOに読み込まれたすべてのバイトを書き込むには、以下のクラスのメソッドを使用します。

int CSslConnectionContext::Store(BYTE* pbData, DWORD dwDataLength) 
{ 
    int bytes = 0; 
    if (dwDataLength > 0) 
    { 
     bytes = BIO_write(bio[BIO_RECV], pbData, dwDataLength); 
    } 

    return bytes; 
} 

私はその後すぐに復号化されたデータを取得するためにSSL_readメソッドを呼び出します。

int CSslConnectionContext::Read(BYTE* pbBuffer, DWORD dwBufferSize) 
{ 
    int bytes = SSL_read(ssl, pbBuffer, dwBufferSize); 
    return bytes; 
} 

SSL_readが正の数を返した場合、私のアプリケーションで利用可能な復号化データが得られました。

ソケットの読み取りが1回の読み取りで復号化に必要なすべてのデータを取得しないとどうなるかはわかりません。

データを復号化できるようにするために100バイトが必要で、最初の読み取りで80が得られる場合は、それらの80でBIO_write()を呼び出し、次の20を取得するために別のソケット読み取りを行い、BIO_write )の20バイトだけで?

  1. コールBIO_write()80バイトの:

    それとも、私は80を読んだとき、私はこのような何かを行うので、私のコードを記述する必要があります。

  2. これが障害インジケータを返す場合、その80バイトを保持します。
  3. ソケットから次の20バイトを読み取り、バッファされた80バイトに追加します。
  4. 100バイト
+0

[SSL_read()](https://www.openssl.org/docs/manmaster/man3/SSL_read.html)のmanページは、SSL_readが実行される前に、元のバイオにもっと多くのデータが必要な場合を処理しているようですすべてのデータを返します。この場合、SSL_read()は負の数を返し、SSL_get_error()はSSL_WANT_READまたはSSL_WANT_WRITEに対応する値を返します。 –

答えて

1

とコールBIO_write()OpenSSLは内部バッファを保持している - TCPスタックの一番上に - さんは、SSLスタックを呼び出してみましょう。 OpenSSLライブラリはSSLスタックを処理します。 BIO_xxx()関数は、さまざまなエンドポイント、つまりメモリ、ソケット上で動作できます。 実際に動作する項目によって動作が異なります。たとえば、BIO_write()がメモリ(BIO_s_mem)を使用する場合、BIO_writeは不十分なメモリを除いて決して失敗しません。しかし、ソケットを使用していて、ソケットが非ブロックの場合、エラー時にエラーを返すか、ソケットバッファがいっぱいになっているすべての要求バイトの代わりに、いくつかのバイト数を書き込むことができます。

ので、/ハンドルを使用する方法バッファは、多くの要因に依存するが、最も顕著なものは以下のとおりです。

  • ブロックまたは非ブロックIO
  • (メモリ、ソケットなど)上で動作し
  • BIOオブジェクト
  • 例えば

あなたがBIO_s_memを使用してソケット操作を非ブロックしている場合は、以下の技術を適用することができます。

  1. BIO_writeを使用してバッファを書き込み、失敗したかどうかを確認します。失敗しなかった場合は、すべてのバッファをSSLスタックに書き込んだことを確認できます。
  2. Read_SSLを呼び出してエラーをチェックし、エラーがWANT_READまたはWANT_WRITEの場合は、有効なレコードを読み取るためにさらに多くのデータをSSLスタックに書き込む必要があります。質問や例えば

あなたは、部分的に(たとえ1バイト、あなたはできる限り多くを)書くことができます。たとえば、ソケットから80バイトを読み込んだ場合は、BIO_writeを使用して書き込みます。その後、SSL_readの呼び出しが失敗する可能性があります(WANT_READ、WANT_WRITE、またはその他)。次に、ソケットから20バイトを受信し、BIO_writeを使用してこれらのバイトを書き込みます。その後、SSL_readを再度呼び出します。 SSL_readがエラーなしで返されると、これはSSLスタックが有効なレコードをデコードしたことを意味します。

しかし、SSL読み込み/書き込みを処理するためにselect()を使用してノンブロッキングソケットで待機することは非常に面倒なことを理解することは非常に重要です。 1つのSSL_writeは、ソケットのREADイベントを既に待っている間に、複数のソケットへの書き込みを行うことができます。

+0

ありがとうHayati。あなたの例(BIO_s_memとnon-blockingソケット)はまさに私がやっていることです。それは私の80バイトの書き込みの例のように聞こえ、20バイトはOKです。それはそれが動作する方法ですか?各BIO_write()は、SSL_read()が呼び出されるまで内部バッファにデータを追加しますか? – Ken

+0

はい、内部SSLバッファを追加します。私はあなたのケースをカバーするために私の答えを更新しました。 –

関連する問題