wolfSSL軽量TLSで代替I / Oを使用する

以前に何度か(ここここ)wolfSSLのI / O抽象化レイヤーと代替I / Oメディアのサポートについて説明しました。この有用な機能について読者の記憶をリフレッシュしたいと考えました。この文脈で「伝統的ではないI / O」とは、TCP / IPやUDP以外の上でSSL / TLSを実行することを意味します。たとえば、Bluetooth、シリアル接続、メモリバッファ、独自の転送プロトコルなどです。わたしたちは、軽量なTLSソリューションを探している組込みプロジェクトでは、そういうことがよくあると考えています。

wolfSSL I / Oアブストラクションレイヤ
wolfSSLは、アプリケーション固有のI / Oルーチンをプラグインするメカニズムを提供しています。まず、wolfSSLライブラリのデフォルトでは、wolfSSL_set_fd()でキャッシュされたファイル記述子を使ってシステムの(BSDの) recv()やsend()などのBSDソケットAPIを呼び出すようになっています。
I / Oコールバック関数のプロトタイプは次のとおりです。
typedef int(* CallbackIORecv)(WOLFSSL * ssl、char * buf、int sz、void * ctx);
typedef int(* CallbackIOSend)(WOLFSSL * ssl、char * buf、int sz、void * ctx);
デフォルトの場合、ネットワークソケットのファイル記述子は、 “ctx”パラメータでI / Oコールバックに渡されます。 “ssl”パラメータは、現在のwolfSSLセッションへのポインタであり、コールバックは必要に応じてセッションレベルの詳細にアクセスできます。
受信時は、 “buf”は、wolfSSLの復号化された受信テキストをコピーすべきバッファを指し、 “sz”はバッファのサイズです。コールバックは、 “sz”バイトを “buf”、または使用可能なバイト数だけコピーする必要があります。 sendの場合、 “buf”はwolfSSLが送信する暗号化すべきテキストを書き込んだバッファを指し、 “sz”はそのバッファのサイズを指します。コールバックは “buf”から “sz”バイトを転送媒体を介して送信する必要があります。どちらの場合も、書き込まれたバイト数または読み込まれたバイト数を返すか、あるいは適用可能なエラーコードを返します。
独自のI / OコールバックをWOLFSSL_CTXに登録するには、関数wolfSSL_SetIORecv()とwolfSSL_SetIOSend()を使用します。
wolfSSL_SetIORecv(ctx、myCBIORecv);
wolfSSL_SetIOSend(ctx、myCBIOSend);

 

メモリバッファを使用した簡単な例

これをより理解しやすくするために、簡単な例を見てみましょう。代替I / Oのユースケースの1つは、複数のクライアントからデータを受信したり、STDINおよびSTDOUTを介してTLSを処理するサーバーです。このアプリケーションでは、4つのバッファが存在する可能性があります。

  • cipher-receive   通信相手から受信した暗号化されたデータ
  • cipher-send       通信相手に送信する暗号化されたデータ
  • clear-receive     wolfSSLから受信したデータをクリア
  • clear-send         wolfSSLに渡したデータをクリア

これらのバッファへのポインタ、そのサイズの値、および読み書き位置は、ユーザ定義の構造体に置くことができます。この構造体へのポインタは、関数wolfSSL_SetIOReadCtx()とwolfSSL_SetIOWriteCtx()を使ってwolfSSLセッションにキャッシュされます。
wolfSSL_SetIOReadCtx(ssl、buffer_data);
wolfSSL_SetIOWriteCtx(ssl、buffer_data);
アプリケーションは暗号文のブロックをバッファ “cipher-receive”に受け取り、wolfSSL_read(ssl、buffer_data-> clear_receive)を呼び出して、wolfSSLに登録された受信コールバックを呼び出させます。受信コールバックには、バッファ、バッファのサイズ、および「cipher-receive」バッファを含むコンテキスト(ctx)が与えられます。コールバックは、wolfSSL_read()への一回の呼び出しで何回も内部的に呼び出されることがあります。 「暗号受信」バッファが空の場合、コールバックは -2(WOLFSSL_CBIO_ERR_WANT_READ)を返します。それ以外の場合は、「buf」にコピーされたバイト数を返します。 WOLFSSL_CBIO_ERR_WANT_READは、コールバックがデータを要求した時点で読み込み可能なデータがなかったことを示すエラー値です。この場合、データを読み込む準備ができたら、アプリケーションはループバックして、上位のAPI呼び出し(wolfSSL_read()、wolfSSL_connect()など)をもう一度行う必要があります。
wolfSSLライブラリがハンドシェーク中にデータを送信する場合、またはwolfSSL_send()がアプリケーションから平文テキストで呼び出された場合、ライブラリは登録されたsendコールバックを呼び出します。コールバックには、暗号化されたデータの入ったバッファと、暗号化されたデータの長さが与えられます。この例では、コールバックはこの暗号テキストを「cipher-send」にコピーし、コピーされたバイト数を返します。 「暗号送信」バッファが要求にたいして十分に大きくなければ、コールバックは -2(WOLFSSL_CBIO_ERR_WANT_WRITE)を返します。

その他の参照

wolfSSL I / O抽象レイヤの使用例として、ファイルを転送媒体として使用する場合のクライアント/サーバアプリケーションのサンプルがあります。
https://github.com/wolfSSL/wolfssl-examples/tree/master/custom-io-callbacks
 
さらに詳しい情報は弊社問い合わせ窓口 (info@wolfssl.com, info@wolfssl.jp: 日本語)までお問い合わせください。
原文: https://www.wolfssl.com/wolfssl-alternative-io-support/
wolfSSLホーム:www.wolfssl.jp (English:www.wolfssl.com)