3 セキュリティのプログラミング
次の項では、Oracle Tuxedo ATMIアプリケーションのセキュリティをコーディングする方法について説明します。
3.1 セキュリティのプログラミングとは
セキュリティのプログラミングとは、アプリケーション・トランザクション・モニター・インタフェース(ATMI)アプリケーション用のセキュリティ・コードを記述する作業です。アプリケーション・プログラマは、プログラムのロジックを表すコードを記述するほか、ATMIを使用して、アプリケーション・コードをOracle Tuxedoトランザクション・モニターにリンクします。ATMIプログラミング・インタフェースを使用すると、Oracle Tuxedoトランザクション・モニターで制御される、アプリケーション・クライアントとアプリケーション・サーバー間の通信を実現できます。ATMIには、CおよびCOBOL用の実装があります。
次の図は、アプリケーション・プログラマが、ATMI関数を使用して、ユーザーを認証したり、ユーザーによるアクセスを制御したり、公開キーによる暗号化の技術をアプリケーションに組み込んだりできることを示しています。ただし、図が示すとおり、監査およびリンク・レベルの暗号化を行うためのATMI関数は、アプリケーション・レベルでは用意されていません。監査は、Oracle Tuxedoのシステム・レベルで実行されます。また、リンク・レベルの暗号化は、アプリケーション管理者側で構成します。
図3-1 Oracle Tuxedoセキュリティのプログラミング

親トピック: セキュリティのプログラミング
3.2 セキュリティを備えたATMIアプリケーションのプログラミング
Oracle Tuxedoシステムには、セキュリティのニーズに応じた、様々なATMI関数が用意されています。
記述するセキュリティ・コードの種類 | 使用するATMI関数 |
---|---|
クライアントがATMIアプリケーションに参加し、アプリケーション・サービスにアクセスするためのクライアント・プログラム。 | ATMIアプリケーションに参加するクライアント用のATMI関数。認証および認可のプラグインに対するシステム・レベルの呼出しを行います。 |
クライアント/サーバー間で送受信されるデータの整合性と機密性を保つためのクライアント・プログラムおよびサーバー・プログラム。 | 公開キーセキュリティ。エンド・ツー・エンドのデジタル署名およびデータの暗号化をサポートします。 |
ノート:
親トピック: セキュリティのプログラミング
3.3 プログラミング環境の設定
セキュリティ・コードを記述するため、アプリケーション・プログラマには次の権限が必要です。
- Oracle Tuxedoのライブラリおよびコマンドに対するアクセス権
- Oracle Tuxedoシステムのディレクトリ構造内にあるディレクトリとファイルに対する読取り権および実行権
必要なライブラリおよびコマンドにアクセスするには、環境内で、TUXCONFIG
、TUXDIR
、APPDIR
、およびその他の環境変数を設定する必要があります。詳細は、『Oracle Tuxedoアプリケーション実行時の管理』の「環境変数の設定」を参照してください。
アプリケーション管理者は、ディレクトリおよびファイルのパーミッションを設定します。必要なパーミッションを取得するには、担当の管理者に問い合せてください。
親トピック: セキュリティのプログラミング
3.4 ATMIアプリケーションにクライアント・プログラムを参加させるためのセキュリティ・コードの記述方法
クライアント・プログラムには、アプリケーションまたはコンピュータ以外からのデータを収集したり、データをメッセージに組み込んだり、処理対象のメッセージをサーバーに転送する、という役割があります。ユーザーは、現金自動預入支払機(ATM)、データ入力端末、およびグラフィックス用デバイスなどを使用することにより、クライアント・プログラムを利用します。
デフォルトの認証および認可では、5つのセキュリティ・レベルのうち、いずれかをアプリケーションに設定できます。最も低いセキュリティ・レベルでは、認証は行われません。最も高いセキュリティ・レベルでは、アクセス制御リストの機能により、サービスを実行し、イベントをポストし、アプリケーション・キューのメッセージをキューに登録(または登録解除)するユーザーが決定されます。ATMIアプリケーションに対するセキュリティ・レベルの設定は、アプリケーション管理者の役割です。
クライアント・プログラムをATMIアプリケーションに参加させるため、アプリケーション・プログラマは、次の2つのタスクを実行する必要があります。
- 特定のクライアント・プロセスのセキュリティ・データを取得します。
- 取得したデータをOracle Tuxedoシステムに渡します。
次のリストに示されている擬似コードは、基本的なクライアント・プログラムの動作を示しています。セキュリティ関連の文は太字で示します。
リスト クライアントの擬似コード
main()
{
call tpchkauth() to check security level of ATMI application
get usrname, cltname
prompt for application password
prompt for per-user password
allocate a TPINIT buffer
place initial client identification into TPINIT buffer
call tpinit() to enroll as a client of the ATMI application
allocate buffer
do while true {
place user input in buffer
send service request
receive reply
pass reply to user }
leave application }
上のリスト内の大部分の文は、CまたはCOBOLのATMI関数によって実装されます。ただし、ここではC言語の実装だけを示しています。
Cで記述されたクライアント・プログラムは、tpinit(3c)を使用して、ATMIアプリケーションに設定されたセキュリティ・レベルに準拠し、アプリケーションに参加します。tpinit()
の引数は、TPINIT
バッファに対するポインタです。COBOLアプリケーションの場合、クライアント・プログラムはTPINITIALIZE(3cbl)
を呼び出し、引数としてTPINFDEF-REC
レコードに対するポインタを取ります。
ノート:
- セキュリティ・データの取得
- ATMIアプリケーションへの参加
- 『Cを使用したOracle Tuxedo ATMIアプリケーションのプログラミング』および『COBOLを使用したOracle Tuxedo ATMIアプリケーションのプログラミング』の「クライアントのコーディング」
- 『Oracle Tuxedo ATMI C関数リファレンス』の
「tpinit(3c)」
- 『Oracle Tuxedo ATMI COBOL関数リファレンス』の
TPINITIALIZE(3cbl)に関する項
- 公開キーセキュリティの管理
- 認可の管理
- デフォルトの認証と認可
- セキュリティを備えたATMIアプリケーションのプログラミング
親トピック: セキュリティのプログラミング
3.5 セキュリティ・データの取得
Oracle Tuxedoシステムには、様々なアプリケーションに対応できるように記述された一般的なクライアント・プログラム用のATMI関数が用意されています。クライアントは、このATMI関数を使用して、参加先のATMIアプリケーションに必要なセキュリティ・レベルを決定できます。このATMI関数は、tpchkauth(3c)(C)またはTPCHKAUTH(3cbl)
(COBOL)であり、デフォルトの認証および認可を使用するATMIアプリケーションで実行されます。tpchkauth()
関数およびTPCHKAUTH()
関数は、カスタマイズした認証または認可を使用するATMIアプリケーションでも使用できます。ただし、使用方法は、カスタマイズしたセキュリティ機能がどのように実装されているかに応じて異なります。ここでは、主にデフォルトの認証および認可の場合について説明します。
Cを使用するアプリケーション・プログラマは、tpchkauth()
を使用してアプリケーションのセキュリティ・レベルをチェックしてから、tpinit(3c)を呼び出します。これで、クライアント・プログラムは、tpinit()
呼出しに必要なATMIアプリケーション・パスワードとユーザー認証データの入力を要求できます。tpchkauth()
は引数なしで呼び出されます。
COBOLを使用するアプリケーション・プログラマは、同じ目的でTPCHKAUTH()
を使用してから、TPINITIALIZE(3cbl).を呼び出しますTPCHKAUTH(3cbl)とTPINITIALIZE(3cbl)の構文および機能は、tpchkauth(3c)とtpinit(3c)の場合と同じです。
tpchkauth()
関数(TPCHKAUTH()
ルーチン)を呼び出すと、次のいずれかの値が返されます。
- TPNOAUTH
- 通常のオペレーティング・システムへのログイン、およびファイルに対するパーミッションの指定以外は必要ありません。
TPNOAUTH
は、セキュリティ・レベルがNONE
のときに返されます。 - TPSYSAUTH
- アプリケーション・パスワードが必要です。クライアント・プログラムは、パスワードの入力をユーザーに要求し、入力されたパスワードを
TPINIT
バッファ(Cの場合)またはTPINFDEF-REC
レコード(COBOLの場合)のパスワード・フィールドに格納します。TPSYSAUTH
は、セキュリティ・レベルがAPP_PW
のときに返されます。 - TPAPPAUTH
- アプリケーション・パスワードが必要です。クライアントは、
TPINIT
バッファ(Cの場合)またはTPINFDEF-REC
レコード(COBOLの場合)のデータ・フィールド内の認証サービスに渡す値を指定するよう要求されます。TPAPPAUTH
は、セキュリティ・レベルがUSER_AUTH
、ACL
、またはMANDATORY_ACL
のときに返されます。
関連項目:
- ATMIアプリケーションへの参加
- 『Oracle Tuxedo Cを使用したOracle Tuxedo ATMIアプリケーションのプログラミング』および『Oracle Tuxedo COBOLを使用したOracle Tuxedo ATMIアプリケーションのプログラミング』の「クライアントのコーディング」
- 『Oracle Tuxedo ATMI C関数リファレンス』の
「tpinit(3c)」
および「tpchkauth(3c)」
- 『Oracle Tuxedo ATMI COBOL関数リファレンス』の
TPINITIALIZE(3cbl)
およびTPCHKAUTH(3cbl)に関する項
- デフォルトの認証と認可
- セキュリティを備えたATMIアプリケーションのプログラミング
親トピック: セキュリティのプログラミング
3.6 ATMIアプリケーションへの参加
セキュリティが設定されたATMIアプリケーションでは、TPINIT
バッファ(Cの場合)またはTPINFDEF-REC
レコード(COBOLの場合)を使用して、Oracle Tuxedoシステムにセキュリティ情報を渡す必要があります。TPINIT
バッファは、特殊な型付きバッファであり、クライアントがATMIアプリケーションに参加しようとするときに、クライアントのIDおよび認証情報をシステムに渡すためにクライアント・プログラムで使用されます。COBOLの場合は、TPINFDEF-REC
レコードが使用されます。
ヘッダー・ファイルatmi.h
にTPINIT
が定義され、COBOL COPY
ファイルにTPINFDEF-REC
が定義されます。これらの構造体は次のとおりです:
TPINIT構造体 | TPINFDEF-REC構造体 | ||
---|---|---|---|
char char char char long long long ノート: MAXTIDENT には30文字まで含めることができます。
|
usrname[MAXTIDENT+2]; cltname[MAXTIDENT+2]; passwd[MAXTIDENT+2]; grpname[MAXTIDENT+2]; flags; datalen; data;
|
05 USRNAME 05 CLTNAME 05 PASSWD 05 GRPNAME 05 NOTIFICATION-FLAG 88 TPU-SIG 88 TPU-DIP 88 TPU-IGN 05 ACCESS-FLAG 88 TPSA-FASTPATH 88 TPSA-PROTECTED 05 DATLEN |
PIC X(30). PIC X(30). PIC X(30). PIC X(30). PIC S9(9) COMP-5. VALUE 1. VALUE 2. VALUE 3. PIC S9(9) COMP-5. VALUE 1. VALUE 2. PIC S9(9) COMP-5. |
次の表で、TPINIT
バッファおよびTPINFDEF-REC
レコードのフィールドについて説明します:
表3-1 TPINITバッファおよびTPINFDEF-RECレコードのフィールド
TPINITのフィールド | TPINFDEF-RECのフィールド | 説明 |
---|---|---|
usrname |
USRNAME
|
ヌルで終了する30文字までの文字列。ユーザー名は呼出し側を表します。クライアント・プログラムの作成者は、ホスト・オペレーティング・システムへのログイン時に使用したログイン名を使用できます。 |
cltname |
CLTNAME |
クライアント名。*ヌルで終了する30文字までの文字列。クライアント名はクライアント・プログラムを表します。クライアント・プログラムの作成者は、このフィールドを使用して、クライアント・プログラム実行時のユーザーのロールやジョブを指定することができます。 |
passwd |
PASSWD |
アプリケーション・パスワード*。tpinit() またはTPINITIALIZE() は、このパスワードをTUXCONFIGファイル**に格納されている構成済のアプリケーション・パスワードと比較して、パスワードの検証を行います。
|
grpname
|
GRPNAME |
グループ名。ヌルで終了する30文字までの文字列。このフィールドはセキュリティとは無関係です。グループ名を使用すると、UBBCONFIGファイルで定義されているリソース・マネージャのグループにクライアントを関連付けることができます。 |
flags
|
NOTIFICATION-FLAG TPU-SIG TPU-DIP TPU-IGN ACCESS-FLAG TPSA-FASTPATH TPSA-PROTECTED |
通知フラグおよびアクセス・フラグ。このフィールドはセキュリティとは無関係です。フラグを設定すると、クライアントに対して使用する通知メカニズムおよびシステムのアクセス・モードを指定できます。選択内容は、UBBCONFIG ファイルのRESOURCESセクションの値をオーバーライドします(ただし、一部の例外を除く)。
|
datalen |
DATALEN
|
後に続く*ユーザー固有データ***の長さ。Cで記述されたクライアント・プログラムの作成者は、送信予定のユーザー固有データのバイト数を指定してTPINITNEED を呼び出して、このフィールドのサイズ値を取得できます。TPINITNEED は、atmi.h ヘッダー・ファイルに組み込まれているマクロです。
|
data |
N/A |
固定長*ではないユーザー固有データ***。tpinit() またはTPINITIALIZE() は、このユーザー固有データを認証サーバーに転送し、検証します。デフォルトの認証の場合、認証サーバーはAUTHSVR です。
|
* このフィールドは、デフォルトの認証および認可でUSER_AUTH、ACL 、またはMANDATORY_ACL のセキュリティ・レベルが指定された場合に必要です。** バイナリ形式のUBBCONFIG ファイル。tmloadcf(1) を使用して作成されます。*** 通常はユーザー・パスワード。
|
クライアント・プログラムは、tpalloc(3c)を呼び出してTPINIT
バッファを割り当てます。次のリストに示されているサンプル・コードでは、8バイトのアプリケーション固有のデータをtpinit()
に渡す準備を行い、クライアントがATMIアプリケーションに参加できるようにします。
リスト TPINITバッファを割り当ててATMIアプリケーションに参加する
.
.
.
TPINIT *tpinfo;
.
.
.
if ((tpinfo = (TPINIT *)tpalloc("TPINIT",(char *)NULL,
TPINITNEED(8))) == (TPINIT*)NULL){
Error Routine
}
.
.
.
tpinit(tpinfo) /* join an ATMI application */
.
.
.
ワークステーション・クライアントがtpinit()
関数またはTPINITIALIZE()
ルーチンを呼び出してATMIアプリケーションに参加すると、次の主なイベントが発生します。
- イニシエータのワークステーション・クライアントおよびターゲットのワークステーション・リスナー(WSL)が、リンク・レベルの暗号化(LLE)のmin-max値を交換します。これらの値は、イニシエータのワークステーション・クライアントとターゲットのWSHとの間でリンクを確立するために使用されます。LLEについては、「リンク・レベルの暗号化」を参照してください。
- イニシエータのワークステーション・クライアントとターゲットのWSHは、セキュリティ・トークンの交換によってお互いを認証します。デフォルトの認証の場合、クライアントのセキュリティ・データが
TPINIT
バッファまたはTPINFDEF-REC
レコードからターゲットのWSHに転送されると、認証は成功します。 - 認証に成功すると、イニシエータのワークステーション・クライアントは、
usrname
、cltname
、およびflags
の3つのフィールド値を含む別のバッファをターゲットのWSHに送信し、認証済のワークステーション・クライアントに関するこれらの情報が確実に伝わるようにします。
ネイティブ・クライアントがtpinit()
関数またはTPINITIALIZE()
ルーチンを呼び出してATMIアプリケーションに参加すると、認証だけが行われます。基本的に、ネイティブ・クライアントは、自分自身を認証します。
3.6.1 クライアントのセキュリティ・データの転送
次のリストは、ワークステーション・クライアントのTPINIT
バッファからデータを転送する様子を示しています。この図は、TPINFDEF-REC
レコードからデータを転送するプロセスを示しています。
図3-2 ワークステーション・クライアントのTPINITバッファからデータを転送する

ノート:
上の図に示す認可手順は、ネイティブ・クライアントがATMIアプリケーションに参加しようとする場合も基本的に同じです。ただし、ネットワーク・リンクやWSHは無関係です。ネイティブ・クライアントは、自分自身を認証するためです。上の図では、デフォルトの認証を使用するか、またはカスタマイズした認証を使用するかにより、Oracle Tuxedoシステムに送信される情報が異なる点に注意してください。デフォルトの認証の場合、cltname
、grpname
およびflags
の各フィールドの値が、プラグイン・インタフェース以外の方法で、ワークステーション・クライアントのデフォルトの認証プラグインに送信されます。一方、カスタマイズした認証の場合、クライアント・プログラムの作成者は、これらの値のほか、data
フィールドで選択した可変長の別の値を組み込むこともできます。
デフォルトの認証を使用する場合、ワークステーション・クライアントの認証プラグインでは、passwd
/ PASSWD
フィールドが使用され、ネットワーク経由で転送される情報が暗号化されます。このとき、暗号化アルゴリズムとして、56ビットのDES (Data Encryption Standard)が使用されます。ターゲットのWSHにある認証プラグインでは、TUXCONFIG
ファイルに格納されているアプリケーション・パスワードを使用して、この情報を復号化します。ネイティブ・クライアントの場合は、単に、passwd
/ PASSWD
フィールドの値と、TUXCONFIG
ファイルに格納されているアプリケーション・パスワードが比較されます。
ノート:
ワークステーション・クライアントでは、passwd/ PASSWDフィールドの値が、認証プラグイン・インタフェース以外の方法で、認証プラグインに送信されます。WSHでは、TUXCONFIG
ファイルに格納されたアプリケーション・パスワードが、アプリケーションの起動時に、認証プラグイン・インタフェースによって認証プラグインに送信されます。
ワークステーション・クライアントの認証に成功すると、tpinit()
関数は、最後の処理として、usrname
、cltname
、およびflags
の3つのフィールド値を含む別のバッファをWSHに送信し、認証済のワークステーション・クライアントに関するこれらの情報が確実に伝わるようにします。TPINITIALIZE()
ルーチンの場合も、最後の処理として、同様の情報を含む別のバッファを送信します。カスタマイズした認証プラグインでは、認証手順でこれらの情報がWSHに送信されない場合がありますが、WSH側ではレポートを作成するとき、つまりtmadmin(1)
printclient
(pclt
)コマンドを呼び出すときにこれらの情報を必要とします。
ワークステーションまたはネイティブ・クライアントは、セキュリティ・チェックにパスすると、サービス・リクエストを発行したり、応答を受信することができます。
親トピック: ATMIアプリケーションへの参加
3.6.2 ATMIアプリケーションに参加する前のサービス・リクエストの呼出し
ターゲットのATMIアプリケーションのSECURITY
がNONE
に設定されているか、または何も設定されていない場合に、クライアントが、tpinit()
またはTPINITIALIZE()
を呼び出す前にサービス・リクエスト(またはATMI関数)を呼び出すと、Oracle Tuxedoシステムは、NULL
パラメータでtpinit()
またはTPINITIALIZE()
を自動的に呼び出します。この操作により、次のような結果になります。
TPINIT
またはTPINFDEF-REC
の機能は使用できません。- クライアントの命名、非請求の通知、およびシステムのアクセス・モードには、デフォルト値が使用されます。
- クライアントをリソース・マネージャのグループに関連付けることはできません。
- アプリケーション・パスワードは指定できません。
ターゲットのATMIアプリケーションのSECURITY
がAPP_PW
、USER_AUTH
、ACL
、またはMANDATORY_ACL
に設定されている場合に、クライアントが、tpinit()
またはTPINITIALIZE()
を呼び出す前にサービス・リクエスト(またはATMI関数)を呼び出すと、そのサービス・リクエストは拒否されます。
関連項目:
- 『Oracle Tuxedo Cを使用したOracle Tuxedo ATMIアプリケーションのプログラミング』および『Oracle Tuxedo COBOLを使用したOracle Tuxedo ATMIアプリケーションのプログラミング』のクライアントのコーディングに関する項
- 『Oracle Tuxedo ATMI C関数リファレンス』の「tpinit(3c)」および「tpalloc(3c)」
- 『Oracle Tuxedo ATMI COBOL関数リファレンス』の
TPINITIALIZE(3cbl)に関する項
- デフォルトの認証と認可
- セキュリティを備えたATMIアプリケーションのプログラミング
親トピック: ATMIアプリケーションへの参加
3.7 データの整合性と機密性を保護するためのセキュリティ・コードの記述方法
公開キーによるセキュリティは、エンド・ツー・エンドのデジタル署名およびデータの暗号化で構成されています。これらの2つの機能は、Oracle Tuxedo ATMI関数で実現できます。インターネット上でアプリケーションを使用する場合は、公開キーでセキュリティ保護されたATMIアプリケーションの方が、保護されていないアプリケーションより安全です。
エンド・ツー・エンドのデジタル署名とデータの暗号化は、メッセージ・ベースのデジタル署名およびメッセージ・ベースの暗号化の機能によって実現できます。これらの機能は、PKCS-7標準に基づいています。PKCS-7は、RSA Laboratoriesが主要な通信会社の協力のもとに開発した、PKCS (Public-Key Cryptography Standards)という規格の1つです。
メッセージ・ベースのデジタル署名では、送信者のIDを特定のメッセージ・バッファとバインドすることにより、データの整合性を保ち、送信者がメッセージを送信した事実を否認できないようにします。メッセージ・ベースの暗号化では、指定した受信者だけがメッセージを復号化できるため、メッセージの機密性が保たれます。
デジタル署名および暗号化は、ATMIのメッセージ・バッファ単位で行われます。したがって、これらの機能は、既存のATMIのプログラミング・インタフェースおよび通信パラダイムと互換性があります。メッセージ・バッファは、署名することも暗号化することもできます。メッセージ・バッファに関連するデジタル署名の数と暗号化エンベロープの数の間に、関係を成立させる必要はありません。
ノート:
各暗号化エンベロープには、メッセージの受信者を識別し、受信者がメッセージを復号化するために必要な情報が含まれています。3.7.1 公開キーによるセキュリティのATMIインタフェース
公開キーによるセキュリティのATMIは、次の処理を行う関数群です。
- 主要なリソースをオープンおよびクローズします。
- 主要なオプション・パラメータを表示および変更します。
- メッセージ・バッファを署名および封印(暗号化)します。
- メッセージ・バッファに関連付けられたデジタル署名および暗号化情報にアクセスします。
- 型付きメッセージ・バッファを、マシンに依存しないエクスポート可能な文字列表現に変換します(バッファに関連する暗号化エンベロープやデジタル署名の生成を含む)。
公開キーによるセキュリティのATMIインタフェースには、CおよびCOBOLの2つの実装があります。ただし、ATMI COBOL言語バインディングでは、メッセージ・バッファがサポートされません。したがって、個別のバッファに対する明示的な署名、暗号化、および問合せ操作は、COBOLのアプリケーションでは使用できません。一方、キー管理のインタフェースでは、COBOL言語バインドがサポートされているため、AUTOSIGN
モードで署名を生成したり、AUTOENCRYPT
モードで暗号化エンベロープを生成できます。署名の自動検証機能または自動復号化機能に関するすべての操作は、COBOLのクライアント・プロセスおよびサーバー・プロセスに適用できます。
ノート:
COBOLのTPKEYDEF
レコードは、メッセージ・ベースのデジタル署名と暗号化操作を実行するための公開キーと秘密キーの管理に使用されます。TPKEYDEF
レコードの詳細は、『Oracle Tuxedo ATMI COBOL関数リファレンス』の紹介部分にある「COBOL言語ATMIの戻り値とその他の定義」を参照してください。
次の各表は、公開キーによるセキュリティのATMIをまとめたものです。各関数については、『Oracle Tuxedo ATMI C関数リファレンス』および『Oracle Tuxedo ATMI COBOL関数リファレンス』も参照してください。
表3-2 公開キーによるセキュリティのATMIインタフェースの関数
使用する関数 | 目的 |
---|---|
tpkey_open(3c) |
デジタル署名の生成、メッセージの暗号化、またはメッセージの復号化のためのキー・ハンドルをオープンします。キーは、ハンドルを使用して表示および操作します。ハンドルには関連するデータがあり、ATMIアプリケーションはこのデータを使用して、ハンドルが指定する項目を検索したり、項目にアクセスします。キーは、次のいずれか、または複数の役割を果します。
|
tpkey_getinfo(3c) |
キー・ハンドルに関連付けられた情報を取得します。暗号化のサービス・プロバイダに固有の情報も含まれていますが、次の属性に関しては、すべてのサービス・プロバイダでサポートされます。
|
tpkey_setinfo(3c)
|
キー・ハンドルに関連付けられたオプションの属性パラメータを設定します。キー・ハンドルの属性のうち、主要な属性は、tpkey_getinfo() ですでに説明しています。このほか、特定の暗号サービス・プロバイダに固有な属性を使用することもできます。
|
tpkey_close(3c) |
すでにオープンしたキー・ハンドルをクローズします。キー・ハンドルは、tpkey_open() を使用して明示的にオープンしたり、tpenvelope() を使用して暗黙的に(自動的に)オープンできます。
|
tpsign(3c) |
デジタル署名の型付きメッセージ・バッファをマークします。公開キーソフトウェアは、メッセージが送信される直前にデジタル署名を生成します。 |
tpseal(3c) |
暗号化の型付きメッセージ・バッファをマークします。公開キーソフトウェアは、メッセージが送信される直前にメッセージを暗号化します。 |
tpenvelope(3c) |
型付きメッセージ・バッファに関連付けられたデジタル署名および暗号化情報にアクセスします。tpenvelope() は、特定のメッセージ・バッファに添付されたデジタル署名および暗号化エンベロープに関するステータス情報を返します。また、各デジタル署名や暗号化エンベロープに関連付けられたキー・ハンドルも返します。デジタル署名のキー・ハンドルは署名者を識別し、暗号化エンベロープのキー・ハンドルはメッセージの受信者を識別します。
|
tpexport(3c) |
型付きメッセージ・バッファを、マシンに依存しない(外部化された)エクスポート可能な文字列表現に変換します。tpexport() は、このバッファを外部化された文字列表現に変換する直前に、型付きメッセージ・バッファに関連付けられたデジタル署名や暗号化エンベロープを生成します。外部化された文字列表現は、任意の通信メカニズムを使用して、プロセス間、マシン間、またはドメイン間で送信できます。この文字列表現は恒久的なストレージにアーカイブできます。
|
tpimport(3c) |
外部化された文字列表現を型付きメッセージ・バッファに変換します。変換中、tpimport() は、必要に応じてメッセージを復号化し、関連するデジタル署名を検証します。
|
表3-3 公開キーによるセキュリティのATMIのCOBOLルーチン
使用するルーチン | 目的 |
---|---|
TPKEYOPEN(3cbl) |
デジタル署名の生成、メッセージの暗号化、またはメッセージの復号化のためのキー・ハンドルをオープンします。キーは、ハンドルを使用して表示および操作します。ハンドルには関連するデータがあり、ATMIアプリケーションはこのデータを使用して、ハンドルが指定する項目を検索したり、項目にアクセスします。キーは、次のいずれか、または複数の役割を果します。
|
TPKEYGETINFO(3cbl) |
キー・ハンドルに関連付けられた情報を取得します。暗号化のサービス・プロバイダに固有の情報も含まれていますが、次の属性に関しては、すべてのサービス・プロバイダでサポートされます。
|
TPKEYSETINFO(3cbl) |
キー・ハンドルに関連付けられたオプションの属性パラメータを設定します。キー・ハンドルの属性のうち、主要な属性は、 TPKEYGETINFO() ですでに説明しています。このほか、特定の暗号サービス・プロバイダに固有な属性を使用することもできます。
|
TPKEYCLOSE(3cbl) |
TPKEYOPEN() を使用してすでにオープンしたキー・ハンドルをクローズします。
|
3.7.2 公開キーのセキュリティで推奨されている事項について
- デジタル署名の生成またはデータの復号化に使用したキー・ハンドルが不要になったら、
tpkey_close()
を使用してただちに解放してください。 - リプレイ攻撃を防ぐため、デジタル署名は、特定の操作に関する詳しい情報を指定したメッセージ・バッファに対してのみ作成してください。たとえば、「預金残高を確認しました」というメッセージだけを含むバッファは危険です。簡単に傍受され、再利用されてしまうためです。一方、操作に固有な情報を多く含むメッセージはより安全です。たとえば、「2001年7月31日付けのJohn Smith様の確認コード123456789、口座987654321の預金残高は、$100.00です」という詳しいメッセージであれば、傍受されても簡単に再利用することはできません。
3.8 署名付きメッセージの送信と受信
メッセージ・ベースのデジタル署名では、エンド・ツー・エンドの認証が行われ、メッセージの整合性が保たれます。この機能のしくみについては、1-37ページの「ATMI PKCS-7のエンド・ツー・エンドのデジタル署名」の図を参照してください。
ATMIのメッセージ・バッファにデジタル署名を追加するには、発信元のプロセスまたはユーザーがメッセージ・バッファに署名します。この署名には、メッセージ・バッファの内容から得た、暗号法的に安全なチェックサムと、署名者のローカル・クロックに基づいたタイムスタンプが含まれています。
このメッセージ・バッファに対するアクセス権がある場合は、署名者の署名が本物であるかどうか、メッセージ・バッファの内容が変更されていないかどうか、およびタイムスタンプが検証者のローカル・クロックで受け付ける時刻の範囲内かどうかを検証できます。さらに、時間に依存しない、サード・パーティによる検証を行うと、メッセージの非否認性を保証できます。つまり、発信元のプロセスまたはユーザーは、メッセージを送信した事実を否認したり、メッセージが改ざんされたと主張することはできません。
3.8.1 署名付きメッセージを送信するためのコードの作成
次の図では、署名付きメッセージを送信するコードを記述する手順を示します。
図3-3 署名付きメッセージの送信手順

これらのステップおよびメッセージ・バッファが署名されるしくみについては、次の項を参照してください。
- ステップ1:デジタル署名用のキー・ハンドルをオープンする
- ステップ2 (オプション):キー・ハンドルの情報を取得する
- ステップ3 (オプション):キー・ハンドルの情報を変更する
- ステップ4:バッファを割り当ててメッセージを指定する
- ステップ5:デジタル署名を添付するバッファにマークを付ける
- ステップ6:メッセージを送信する
- ステップ7:署名者のキー・ハンドルをクローズする
- デジタル署名の生成方法
親トピック: 署名付きメッセージの送信と受信
3.8.1.1 ステップ1: デジタル署名用のキー・ハンドルをオープンする
まず、tpkey_open(3c)関数またはTPKEYOPEN(3cbl)
ルーチンを呼び出して、発信元プロセスが、署名者の秘密キーおよび関連するデジタル証明書を使用できるようにします。秘密キーは厳しくセキュリティ保護されているため、秘密キーを所有することは、署名者のIDを所有することと同等の意味があります。
署名者の秘密キーにアクセスするため、発信元プロセスは、署名者として動作する権限があることを証明する必要があります。証明の条件は、公開キーのプラグイン・インタフェースの実装によって異なります。デフォルトの公開キーの実装では、呼出しプロセス側が秘密のパスワードを入力する必要があります。
発信元プロセスがtpkey_open()
を呼び出してキー・ハンドルをオープンするとき、TPKEY_SIGNATURE
フラグまたはTPKEY_AUTOSIGN
フラグを指定して、そのキー・ハンドルがメッセージ・バッファのデジタル署名に使用されることを示します。通常、クライアントはtpinit()
を呼び出した後でこの呼出しを行い、サーバーはtpsvrinit()
を呼び出して初期化を行うときにこの呼出しを行います。
TPKEY_AUTOSIGN
フラグを使用してキー・ハンドルをオープンすると、署名の自動生成が可能になります。以降、発信元プロセスは、メッセージ・バッファが送信されるたびに、メッセージ・バッファに自動的に署名します。TPKEY_AUTOSIGN
フラグを使用すると、次の3つの利点があります。
- セキュリティ保護されたATMIアプリケーションではATMI呼出しが少なくなるため、アプリケーション・プログラマの作業が減ります。
- 最小限のコーディングを行うだけで、既存のATMIアプリケーションにデジタル署名の技術を組み込むことができます。
- デジタル署名のないバッファがセキュリティ保護されていないネットワーク上で送信されてしまう、というプログラミング上のエラーの数を抑えることができます。
次のリストに、署名者のキー・ハンドルをオープンする方法を示します。TPKEY
は、atmi.h
ヘッダー・ファイルで定義される特殊なデータ型です。
リスト 署名者のキー・ハンドルをオープンする例
main(argc, argv)
int argc;
char *argv[];
#endif
{
TPKEY sdo_key;
char *sdo_location;
.
.
.
if (tpkey_open(&sdo_key, “sdo”,
sdo_location,
NULL, 0, TPKEY_SIGNATURE) ==
-1) {
(void) fprintf(stderr,
“tpkey_open sdo failed
tperrno=%d(%s)\n”,
tperrno, tpstrerror(tperrno));
exit(1);
}
.
.
.
}
親トピック: 署名付きメッセージを送信するためのコードの作成
3.8.1.2 ステップ2 (オプション): キー・ハンドルの情報を取得する
署名者のキー・ハンドルの情報を取得して、キーの有効性を確認することができます。そのためには、 tpkey_getinfo(3c)関数またはTPKEYGETINFO(3cbl)
ルーチンを呼び出します。返される情報の中には、暗号サービス・プロバイダに固有の情報も含まれていますが、主要な属性は、すべてのプロバイダで共通です。
デフォルトの公開キーの実装では、メッセージ・バッファの署名を計算するための次の署名モードがサポートされています。
- RSA公開キー署名によるMD5メッセージ・ダイジェスト・アルゴリズム
- RSA公開キー署名によるSHA-1メッセージ・ダイジェスト・アルゴリズム
メッセージ・ダイジェスト・アルゴリズムはDIGEST_ALG
のキー属性によって制御され、公開キー署名はSIGNATURE_ALG
のキー属性によって制御されます。サポートされている公開キーのサイズは512 - 2048ビットであり、安全性とパフォーマンスを実現するためには十分な範囲です。公開キーのサイズは、SIGNATURE_BITS
キー属性によって制御されます。
デフォルトの公開キーの実装では、前述のアルゴリズムおよびキー・サイズの範囲で作成されたデジタル証明書の署名だけが認識されます。
次のリストに、署名者のキー・ハンドルに関する情報を取得する方法を示します。
リスト 署名者のキー・ハンドルに関する情報を取得する例
main(argc, argv)
int argc;
char *argv[];
#endif
{
TPKEY sdo_key;
char principal_name[PNAME_LEN];
long pname_len = PNAME_LEN;
.
.
.
if (tpkey_getinfo(sdo_key, “PRINCIPAL”,principal_name,&pname_len, 0) == -1) {(void) fprintf(stdout,
“Unable to get information about principal: %d(%s)\n”,
tperrno,
tpstrerror(tperrno));
.
.
.
exit(1);
}
.
.
.
}
親トピック: 署名付きメッセージを送信するためのコードの作成
3.8.1.3 ステップ3 (オプション): キー・ハンドルの情報を変更する
署名者のキー・ハンドルに関連付けられたオプション属性を設定するには、tpkey_setinfo(3c)関数またはTPKEYSETINFO(3cbl)
ルーチンを呼び出します。キー・ハンドル属性は、暗号サービス・プロバイダによって異なります。
次のリストのサンプル・コードでは、署名者のキー・ハンドルに関連付けられた情報を変更する方法を示します。
リスト 署名者のキー・ハンドルに関連付けられた情報を変更する例
main(argc, argv)
int argc;
char *argv[];
#endif
{
TPKEY sdo_key;
static const unsigned char sha1_objid[] = {
0x06, 0x05, 0x2b, 0x0e, 0x03,0x02, 0x1a
};
.
.
.
if (tpkey_setinfo(sdo_key, “DIGEST_ALG”, (void *) sha1_objid,
sizeof(sha1_objid), 0) == -1){
(void) fprintf(stderr, “tpkey_setinfo failed
tperrno=%d(%s)\n”,
tperrno, tpstrerror(tperrno));
return(1);
}
.
.
.
}
親トピック: 署名付きメッセージを送信するためのコードの作成
3.8.1.4 ステップ4: バッファを割り当ててメッセージを指定する
型付きメッセージ・バッファを割り当てるには、tpalloc(3c)関数を呼び出します。続いて、バッファにメッセージを指定します。
親トピック: 署名付きメッセージを送信するためのコードの作成
3.8.1.5 ステップ5: デジタル署名を添付するバッファにマークを付ける
メッセージ・バッファにデジタル署名のマークを付ける(登録する)には、tpsign(3c)関数を呼び出します。この関数を呼び出すと、署名者のキー・ハンドルのコピーがメッセージ・バッファに添付されます。TPKEY_AUTOSIGN
フラグを指定してキーをオープンすると、tpsign()
を明示的に呼び出さなくても、デジタル署名を添付するメッセージには自動的にマークが付きます。署名パラメータは保存され、後で使用するためにバッファに関連付けられます。
次のサンプル・コードは、デジタル署名を添付するメッセージ・バッファにマークを付ける方法を示しています。
リスト デジタル署名を添付するメッセージ・バッファにマークを付ける例
main(argc, argv)
int argc;
char *argv[];
#endif
{
TPKEY sdo_key;
char *sendbuf, *rcvbuf;
.
.
.
if (tpsign(sendbuf, sdo_key, 0) == -1) {
(void) fprintf(stderr, “tpsign failed tperrno=%d(%s)\n”,
tperrno,tpstrerror(tperrno));
tpfree(rcvbuf);
tpfree(sendbuf);
tpterm();
(void) tpkey_close(sdo_key,0);
exit(1);
}
.
.
.
}
親トピック: 署名付きメッセージを送信するためのコードの作成
3.8.1.6 ステップ6: メッセージを送信する
メッセージ・バッファにデジタル署名のマークを付けた後、次のいずれかのC関数またはCOBOLルーチンを使用して、メッセージ・バッファを送信します。
-
tpcall()
またはTPCALL
-
tpbroadcast()
またはTPBROADCAST
-
tpconnect()
またはTPCONNECT
-
tpenqueue()
またはTPENQUEUE
-
tpforward()
-
tpnotify()
またはTPNOTIFY
-
tppost()
またはTPPOST
-
tpreturn()
またはTPRETURN
-
tpsend()
またはTPSEND
親トピック: 署名付きメッセージを送信するためのコードの作成
3.8.1.7 ステップ7: 署名者のキー・ハンドルをクローズする
tpkey_close(3c)関数またはTPKEYCLOSE(3cbl)
ルーチンを呼び出して、署名者のキー・ハンドルとそれに関連付けられたすべてのリソースを解放します。
親トピック: 署名付きメッセージを送信するためのコードの作成
3.8.1.8 デジタル署名の生成方法
公開キー・ソフトウェアは、送信前にメッセージ・バッファにデジタル署名します。デジタル署名されたバッファが複数回送信される場合は、送信のたびに新しい署名が生成されます。したがって、デジタル署名を行うメッセージ・バッファにマークを付けた後で、そのメッセージ・バッファを変更することができます。
公開キー・ソフトウェアは、次の3ステップの手順でデジタル署名を生成します。
- digest [message_buffer_data + buffer_type_string + buffer_subtype_string] = hash1
- digest [hash1 + local_timestamp + PKCS-7_message_type] = hash2
- {hash2}signer's_private_key = encrypted_hash2 = digital_signature
digest[ ]という表記法は、メッセージ・ダイジェスト・アルゴリズム(この場合はMD5またはSHA-1)を使用して[ ]内のハッシュ値が計算されることを示します。{ }keyという表記法は、keyを使用して{ }内が暗号化または復号化されることを示します。この場合、計算されたハッシュ値は、署名者の秘密キーを使用して暗号化されます。
3.8.1.8.1 署名のタイムスタンプ
デジタル署名には、ローカル・システムのクロックに基づいたタイムスタンプが組み込まれます。このようなタイムスタンプを組み込むことにより、受信者が署名を検証するときに、タイムスタンプ値の改ざんが検出されます。さらに、デジタル署名付きメッセージが宛先にルーティングされるとき、そのメッセージにはタイムスタンプのコピーが添付されます。タイムスタンプは、秒単位まで表記されます。また、タイムスタンプは、PKCS-9のSigningTime
形式で表記されます。
親トピック: デジタル署名の生成方法
3.8.1.8.2 複数の署名について
1つのメッセージ・バッファには、複数の署名を関連付けることができます。つまり、1つのメッセージ・バッファに対して、任意の数の署名者が同時に署名できます。署名できるのは、ユーザーまたはプロセスです。各署名者は、自分の秘密キーを使用してメッセージ・バッファに署名します。
署名が異なる場合は、別のメッセージ・ダイジェスト・アルゴリズムまたはデジタル署名アルゴリズムを使用している可能性があります。同じメッセージ・ダイジェストおよびデジタル署名アルゴリズムを使用した署名が2つある場合、ハッシュ値はどちらか1つだけに対してだけ計算されます。
親トピック: デジタル署名の生成方法
3.8.1.8.3 署名付きメッセージの内容
デジタル署名付きのメッセージ・バッファは、SignedData
というメッセージ・タイプのバージョン1として、PKCS-7形式で表現されます。Oracle Tuxedoシステムで使用されるメッセージ・タイプSignedData
は、次の項目で構成されます。
- 1つ以上のデジタル署名。各デジタル署名は、署名者に固有な次の情報で構成されています。
- 署名者のX.509v3形式の証明書
- メッセージ・ダイジェストおよびデジタル署名アルゴリズムの識別子
- ローカル・クロックに基づくタイムスタンプ
- メッセージの内容。メッセージ・バッファのデータ、バッファ・タイプの文字列、およびバッファのサブタイプの文字列をまとめてOracle Tuxedoのエンコード形式で表現したものです。このエンコード形式により、メッセージ・バッファの署名は、どのマシンのアーキテクチャを使用しても検証できます。
次の図に示すように、メッセージの内容は、SignedData
というメッセージ・タイプによって包含されています。
図3-4 SignedDataメッセージ・タイプ

親トピック: デジタル署名の生成方法
3.8.2 署名付きメッセージの受信方法
署名付きメッセージ・バッファを受信するためのATMIアプリケーション・コードは必要ありません。公開キーソフトウェアは、添付されたデジタル署名を自動的に検証し、そのメッセージを受信側のプロセスに渡します。
受信側のプロセスのかわりに動作する公開キーソフトウェアは、署名付きメッセージ・バッファを受信すると、次のタスクを実行します。
- 署名者のデジタル証明書、メッセージ・ダイジェスト・アルゴリズム、デジタル署名アルゴリズム、署名のタイムスタンプなど、受信されたメッセージに添付されているデジタル署名情報を読み取ります。
- 署名者の公開キー(署名者のデジタル証明書に格納)とデジタル署名アルゴリズムを使用して、添付されたデジタル署名(暗号化されたハッシュ値)を復号化します。
- 次に示すように、次の2ステップ手順に示されるとおり、受信したメッセージのハッシュ値を再計算します。
- digest[message_buffer_data + buffer_type_string + buffer_subtype_string] = hash1
- digest[hash1 + received_timestamp + PKCS-7_message_type] = hash2
- 再計算されたハッシュ値と受信したハッシュ値を比較します。これらが同一でない場合、メッセージ・バッファが破棄されます。
- 受信したタイムスタンプとローカル・システムのクロックを比較します。タイムスタンプが許容範囲内にない場合、メッセージ・バッファは破棄されます。
- メッセージ・バッファがステップ4および5のチェックにパスすると、公開キーソフトウェアは、メッセージ・バッファのデータ、バッファ・タイプの文字列、およびバッファのサブタイプの文字列をデコードし、受信側のプロセスにメッセージを渡します。これは、発信元プロセスで行われるエンコードと逆のステップです。このOracle Tuxedoのエンコード形式により、メッセージ・バッファの署名は、どのマシンのアーキテクチャを使用しても検証できます。
ノート:
添付されたデジタル署名をどれも検証できない場合、受信側のプロセスは、メッセージ・バッファを受け取りません。さらに、受信側のプロセスは、メッセージ・バッファをまったく認識しません。3.8.2.1 デジタル署名を検証する
公開キーソフトウェアは、クライアント・プロセス、サーバー・プロセス、またはメッセージ・バッファの内容を読み取るシステム・プロセスに署名付きメッセージ・バッファがあると、メッセージに添付されたデジタル署名を自動的に検証します。ただし、パイプ役として機能するシステム・プロセス (メッセージの内容は読み取らない)の場合、メッセージに添付されたデジタル署名は検証されません。たとえば、ブリッジおよびワークステーション・ハンドラ(WSH)は、パイプ役として機能するシステム・プロセスの例です。
署名に記録されたタイムスタンプは、非同期のクロックに基づいているため、特に、PCまたはパーソナル・コンピュータで署名が行われた場合は、完全に信頼できません。ただし、遠い過去または将来を示すタイムスタンプが記録されたリクエストを、サーバー側で拒否することができます。タイムスタンプに基づいてリクエストを拒否する機能を使用すると、リプレイ攻撃から保護することができます。
親トピック: 署名付きメッセージの受信方法
3.8.2.2 入力バッファの署名を検証および送信する
メッセージ・バッファが入力パラメータとしてATMI関数(tpacall()
など)に渡された場合、公開キーソフトウェアは、メッセージにあらかじめ添付された署名を検証してから、メッセージを転送します。この動作によって、複数のプロセスからの署名を付けた情報を、安全かつ確実に転送することができます。
サーバーが受信したメッセージ・バッファを変更して転送すると、元の署名は無効になります。この場合、公開キーソフトウェアは、無効な署名を検出して破棄します。このプロセスの例は、「入力バッファの暗号化エンベロープを破棄する」を参照してください。
親トピック: 署名付きメッセージの受信方法
3.8.2.3 出力バッファの署名を置換する
メッセージ・バッファが出力パラメータとしてATMI関数(tpgetreply()
など)に渡された場合、公開キーソフトウェアは、このバッファに関連付けられた署名の情報を削除します。この情報には、保留中の署名、およびバッファの前回使用時の署名が含まれます。(保留中の署名とは、メッセージ・バッファに登録された署名です。)
この操作が正常に終了すると、新しい署名の情報が新しいバッファの内容に関連付けられる場合があります。
親トピック: 署名付きメッセージの受信方法
3.9 暗号化されたメッセージの送信と受信
メッセージ・ベースの暗号化では、エンド・ツー・エンドでデータの機密性が保たれます。この機能のしくみについては、1-42ページの「ATMI PKCS-7のエンド・ツー・エンドの暗号化」の図を参照してください。
メッセージは、発信元プロセスを離れる直前に暗号化され、その状態は受信側のプロセスで受信されるまで保持されます。メッセージは、オペレーティング・システムのメッセージ・キュー、システム・プロセス、ディスク・ベース・キューなどの中継ポイントのほか、サーバー間のネットワーク・リンクで転送される間もオペークです。
3.9.1 暗号化されたメッセージを送信するためのコードの作成
図3-5 暗号化されたメッセージの送信手順

これらのステップおよびメッセージ・バッファが暗号化されるしくみについては、次の項を参照してください。
- ステップ1:暗号化用のキー・ハンドルをオープンする
- ステップ2 (オプション):キー・ハンドルの情報を取得する
- ステップ3 (オプション):キー・ハンドルの情報を変更する
- ステップ4:バッファを割り当ててメッセージを指定する
- ステップ5:暗号化するバッファにマークを付ける
- ステップ6:メッセージを送信する
- ステップ7:暗号化キー・ハンドルをクローズする
- メッセージ・バッファの暗号化方法
親トピック: 暗号化されたメッセージの送信と受信
3.9.1.1 ステップ1: 暗号化用のキー・ハンドルをオープンする
tpkey_open(3c)関数またはTPKEYOPEN(3cbl)
ルーチンを呼び出して、発信元プロセスが、ターゲット受信者のデジタル証明書を使用できるようにします。ターゲット受信者とは、クライアント、サービス、サーバー・グループ、ゲートウェイ・グループ、サーバー・マシン、または複数のサーバーを含むドメイン全体のことです。
発信元プロセスがtpkey_open()
を呼び出してキー・ハンドルをオープンするとき、TPKEY_ENCRYPT
フラグまたはTPKEY_AUTOENCRYPT
フラグを指定して、そのキー・ハンドルがメッセージ・バッファの暗号化に使用されることを示します。通常、クライアントはtpinit()
を呼び出した後でこの呼出しを行い、サーバーはtpsvrinit()
を呼び出して初期化を行うときにこの呼出しを行います。
TPKEY_AUTOENCRYPT
フラグを使用してキー・ハンドルをオープンすると、暗号化の自動処理が可能になります。以降、発信元プロセスは、メッセージ・バッファが送信されるたびに、メッセージ・バッファを自動的に暗号化します。TPKEY_AUTOENCRYPT
フラグを使用すると、次の3つの利点があります。
- セキュリティ保護されたATMIアプリケーションではATMI呼出しが少なくなるため、アプリケーション・プログラマの作業が減ります。
- 最小限のコーディングを行うだけで、既存のATMIアプリケーションに暗号化の技術を組み込むことができます。
- 暗号化されていない(平文の)バッファがセキュリティ保護されていないネットワーク上で送信されてしまう、というプログラミング上のエラーの数を抑えることができます。
リストに、暗号化キー・ハンドルをオープンする方法を示します。TPKEY
は、atmi.h
ヘッダー・ファイルで定義される特殊なデータ型です。
リスト 暗号化キー・ハンドルをオープンする例
main(argc, argv)
int argc;
char *argv[];
#endif
{
TPKEY tu_key;
.
.
.
if (tpkey_open(&tu_key,
“TOUPPER”, NULL,
NULL, 0, TPKEY_ENCRYPT) == -1)
{
(void) fprintf(stderr,
“tpkey_open tu failed
tperrno=%d(%s)\n”,tperrno, tpstrerror(tperrno));
exit(1);
}
.
.
.
}
親トピック: 暗号化されたメッセージを送信するためのコードの作成
3.9.1.2 ステップ2 (オプション): キー・ハンドルの情報を取得する
暗号化キー・ハンドルの情報を取得して、キーの有効性を確認することができます。そのためには、 tpkey_getinfo(3c)関数またはTPKEYGETINFO(3cbl)
ルーチンを呼び出します。返される情報の中には、暗号サービス・プロバイダに固有の情報も含まれていますが、主要な属性は、すべてのプロバイダで共通です。
デフォルトの公開キーの実装では、バルク・データを暗号化するための3つのアルゴリズムがサポートされています。
- DES (DES-CBC) - CBC (Cipher Block Chaining)モードで実行する64ビット単位のブロック暗号です。56ビット(64ビットの暗号化キーから8パリティ・ビットを引いたもの)のキーを使用し、米国以外の国でも使用できます。DESはData Encryption Standardの略です。
- 3DES (2つのキーによるTriple DES) - EDE (Encrypt-Decrypt-Encrypt)モードで実行する128ビット単位のブロック暗号です。 3DESでは、56ビット(実際には112ビット)のキーを使用します。米国から輸出することは禁止されています。
- RC2 - 40 - 128ビットの範囲で、暗号キーのサイズを変更できるブロック暗号です。DESより高速であり、40ビットの暗号キーは輸出できます。米国籍の企業の海外子会社および海外支店であれば、56ビットの暗号キーを使用することができます。公開キー・ソフトウェアでは、暗号キーの長さを128ビットに制限していますが、米国では実質的に、RC2にはどんな長さのキーを使用することもできます。RC2はRivest's Cipher 2の略です。
暗号化のレベルは、ENCRYPT_BITS
のキー属性によって制御され、アルゴリズムはENCRYPT_ALG
のキー属性によって制御されます。ENCRYPT_ALG
で固定キー長によるアルゴリズムが設定されると、ENCRYPT_BITS
の値が自動的に調整されます。
次のリストに、暗号化キー・ハンドルに関する情報を取得する方法を示します。
リスト 暗号化キー・ハンドルに関する情報を取得する例
main(argc, argv)
int argc;
char *argv[];
#endif
{
TPKEY tu_key;
char principal_name[PNAME_LEN];
long pname_len = PNAME_LEN;
.
.
.
if (tpkey_getinfo(tu_key,
“PRINCIPAL”,
principal_name,
&pname_len, 0) == -1) {
(void) fprintf(stdout,
“Unable to get information
about
principal: %d(%s)\n”,
tperrno,
tpstrerror(tperrno));
.
.
.
exit(1);
}
.
.
.
}
親トピック: 暗号化されたメッセージを送信するためのコードの作成
3.9.1.3 ステップ3 (オプション): キー・ハンドルの情報を変更する
暗号化キー・ハンドルに関連付けられたオプション属性を設定するには、tpkey_setinfo(3c)関数またはTPKEYSETINFO(3cbl)
ルーチンを呼び出します。キー・ハンドル属性は、暗号サービス・プロバイダによって異なります。
次のリストに、暗号化キー・ハンドルに関連付けられている情報を変更する方法を示します。
リスト 暗号化キー・ハンドルに関連付けられた情報を変更する例
main(argc, argv)
int argc;
char *argv[];
#endif
{
TPKEY tu_key;
static const unsigned char rc2_objid[] = {
0x06, 0x08, 0x2a, 0x86, 0x48,0x86, 0xf7, 0x0d, 0x03, 0x02
};
.
.
.
if (tpkey_setinfo(tu_key, “ENCRYPT_ALG”, (void *) rc2_objid,
sizeof(rc2_objid), 0) == -1){
(void) fprintf(stderr, “tpkey_setinfo failed
tperrno=%d(%s)\n”,
tperrno,tpstrerror(tperrno));
return(1);
}
.
.
.
}
親トピック: 暗号化されたメッセージを送信するためのコードの作成
3.9.1.4 ステップ4: バッファを割り当ててメッセージを指定する
型付きメッセージ・バッファを割り当てるには、tpalloc(3c)関数を呼び出します。続いて、バッファにメッセージを指定します。
親トピック: 暗号化されたメッセージを送信するためのコードの作成
3.9.1.5 ステップ5: 暗号化するバッファにマークを付ける
メッセージ・バッファに暗号化のマークを付ける(登録する)には、tpseal(3c)関数を呼び出します。この関数を呼び出すと、暗号化キー・ハンドルのコピーがメッセージ・バッファに添付されます。TPKEY_AUTOENCRYPT
フラグを使用してキーをオープンすると、tpseal()
を明示的に呼び出さなくても、暗号化するメッセージには自動的にマークが付きます。
次のリストに、暗号化するメッセージ・バッファにマークを付ける方法を示します。
リスト 暗号化するメッセージ・バッファにマークを付ける例
main(argc, argv)
int argc;
char *argv[];
#endif
{
TPKEY tu_key;
char *sendbuf, *rcvbuf;
.
.
.
if (tpseal(sendbuf, tu_key, 0) == -1) {
(void) fprintf(stderr,
“tpseal failed tperrno=%d(%s)\n”,
tperrno,tpstrerror(tperrno));
tpfree(rcvbuf);
tpfree(sendbuf);
tpterm();
(void) tpkey_close(tu_key,
0);
exit(1);
}
.
.
.
}
親トピック: 暗号化されたメッセージを送信するためのコードの作成
3.9.1.6 ステップ6: メッセージを送信する
メッセージ・バッファに暗号化のマークを付けた後、次のいずれかのC関数またはCOBOLルーチンを使用して、メッセージ・バッファを送信します。
-
tpcall()
またはTPCALL
-
tpbroadcast()
またはTPBROADCAST
-
tpconnect()
またはTPCONNECT
-
tpenqueue()
またはTPENQUEUE
-
tpforward()
-
tpnotify()
またはTPNOTIFY
-
tppost()
またはTPPOST
-
tpreturn()
またはTPRETURN
-
tpsend()
またはTPSEND
親トピック: 暗号化されたメッセージを送信するためのコードの作成
3.9.1.7 ステップ7: 暗号化キー・ハンドルをクローズする
tpkey_close(3c)関数またはTPKEYCLOSE(3cbl)
ルーチンを呼び出して、暗号化キー・ハンドルとそれに関連付けられたすべてのリソースを解放します。
親トピック: 暗号化されたメッセージを送信するためのコードの作成
3.9.1.8 メッセージ・バッファの暗号化方法
公開キーソフトウェアは、メッセージ・バッファが送信される直前に、メッセージを暗号化して暗号化エンベロープを添付します。暗号化エンベロープにより、ターゲットの受信者はメッセージを復号化できます。封印されたバッファが複数回送信される場合は、送信のたびに暗号化が実行されます。したがって、暗号化するメッセージ・バッファにマークを付けた後で、そのメッセージ・バッファを変更することができます。
公開キー・ソフトウェアは、次の2ステップ手順を実行して、メッセージ・バッファの内容を暗号化し、暗号化メッセージの受信者用の暗号化エンベロープを生成します。
- {message_buffer_data + buffer_type_string + buffer_subtype_string}session_key = encrypted_message
- {session_key}recipient's_public_key = encrypted_session_key = encryption_envelope_for_recipient
{ }keyという表記法は、keyを使用して{ }内が暗号化または復号化されることを示します。ステップ1では、セッション・キーを使用してメッセージ・バッファが暗号化され、ステップ2では、受信者の公開キーを使用してセッション・キーが暗号化されます。
3.9.1.8.1 複数のメッセージ受信者について
1つのメッセージ・バッファには、複数の暗号化エンベロープを関連付けることができます。つまり、異なる秘密キーを持つ複数の受信者が、暗号化されたメッセージを受信し、復号化することができます。受信者となるのは、ユーザーまたはプロセスです。メッセージが複数の受信者に対して暗号化されると、メッセージは一度だけ暗号化されますが、セッション・キーは各受信者の公開キーで暗号化されます。暗号化されたメッセージには、すべての暗号化エンベロープが添付されます。
1つのメッセージ・バッファに複数の暗号化エンベロープが関連付けられた場合、すべての暗号化エンベロープは、そのアルゴリズムに対して同じ対称キー・アルゴリズムと同じキー・サイズを使用しなければなりません。
親トピック: メッセージ・バッファの暗号化方法
3.9.1.8.2 暗号化されたメッセージの内容
暗号化されたメッセージ・バッファは、EnvelopedData
というメッセージ・タイプのバージョン0として、PKCS-7形式で表現されます。Oracle Tuxedoシステムで使用されるメッセージ・タイプEnvelopedData
は、次の項目で構成されます。
- どのATMIプロセスからも読み取ることができる、平文で表記された受信者のリスト
- 1人または複数の受信者のための暗号化エンベロープ
- 公開キーのアルゴリズムおよび関連するパラメータ(セッション・キーはこのアルゴリズムで暗号化されます)
- 対称キーのアルゴリズムおよび関連するパラメータ(バルク・データはこのアルゴリズムで暗号化されます)
- 暗号化されたバルク・データ。メッセージ・バッファのデータ、バッファ・タイプの文字列、バッファのサブタイプの文字列、およびデジタル署名(デジタル署名がある場合)をまとめたものであり、次の変換処理が実行されます。
- メッセージ・バッファ・データ、バッファ・タイプの文字列、およびバッファのサブタイプの文字列をOracle Tuxedoのエンコード形式に変換し、コンポジット・エンコード・データを生成します。このOracle Tuxedoのエンコード形式により、メッセージ・バッファは、どのマシンのアーキテクチャを使用しても復号化できます。
- Deflate圧縮アルゴリズムを使用して、コンポジット・エンコード・データおよびデジタル署名(デジタル署名がある場合)を圧縮し、コンポジット圧縮データを生成します。
- ランダムに生成されたセッション・キーおよび対称キー・アルゴリズム(このリストの前半で説明)を使用してコンポジット圧縮データを暗号化し、バルク・データを暗号化します。
次の図は、EnvelopedData
メッセージ・タイプの場合のエンベロープの階層を示しています。SignedData
メッセージ・タイプは、メッセージに1つまたは複数のデジタル署名が関連付けられている場合にのみ、この階層に含まれます。
図3-6 EnvelopedDataメッセージ・タイプ

上の図に示すように、メッセージ・バッファは、署名することも暗号化することもできます。メッセージ・バッファに関連するデジタル署名の数と暗号化エンベロープの数の間に、関係を成立させる必要はありません。
メッセージ・バッファに対して署名と暗号化の両方が実行されると、まず、暗号化されていないデータに対する署名が生成されます。次に、添付される署名の数および署名者のIDが、バルク・データの暗号化機能により暗号化されます。
ノート:
署名を検証する前に、メッセージのデータを復号化するための適切な復号化キーを使用できる状態にしておく必要があります。親トピック: メッセージ・バッファの暗号化方法
3.9.2 暗号化されたメッセージを受信するためのコードの記述
暗号化されたメッセージを受信するためのコードを記述する手順は、次のステップを含みます:
tpkey_open()
を呼び出して、ターゲット受信者のキー・ハンドルをオープンします。tpkey_open
を呼び出すと、受信者の秘密キーおよびデジタル証明書に対するキー・ハンドルが返されます。- (オプション):
tpkey_getinfo()
を呼び出して、復号化キー・ハンドルに関する情報を取得します。 - (オプション):
tpkey_setinfo()
を呼び出して、復号化キー・ハンドルに関連付けられた情報を変更します。 tpkey_close()
を呼び出して、復号化キー・ハンドルをクローズします。tpkey_close()
を呼び出すと、キー・ハンドルとそれに関連付けられたすべてのリソースが解放されます。
これらのステップおよびメッセージ・バッファが復号化されるしくみについては、次の項を参照してください。
- ステップ1:復号化用のキー・ハンドルをオープンする
- ステップ2 (オプション):キー・ハンドルの情報を取得する
- ステップ3 (オプション):キー・ハンドルの情報を変更する
- ステップ4:復号化キー・ハンドルをクローズする
- メッセージ・バッファの復号化方法
親トピック: 暗号化されたメッセージの送信と受信
3.9.2.1 ステップ1: 復号化用のキー・ハンドルをオープンする
tpkey_open(3c)関数またはTPKEYOPEN(3cbl)
ルーチンを呼び出して、受信側のプロセスが、ターゲット受信者の秘密キーおよび関連するデジタル証明書を使用できるようにします。受信側のプロセスとは、クライアント、サービス、サーバー・グループ、ゲートウェイ・グループ、サーバー・マシン、または複数のサーバーを含むドメイン全体のことです。
アプリケーション管理者は、ATMIアプリケーションのUBBCONFIG
ファイルを構成して、ATMIアプリケーションの起動時に復号化キー・ハンドルを自動的にオープンするように指定できます。この方法では、サーバーごとに使用できる復号化キー・ハンドルは1つだけです。詳細は、2-56ページの「プラグインによる復号化キーの初期化」を参照してください。
起動時に受信側のプロセスの復号化キー・ハンドルをオープンするようにATMIアプリケーションが構成されていない場合、受信側のプロセスは自身でtpkey_open()
を呼び出します。または、受信側のプロセスは、別のtpkey_open()
を呼び出して、別の復号化キー・ハンドルをオープンすることもできます。
ターゲット受信者の秘密キーにアクセスするため、受信側のプロセスは、ターゲット受信者として動作する権限があることを証明する必要があります。証明の条件は、公開キーのプラグイン・インタフェースの実装によって異なります。デフォルトの公開キーの実装では、呼出しプロセス側が秘密のパスワードを入力する必要があります。
受信側のプロセスがtpkey_open()
を呼び出してキー・ハンドルをオープンするとき、TPKEY_DECRYPT
フラグを指定して、そのハンドルがメッセージ・バッファの復号化に使用されることを示します。通常、クライアントはtpinit()
を呼び出した後でこの呼出しを行い、サーバーはtpsvrinit()
を呼び出して初期化を行うときにこの呼出しを行います。
次のリストに、復号化キー・ハンドルをオープンする方法を示します。TPKEY
は、atmi.h
ヘッダー・ファイルで定義される特殊なデータ型です。
リスト 復号化キー・ハンドルをオープンする例
TPKEY tu_key;
tpsvrinit(argc, argv)
int argc;
char **argv;
#endif
{
char *tu_location;
.
.
.
if (tpkey_open(&tu_key,
“TOUPPER”, tu_location,
NULL, 0, TPKEY_DECRYPT) == -1)
{
userlog(“Unable to open
private key: %d(%s)”,
tperrno,
tpstrerror(tperrno));
return(-1)
}
.
.
.
}
親トピック: 暗号化されたメッセージを受信するためのコードの記述
3.9.2.2 ステップ2 (オプション): キー・ハンドルの情報を取得する
復号化キー・ハンドルの情報を取得して、キーの有効性を確認することができます。そのためには、tpkey_getinfo(3c)関数またはTPKEYGETINFO(3cbl)ルーチンを呼び出します。返される情報の中には、暗号サービス・プロバイダに固有の情報も含まれていますが、主要な属性は、すべてのプロバイダで共通です。
次のリストに、復号化キー・ハンドルに関する情報を取得する方法を示します。
リスト 復号化キー・ハンドルに関する情報を取得する例
TPKEY tu_key;
tpsvrinit(argc, argv)
int argc;
char **argv;
#endif
{
char principal_name[PNAME_LEN];
long pname_len = PNAME_LEN;
.
.
.
if (tpkey_getinfo(tu_key,
“PRINCIPAL”,
principal_name,
&pname_len, 0) == -1) {
(void) fprintf(stdout,
“Unable to get information
about
principal: %d(%s)\n”,
tperrno,
tpstrerror(tperrno));
.
.
.
exit(1);
}
.
.
.
}
親トピック: 暗号化されたメッセージを受信するためのコードの記述
3.9.2.3 ステップ3 (オプション): キー・ハンドルの情報を変更する
復号化キー・ハンドルに関連付けられたオプション属性を設定するには、tpkey_setinfo(3c)関数またはTPKEYSETINFO(3cbl)ルーチンを呼び出します。キー・ハンドル属性は、暗号サービス・プロバイダによって異なります。
次のリストに、復号化キー・ハンドルに関連付けられている情報を変更する方法を示します。
リスト 復号化キー・ハンドルに関連付けられた情報を変更する例
TPKEY tu_key;
tpsvrinit(argc, argv)
int argc;
char **argv;
#endif
{
TM32U mybits = 128;
.
.
.
if (tpkey_setinfo(tu_key,
“ENCRYPT_BITS”, &mybits,
sizeof(mybits), 0) == -1)
{
(void) fprintf(stderr,
“tpkey_setinfo failed
tperrno=%d(%s)\n”,
tperrno,
tpstrerror(tperrno));
return(1);
}
.
.
.
}
親トピック: 暗号化されたメッセージを受信するためのコードの記述
3.9.2.4 ステップ4: 復号化キー・ハンドルをクローズする
tpkey_close(3c)関数またはTPKEYCLOSE (3cbl)
ルーチンを呼び出して、復号化キー・ハンドルとそれに関連付けられたすべてのリソースを解放します。
親トピック: 暗号化されたメッセージを受信するためのコードの記述
3.9.2.5 メッセージ・バッファの復号化方法
公開キーソフトウェアは、Oracle Tuxedoのクライアント・プロセス、サーバー・プロセス、またはメッセージ・バッファの内容を読み取るシステム・プロセスに暗号化されたメッセージ・バッファがあると、そのメッセージ・バッファを自動的に復号化します。復号化の自動処理を成功させるには、受信側のプロセスで、添付された暗号化エンベロープのいずれかで指定されている復号化キー(TPKEY_DECRYPT
)をオープンしておく必要があります。
受信側のプロセスのかわりに動作する公開キーソフトウェアは、暗号化されたメッセージ・バッファを受信すると、次のタスクを実行します。
- 添付された暗号化エンベロープ内のターゲット受信者の名前を読み取ります。
- セッション・キーを復元するには、受信者の秘密キーと公開キーアルゴリズムを使用して、受信者の暗号化エンベロープを復号化します。
- 復元されたセッション・キーと対称キー・アルゴリズムを使用して、メッセージを復号化します。
- メッセージを圧縮解除します。
- デジタル署名があれば検証します。(「署名付きメッセージの受信方法」を参照してください。)
- メッセージ・バッファがステップ5のチェックにパスすると、公開キーソフトウェアは、メッセージ・バッファのデータ、バッファ・タイプの文字列、およびバッファのサブタイプの文字列をデコードし、受信側のプロセスに平文化されたメッセージを渡します。これは、発信元プロセスで行われるエンコードと逆のステップです。このOracle Tuxedoのエンコード形式により、メッセージ・バッファは、どのマシンのアーキテクチャを使用しても復号化できます。
- 添付されたデジタル署名をどれも検証できない場合、または、メッセージ・バッファを復号化できない場合、受信側のプロセスはメッセージ・バッファを受け取りません。さらに、受信側のプロセスは、メッセージ・バッファをまったく認識しません。
ただし、パイプ役として機能するシステム・プロセス (メッセージの内容は読み取らない)の場合、メッセージは復号化されません。たとえば、ブリッジおよびワークステーション・ハンドラ(WSH)は、パイプ役として機能するシステム・プロセスの例です。
WSHは、パイプ役の特殊な例です。データ依存型ルーティング用に構成されたWSHは、メッセージ・バッファを受信するとそれを読み取り、バッファのルーティング方法を決定します。つまり、まず、公開キーソフトウェアは、受信したメッセージ・バッファのコピーを作成し、そのコピーを復号化してWSHに渡します。WSHは、復号化されたコピーを解析し、そのメッセージ・バッファをルーティングする方法を決定すると、元のメッセージ・バッファをそのまま適切なサーバーにルーティングします。(データ依存型ルーティングと公開キーセキュリティとの相互運用の詳細は、「データ依存型ルーティングとの互換性および相互運用性」を参照してください。)
3.9.2.5.1 入力バッファの暗号化エンベロープを破棄する
メッセージ・バッファが入力パラメータとしてATMI関数(tpacall()
など)に渡された場合、公開キーソフトウェアは、メッセージにあらかじめ添付された暗号化エンベロープを破棄します。この機能により、中継プロセスで変更された元のメッセージが、ターゲット受信者側で受け取られないようにすることができます。
このプロセスの例として、次の図に示すシナリオを考えてみます。
図3-7 暗号化された署名付きメッセージを転送する例

この例は、Manager
という名前のサーバー・プロセスが、Employee
というクライアント・プロセスから、暗号化された署名付きメッセージ・バッファを受信する様子を示しています。サーバーは、受信したメッセージ・バッファを復号化して読み取った後で、Purchasing
サービス用に署名および封印し、Purchasing
に送信します。
この操作を次に詳しく説明します。
- ワークステーション・ハンドラ(WSH)は、暗号化された署名付きメッセージ・バッファをEmployeeというクライアントから受け取ると、そのまま転送します。
WSHプロセスには、データ依存型ルーティングが構成されています。これについては、3-46ページの「メッセージ・バッファの復号化方法」を参照してください。公開キー・ソフトウェアは、WSHプロセスですでにオープンした復号化キーを使用して、受信したメッセージ・バッファのコピーを復号化します。次に、復号化したメッセージのコピーをWSHに渡します。WSHは、復号化されたコピーを解析してから、受信したメッセージ・バッファをそのまま
WSHプロセスにデータ依存型ルーティングが構成されていない場合、Manager
プロセスに転送します。Employee
プロセスは、WSHプロセスのメッセージ・バッファに対してtpseal()
を呼び出す必要はありません。また、WSHプロセスも復号化キーをオープンする必要はありません。データ依存型ルーティングが構成されているかどうかにかかわらず、WSHはデジタル署名の検証を行いません。
- メッセージ・バッファが
Manager
プロセスで受け取られると、公開キーソフトウェアは次の操作を行います。Manager
プロセスですでにオープンした復号化キーを使用して、メッセージ・バッファを復号化します。- Employeeの署名を検証します。
- デジタル署名や暗号化情報のないメッセージを
Manager
に渡します。
Manager
は、tpenvelope()
を繰り返し呼び出して、メッセージ・バッファに関連付けられたデジタル署名と暗号化の情報を調べます。tpenvelope()
からは、次の情報が返されます。- デジタル署名の情報。署名者の公開キーおよび
TPSIGN_OK
というデジタル署名のステータスが含まれます。 - 暗号化の情報。WSHプロセスの公開キーおよび
Manager
プロセス自身の公開キーが含まれます。
- デジタル署名の情報。署名者の公開キーおよび
Manager
は、署名者の公開キーを引数に指定してtpkey_getinfo()
を呼び出し、署名者に関するさらに詳しい情報(プリンシパル名など)を取得します。Manager
は、署名者を確認し、Employeeからのリクエスト(メッセージで指定)が有効であると判断すると、次の操作を行います。tpsign()
を呼び出し、Manager
によるデジタル署名を添付するメッセージ・バッファにマークを付けますtpseal()
を呼び出して、メッセージ・バッファにPurchasing
用の暗号化のマークを付けます。tpforward()
(またはデータの送信に使用する別の関数)を呼び出して、メッセージをPurchasing
に送信します。
送信前に、公開キー・ソフトウェアは次のタスクを実行します。
- Managerのデジタル署名を生成します。
- Employeeのデジタル署名を検証します。
- メッセージの内容および関連するデジタル署名を暗号化します。
- Purchasing用の暗号化エンベロープを作成します。
親トピック: メッセージ・バッファの復号化方法
3.10 デジタル署名および暗号化情報の調査
公開キーソフトウェアでは、次の順序指定が適用されます。
- デジタル署名の登録リクエストおよびデジタル署名がメッセージ・バッファに添付される順序
- 暗号化の登録リクエストおよび暗号化エンベロープがメッセージ・バッファに添付される順序
プロセスは、ターゲットのメッセージ・バッファを引数に指定してtpenvelope()
関数を呼び出すことにより、この情報を取得します。tpenvelope()
については、『Oracle Tuxedo ATMI C関数リファレンス』のtpenvelope(3c)のリファレンス・ページを参照してください。
デジタル署名登録リクエスト、デジタル署名、暗号化登録リクエスト、およびメッセージ・バッファに関連付けられている暗号化エンベロープの複数のオカレンスが同時に存在することがあります。これらのオカレンスは順番に格納され、最初の項目が0位置に、以降の項目は0に続く連続する位置に格納されます。tpenvelope()
のoccurrence
入力パラメータは、リクエストされた項目を示します。occurrence
の値が最後の項目の位置を過ぎると、tpenvelope()
はTPENOENT
エラー状態で異常終了します。TPENOENT
が返されるまでtpenvelope()
を繰り返し呼び出すことにより、すべての項目を調べることができます。
発信元プロセスでは通常、デジタル署名および暗号化の情報は、メッセージが送信されるまで保留状態になっています。受信プロセスでは、デジタル署名が確認され、暗号化と復号化もすでに行われています。
親トピック: セキュリティのプログラミング
3.10.1 発信元プロセスがtpenvelopeを呼び出したときの動作
発信元プロセスが発信元メッセージ・バッファを引数としてtpenvelope()
を呼び出すと、tpenvelope()
は次をレポートします:
TPSIGN_PENDING
状態にあるとしてメッセージ・バッファに明示的に登録されたすべてのデジタル署名リクエスト。発信元プロセスは、tpsign(3c)関数を呼び出して、デジタル署名リクエストを明示的に登録します。- これもまた
TPSIGN_PENDING
状態にあるとしてメッセージ・バッファに暗黙的に登録されたすべてのデジタル署名リクエスト。発信元プロセスは、TPKEY_AUTOSIGN
フラグを指定してtpkey_open(3c)を呼び出し、デジタル署名リクエストを暗黙的に登録します。 TPSEAL_PENDING
状態にあるとしてメッセージ・バッファに明示的に登録されたすべての暗号化(シール)リクエスト。発信元プロセスは、tpseal(3c)関数を呼び出して、暗号化リクエストを明示的に登録します。- これもまた
TPSEAL_PENDING
状態にあるとしてメッセージ・バッファに暗黙的に登録されたすべての暗号化(シール)リクエスト。発信元プロセスは、TPKEY_AUTOENCRYPT
フラグを指定してtpkey_open()
を呼び出し、暗号化リクエストを暗黙的に登録します。
tpenvelope()
は、ステータスの情報のほか、デジタル署名または暗号化の登録リクエストに関連付けられたキー・ハンドルも返します。プロセスは、キー・ハンドルを引数としてtpkey_getinfo(3c)関数を呼び出し、キー・ハンドルに関する詳しい情報を取得できます。
親トピック: デジタル署名および暗号化情報の調査
3.10.2 受信側のプロセスがtpenvelopeを呼び出したときの動作
プロセスがメッセージ・バッファを受信するときは、メッセージの内容だけを受信します。メッセージ・バッファに関連付けられているデジタル署名や暗号化エンベロープは受信しません。受信側のプロセスは、tpenvelope()
を呼び出して、添付されたデジタル署名や暗号化エンベロープに関する情報を取得する必要があります。
受信側のプロセスが受信メッセージ・バッファを引数としてtpenvelope()
を呼び出すと、tpenvelope()
は次のレポートを作成します。
- メッセージ・バッファに添付されたデジタル署名。デジタル署名は、次のいずれかの状態になります。
-
TPSIGN_OK
- デジタル署名は検証されました。
-
TPSIGN_TAMPERED_MESSAGE
- メッセージ・バッファの内容が変更されたため、デジタル署名は無効です。
-
TPSIGN_TAMPERED_CERT
- 署名者のデジタル証明書が変更されたため、デジタル署名は無効です。
-
TPSIGN_REVOKED_CERT
- 署名者のデジタル証明書が取り消されたため、デジタル署名は無効です。
-
TPSIGN_POSTDATED
- タイムスタンプが遠い将来の時刻を示しているため、デジタル署名は無効です。
-
TPSIGN_EXPIRED_CERT
- 署名者のデジタル証明書の有効期限が切れたため、デジタル署名は無効です。
-
TPSIGN_EXPIRED
- タイムスタンプが古すぎるため、デジタル署名は無効です。
-
TPSIGN_UNKNOWN
- 署名者のデジタル証明書が不明な認証局(CA)によって発行されたため、デジタル署名は無効です。
-
- メッセージ・バッファに添付された暗号化エンベロープ。暗号化エンベロープは、次のいずれかの状態になります。
-
TPSEAL_OK
- 暗号化エンベロープは有効です。
-
TPSEAL_TAMPERED_CERT
- ターゲット受信者のデジタル証明書が変更されたため、暗号化エンベロープは無効です。ターゲット受信者は、メッセージ・バッファを受信しません。
-
TPSEAL_REVOKED_CERT
- ターゲット受信者のデジタル証明書が取り消されたため、暗号化エンベロープは無効です。ターゲット受信者は、メッセージ・バッファを受信しません。
-
TPSEAL_EXPIRED_CERT
- ターゲット受信者のデジタル証明書の有効期限が切れたため、暗号化エンベロープは無効です。(ターゲット受信者は、メッセージ・バッファを受信しません。)
-
TPSEAL_UNKNOWN
- ターゲット受信者のデジタル証明書が不明な認証局(CA)から発行されたため、暗号化エンベロープは無効です。ターゲット受信者は、メッセージ・バッファを受信しません。
-
tpenvelope()
は、ステータスの情報のほか、デジタル署名または暗号化エンベロープに関連付けられたキー・ハンドルも返します。プロセスは、キー・ハンドルを引数としてtpkey_getinfo(3c)関数を呼び出し、キー・ハンドルに関する詳しい情報を取得できます。
受信側のプロセスが、メッセージ・バッファを受信した後でtpsign()
を呼び出してデジタル署名リクエストを登録した場合、tpenvelope()
は登録のステータスをTPSIGN_PENDING
としてレポートします。同様に、受信側のプロセスが、メッセージ・バッファを受信した後でtpseal()
を呼び出して暗号化(封印)リクエストを登録した場合は、tpenvelope()
は登録のステータスをTPSEAL_PENDING
としてレポートします。
受信側のプロセスが署名付きメッセージ・バッファを受信した後でその内容を変更すると、添付された署名は無効になります。その結果、tpenvelope()
は署名を検証できないため、TPSIGN_TAMPERED_MESSAGE
という署名ステータスをレポートします。
親トピック: デジタル署名および暗号化情報の調査
3.10.3 コンポジット署名ステータスの理解
メッセージ・バッファに複数のデジタル署名がある場合、公開キーソフトウェアは、tpenvelope()
と同等の内部関数を呼び出して、各デジタル署名の状態を調べます。次に、特定の規則に従い、複数のデジタル署名の状態を合成したコンポジット署名ステータスを生成します。次の表に、コンポジット署名ステータスを生成する規則を示します。
表3-4 コンポジット署名ステータス
存在するステータス | 存在しないステータス | 結果のステータス |
---|---|---|
TPSIGN_TAMPERED_MESSAGE |
... |
TPSIGN_TAMPERED_MESSAGE |
TPSIGN_TAMPERED_CERT |
TPSIGN_TAMPERED_MESSAGE |
TPSIGN_TAMPERED_CERT |
TPSIGN_REVOKED_CERT |
TPSIGN_TAMPERED_MESSAGE TPSIGN_TAMPERED_CERT |
TPSIGN_REVOKED_CERT |
TPSIGN_POSTDATED |
TPSIGN_TAMPERED_MESSAGE TPSIGN_TAMPERED_CERT TPSIGN_REVOKED_CERT |
TPSIGN_POSTDATED |
TPSIGN_EXPIRED_CERT |
TPSIGN_TAMPERED_MESSAGE TPSIGN_TAMPERED_CERT TPSIGN_REVOKED_CERT TPSIGN_POSTDATED |
TPSIGN_EXPIRED_CERT |
TPSIGN_OK |
TPSIGN_TAMPERED_MESSAGE TPSIGN_TAMPERED_CERT TPSIGN_REVOKED_CERT TPSIGN_POSTDATED TPSIGN_EXPIRED_CERT |
TPSIGN_OK |
TPSIGN_EXPIRED |
TPSIGN_TAMPERED_MESSAGE TPSIGN_TAMPERED_CERT TPSIGN_REVOKED_CERT TPSIGN_POSTDATED TPSIGN_EXPIRED_CERTTPSIGN_OK |
TPSIGN_EXPIRED |
TPSIGN_UNKNOWN |
TPSIGN_TAMPERED_MESSAGE TPSIGN_TAMPERED_CERT TPSIGN_REVOKED_CERT TPSIGN_POSTDATED TPSIGN_EXPIRED_CERT TPSIGN_OK TPSIGN_EXPIRED |
TPSIGN_UNKNOWN |
TPSIGN_OK
またはTPSIGN_UNKNOWN
のコンポジット署名ステータスが付いていないメッセージ・バッファは、受信されても破棄され、受信されなかったように扱われます。ATMIアプリケーションの
ファイルのUBBCONFIG
SIGNATURE_REQUIRED
パラメータがY
(はい)に設定されている場合は、TPSIGN_OK
のコンポジット署名ステータスが付いていない メッセージ・バッファを受信しても破棄され、受信されなかったように扱われます。詳細は、「受信メッセージに対する署名ポリシーの適用」を参照してください。
ただし、前の段落で説明した署名付きメッセージ・バッファの処理の例外として、tpimport(3c)関数があります。tpimport(3c)関数は、コンポジット署名ステータスとは関係なく、受信したメッセージ・バッファを送信します。
親トピック: デジタル署名および暗号化情報の調査
3.10.4 tpenvelopeのサンプル・コード
次のリストに、tpenvelope()
を使用して、メッセージ・バッファに関連付けられているデジタル署名と暗号化の情報を調べる方法を示します。
リスト tpenvelopeの使用例
main(argc, argv)
int argc;
char *argv[];
#endif
{
TPKEY tu_key;
TPKEY sdo_key;
TPKEY output_key;
char *sendbuf, *rcvbuf;
int ret;
int occurrence = 0;
long status;
char principal_name[PNAME_LEN];
long pname_len = PNAME_LEN;
int found = 0;
.
.
.
output_key = NULL;
ret = tpenvelope(rcvbuf, 0, occurrence, &output_key,
&status, NULL, 0);
while (ret != -1) {
if (status == TPSIGN_OK) {
if (tpkey_getinfo(output_key, “PRINCIPAL”,
principal_name, &pname_len, 0) == -1) {
(void) fprintf(stdout, “Unable to get information
about principal: %d(%s)\n”,
tperrno, tpstrerror(tperrno));
tpfree(sendbuf);
tpfree(rcvbuf);
tpterm();
(void) tpkey_close(tu_key, 0);
(void) tpkey_close(sdo_key, 0);
(void) tpkey_close(output_key, 0);
exit(1);
}
/* Do not forget to free resources */
(void) tpkey_close(output_key, 0);
output_key = NULL;
found = 1;
break;
}
/* Do not forget to free resources */
(void) tpkey_close(output_key, 0);
output_key = NULL;
occurrence++;
ret = tpenvelope(rcvbuf, 0, occurrence, &output_key,
&status, NULL, 0);
}
.
.
.
}
親トピック: デジタル署名および暗号化情報の調査
3.11 型付きメッセージ・バッファの外部化
外部化された表現とは、通常はバッファが送信される直前にメッセージ・バッファに追加されるATMIヘッダー情報が含まれないメッセージ・バッファのことです。署名付きメッセージ・バッファを外部化された表現に変換すると、署名付きデータを「パス・スルー(通過)」させたり、署名付きバッファを長期間保存しておき、バッファ送信した事実を否認できないようにすることができます。また、復号化キーを使用しないで、暗号化されたメッセージ・バッファを中継プロセス経由で伝送することもできます。
3.11.1 外部化された表現の作成方法
ATMIプロセスは、tpexport(3c)関数を呼び出して、型付きメッセージ・バッファを外部化された表現に変換します。メッセージ・バッファに関連付けられた保留状態の署名は、そのメッセージ・バッファがATMI関数によって別のプロセスに送信された場合のように、tpexport()
が呼び出されたときに生成されます。同様に、メッセージ・バッファに関連付けられた保留中の封印は、そのメッセージ・バッファがATMI通信関数によって別のプロセスに送信された場合のように、tpexport()
が呼び出されたときに生成されます。
外部化された表現のメッセージ・バッファは、バイナリ形式のPKCS-7形式で保存されます。文字列で指定する必要がある場合、呼出しプロセスは、TPEX_STRING
フラグを指定してtpexport()
を呼び出す必要があります。
ノート:
外部化された表現の型付きメッセージ・バッファを作成する機能は、公開キーセキュリティにユニークなものではありません。プロセスは、tpexport()
を呼び出して型付きメッセージ・バッファを外部化することができます。メッセージ・バッファに対してデジタル署名または暗号化のマークが付けられているかどうかは無関係です。
親トピック: 型付きメッセージ・バッファの外部化
3.11.2 外部化された表現の変換方法
受信側のプロセスは、tpimport(3c)関数を呼び出して、外部化された表現のメッセージ・バッファを型付きメッセージ・バッファに変換します。tpimport()
関数も、必要に応じて復号化を行い、関連するデジタル署名があれば検証します。
親トピック: 型付きメッセージ・バッファの外部化
3.11.3 tpexportおよびtpimportのサンプル・コード
次のリストに、tpexport()
を使用して型付きメッセージ・バッファを外部化された表現に変換する方法、およびtpimport()
を使用して外部化された表現を型付きメッセージ・バッファに戻す方法を示します。
リスト tpexportおよびtpimportの使用例
static void hexdump _((unsigned char *, long));
#define MAX_BUFFER 80000
main(argc, argv)
int argc;
char *argv[];
#endif
{
char *databuf;
char exportbuf[MAX_BUFFER];
long exportbuf_size = 0;
char *importbuf = NULL;
long importbuf_size = 0;
int go_on = 1;
.
.
.
exportbuf_size = 0;
while (go_on == 1) {
if (tpexport(databuf, 0, exportbuf, &exportbuf_size, 0)
== -1) {
if (tperrno == TPELIMIT) {
printf(“%d tperrno is TPELIMIT, exportbuf_size=%ld\n”,
__LINE__, exportbuf_size);
if (exportbuf_size > MAX_BUFFER) {
return(1);
}
}
else {
printf(“tpexport(%d) failed: tperrno=%d(%s)\n”,
__LINE__, tperrno, tpstrerror(tperrno));
return(1);
}
}
else {
go_on = 0;
}
}
.
.
.
hexdump((unsigned char *) exportbuf, (long) exportbuf_size);
if (tpimport(exportbuf, exportbuf_size, &importbuf,
&importbuf_size, 0) == -1) {
printf(“tpimport(%d) failed: tperrno=%d(%s)\n”,
__LINE__, tperrno, tpstrerror(tperrno));
return(1);
}
.
.
.
}
親トピック: 型付きメッセージ・バッファの外部化