GSS-API のプログラミング

データ保護

ピア間 (つまり、クライアントとサーバー間) でコンテキストが確立された後、メッセージは送信する前に保護できます。

コンテキストを確立しメッセージを送信するだけの場合、最も基本的な GSS-API 保護である「認証」が使用されます。 認証を使用すると、受信側は、送信側であるべきと要求されているプリンシパルからのメッセージであるかどうかを知ることができます。使用される実際のセキュリティ機構によって異なりますが、GSS-API は次の 2 つの保護も提供します。

図 1–11 に、2 つの関数の違いを示します。

図 1–11 gss_get_mic()gss_wrap()

gss_get_mic 関数と gss_wrap 関数の違いを示しています。

どちらの関数を使用するかは、ユーザーの必要性によって異なります。gss_wrap() は整合性サービスも含むため、多くのプログラムは gss_wrap() を使用します。機密性サービスを使用できるかどうかをテストするには、機密性サービスを付けて (または、付けずに) gss_wrap() を呼び出します。使用例は、データの送信(プログラムリストは call_server()) を参照してください。しかし、gss_get_mic() で保護されたメッセージは受信側がラップ解除する必要がないため、gss_wrap() を使用するときよりも CPU サイクルを節約できます。したがって、機密性が必要ないプログラムは gss_get_mic() でメッセージを保護する傾向にあります。

gss_get_mic() によるメッセージのタグ付け

gss_get_mic() を使用すると、プログラムは暗号化 MIC をメッセージに追加できます。受信側は gss_verify_mic() を呼び出し、この MIC をチェックすることによって、受信したメッセージが送信されたメッセージと同じであるかどうかを調べることができます。次に、gss_get_mic() の形式を示します。



OM_uint32 gss_get_mic (
OM_uint32          *minor_status,
const gss_ctx_id_t context_handle,
gss_qop_t          qop_req,
const gss_buffer_t message_buffer,
gss_buffer_t       msg_token)

minor_status

実際の機構から戻される状態コード。

context_handle

メッセージが送信されるコンテキスト。

qop_req

要求する QOP (保護品質)。MIC を生成するときに使用される暗号化アルゴリズムです。移植性のためには、アプリケーションは可能な限りデフォルトの QOP を指定するべきです。つまり、この引数に GSS_C_QOP_DEFAULT を設定します。デフォルト以外の QOP の指定については、付録 C 「OID の指定」 を参照してください。

message_buffer

MIC をタグ付けするメッセージ。この引数は gss_buffer_desc オブジェクトの形式である必要があります 。文字列および類似のデータを参照してください。アプリケーションが使用し終わったときには、gss_release_buffer() で解放する必要があります。

msg_token

メッセージと MIC が入っているトークン。使用し終わったときには、gss_release_buffer() で解放する必要があります。

gss_get_mic() はメッセージと MIC を別々に出力します。これは、gss_wrap() とは異なります。gss_wrap() は両方を一緒にして出力します。さらに重要なことは、受信側アプリケーションがメッセージと MIC を受信および区別できる必要があるということです。メッセージと MIC を適切に処理するには、次のような方法があります。

正常に終了した場合、gss_get_mic()GSS_S_COMPLETE を戻します。指定した QOP が有効でなかった場合、gss_get_mic()GSS_S_BAD_QOP を戻します。詳細は、gss_get_mic(3GSS) のマニュアルページを参照してください。

gss_wrap() によるメッセージのラップ

メッセージは gss_wrap() 関数で「ラップ」することも可能です。gss_get_mic() と同様に、gss_wrap() は MIC を提供します。機密性が要求される場合 (かつ、実際の機構で使用できる場合)、gss_wrap() はさらにメッセージを暗号化します。メッセージの受信側は gss_unwrap() でメッセージを「ラップ解除」します。次に、gss_unwrap() の形式を示します。



OM_uint32 gss_wrap (
OM_uint32          *minor_status,
const gss_ctx_id_t context_handle,
int                conf_req_flag,
gss_qop_t          qop_req
const gss_buffer_t input_message_buffer,
int                *conf_state,
gss_buffer_t       output_message_buffer )

minor_status

実際のセキュリティ機構から戻される状態コード。

context_handle

このメッセージが送信されるコンテキスト。

conf_req_flag

機密性サービス (暗号化) を要求するためのフラグ。0 以外の場合、機密性と整合性の両方を要求します。0 の場合、整合性サービスだけを要求します。

qop_req

要求する QOP (保護品質)。MIC を生成するときと暗号化を行うときに使用される暗号化アルゴリズムです。移植性のためには、アプリケーションは可能な限りデフォルトの QOP を指定するべきです。つまり、この引数に GSS_C_QOP_DEFAULT を設定します。デフォルト以外の QOP の指定については、付録 C 「OID の指定」 を参照してください。

input_message_buffer

ラップするメッセージ。この引数は gss_buffer_desc オブジェクトの形式である必要があります。文字列および類似のデータを参照してください。アプリケーションが使用し終わったときには、gss_release_buffer() で解放する必要があります。

conf_state

関数が戻ったときに、機密性が適用されたかどうかを示すフラグ。0 以外の場合、機密性、メッセージ起点認証、および整合性サービスが適用されたことを示します。0 の場合、メッセージ起点認証と整合性だけが適用されたことを示します。必要ない場合は、NULL を指定します。

output_message_buffer

ラップしたメッセージ用のバッファ。アプリケーションがメッセージを処理した後には、gss_release_buffer() で解放する必要があります。

gss_get_mic() とは違い、gss_wrap() はメッセージと MIC を一緒にラップし、1 つの出力メッセージにします。したがって、メッセージを転送する関数は 1 回呼び出すだけでかまいません。メッセージの受信側では、gss_unwrap() でメッセージを抽出します。なお、MIC はアプリケーションからは見えません。

メッセージが正常にラップされた場合、gss_wrap()GSS_S_COMPLETE を戻します。要求した QOP が有効でなかった場合、gss_wrap()GSS_S_BAD_QOP を戻します。gss_wrap() の使用例は、データの送信(プログラムリストは call_server()を参照してください。詳細は、gss_wrap(3GSS) のマニュアルページを参照してください。

ラップのサイズ

gss_wrap() でメッセージをラップすると、メッセージのサイズが増加します。保護されたメッセージパケットは、転送プロトコルを通過できるぐらいのサイズである必要があります。したがって、GSS-API の gss_wrap_size_limit 関数を使用して、ラップしても転送プロトコルを通過できるメッセージの最大サイズを計算します。この最大サイズを超える場合、アプリケーションは gss_wrap() を呼び出す前にメッセージを分割できます。メッセージを実際にラップする前にはラップサイズの制限値をチェックするように習慣付けましょう。

サイズの増加量は次の 2 つの影響を受けます。

次に、gss_wrap_size_limit() の形式を示します。



OM_uint32 gss_wrap_size_limit (
OM_uint32          *minor_status,
const gss_ctx_id_t context_handle,
int                conf_req_flag,
gss_qop_t          qop_req,
OM_uint32          req_output_size,
OM_uint32          *max_input_size)

minor_status

実際の機構から戻される状態コード。

context_handle

データが転送されるコンテキスト。

conf_req_flag

機密性サービス (暗号化) を要求するためのフラグ。0 以外の場合、機密性と整合性の両方を要求します。0 の場合、整合性サービスだけを要求します。

qop_req

要求する QOP (保護品質)。MIC を生成するときと暗号化を行うときに使用される暗号化アルゴリズムです。移植性のためには、アプリケーションは可能な限りデフォルトの QOP を指定するべきです。つまり、この引数に GSS_C_QOP_DEFAULT を設定します。デフォルト以外の QOP の指定については、付録 C 「OID の指定」 を参照してください。

req_output_size

指定した転送プロトコルが処理できるデータ片の最大サイズ (型は int)。この情報は、ユーザーが自ら提供する必要があります。つまり、GSS-API はプロトコルに依存しないため、どのプロトコルが使用されるのかを知る方法がありません。

max_input_size

関数から戻される値。つまり、ラップしたときに req_output_size を超えないような、ラップしていないメッセージの最大サイズ。

正常に終了した場合、gss_wrap_size_limit()GSS_S_COMPLETE を戻します。指定した QOP が有効でなかった場合、gss_wrap_size_limit()GSS_S_BAD_QOP を戻します。gss_wrap_size_limit() でオリジナルのメッセージの最大サイズを求める例 (機密性を使用する場合と使用しない場合の両方) については、call_server()を参照してください。

この機能は gss_wrap() を呼び出した時点でのシステムリソースの可用性に依存するため、この呼び出しが正常に終了したとしても、必ずしも、gss_wrap()max_input_size 以下のバイトの長さを持つメッセージを保護できるとは保証できません。詳細は、gss_wrap_size_limit(3GSS) のマニュアルページを参照してください。