InitializeSecurityContext (Schannel) 関数

InitializeSecurityContext (Schannel) 関数は、資格情報ハンドルからクライアント側の送信セキュリティ コンテキストを開始します。 関数は、クライアント アプリケーションとリモート ピアの間に セキュリティ コンテキスト を構築するために使用されます。 InitializeSecurityContext (Schannel) は、クライアントがリモート ピアに渡す必要があるトークンを返します。このトークンは、ピアが AcceptSecurityContext (Schannel) 呼び出しを通じてローカル セキュリティ実装に送信します。 生成されるトークンは、すべての呼び出し元によって不透明と見なされる必要があります。

通常、 InitializeSecurityContext (Schannel) 関数は、十分な セキュリティ コンテキスト が確立されるまでループで呼び出されます。

構文

SECURITY_STATUS SEC_Entry InitializeSecurityContext(
  _In_opt_    PCredHandle    phCredential,
  _In_opt_    PCtxtHandle    phContext,
  _In_opt_    SEC_CHAR       *pszTargetName,
  _In_        ULONG          fContextReq,
  _In_        ULONG          Reserved1,
  _In_        ULONG          TargetDataRep,
  _In_opt_    PSecBufferDesc pInput,
  _In_        ULONG          Reserved2,
  _Inout_opt_ PCtxtHandle    phNewContext,
  _Inout_opt_ PSecBufferDesc pOutput,
  _Out_       PULONG         pfContextAttr,
  _Out_opt_   PTimeStamp     ptsExpiry
);

パラメーター

phCredential[in, optional]

AcquireCredentialsHandle (Schannel) によって返される資格情報のハンドル。 このハンドルは、 セキュリティ コンテキストを構築するために使用されます。 InitializeSecurityContext (Schannel) 関数には、最初の呼び出しで少なくとも OUTBOUND 資格情報が必要です。 以降の呼び出しでは、これは になります NULL

phContext[in, optional]

CtxtHandle 構造体へのポインター。 InitializeSecurityContext (Schannel) の最初の呼び出しでは、このポインターは ですNULL。 今後の呼び出しでは、このパラメーターは、この関数の最初の呼び出しによって phNewContext パラメーターで返される部分的に形成されたコンテキストへのハンドルへのポインターです。

警告

InitializeSecurityContext (Schannel) の同時呼び出しでは、同じコンテキスト ハンドルを使用しないでください。 セキュリティ サービス プロバイダーの API 実装はスレッド セーフではありません。

pszTargetName[in, optional]

ターゲット サーバーを一意に識別する null で終わる文字列へのポインター。 Schannel は、この値を使用してサーバー証明書を確認します。 Schannel は、接続を再確立するときに、この値を使用してセッション キャッシュ内のセッションを検索します。 キャッシュされたセッションは、次のすべての条件が満たされている場合にのみ使用されます。

  • ターゲット名は同じです。
  • キャッシュ エントリの有効期限が切れていない。
  • 関数を呼び出すアプリケーション プロセスは同じです。
  • ログオン セッションは同じです。
  • 資格情報ハンドルは同じです。

fContextReq[in]

コンテキストの要求を示すビット フラグ。 すべてのパッケージがすべての要件をサポートできるわけではありません。 このパラメーターに使用されるフラグには、ISC_REQ_DELEGATEなど、ISC_REQ_がプレフィックスとして付けられます。 このパラメーターには、次の属性フラグの 1 つ以上を指定できます。

意味
ISC_REQ_ALLOCATE_MEMORY セキュリティ パッケージは、出力バッファーを割り当てます。 出力バッファーの使用が完了したら、 FreeContextBuffer 関数を呼び出して解放します。
ISC_REQ_CONFIDENTIALITY EncryptMessage 関数を使用してメッセージを暗号化します。
ISC_REQ_CONNECTION セキュリティ コンテキストでは、書式設定メッセージは処理されません。
ISC_REQ_EXTENDED_ERROR エラーが発生すると、リモート パーティに通知されます。
ISC_REQ_INTEGRITY EncryptMessage 関数と MakeSignature 関数を使用して、メッセージに署名し、署名を確認します。
ISC_REQ_MANUAL_CRED_VALIDATION Schannel は、サーバーを自動的に認証することはできません。
ISC_REQ_MUTUAL_AUTH サービスの相互認証ポリシーが満たされます。
注意: これは、必ずしも相互認証が実行されるという意味ではなく、サービスの認証ポリシーが満たされていることを意味します。 相互認証が確実に実行されるようにするには、 QueryContextAttributes (Schannel) 関数を呼び出します。
ISC_REQ_REPLAY_DETECT EncryptMessage 関数または MakeSignature 関数を使用してエンコードされた再生済みメッセージを検出します。
ISC_REQ_SEQUENCE_DETECT 受信したメッセージを順番に検出します。
ISC_REQ_STREAM ストリーム指向の接続をサポートします。
ISC_REQ_USE_SUPPLIED_CREDS Schannel は、クライアントの資格情報を自動的に指定しようとしないでください。

要求された属性は、クライアントでサポートされていない可能性があります。 詳細については、 pfContextAttr パラメーターを参照してください。

さまざまな属性の詳細については、「 コンテキスト要件」を参照してください。

予約済み 1[in]

このパラメーターは予約済みであり、0 に設定する必要があります。

TargetDataRep[in]

このパラメーターは Schannel では使用されません。 0 に設定します。

pInput[in, optional]

パッケージへの入力として提供されるバッファーへのポインターを含む SecBufferDesc 構造体へのポインター。 クライアント コンテキストがサーバーによって開始されていない限り、このパラメーターの値は NULL 関数の最初の呼び出しで指定する必要があります。 以降の関数の呼び出し時、またはクライアント コンテキストがサーバーによって開始された場合、このパラメーターの値は、リモート コンピューターから返されるトークンを保持するのに十分なメモリが割り当てられたバッファーへのポインターです。

最初の呼び出し後にこの関数を呼び出す場合は、2 つのバッファーが必要です。 1 つ目の 型は SECBUFFER_TOKEN で、サーバーから受信したトークンが含まれています。 2 番目のバッファーの型は SECBUFFER_EMPTYpvBuffer メンバーと cbBuffer メンバーの両方を 0 に設定します。

予約済み 2[in]

このパラメーターは予約済みであり、0 に設定する必要があります。

phNewContext[in, out, optional]

CtxtHandle 構造体へのポインター。 InitializeSecurityContext (Schannel) の最初の呼び出しで、このポインターは新しいコンテキスト ハンドルを受け取ります。 2 番目の呼び出しでは、 phNewContextphContext パラメーターで指定されたハンドルと同じにすることができます。 phNewContext をNULLしないでください。

pOutput[in, out, optional]

出力データを受信する SecBuffer 構造体へのポインターを含む SecBufferDesc 構造体へのポインター。 バッファーが入力にSEC_READWRITEとして入力された場合は、出力時にそのバッファーが存在します。 システムは、要求された場合 (ISC_REQ_ALLOCATE_MEMORYを介して) セキュリティ トークンのバッファーを割り当て、セキュリティ トークンのバッファー記述子のアドレスを入力します。

ISC_REQ_ALLOCATE_MEMORY フラグが指定されている場合、Schannel SSP はバッファーのメモリを割り当て、 SecBufferDesc に適切な情報を格納します。 さらに、呼び出し元は SECBUFFER_ALERT 型のバッファーを渡す必要があります。 出力時に、アラートが生成された場合、このバッファーにはそのアラートに関する情報が含まれており、関数は失敗します。

pfContextAttr[out]

確立されたコンテキストの 属性 を示すビット フラグのセットを受け取る変数へのポインター。 さまざまな属性の説明については、「 コンテキスト要件」を参照してください。

このパラメーターに使用されるフラグには、ISC_RET_DELEGATEなどのISC_RETがプレフィックスとして付けられます。 有効な値の一覧については、 fContextReq パラメーターを参照してください。

最終的な関数呼び出しが正常に返されるまで、セキュリティ関連の属性をチェックしないでください。 セキュリティに関連しない属性フラグ (ASC_RET_ALLOCATED_MEMORY フラグなど) は、最終的な戻り値の前に確認できます。

注意

特定のコンテキスト属性は、リモート ピアとのネゴシエーション中に変更される可能性があります。

ptsExpiry[out, optional]

コンテキストの有効期限を受け取る TimeStamp 構造体へのポインター。 セキュリティ パッケージでは、常にローカル時刻にこの値を返すようにお勧めします。 このパラメーターは省略可能であり、 NULL 有効期間の短いクライアントに渡す必要があります。

戻り値

関数が成功した場合、関数は次のいずれかの成功コードを返します。

リターン コード 説明
SEC_I_COMPLETE_AND_CONTINUE クライアントは CompleteAuthToken を 呼び出し、出力をサーバーに渡す必要があります。 その後、クライアントは返されたトークンを待機し、別の呼び出しで InitializeSecurityContext (Schannel) に渡します。
SEC_I_COMPLETE_NEEDED クライアントはメッセージの作成を完了し、 CompleteAuthToken 関数を呼び出す必要があります。
SEC_I_CONTINUE_NEEDED クライアントは出力トークンをサーバーに送信し、戻りトークンを待つ必要があります。 返されたトークンは、 InitializeSecurityContext (Schannel) の別の呼び出しで渡されます。 出力トークンは空にすることができます。
SEC_I_INCOMPLETE_CREDENTIALS サーバーがクライアント認証を要求し、指定された資格情報に証明書が含まれていないか、サーバーによって信頼されている証明機関 (CA) によって証明書が発行されていません。 詳細については、「解説」を参照してください。
SEC_E_INCOMPLETE_MESSAGE メッセージ全体のデータがネットワークから読み取られなかった。
この値が返されると、pInput バッファーには、SECBUFFER_MISSING の BufferType メンバーを持つ SecBuffer 構造体が含まれますSecBuffercbBuffer メンバーには、この関数が成功する前に関数がクライアントから読み取る必要がある追加バイト数を示す値が含まれています。 この数値は常に正確であるとは限りませんが、 を使用すると、この関数の複数の呼び出しを回避することでパフォーマンスを向上させることができます。
SEC_E_OK セキュリティ コンテキストが正常に初期化されました。 別の InitializeSecurityContext (Schannel) 呼び出しは必要ありません。 関数が出力トークンを返す場合、つまり pOutput のSECBUFFER_TOKENの長さが 0 以外の場合は、そのトークンをサーバーに送信する必要があります。

関数が失敗した場合、関数は次のいずれかのエラー コードを返します。

リターン コード 説明
SEC_E_INSUFFICIENT_MEMORY 要求されたアクションを完了するのに十分なメモリがありません。
SEC_E_INTERNAL_ERROR SSPI エラー コードにマップされないエラーが発生しました。
SEC_E_INVALID_HANDLE 関数に渡されたハンドルが無効です。
SEC_E_INVALID_TOKEN このエラーは、転送中にトークンが破損した、サイズが正しくないトークン、間違った制約付き 委任に渡されたトークンなど、不正な形式の入力トークンが原因です。 クライアントとサーバーが適切な 制約付き委任をネゴシエートしなかった場合、間違ったパッケージにトークンを渡すと発生する可能性があります。
SEC_E_LOGON_DENIED ログオンに失敗しました。
SEC_E_NO_AUTHENTICATING_AUTHORITY 認証のために機関に問い合わせることができませんでした。 認証側のドメイン名が間違っているか、ドメインに到達できないか、信頼関係の障害が発生している可能性があります。
SEC_E_NO_CREDENTIALS 制約付き委任では資格情報を使用できません。
SEC_E_TARGET_UNKNOWN ターゲットが認識されませんでした。
SEC_E_UNSUPPORTED_FUNCTION fContextReq パラメーターで無効なコンテキスト属性フラグ (ISC_REQ_DELEGATEまたはISC_REQ_PROMPT_FOR_CREDS) が指定されました。
SEC_E_WRONG_PRINCIPAL 認証要求を受信したプリンシパルは、 pszTargetName パラメーターに渡されたものと同じではありません。 これは、相互認証の失敗を示します。
SEC_E_APPLICATION_PROTOCOL_MISMATCH クライアントとサーバーの間に共通のアプリケーション プロトコルが存在しません。

解説

呼び出し元は、最終的なコンテキスト属性で十分かどうかを判断します。 たとえば、機密性が要求されたが確立できなかった場合、一部のアプリケーションは接続を直ちにシャットダウンすることを選択できます。

セキュリティ コンテキストの属性が十分でない場合、クライアントは DeleteSecurityContext 関数を呼び出して、部分的に作成されたコンテキストを解放する必要があります。

InitializeSecurityContext (Schannel) 関数は、クライアントが送信コンテキストを初期化するために使用します。

2 脚の セキュリティ コンテキストの場合、呼び出し元のシーケンスは次のようになります。

  1. クライアントは phContext を に設定して 関数を NULL 呼び出し、バッファー記述子に入力メッセージを入力します。
  2. セキュリティ パッケージはパラメーターを調べて不透明なトークンを構築し、それをバッファー配列の TOKEN 要素に配置します。 fContextReq パラメーターに ISC_REQ_ALLOCATE_MEMORY フラグが含まれている場合、セキュリティ パッケージはメモリを割り当て、TOKEN 要素内のポインターを返します。
  3. クライアントは、 pOutput バッファーで返されたトークンをターゲット サーバーに送信します。 その後、サーバーは AcceptSecurityContext (Schannel) 関数の呼び出しでトークンを入力引数として渡します。
  4. AcceptSecurityContext (Schannel) はトークンを返します。このトークンは、最初の呼び出しがSEC_I_CONTINUE_NEEDED返された場合に、 InitializeSecurityContext (Schannel) の 2 回目の呼び出しのためにサーバーがクライアントに送信します。

相互認証などの複数の脚の セキュリティ コンテキストの場合、呼び出しシーケンスは次のようになります。

  1. クライアントは前述のように関数を呼び出しますが、パッケージは成功コードSEC_I_CONTINUE_NEEDED返します。
  2. クライアントは出力トークンをサーバーに送信し、サーバーの応答を待機します。
  3. サーバーの応答を受信すると、クライアントは InitializeSecurityContext (Schannel) を再度呼び出し、 phContext は最後の呼び出しから返されたハンドルに設定されます。 サーバーから受信したトークンは、 pInput パラメーターで指定されます。
  4. InitializeSecurityContext (Schannel) の同時呼び出しでは phContext 値を使用しないでください。 セキュリティ プロバイダーの実装はスレッド セーフではありません。

サーバーが正常に応答した場合、 セキュリティ パッケージ は SEC_E_OKを返し、セキュリティで保護されたセッションが確立されます。

関数がいずれかのエラー応答を返す場合、サーバーの応答は受け入れられず、セッションは確立されません。

関数がSEC_I_CONTINUE_NEEDED、SEC_I_COMPLETE_NEEDED、またはSEC_I_COMPLETE_AND_CONTINUEを返す場合は、手順 2 と 3 が繰り返されます。

セキュリティ コンテキストを初期化するには、基になる認証メカニズムと、fContextReq パラメーターで指定された選択肢に応じて、この関数の複数の呼び出しが必要になる場合があります。

fContextReq パラメーターと pfContextAttributes パラメーターは、さまざまなコンテキスト属性を表すビットマスクです。 さまざまな属性の説明については、「 コンテキスト要件」を参照してください。 pfContextAttributes パラメーターは、成功した戻り値に対して有効ですが、コンテキストのセキュリティ側面に関連するフラグを調べる必要があるのは、最終的に成功した戻り時のみです。 中間の戻り値は、たとえば、ISC_RET_ALLOCATED_MEMORY フラグを設定できます。

ISC_REQ_USE_SUPPLIED_CREDS フラグが設定されている場合、 セキュリティ パッケージpInput 入力バッファーでSECBUFFER_PKG_PARAMSバッファーの種類を探す必要があります。 これは一般的なソリューションではありませんが、必要に応じて セキュリティ パッケージ とアプリケーションの強力なペアリングが可能になります。

ISC_REQ_ALLOCATE_MEMORY指定した場合、呼び出し元は FreeContextBuffer 関数を呼び出してメモリを解放する必要があります。

たとえば、入力トークンは LAN マネージャーからのチャレンジである可能性があります。 この場合、出力トークンはチャレンジに対する NTLM で暗号化された応答になります。

クライアントが実行するアクションは、この関数からのリターン コードによって異なります。 戻りコードがSEC_E_OKされている場合、2 回目の InitializeSecurityContext (Schannel) 呼び出しは行われず、サーバーからの応答は期待されません。 戻りコードがSEC_I_CONTINUE_NEEDED場合、クライアントはサーバーからの応答でトークンを受け取り、 InitializeSecurityContext (Schannel) の 2 回目の呼び出しで渡します。 SEC_I_COMPLETE_NEEDED戻りコードは、クライアントがメッセージの作成を完了し、 CompleteAuthToken 関数を呼び出す必要があることを示します。 SEC_I_COMPLETE_AND_CONTINUE コードには、これらの両方のアクションが組み込まれています。

InitializeSecurityContext (Schannel) が最初の (または唯一の) 呼び出しで成功を返す場合、呼び出し元は最終的に、認証交換の後の区間で呼び出しが失敗した場合でも、返されたハンドルで DeleteSecurityContext 関数を呼び出す必要があります。

クライアントは、正常に完了した後に InitializeSecurityContext (Schannel) を再度呼び出す場合があります。 これは、再認証が必要であることを セキュリティ パッケージ に示します。

カーネル モードの呼び出し元には、次の違いがあります。ターゲット名は、VirtualAlloc を使用して仮想メモリに割り当てる必要がある Unicode 文字列です。プールから割り当ててはいけません。 pInput および pOutput で渡され、提供されるバッファーは、プール内ではなく仮想メモリ内に存在する必要があります。

関数がSEC_I_INCOMPLETE_CREDENTIALSを返す場合は、資格情報に有効で信頼できる証明書を指定したことをチェックします。 証明書は、 AcquireCredentialsHandle (Schannel) 関数を呼び出すときに指定されます。 証明書は、サーバーによって信頼されている証明機関 (CA) によって発行されたクライアント認証証明書である必要があります。 サーバーによって信頼される CA の一覧を取得するには、 QueryContextAttributes (Schannel) 関数を呼び出し、SECPKG_ATTR_ISSUER_LIST_EX属性を指定します。

クライアント アプリケーションがサーバーによって信頼されている CA から認証証明書を受け取った後、アプリケーションは AcquireCredentialsHandle (Schannel) 関数を呼び出し、 InitializeSecurityContext (Schannel) を再度呼び出し、 phCredential パラメーターに新しい資格情報を指定して新しい資格情報を作成します。

要件

要件
サポートされている最小のクライアント Windows 8.1 [デスクトップ アプリのみ]
サポートされている最小のサーバー Windows Server 2012 R2 [デスクトップ アプリのみ]
Header Sspi.h (Security.h を含む)
ライブラリ Secur32.lib
[DLL] Secur32.dll

こちらもご覧ください

SSPI 関数

AcceptSecurityContext (Schannel)

AcquireCredentialsHandle (Schannel)

CompleteAuthToken

DeleteSecurityContext

FreeContextBuffer

SecBuffer

SecBufferDesc