Developer's Guide to Oracle® Solaris 11 Security

Exit Print View

Updated: July 2014
 
 

Specifying an OID

You should use the default QOP and mechanism provided by the GSS-API if at all possible. See GSS-API OIDs. However, you might have your own reasons for specifying OIDs. This appendix describes how to specify OIDs.

Files with OID Values

For convenience, the GSS-API does allow mechanisms and QOPs to be displayed in human-readable form. On Oracle Solaris systems, two files, /etc/gss/mech and /etc/gss/qop, contain information about available mechanisms and available QOPs. If you do not have access to these files, then you must provide the string literals from some other source. The published Internet standard for that mechanism or QOP should serve that purpose.

/etc/gss/mech File

    The /etc/gss/mech file lists the mechanisms that are available. /etc/gss/mech contains the names in both the numerical format and the alphabetic form. /etc/gss/mech presents the information in this format:

  • Mechanism name, in ASCII

  • Mechanism's OID

  • Shared library for implementing the services that are provided by this mechanism

  • Optionally, the kernel module for implementing the service

A sample /etc/gss/mech might look like Example D–1.

Example D-1  The /etc/gss/mech File
# 
# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.


#
#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 File

The /etc/gss/qop file stores, for all mechanisms installed, all the QOPs supported by each mechanism, both as an ASCII string and as the corresponding 32–bit integer. A sample /etc/gss/qop might look like the following example.

Example D-2  The /etc/gss/qop File
#
# Copyright (c) 2000,2012

 by Oracle and/or its affiliates. All rights reserved. .
# 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() Function

For backward compatibility with earlier versions of the GSS-API, this implementation of the GSS-API supports the function gss_str_to_oid(). gss_str_to_oid() converts a string that represents a mechanism or QOP to an OID. The string can be either as a number or a word.


Caution

Caution  - gss_str_to_oid(), gss_oid_to_str(), and gss_release_oid() are not supported by some implementations of the GSS-API to discourage the use of explicit, non-default mechanisms and QOPs.


The mechanism string can be hard-coded in the application or come from user input. However, not all implementations of the GSS-API support gss_str_to_oid(), so applications should not rely on this function.

The number that represents a mechanism can have two different formats. The first format, { 1 2 3 4 }, is officially mandated by the GSS-API specifications. The second format, 1.2.3.4, is more widely used but is not an official standard format. gss_str_to_oid() expects the mechanism number in the first format, so you must convert the string if the string is in the second format before calling gss_str_to_oid(). An example of gss_str_to_oid() is shown in Example D–3. If the mechanism is not a valid one, gss_str_to_oid() returns GSS_S_BAD_MECH.

Because gss_str_to_oid() allocates GSS-API data space, the gss_release_oid() function exists is provided to remove the allocated OID when you are finished. Like gss_str_to_oid(), gss_release_oid() is not a generally supported function and should not be relied upon in programs that aspire to universal portability.

Constructing Mechanism OIDs

Because gss_str_to_oid() cannot always be used, there are alternative techniques for finding and selecting mechanisms. One way is to construct a mechanism OID manually and then compare that mechanism to a set of available mechanisms. Another way is to get the set of available mechanisms and choose one from the set.

The gss_OID type has the following form:

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

where the elements field of this structure points to the first byte of an octet string containing the ASN.1 BER encoding of the value portion of the normal BER TLV encoding of the gss_OID. The length field contains the number of bytes in this value. For example, the gss_OID value that corresponds to the DASS X.509 authentication mechanism has a length field of 7 and an elements field that points to the following octal values: 53,14,2,207,163,7,5.

One way to construct a mechanism OID is to declare a gss_OID and then initialize the elements manually to represent a given mechanism. As above, the input for the elements values can be hard-coded, obtained from a table, or entered by a user. This method is somewhat more painstaking than using gss_str_to_oid() but achieves the same effect.

This constructed gss_OID can then be compared against a set of available mechanisms that have been returned by the functions gss_indicate_mechs() or gss_inquire_mechs_for_name(). The application can check for the constructed mechanism OID in this set of available mechanisms by using the gss_test_oid_set_member() function. If gss_test_oid_set_member() does not return an error, then the constructed OID can be used as the mechanism for GSS-API transactions.

As an alternative to constructing a preset OID, the application can use gss_indicate_mechs() or gss_inquire_mechs_for_name() to get the gss_OID_set of available mechanisms. A gss_OID_set has the following form:

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

where each of the elements is a gss_OID that represents a mechanism. The application can then parse each mechanism and display the numerical representation. A user can use this display to choose the mechanism. The application then sets the mechanism to the appropriate member of the gss_OID_set. The application can also compare the desired mechanisms against a list of preferred mechanisms.

createMechOid() Function

This function is shown for the sake of completeness. Normally, you should use the default mechanism, which is specified by GSS_C_NULL_OID.

Example D-3  createMechOid() Function
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);
}

Specifying a Non-Default Mechanism

parse_oid() converts the name of a security mechanism on the command line to a compatible OID.

Example D-4  parse_oid() Function
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);
}