Oracle Solaris セキュリティーサービス開発ガイド

付録 C OID の指定

できるだけ GSS-API が提供するデフォルトの QOP および機構を使用してください。「GSS-API の OID」を参照してください。ただし、何らかの理由で QOP の OID を指定する必要がある場合があります。この付録では、OID を指定する方法について説明します。この章の内容は次のとおりです。

OID 値が含まれるファイル

GSS-API では、機構と QOP を人が読める形式で表示することができます。Solaris システムでは、/etc/gss/mech/etc/gss/qop の 2 つのファイルに、使用できる機構と QOP についての情報が含まれています。この 2 つのファイルへのアクセス権がない場合は、他のソースから文字列リテラルを提供する必要があります。その機構や QOP 用に公開されているインターネット標準は、この目的にかなっています。

/etc/gss/mech ファイル

/etc/gss/mech ファイルには、使用できる機構のリストが含まれています。/etc/gss/mech には、機構名が数値とアルファベットの両方の形式で格納されています。/etc/gss/mech の各行は、次の書式で構成されています。

Example C–1 に、例 C–1 ファイルの例を示します。


例 C–1 /etc/gss/mech ファイル

# 
# Copyright 2003 Sun Microsystems, Inc.  All rights reserved.
# Use is subject to license terms.
#
#ident	"@(#)mech	1.12	03/10/20 SMI"
#
# This file contains the GSS-API based security mechanism names,
# the associated object identifiers (OID) and a shared library that 
# implements the services for the mechanisms under GSS-API.
#
# Mechanism Name	Object Identifier	Shared Library	Kernel Module
[Options]
#
kerberos_v5		1.2.840.113554.1.2.2	mech_krb5.so kmech_krb5 
spnego			1.3.6.1.5.5.2		mech_spnego.so.1 [msinterop]
diffie_hellman_640_0	1.3.6.4.1.42.2.26.2.4	dh640-0.so.1
diffie_hellman_1024_0	1.3.6.4.1.42.2.26.2.5	dh1024-0.so.1

/etc/gss/qop ファイル

/etc/gss/qop ファイルには、導入されたすべての機構用に、各機構がサポートするすべての QOP が、ASCII 文字列とそれに対応する 32 ビット整数の両方で格納されます。次に、/etc/gss/qop ファイルの例を示します。


例 C–2 /etc/gss/qop ファイル

#
# Copyright (c) 2000, by Sun Microsystems, Inc.
# All rights reserved.
#
#ident  "@(#)qop 1.3     00/11/09 SMI" 
#
# This file contains information about the GSS-API based quality of
# protection (QOP), its string name and its value (32-bit integer).
#
# QOP string                    QOP Value       Mechanism Name
#
GSS_KRB5_INTEG_C_QOP_DES_MD5    0               kerberos_v5
GSS_KRB5_CONF_C_QOP_DES         0               kerberos_v5

gss_str_to_oid() 関数

旧バージョンの GSS-API との下位互換性のため、この実装の GSS-API は gss_str_to_oid() 関数をサポートします。gss_str_to_oid() は、機構または QOP を表す文字列を OID に変換します。この文字列は、数値または ASCII 文字列のどちらでもかまいません。


注意 – 注意 –

デフォルトの機構と QOP を使用することが強く推奨されているため、gss_str_to_oid()gss_oid_to_str()、および gss_release_oid() をサポートしていない GSS-API の実装もあります。


機構を表す文字列は、アプリケーション内でハードコード化することも、ユーザー入力から取得することも可能です。しかし、必ずしもすべての GSS-API の実装が gss_str_to_oid() 関数をサポートしているわけではないため、アプリケーションはこの関数に依存すべきではありません。

機構を表す数値には、2 つの異なる形式を指定できます。1 つは { 1 2 3 4 } であり、GSS-API 仕様によって正式に認められています。もう 1 つは 1.2.3.4 で、こちらの方が広く使用されていますが、正式な標準形式ではありません。gss_str_to_oid() は機構の数値として最初の形式を期待します。したがって、2 番目の形式を使用している場合は、gss_str_to_oid() を呼び出す前に 1 番目の形式に変換する必要があります。gss_str_to_oid() の例については、例 C–3 を参照してください。機構が有効でない場合、gss_str_to_oid()GSS_S_BAD_MECH を戻します。

gss_str_to_oid() は GSS-API データ領域を割り当てるため、終了時には、割り当てられた OID を gss_release_oid() 関数で削除する必要があります。gss_str_to_oid() と同様に、gss_release_oid() も一般的にサポートされている関数ではありません。したがって、移植性を最大限にしたいプログラムはこの関数に依存すべきではありません。

機構 OID の構築

gss_str_to_oid() は常に使用できるわけではないため、機構を調べて選択する方法がほかにもいくつかあります。1 つは、機構 OID を手動で構築し、その機構を使用できる機構の集合と比較する方法です。もう 1 つは、使用できる機構の集合を取得して、その中から 1 つを選択する方法です。

次に、gss_OID 型の形式を示します。

typedef struct gss_OID_desc struct {
     OM_uint32 length;
     void           *elements;
} gss_OID_desc, *gss_OID;

この構造体の elements フィールドは、gss_OID の通常の BER TLV エンコーディングの値の部分の ASN.1 BER エンコーディングが格納されているオクテット文字列の最初のバイトを指します。length フィールドには、この値のバイト数が格納されています。たとえば、DASS X.509 認証機構に対応する gss_OID 値の場合、length フィールドは 7 で、elements フィールドは 8 進数で「53,14,2,207,163,7,5」となる値を指します。  

機構 OID を構築する 1 つの方法は、gss_OID を宣言し、次にその要素を手動で初期化して、その機構を表すようにします。前述のとおり、elements 値はハードコード化することも、表から取得することも、ユーザーが入力することもできます。この方法は、gss_str_to_oid() を使用するよりも手がかかりますが、同じ効果が得られます。

次に、手動で構築した gss_OID を、使用できる機構の集合と比較します。使用できる機構の集合は、gss_indicate_mechs() または gss_inquire_mechs_for_name() の関数から戻されたものです。手動で構築した機構 OID が、使用できる機構の集合の中に存在するかどうかを調べるには、gss_test_oid_set_member() 関数を使用します。gss_test_oid_set_member() がエラーを戻さなかった場合、手動で構築した OID は GSS-API トランザクション用の機構として使用できます。

OID を手動で構築する代わりに、gss_indicate_mechs() または gss_inquire_mechs_for_name() を使用すると、使用できる機構の gss_OID_set を取得できます。次に、gss_OID_set の形式を示します。

typedef struct gss_OID_set_desc_struct {
     OM_uint32 length;
     void           *elements;
} gss_OID_set_desc, *gss_OID_set;

elements は機構を表す gss_OID です。アプリケーションは、各機構を解析し、それぞれの数値表現を表示できます。ユーザーはこの表示を使用して機構を選択できます。次に、アプリケーションは 選択した機構が gss_OID_set の適切なメンバーになるように設定します。また、希望する機構と使用できる機構のリストを比較することもできます。

createMechOid() 関数

この関数は、完全を期すためにここに表示されています。通常は、GSS_C_NULL_OID によって指定されるデフォルトの機構を使用するようにしてください。


例 C–3 createMechOid() 関数

gss_OID createMechOid(const char *mechStr)
{
        gss_buffer_desc mechDesc;
        gss_OID mechOid;
        OM_uint32 minor;

        if (mechStr == NULL)
                return (GSS_C_NULL_OID);

        mechDesc.length = strlen(mechStr);
        mechDesc.value = (void *) mechStr;

        if (gss_str_to_oid(&minor, &mechDesc, &mechOid) !
            = GSS_S_COMPLETE) {
                fprintf(stderr, "Invalid mechanism oid specified <%s>",
                                mechStr);
                return (GSS_C_NULL_OID);
        }

        return (mechOid);
}

デフォルト以外の機構の指定

parse_oid() は、コマンド行で指定されたセキュリティー機構名を互換性のある OID に変換します。


例 C–4 parse_oid() 関数

static void parse_oid(char *mechanism, gss_OID *oid)
{
    char        *mechstr = 0, *cp;
    gss_buffer_desc tok;
    OM_uint32 maj_stat, min_stat;
   
    if (isdigit(mechanism[0])) {
        mechstr = malloc(strlen(mechanism)+5);
        if (!mechstr) {
            printf("Couldn't allocate mechanism scratch!\n");
            return;
        }
        sprintf(mechstr, "{ %s }", mechanism);
        for (cp = mechstr; *cp; cp++)
            if (*cp == '.')
                *cp = ' ';
        tok.value = mechstr;
    } else
        tok.value = mechanism;
    tok.length = strlen(tok.value);
    maj_stat = gss_str_to_oid(&min_stat, &tok, oid);
    if (maj_stat != GSS_S_COMPLETE) {
        display_status("str_to_oid", maj_stat, min_stat);
        return;
    }
    if (mechstr)
        free(mechstr);
}