Solaris 开发者安全性指南

附录 C 指定 OID

应尽可能使用缺省 QOP 和 GSS-API 所提供的机制。请参见GSS-API OID。但是,您可能会出于自己的考虑指定 OID。本附录介绍了如何指定 OID。本附录包含以下主题:

包含 OID 值的文件

为方便起见,GSS-API 允许以可读方式显示机制和 QOP。在 Solaris 系统上,有两个文件(/etc/gss/mech/etc/gss/qop)中包含有关可用机制和可用 QOP 的信息。如果无权访问这些文件,则必须提供来自其他源代码的串文字。针对该机制或 QOP 发布的 Internet 标准应当可以实现此目的。

/etc/gss/mech 文件

/etc/gss/mech 文件列出了可用的机制,其中包含数值和字母两种格式的名称,它将显示以下格式的信息:

样例 /etc/gss/mech 可能如示例 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。字符串可以采用数字或字的形式。


注意 – 注意 –

某些 GSS-API 实现不支持 gss_str_to_oid()gss_oid_to_str()gss_release_oid(),因此不建议使用显式的非缺省机制和 QOP。


机制字符串可以硬编码到应用程序中,也可以来自用户输入的内容。但是,并非所有的 GSS-API 实现都支持 gss_str_to_oid(),因此应用程序不应当依赖此函数。

表示机制的数字可以采用两种不同的格式:第一种格式 { 1 2 3 4 } 是 GSS-API 规范要求使用的正式格式。第二种格式 1.2.3.4 的使用更为广泛,但不是正式的标准格式。 gss_str_to_oid() 应当使用第一种格式的机制数字,因此,在调用 gss_str_to_oid() 之前,必须对采用第二种格式的字符串进行转换。示例 C–3 中显示了 gss_str_to_oid() 的示例。如果机制无效,gss_str_to_oid() 将返回 GSS_S_BAD_MECH

由于 gss_str_to_oid() 会分配 GSS-API 数据空间,因此在完成操作时会使用已有的 gss_release_oid() 函数来删除所分配的 OID。与 gss_str_to_oid() 一样,gss_release_oid() 也不是广泛支持的函数,因此对于希望具有通用可移植性的程序来说,不应依赖此函数。

构造机制 OID

由于无法始终使用 gss_str_to_oid(),因此提供了多种用于查找和选择机制的备用方法。一种方法是手动构造机制 OID,然后将该机制与一组可用的机制进行比较。另一种方法是获取一组可用机制并从其中选择一个机制。

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 值包含一个值为 7 的length 字段和一个指向以下八位字节值的 elements 字段:53,14,2,207,163,7,5

构造机制 OID 的一种方法是声明 gss_OID,然后手动初始化表示指定机制的元素。如上所述,elements 值的输入可以是从表中获取的硬编码值,也可以由用户输入。此方法比使用 gss_str_to_oid() 稍微麻烦些,但是二者的效果相同。

然后,可以将所构造的 gss_OIDgss_indicate_mechs()gss_inquire_mechs_for_name() 函数已返回的一组可用机制进行比较。应用程序可以使用 gss_test_oid_set_member() 函数来检查这组可用机制中是否存在所构造的机制 OID。如果 gss_test_oid_set_member() 没有返回错误,则表明可以将所构造的 OID 用作 GSS-API 事务的机制。

构造预设 OID 的另一种方法是使应用程序使用 gss_indicate_mechs()gss_inquire_mechs_for_name() 来获取可用机制的 gss_OID_setgss_OID_set 具有以下格式:

typedef struct gss_OID_set_desc_struct {

     OM_uint32 length;

     void           *elements;

} gss_OID_set_desc, *gss_OID_set;

其中,每个元素都是一个表示相应机制的 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);

}