RFC2744 - Generic Security Service API Version 2 : C-bindings
时间:2023-11-16 19:53:46
来源:网络
浏览:11次
Network Working Group J. Wray
Request for Comments: 2744 Iris Associates
Obsoletes: 1509 January 2000
Category: Standards Track
Generic Security Service API Version 2 : C-bindings
Status of this Memo
This document specifies an Internet standards track protocol for the
Internet community, and requests discussion and suggestions for
improvements. Please refer to the current edition of the "Internet
Official Protocol Standards" (STD 1) for the standardization state
and status of this protocol. Distribution of this memo is unlimited.
Copyright Notice
Copyright (C) The Internet Society (2000). All Rights Reserved.
Abstract
This document specifies C language bindings for Version 2, Update 1
of the Generic Security Service Application Program Interface (GSS-
API), which is described at a language-independent conceptual level
in RFC-2743 [GSSAPI]. It obsoletes RFC-1509, making specific
incremental changes in response to implementation eXPerience and
liaison requests. It is intended, therefore, that this memo or a
sUCcessor version thereof will become the basis for subsequent
progression of the GSS-API specification on the standards track.
The Generic Security Service Application Programming Interface
provides security services to its callers, and is intended for
implementation atop a variety of underlying cryptographic mechanisms.
Typically, GSS-API callers will be application protocols into which
security enhancements are integrated through invocation of services
provided by the GSS-API. The GSS-API allows a caller application to
authenticate a principal identity associated with a peer application,
to delegate rights to a peer, and to apply security services such as
confidentiality and integrity on a per-message basis.
1. Introduction
The Generic Security Service Application Programming Interface
[GSSAPI] provides security services to calling applications. It
allows a communicating application to authenticate the user
associated with another application, to delegate rights to another
application, and to apply security services such as confidentiality
and integrity on a per-message basis.
There are four stages to using the GSS-API:
a) The application acquires a set of credentials with which it may
prove its identity to other processes. The application"s
credentials vouch for its global identity, which may or may not be
related to any local username under which it may be running.
b) A pair of communicating applications establish a joint security
context using their credentials. The security context is a pair
of GSS-API data structures that contain shared state information,
which is required in order that per-message security services may
be provided. Examples of state that might be shared between
applications as part of a security context are cryptographic keys,
and message sequence numbers. As part of the establishment of a
security context, the context initiator is authenticated to the
responder, and may require that the responder is authenticated in
turn. The initiator may optionally give the responder the right
to initiate further security contexts, acting as an agent or
delegate of the initiator. This transfer of rights is termed
delegation, and is achieved by creating a set of credentials,
similar to those used by the initiating application, but which may
be used by the responder.
To establish and maintain the shared information that makes up the
security context, certain GSS-API calls will return a token data
structure, which is an opaque data type that may contain
cryptographically protected data. The caller of such a GSS-API
routine is responsible for transferring the token to the peer
application, encapsulated if necessary in an application-
application protocol. On receipt of such a token, the peer
application should pass it to a corresponding GSS-API routine
which will decode the token and extract the information, updating
the security context state information accordingly.
c) Per-message services are invoked to apply either:
integrity and data origin authentication, or confidentiality,
integrity and data origin authentication to application data,
which are treated by GSS-API as arbitrary octet-strings. An
application transmitting a message that it wishes to protect will
call the appropriate GSS-API routine (gss_get_mic or gss_wrap) to
apply protection, specifying the appropriate security context, and
send the resulting token to the receiving application. The
receiver will pass the received token (and, in the case of data
protected by gss_get_mic, the accompanying message-data) to the
corresponding decoding routine (gss_verify_mic or gss_unwrap) to
remove the protection and validate the data.
d) At the completion of a communications session (which may extend
across several transport connections), each application calls a
GSS-API routine to delete the security context. Multiple contexts
may also be used (either successively or simultaneously) within a
single communications association, at the option of the
applications.
2. GSS-API Routines
This section lists the routines that make up the GSS-API, and
offers a brief description of the purpose of each routine.
Detailed descriptions of each routine are listed in alphabetical
order in section 5.
Table 2-1 GSS-API Credential-management Routines
Routine Section Function
------- ------- --------
gss_acquire_cred 5.2 Assume a global identity; OBTain
a GSS-API credential handle for
pre-existing credentials.
gss_add_cred 5.3 Construct credentials
incrementally
gss_inquire_cred 5.21 Obtain information about a
credential
gss_inquire_cred_by_mech 5.22 Obtain per-mechanism information
about a credential.
gss_release_cred 5.27 Discard a credential handle.
Table 2-2 GSS-API Context-Level Routines
Routine Section Function
------- ------- --------
gss_init_sec_context 5.19 Initiate a security context with
a peer application
gss_accept_sec_context 5.1 Accept a security context
initiated by a
peer application
gss_delete_sec_context 5.9 Discard a security context
gss_process_context_token 5.25 Process a token on a security
context from a peer application
gss_context_time 5.7 Determine for how long a context
will remain valid
gss_inquire_context 5.20 Obtain information about a
security context
gss_wrap_size_limit 5.34 Determine token-size limit for
gss_wrap on a context
gss_export_sec_context 5.14 Transfer a security context to
another process
gss_import_sec_context 5.17 Import a transferred context
Table 2-3 GSS-API Per-message Routines
Routine Section Function
------- ------- --------
gss_get_mic 5.15 Calculate a cryptographic message
integrity code (MIC) for a
message; integrity service
gss_verify_mic 5.32 Check a MIC against a message;
verify integrity of a received
message
gss_wrap 5.33 Attach a MIC to a message, and
optionally encrypt the message
content;
confidentiality service
gss_unwrap 5.31 Verify a message with attached
MIC, and decrypt message content
if necessary.
Table 2-4 GSS-API Name manipulation Routines
Routine Section Function
------- ------- --------
gss_import_name 5.16 Convert a contiguous string name
to internal-form
gss_display_name 5.10 Convert internal-form name to
text
gss_compare_name 5.6 Compare two internal-form names
gss_release_name 5.28 Discard an internal-form name
gss_inquire_names_for_mech 5.24 List the name-types supported by
the specified mechanism
gss_inquire_mechs_for_name 5.23 List mechanisms that support the
specified name-type
gss_canonicalize_name 5.5 Convert an internal name to an MN
gss_export_name 5.13 Convert an MN to export form
gss_duplicate_name 5.12 Create a copy of an internal name
Table 2-5 GSS-API Miscellaneous Routines
Routine Section Function
------- ------- --------
gss_add_oid_set_member 5.4 Add an object identifier to
a set
gss_display_status 5.11 Convert a GSS-API status code
to text
gss_indicate_mechs 5.18 Determine available underlying
authentication mechanisms
gss_release_buffer 5.26 Discard a buffer
gss_release_oid_set 5.29 Discard a set of object
identifiers
gss_create_empty_oid_set 5.8 Create a set containing no
object identifiers
gss_test_oid_set_member 5.30 Determines whether an object
identifier is a member of a set.
Individual GSS-API implementations may augment these routines by
providing additional mechanism-specific routines if required
functionality is not available from the generic forms. Applications
are encouraged to use the generic routines wherever possible on
portability grounds.
3. Data Types and Calling Conventions
The following conventions are used by the GSS-API C-language
bindings:
3.1. Integer types
GSS-API uses the following integer data type:
OM_uint32 32-bit unsigned integer
Where guaranteed minimum bit-count is important, this portable data
type is used by the GSS-API routine definitions. Individual GSS-API
implementations will include appropriate typedef definitions to map
this type onto a built-in data type. If the platform supports the
X/Open xom.h header file, the OM_uint32 definition contained therein
should be used; the GSS-API header file in Appendix A contains logic
that will detect the prior inclusion of xom.h, and will not attempt
to re-declare OM_uint32. If the X/Open header file is not available
on the platform, the GSS-API implementation should use the smallest
natural unsigned integer type that provides at least 32 bits of
precision.
3.2. String and similar data
Many of the GSS-API routines take arguments and return values that
describe contiguous octet-strings. All such data is passed between
the GSS-API and the caller using the gss_buffer_t data type. This
data type is a pointer to a buffer descriptor, which consists of a
length field that contains the total number of bytes in the datum,
and a value field which contains a pointer to the actual datum:
typedef struct gss_buffer_desc_struct {
size_t length;
void *value;
} gss_buffer_desc, *gss_buffer_t;
Storage for data returned to the application by a GSS-API routine
using the gss_buffer_t conventions is allocated by the GSS-API
routine. The application may free this storage by invoking the
gss_release_buffer routine. Allocation of the gss_buffer_desc object
is always the responsibility of the application; unused
gss_buffer_desc objects may be initialized to the value
GSS_C_EMPTY_BUFFER.
3.2.1. Opaque data types
Certain multiple-Word data items are considered opaque data types at
the GSS-API, because their internal structure has no significance
either to the GSS-API or to the caller. Examples of such opaque data
types are the input_token parameter to gss_init_sec_context (which is
opaque to the caller), and the input_message parameter to gss_wrap
(which is opaque to the GSS-API). Opaque data is passed between the
GSS-API and the application using the gss_buffer_t datatype.
3.2.2. Character strings
Certain multiple-word data items may be regarded as simple ISO
Latin-1 character strings. Examples are the printable strings passed
to gss_import_name via the input_name_buffer parameter. Some GSS-API
routines also return character strings. All such character strings
are passed between the application and the GSS-API implementation
using the gss_buffer_t datatype, which is a pointer to a
gss_buffer_desc object.
When a gss_buffer_desc object describes a printable string, the
length field of the gss_buffer_desc should only count printable
characters within the string. In particular, a trailing NUL
character should NOT be included in the length count, nor should
either the GSS-API implementation or the application assume the
presence of an uncounted trailing NUL.
3.3. Object Identifiers
Certain GSS-API procedures take parameters of the type gss_OID, or
Object identifier. This is a type containing ISO-defined tree-
structured values, and is used by the GSS-API caller to select an
underlying security mechanism and to specify namespaces. A value of
type gss_OID has the following structure:
typedef struct gss_OID_desc_struct {
OM_uint32 length;
void *elements;
} gss_OID_desc, *gss_OID;
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 corresponding to {iso(1) identified-organization(3) icd-
ecma(12) member-company(2) dec(1011) cryptoAlgorithms(7) DASS(5)},
meaning the DASS X.509 authentication mechanism, has a length field
of 7 and an elements field pointing to seven octets containing the
following octal values: 53,14,2,207,163,7,5. GSS-API implementations
should provide constant gss_OID values to allow applications to
request any supported mechanism, although applications are encouraged
on portability grounds to accept the default mechanism. gss_OID
values should also be provided to allow applications to specify
particular name types (see section 3.10). Applications should treat
gss_OID_desc values returned by GSS-API routines as read-only. In
particular, the application should not attempt to deallocate them
with free(). The gss_OID_desc datatype is equivalent to the X/Open
OM_object_identifier datatype[XOM].
3.4. Object Identifier Sets
Certain GSS-API procedures take parameters of the type gss_OID_set.
This type represents one or more object identifiers (section 2.3). A
gss_OID_set object has the following structure:
typedef struct gss_OID_set_desc_struct {
size_t count;
gss_OID elements;
} gss_OID_set_desc, *gss_OID_set;
The count field contains the number of OIDs within the set. The
elements field is a pointer to an array of gss_OID_desc objects, each
of which describes a single OID. gss_OID_set values are used to name
the available mechanisms supported by the GSS-API, to request the use
of specific mechanisms, and to indicate which mechanisms a given
credential supports.
All OID sets returned to the application by GSS-API are dynamic
objects (the gss_OID_set_desc, the "elements" array of the set, and
the "elements" array of each member OID are all dynamically
allocated), and this storage must be deallocated by the application
using the gss_release_oid_set() routine.
3.5. Credentials
A credential handle is a caller-opaque atomic datum that identifies a
GSS-API credential data structure. It is represented by the caller-
opaque type gss_cred_id_t, which should be implemented as a pointer
or arithmetic type. If a pointer implementation is chosen, care must
be taken to ensure that two gss_cred_id_t values may be compared with
the == operator.
GSS-API credentials can contain mechanism-specific principal
authentication data for multiple mechanisms. A GSS-API credential is
composed of a set of credential-elements, each of which is applicable
to a single mechanism. A credential may contain at most one
credential-element for each supported mechanism. A credential-element
identifies the data needed by a single mechanism to authenticate a
single principal, and conceptually contains two credential-references
that describe the actual mechanism-specific authentication data, one
to be used by GSS-API for initiating contexts, and one to be used
for accepting contexts. For mechanisms that do not distinguish
between acceptor and initiator credentials, both references would
point to the same underlying mechanism-specific authentication data.
Credentials describe a set of mechanism-specific principals, and give
their holder the ability to act as any of those principals. All
principal identities asserted by a single GSS-API credential should
belong to the same entity, although enforcement of this property is
an implementation-specific matter. The GSS-API does not make the
actual credentials available to applications; instead a credential
handle is used to identify a particular credential, held internally
by GSS-API. The combination of GSS-API credential handle and
mechanism identifies the principal whose identity will be asserted by
the credential when used with that mechanism.
The gss_init_sec_context and gss_accept_sec_context routines allow
the value GSS_C_NO_CREDENTIAL to be specified as their credential
handle parameter. This special credential-handle indicates a desire
by the application to act as a default principal. While individual
GSS-API implementations are free to determine such default behavior
as appropriate to the mechanism, the following default behavior by
these routines is recommended for portability:
gss_init_sec_context
1) If there is only a single principal capable of initiating
security contexts for the chosen mechanism that the application
is authorized to act on behalf of, then that principal shall be
used, otherwise
2) If the platform maintains a concept of a default network-
identity for the chosen mechanism, and if the application is
authorized to act on behalf of that identity for the purpose of
initiating security contexts, then the principal corresponding
to that identity shall be used, otherwise
3) If the platform maintains a concept of a default local
identity, and provides a means to map local identities into
network-identities for the chosen mechanism, and if the
application is authorized to act on behalf of the network-
identity image of the default local identity for the purpose of
initiating security contexts using the chosen mechanism, then
the principal corresponding to that identity shall be used,
otherwise
4) A user-configurable default identity should be used.
gss_accept_sec_context
1) If there is only a single authorized principal identity capable
of accepting security contexts for the chosen mechanism, then
that principal shall be used, otherwise
2) If the mechanism can determine the identity of the target
principal by examining the context-establishment token, and if
the accepting application is authorized to act as that
principal for the purpose of accepting security contexts using
the chosen mechanism, then that principal identity shall be
used, otherwise
3) If the mechanism supports context acceptance by any principal,
and if mutual authentication was not requested, any principal
that the application is authorized to accept security contexts
under using the chosen mechanism may be used, otherwise
4)A user-configurable default identity shall be used.
The purpose of the above rules is to allow security contexts to be
established by both initiator and acceptor using the default behavior
wherever possible. Applications requesting default behavior are
likely to be more portable across mechanisms and platforms than ones
that use gss_acquire_cred to request a specific identity.
3.6. Contexts
The gss_ctx_id_t data type contains a caller-opaque atomic value that
identifies one end of a GSS-API security context. It should be
implemented as a pointer or arithmetic type. If a pointer type is
chosen, care should be taken to ensure that two gss_ctx_id_t values
may be compared with the == operator.
The security context holds state information about each end of a peer
communication, including cryptographic state information.
3.7. Authentication tokens
A token is a caller-opaque type that GSS-API uses to maintain
synchronization between the context data structures at each end of a
GSS-API security context. The token is a cryptographically protected
octet-string, generated by the underlying mechanism at one end of a
GSS-API security context for use by the peer mechanism at the other
end. Encapsulation (if required) and transfer of the token are the
responsibility of the peer applications. A token is passed between
the GSS-API and the application using the gss_buffer_t conventions.
3.8. Interprocess tokens
Certain GSS-API routines are intended to transfer data between
processes in multi-process programs. These routines use a caller-
opaque octet-string, generated by the GSS-API in one process for use
by the GSS-API in another process. The calling application is
responsible for transferring such tokens between processes in an OS-
specific manner. Note that, while GSS-API implementors are
encouraged to avoid placing sensitive information within interprocess
tokens, or to cryptographically protect them, many implementations
will be unable to avoid placing key material or other sensitive data
within them. It is the application"s responsibility to ensure that
interprocess tokens are protected in transit, and transferred only to
processes that are trustworthy. An interprocess token is passed
between the GSS-API and the application using the gss_buffer_t
conventions.
3.9. Status values
Every GSS-API routine returns two distinct values to report status
information to the caller: GSS status codes and Mechanism status
codes.
3.9.1. GSS status codes
GSS-API routines return GSS status codes as their OM_uint32 function
value. These codes indicate errors that are independent of the
underlying mechanism(s) used to provide the security service. The
errors that can be indicated via a GSS status code are either generic
API routine errors (errors that are defined in the GSS-API
specification) or calling errors (errors that are specific to these
language bindings).
A GSS status code can indicate a single fatal generic API error from
the routine and a single calling error. In addition, supplementary
status information may be indicated via the setting of bits in the
supplementary info field of a GSS status code.
These errors are encoded into the 32-bit GSS status code as follows:
MSB LSB
------------------------------------------------------------
Calling Error Routine Error Supplementary Info
------------------------------------------------------------
Bit 31 24 23 16 15 0
Hence if a GSS-API routine returns a GSS status code whose upper 16
bits contain a non-zero value, the call failed. If the calling error
field is non-zero, the invoking application"s call of the routine was
erroneous. Calling errors are defined in table 5-1. If the routine
error field is non-zero, the routine failed for one of the routine-
specific reasons listed below in table 5-2. Whether or not the upper
16 bits indicate a failure or a success, the routine may indicate
additional information by setting bits in the supplementary info
field of the status code. The meaning of individual bits is listed
below in table 5-3.
Table 3-1 Calling Errors
Name Value in field Meaning
---- -------------- -------
GSS_S_CALL_INAccessIBLE_READ 1 A required input parameter
could not be read
GSS_S_CALL_INACCESSIBLE_WRITE 2 A required output parameter
could not be written.
GSS_S_CALL_BAD_STRUCTURE 3 A parameter was malformed
Table 3-2 Routine Errors
Name Value in field Meaning
---- -------------- -------
GSS_S_BAD_MECH 1 An unsupported mechanism
was requested
GSS_S_BAD_NAME 2 An invalid name was
supplied
GSS_S_BAD_NAMETYPE 3 A supplied name was of an
unsupported type
GSS_S_BAD_BINDINGS 4 Incorrect channel bindings
were supplied
GSS_S_BAD_STATUS 5 An invalid status code was
supplied
GSS_S_BAD_MIC GSS_S_BAD_SIG 6 A token had an invalid MIC
GSS_S_NO_CRED 7 No credentials were
supplied, or the
credentials were
unavailable or
inaccessible.
GSS_S_NO_CONTEXT 8 No context has been
established
GSS_S_DEFECTIVE_TOKEN 9 A token was invalid
GSS_S_DEFECTIVE_CREDENTIAL 10 A credential was invalid
GSS_S_CREDENTIALS_EXPIRED 11 The referenced credentials
have expired
GSS_S_CONTEXT_EXPIRED 12 The context has expired
GSS_S_FAILURE 13 Miscellaneous failure (see
text)
GSS_S_BAD_QOP 14 The quality-of-protection
requested could not be
provided
GSS_S_UNAUTHORIZED 15 The operation is forbidden
by local security policy
GSS_S_UNAVAILABLE 16 The operation or option is
unavailable
GSS_S_DUPLICATE_ELEMENT 17 The requested credential
element already exists
GSS_S_NAME_NOT_MN 18 The provided name was not a
mechanism name
Table 3-3 Supplementary Status Bits
Name Bit Number Meaning
---- ---------- -------
GSS_S_CONTINUE_NEEDED 0 (LSB) Returned only by
gss_init_sec_context or
gss_accept_sec_context. The
routine must be called again
to complete its function.
See routine documentation for
detailed description
GSS_S_DUPLICATE_TOKEN 1 The token was a duplicate of
an earlier token
GSS_S_OLD_TOKEN 2 The token"s validity period
has expired
GSS_S_UNSEQ_TOKEN 3 A later token has already been
processed
GSS_S_GAP_TOKEN 4 An expected per-message token
was not received
The routine documentation also uses the name GSS_S_COMPLETE, which is
a zero value, to indicate an absence of any API errors or
supplementary information bits.
All GSS_S_xxx symbols equate to complete OM_uint32 status codes,
rather than to bitfield values. For example, the actual value of the
symbol GSS_S_BAD_NAMETYPE (value 3 in the routine error field) is
3<<16. The macros GSS_CALLING_ERROR(), GSS_ROUTINE_ERROR() and
GSS_SUPPLEMENTARY_INFO() are provided, each of which takes a GSS
status code and removes all but the relevant field. For example, the
value obtained by applying GSS_ROUTINE_ERROR to a status code removes
the calling errors and supplementary info fields, leaving only the
routine errors field. The values delivered by these macros may be
directly compared with a GSS_S_xxx symbol of the appropriate type.
The macro GSS_ERROR() is also provided, which when applied to a GSS
status code returns a non-zero value if the status code indicated a
calling or routine error, and a zero value otherwise. All macros
defined by GSS-API evaluate their argument(s) exactly once.
A GSS-API implementation may choose to signal calling errors in a
platform-specific manner instead of, or in addition to the routine
value; routine errors and supplementary info should be returned via
major status values only.
The GSS major status code GSS_S_FAILURE is used to indicate that the
underlying mechanism detected an error for which no specific GSS
status code is defined. The mechanism-specific status code will
provide more details about the error.
3.9.2. Mechanism-specific status codes
GSS-API routines return a minor_status parameter, which is used to
indicate specialized errors from the underlying security mechanism.
This parameter may contain a single mechanism-specific error,
indicated by a OM_uint32 value.
The minor_status parameter will always be set by a GSS-API routine,
even if it returns a calling error or one of the generic API errors
indicated above as fatal, although most other output parameters may
remain unset in such cases. However, output parameters that are
expected to return pointers to storage allocated by a routine must
always be set by the routine, even in the event of an error, although
in such cases the GSS-API routine may elect to set the returned
parameter value to NULL to indicate that no storage was actually
allocated. Any length field associated with such pointers (as in a
gss_buffer_desc structure) should also be set to zero in such cases.
3.10. Names
A name is used to identify a person or entity. GSS-API authenticates
the relationship between a name and the entity claiming the name.
Since different authentication mechanisms may employ different
namespaces for identifying their principals, GSSAPI"s naming support
is necessarily complex in multi-mechanism environments (or even in
some single-mechanism environments where the underlying mechanism
supports multiple namespaces).
Two distinct representations are defined for names:
An internal form. This is the GSS-API "native" format for names,
represented by the implementation-specific gss_name_t type. It is
opaque to GSS-API callers. A single gss_name_t object may contain
multiple names from different namespaces, but all names should
refer to the same entity. An example of such an internal name
would be the name returned from a call to the gss_inquire_cred
routine, when applied to a credential containing credential
elements for multiple authentication mechanisms employing
different namespaces. This gss_name_t object will contain a
distinct name for the entity for each authentication mechanism.
For GSS-API implementations supporting multiple namespaces,
objects of type gss_name_t must contain sufficient information to
determine the namespace to which each primitive name belongs.
Mechanism-specific contiguous octet-string forms. A format
capable of containing a single name (from a single namespace).
Contiguous string names are always accompanied by an object
identifier specifying the namespace to which the name belongs, and
their format is dependent on the authentication mechanism that
employs the name. Many, but not all, contiguous string names will
be printable, and may therefore be used by GSS-API applications
for communication with their users.
Routines (gss_import_name and gss_display_name) are provided to
convert names between contiguous string representations and the
internal gss_name_t type. gss_import_name may support multiple
syntaxes for each supported namespace, allowing users the freedom to
choose a preferred name representation. gss_display_name should use
an implementation-chosen printable syntax for each supported name-
type.
If an application calls gss_display_name(), passing the internal name
resulting from a call to gss_import_name(), there is no guarantee the
the resulting contiguous string name will be the same as the original
imported string name. Nor do name-space identifiers necessarily
survive unchanged after a journey through the internal name-form. An
example of this might be a mechanism that authenticates X.500 names,
but provides an algorithmic mapping of Internet DNS names into X.500.
That mechanism"s implementation of gss_import_name() might, when
presented with a DNS name, generate an internal name that contained
both the original DNS name and the equivalent X.500 name.
Alternatively, it might only store the X.500 name. In the latter
case, gss_display_name() would most likely generate a printable X.500
name, rather than the original DNS name.
The process of authentication delivers to the context acceptor an
internal name. Since this name has been authenticated by a single
mechanism, it contains only a single name (even if the internal name
presented by the context initiator to gss_init_sec_context had
multiple components). Such names are termed internal mechanism
names, or "MN"s and the names emitted by gss_accept_sec_context() are
always of this type. Since some applications may require MNs without
wanting to incur the overhead of an authentication operation, a
second function, gss_canonicalize_name(), is provided to convert a
general internal name into an MN.
Comparison of internal-form names may be accomplished via the
gss_compare_name() routine, which returns true if the two names being
compared refer to the same entity. This removes the need for the
application program to understand the syntaxes of the various
printable names that a given GSS-API implementation may support.
Since GSS-API assumes that all primitive names contained within a
given internal name refer to the same entity, gss_compare_name() can
return true if the two names have at least one primitive name in
common. If the implementation embodies knowledge of equivalence
relationships between names taken from different namespaces, this
knowledge may also allow successful comparison of internal names
containing no overlapping primitive elements.
When used in large access control lists, the overhead of invoking
gss_import_name() and gss_compare_name() on each name from the ACL
may be prohibitive. As an alternative way of supporting this case,
GSS-API defines a special form of the contiguous string name which
may be compared directly (e.g. with memcmp()). Contiguous names
suitable for comparison are generated by the gss_export_name()
routine, which requires an MN as input. Exported names may be re-
imported by the gss_import_name() routine, and the resulting internal
name will also be an MN. The gss_OID constant GSS_C_NT_EXPORT_NAME
indentifies the "export name" type, and the value of this constant is
given in Appendix A. Structurally, an exported name object consists
of a header containing an OID identifying the mechanism that
authenticated the name, and a trailer containing the name itself,
where the syntax of the trailer is defined by the individual
mechanism specification. The precise format of an export name is
defined in the language-independent GSS-API specification [GSSAPI].
Note that the results obtained by using gss_compare_name() will in
general be different from those obtained by invoking
gss_canonicalize_name() and gss_export_name(), and then comparing the
exported names. The first series of operation determines whether two
(unauthenticated) names identify the same principal; the second
whether a particular mechanism would authenticate them as the same
principal. These two operations will in general give the same
results only for MNs.
The gss_name_t datatype should be implemented as a pointer type. To
allow the compiler to aid the application programmer by performing
type-checking, the use of (void *) is discouraged. A pointer to an
implementation-defined type is the preferred choice.
Storage is allocated by routines that return gss_name_t values. A
procedure, gss_release_name, is provided to free storage associated
with an internal-form name.
3.11. Channel Bindings
GSS-API supports the use of user-specified tags to identify a given
context to the peer application. These tags are intended to be used
to identify the particular communications channel that carries the
context. Channel bindings are communicated to the GSS-API using the
following structure:
typedef struct gss_channel_bindings_struct {
OM_uint32 initiator_addrtype;
gss_buffer_desc initiator_address;
OM_uint32 acceptor_addrtype;
gss_buffer_desc acceptor_address;
gss_buffer_desc application_data;
} *gss_channel_bindings_t;
The initiator_addrtype and acceptor_addrtype fields denote the type
of addresses contained in the initiator_address and acceptor_address
buffers. The address type should be one of the following:
GSS_C_AF_UNSPEC Unspecified address type
GSS_C_AF_LOCAL Host-local address type
GSS_C_AF_INET Internet address type (e.g. IP)
GSS_C_AF_IMPLINK ARPAnet IMP address type
GSS_C_AF_PUP pup protocols (eg BSP) address type
GSS_C_AF_CHAOS MIT CHAOS protocol address type
GSS_C_AF_NS XEROX NS address type
GSS_C_AF_NBS nbs address type
GSS_C_AF_ECMA ECMA address type
GSS_C_AF_DATAKIT datakit protocols address type
GSS_C_AF_CCITT CCITT protocols
GSS_C_AF_SNA IBM SNA address type
GSS_C_AF_DECnet DECnet address type
GSS_C_AF_DLI Direct data link interface address type
GSS_C_AF_LAT LAT address type
GSS_C_AF_HYLINK NSC Hyperchannel address type
GSS_C_AF_APPLETALK AppleTalk address type
GSS_C_AF_BSC BISYNC 2780/3780 address type
GSS_C_AF_DSS Distributed system services address type
GSS_C_AF_OSI OSI TP4 address type
GSS_C_AF_X25 X.25
GSS_C_AF_NULLADDR No address specified
Note that these symbols name address families rather than specific
addressing formats. For address families that contain several
alternative address forms, the initiator_address and acceptor_address
fields must contain sufficient information to determine which address
form is used. When not otherwise specified, addresses should be
specified in network byte-order (that is, native byte-ordering for
the address family).
Conceptually, the GSS-API concatenates the initiator_addrtype,
initiator_address, acceptor_addrtype, acceptor_address and
application_data to form an octet string. The mechanism calculates a
MIC over this octet string, and binds the MIC to the context
establishment token emitted by gss_init_sec_context. The same
bindings are presented by the context acceptor to
gss_accept_sec_context, and a MIC is calculated in the same way. The
calculated MIC is compared with that found in the token, and if the
MICs differ, gss_accept_sec_context will return a GSS_S_BAD_BINDINGS
error, and the context will not be established. Some mechanisms may
include the actual channel binding data in the token (rather than
just a MIC); applications should therefore not use confidential data
as channel-binding components.
Individual mechanisms may impose additional constraints on addresses
and address types that may appear in channel bindings. For example,
a mechanism may verify that the initiator_address field of the
channel bindings presented to gss_init_sec_context contains the
correct network address of the host system. Portable applications
should therefore ensure that they either provide correct information
for the address fields, or omit addressing information, specifying
GSS_C_AF_NULLADDR as the address-types.
3.12. Optional parameters
Various parameters are described as optional. This means that they
follow a convention whereby a default value may be requested. The
following conventions are used for omitted parameters. These
conventions apply only to those parameters that are explicitly
documented as optional.
3.12.1. gss_buffer_t types
Specify GSS_C_NO_BUFFER as a value. For an input parameter this
signifies that default behavior is requested, while for an output
parameter it indicates that the information that would be returned
via the parameter is not required by the application.
3.12.2. Integer types (input)
Individual parameter documentation lists values to be used to
indicate default actions.
3.12.3. Integer types (output)
Specify NULL as the value for the pointer.
3.12.4. Pointer types
Specify NULL as the value.
3.12.5. Object IDs
Specify GSS_C_NO_OID as the value.
3.12.6. Object ID Sets
Specify GSS_C_NO_OID_SET as the value.
3.12.7. Channel Bindings
Specify GSS_C_NO_CHANNEL_BINDINGS to indicate that channel bindings
are not to be used.
4. Additional Controls
This section discusses the optional services that a context initiator
may request of the GSS-API at context establishment. Each of these
services is requested by setting a flag in the req_flags input
parameter to gss_init_sec_context.
The optional services currently defined are:
Delegation - The (usually temporary) transfer of rights from
initiator to acceptor, enabling the acceptor to authenticate
itself as an agent of the initiator.
Mutual Authentication - In addition to the initiator authenticating
its identity to the context acceptor, the context acceptor should
also authenticate itself to the initiator.
Replay detection - In addition to providing message integrity
services, gss_get_mic and gss_wrap should include message
numbering information to enable gss_verify_mic and gss_unwrap to
detect if a message has been duplicated.
Out-of-sequence detection - In addition to providing message
integrity services, gss_get_mic and gss_wrap should include
message sequencing information to enable gss_verify_mic and
gss_unwrap to detect if a message has been received out of
sequence.
Anonymous authentication - The establishment of the security context
should not reveal the initiator"s identity to the context
acceptor.
Any currently undefined bits within such flag arguments should be
ignored by GSS-API implementations when presented by an application,
and should be set to zero when returned to the application by the
GSS-API implementation.
Some mechanisms may not support all optional services, and some
mechanisms may only support some services in conjunction with others.
Both gss_init_sec_context and gss_accept_sec_context inform the
applications which services will be available from the context when
the establishment phase is complete, via the ret_flags output
parameter. In general, if the security mechanism is capable of
providing a requested service, it should do so, even if additional
services must be enabled in order to provide the requested service.
If the mechanism is incapable of providing a requested service, it
should proceed without the service, leaving the application to abort
the context establishment process if it considers the requested
service to be mandatory.
Some mechanisms may specify that support for some services is
optional, and that implementors of the mechanism need not provide it.
This is most commonly true of the confidentiality service, often
because of legal restrictions on the use of data-encryption, but may
apply to any of the services. Such mechanisms are required to send
at least one token from acceptor to initiator during context
establishment when the initiator indicates a desire to use such a
service, so that the initiating GSS-API can correctly indicate
whether the service is supported by the acceptor"s GSS-API.
4.1. Delegation
The GSS-API allows delegation to be controlled by the initiating
application via a boolean parameter to gss_init_sec_context(), the
routine that establishes a security context. Some mechanisms do not
support delegation, and for such mechanisms attempts by an
application to enable delegation are ignored.
The acceptor of a security context for which the initiator enabled
delegation will receive (via the delegated_cred_handle parameter of
gss_accept_sec_context) a credential handle that contains the
delegated identity, and this credential handle may be used to
initiate subsequent GSS-API security contexts as an agent or delegate
of the initiator. If the original initiator"s identity is "A" and
the delegate"s identity is "B", then, depending on the underlying
mechanism, the identity embodied by the delegated credential may be
either "A" or "B acting for A".
For many mechanisms that support delegation, a simple boolean does
not provide enough control. Examples of additional ASPects of
delegation control that a mechanism might provide to an application
are duration of delegation, network addresses from which delegation
is valid, and constraints on the tasks that may be performed by a
delegate. Such controls are presently outside the scope of the GSS-
API. GSS-API implementations supporting mechanisms offering
additional controls should provide extension routines that allow
these controls to be exercised (perhaps by modifying the initiator"s
GSS-API credential prior to its use in establishing a context).
However, the simple delegation control provided by GSS-API should
always be able to over-ride other mechanism-specific delegation
controls - If the application instructs gss_init_sec_context() that
delegation is not desired, then the implementation must not permit
delegation to occur. This is an exception to the general rule that a
mechanism may enable services even if they are not requested -
delegation may only be provided at the explicit request of the
application.
4.2. Mutual authentication
Usually, a context acceptor will require that a context initiator
authenticate itself so that the acceptor may make an access-control
decision prior to performing a service for the initiator. In some
cases, the initiator may also request that the acceptor authenticate
itself. GSS-API allows the initiating application to request this
mutual authentication service by setting a flag when calling
gss_init_sec_context.
The initiating application is informed as to whether or not the
context acceptor has authenticated itself. Note that some mechanisms
may not support mutual authentication, and other mechanisms may
always perform mutual authentication, whether or not the initiating
application requests it. In particular, mutual authentication my be
required by some mechanisms in order to support replay or out-of-
sequence message detection, and for such mechanisms a request for
either of these services will automatically enable mutual
authentication.
4.3. Replay and out-of-sequence detection
The GSS-API may provide detection of mis-ordered message once a
security context has been established. Protection may be applied to
messages by either application, by calling either gss_get_mic or
gss_wrap, and verified by the peer application by calling
gss_verify_mic or gss_unwrap.
gss_get_mic calculates a cryptographic MIC over an application
message, and returns that MIC in a token. The application should
pass both the token and the message to the peer application, which
presents them to gss_verify_mic.
gss_wrap calculates a cryptographic MIC of an application message,
and places both the MIC and the message inside a single token. The
Application should pass the token to the peer application, which
presents it to gss_unwrap to extract the message and verify the MIC.
Either pair of routines may be capable of detecting out-of-sequence
message delivery, or duplication of messages. Details of such mis-
ordered messages are indicated through supplementary status bits in
the major status code returned by gss_verify_mic or gss_unwrap. The
relevant supplementary bits are:
GSS_S_DUPLICATE_TOKEN - The token is a duplicate of one that has
already been received and processed. Only
contexts that claim to provide replay detection
may set this bit.
GSS_S_OLD_TOKEN - The token is too old to determine whether or
not it is a duplicate. Contexts supporting
out-of-sequence detection but not replay
detection should always set this bit if
GSS_S_UNSEQ_TOKEN is set; contexts that support
replay detection should only set this bit if the
token is so old that it cannot be checked for
duplication.
GSS_S_UNSEQ_TOKEN - A later token has already been processed.
GSS_S_GAP_TOKEN - An earlier token has not yet been received.
A mechanism need not maintain a list of all tokens that have been
processed in order to support these status codes. A typical
mechanism might retain information about only the most recent "N"
tokens processed, allowing it to distinguish duplicates and missing
tokens within the most recent "N" messages; the receipt of a token
older than the most recent "N" would result in a GSS_S_OLD_TOKEN
status.
4.4. Anonymous Authentication
In certain situations, an application may wish to initiate the
authentication process to authenticate a peer, without revealing its
own identity. As an example, consider an application providing
access to a database containing medical information, and offering
unrestricted access to the service. A client of such a service might
wish to authenticate the service (in order to establish trust in any
information retrieved from it), but might not wish the service to be
able to obtain the client"s identity (perhaps due to privacy concerns
about the specific inquiries, or perhaps simply to avoid being placed
on mailing-lists).
In normal use of the GSS-API, the initiator"s identity is made
available to the acceptor as a result of the context establishment
process. However, context initiators may request that their identity
not be revealed to the context acceptor. Many mechanisms do not
support anonymous authentication, and for such mechanisms the request
will not be honored. An authentication token will be still be
generated, but the application is always informed if a requested
service is unavailable, and has the option to abort context
establishment if anonymity is valued above the other security
services that would require a context to be established.
In addition to informing the application that a context is
established anonymously (via the ret_flags outputs from
gss_init_sec_context and gss_accept_sec_context), the optional
src_name output from gss_accept_sec_context and gss_inquire_context
will, for such contexts, return a reserved internal-form name,
defined by the implementation.
When presented to gss_display_name, this reserved internal-form name
will result in a printable name that is syntactically distinguishable
from any valid principal name supported by the implementation,
associated with a name-type object identifier with the value
GSS_C_NT_ANONYMOUS, whose value us given in Appendix A. The
printable form of an anonymous name should be chosen such that it
implies anonymity, since this name may appear in, for example, audit
logs. For example, the string "<anonymous>" might be a good choice,
if no valid printable names supported by the implementation can begin
with "<" and end with ">".
4.5. Confidentiality
If a context supports the confidentiality service, gss_wrap may be
used to encrypt application messages. Messages are selectively
encrypted, under the control of the conf_req_flag input parameter to
gss_wrap.
4.6. Inter-process context transfer
GSS-API V2 provides routines (gss_export_sec_context and
gss_import_sec_context) which allow a security context to be
transferred between processes on a single machine. The most common
use for such a feature is a client-server design where the server is
implemented as a single process that accepts incoming security
contexts, which then launches child processes to deal with the data
on these contexts. In such a design, the child processes must have
access to the security context data structure created within the
parent by its call to gss_accept_sec_context so that they can use
per-message protection services and delete the security context when
the communication session ends.
Since the security context data structure is expected to contain
sequencing information, it is impractical in general to share a
context between processes. Thus GSS-API provides a call
(gss_export_sec_context) that the process which currently owns the
context can call to declare that it has no intention to use the
context subsequently, and to create an inter-process token containing
information needed by the adopting process to successfully import the
context. After successful completion of gss_export_sec_context, the
original security context is made inaccessible to the calling process
by GSS-API, and any context handles referring to this context are no
longer valid. The originating process transfers the inter-process
token to the adopting process, which passes it to
gss_import_sec_context, and a fresh gss_ctx_id_t is created such that
it is functionally identical to the original context.
The inter-process token may contain sensitive data from the original
security context (including cryptographic keys). Applications using
inter-process tokens to transfer security contexts must take
appropriate steps to protect these tokens in transit.
Implementations are not required to support the inter-process
transfer of security contexts. The ability to transfer a security
context is indicated when the context is created, by
gss_init_sec_context or gss_accept_sec_context setting the
GSS_C_TRANS_FLAG bit in their ret_flags parameter.
4.7. The use of incomplete contexts
Some mechanisms may allow the per-message services to be used before
the context establishment process is complete. For example, a
mechanism may include sufficient information in its initial context-
level token for the context acceptor to immediately decode messages
protected with gss_wrap or gss_get_mic. For such a mechanism, the
initiating application need not wait until subsequent context-level
tokens have been sent and received before invoking the per-message
protection services.
The ability of a context to provide per-message services in advance
of complete context establishment is indicated by the setting of the
GSS_C_PROT_READY_FLAG bit in the ret_flags parameter from
gss_init_sec_context and gss_accept_sec_context. Applications wishing
to use per-message protection services on partially-established
contexts should check this flag before attempting to invoke gss_wrap
or gss_get_mic.
5. GSS-API Routine Descriptions
In addition to the explicit major status codes documented here, the
code GSS_S_FAILURE may be returned by any routine, indicating an
implementation-specific or mechanism-specific error condition,
further details of which are reported via the minor_status parameter.
5.1. gss_accept_sec_context
OM_uint32 gss_accept_sec_context (
OM_uint32 *minor_status,
gss_ctx_id_t *context_handle,
const gss_cred_id_t acceptor_cred_handle,
const gss_buffer_t input_token_buffer,
const gss_channel_bindings_t input_chan_bindings,
const gss_name_t *src_name,
gss_OID *mech_type,
gss_buffer_t output_token,
OM_uint32 *ret_flags,
OM_uint32 *time_rec,
gss_cred_id_t *delegated_cred_handle)
Purpose:
Allows a remotely initiated security context between the application
and a remote peer to be established. The routine may return a
output_token which should be transferred to the peer application,
where the peer application will present it to gss_init_sec_context.
If no token need be sent, gss_accept_sec_context will indicate this
by setting the length field of the output_token argument to zero. To
complete the context establishment, one or more reply tokens may be
required from the peer application; if so, gss_accept_sec_context
will return a status flag of GSS_S_CONTINUE_NEEDED, in which case it
should be called again when the reply token is received from the peer
application, passing the token to gss_accept_sec_context via the
input_token parameters.
Portable applications should be constructed to use the token length
and return status to determine whether a token needs to be sent or
waited for. Thus a typical portable caller should always invoke
gss_accept_sec_context within a loop:
gss_ctx_id_t context_hdl = GSS_C_NO_CONTEXT;
do {
receive_token_from_peer(input_token);
maj_stat = gss_accept_sec_context(&min_stat,
&context_hdl,
cred_hdl,
input_token,
input_bindings,
&client_name,
&mech_type,
output_token,
&ret_flags,
&time_rec,
&deleg_cred);
if (GSS_ERROR(maj_stat)) {
report_error(maj_stat, min_stat);
};
if (output_token->length != 0) {
send_token_to_peer(output_token);
gss_release_buffer(&min_stat, output_token);
};
if (GSS_ERROR(maj_stat)) {
if (context_hdl != GSS_C_NO_CONTEXT)
gss_delete_sec_context(&min_stat,
&context_hdl,
GSS_C_NO_BUFFER);
break;
};
} while (maj_stat & GSS_S_CONTINUE_NEEDED);
Whenever the routine returns a major status that includes the value
GSS_S_CONTINUE_NEEDED, the context is not fully established and the
following restrictions apply to the output parameters:
The value returned via the time_rec parameter is undefined Unless the
accompanying ret_flags parameter contains the bit
GSS_C_PROT_READY_FLAG, indicating that per-message services may be
applied in advance of a successful completion status, the value
returned via the mech_type parameter may be undefined until the
routine returns a major status value of GSS_S_COMPLETE.
The values of the GSS_C_DELEG_FLAG,
GSS_C_MUTUAL_FLAG,GSS_C_REPLAY_FLAG, GSS_C_SEQUENCE_FLAG,
GSS_C_CONF_FLAG,GSS_C_INTEG_FLAG and GSS_C_ANON_FLAG bits returned
via the ret_flags parameter should contain the values that the
implementation expects would be valid if context establishment were
to succeed.
The values of the GSS_C_PROT_READY_FLAG and GSS_C_TRANS_FLAG bits
within ret_flags should indicate the actual state at the time
gss_accept_sec_context returns, whether or not the context is fully
established.
Although this requires that GSS-API implementations set the
GSS_C_PROT_READY_FLAG in the final ret_flags returned to a caller
(i.e. when accompanied by a GSS_S_COMPLETE status code), applications
should not rely on this behavior as the flag was not defined in
Version 1 of the GSS-API. Instead, applications should be prepared to
use per-message services after a successful context establishment,
according to the GSS_C_INTEG_FLAG and GSS_C_CONF_FLAG values.
All other bits within the ret_flags argument should be set to zero.
While the routine returns GSS_S_CONTINUE_NEEDED, the values returned
via the ret_flags argument indicate the services that the
implementation expects to be available from the established context.
If the initial call of gss_accept_sec_context() fails, the
implementation should not create a context object, and should leave
the value of the context_handle parameter set to GSS_C_NO_CONTEXT to
indicate this. In the event of a failure on a subsequent call, the
implementation is permitted to delete the "half-built" security
context (in which case it should set the context_handle parameter to
GSS_C_NO_CONTEXT), but the preferred behavior is to leave the
security context (and the context_handle parameter) untouched for the
application to delete (using gss_delete_sec_context).
During context establishment, the informational status bits
GSS_S_OLD_TOKEN and GSS_S_DUPLICATE_TOKEN indicate fatal errors, and
GSS-API mechanisms should always return them in association with a
routine error of GSS_S_FAILURE. This requirement for pairing did not
exist in version 1 of the GSS-API specification, so applications that
wish to run over version 1 implementations must special-case these
codes.
Parameters:
context_handle gss_ctx_id_t, read/modify context handle for new
context. Supply GSS_C_NO_CONTEXT for first
call; use value returned in subsequent calls.
Once gss_accept_sec_context() has returned a
value via this parameter, resources have been
assigned to the corresponding context, and must
be freed by the application after use with a
call to gss_delete_sec_context().
acceptor_cred_handle gss_cred_id_t, read Credential handle claimed
by context acceptor. Specify
GSS_C_NO_CREDENTIAL to accept the context as a
default principal. If GSS_C_NO_CREDENTIAL is
specified, but no default acceptor principal is
defined, GSS_S_NO_CRED will be returned.
input_token_buffer buffer, opaque, read token obtained from remote
application.
input_chan_bindings channel bindings, read, optional Application-
specified bindings. Allows application to
securely bind channel identification information
to the security context. If channel bindings
are not used, specify GSS_C_NO_CHANNEL_BINDINGS.
src_name gss_name_t, modify, optional Authenticated name
of context initiator. After use, this name
should be deallocated by passing it to
gss_release_name(). If not required, specify
NULL.
mech_type Object ID, modify, optional Security mechanism
used. The returned OID value will be a pointer
into static storage, and should be treated as
read-only by the caller (in particular, it does
not need to be freed). If not required, specify
NULL.
output_token buffer, opaque, modify Token to be passed to
peer application. If the length field of the
returned token buffer is 0, then no token need
be passed to the peer application. If a non-
zero length field is returned, the associated
storage must be freed after use by the
application with a call to gss_release_buffer().
ret_flags bit-mask, modify, optional Contains various
independent flags, each of which indicates that
the context supports a specific service option.
If not needed, specify NULL. Symbolic names are
provided for each flag, and the symbolic names
corresponding to the required flags should be
logically-ANDed with the ret_flags value to test
whether a given option is supported by the
context. The flags are:
GSS_C_DELEG_FLAG
True - Delegated credentials are available
via the delegated_cred_handle
parameter
False - No credentials were delegated
GSS_C_MUTUAL_FLAG
True - Remote peer asked for mutual
authentication
False - Remote peer did not ask for mutual
authentication
GSS_C_REPLAY_FLAG
True - replay of protected messages
will be detected
False - replayed messages will not be
detected
GSS_C_SEQUEN