RFC 1509
Generic Security Service API : C-bindings
RFC 1509: Generic Security Service API : C-bindings ๐
okay bestie, the title block first!! ๐ This is RFC 1509, written by J. Wray from Digital Equipment Corporation in September 1993. It's in the Network Working Group stream and it's an Internet standards track protocol doc ๐ง. It doesn't list anything it obsoletes or updates, so there's no drama there โจ.
Status of This Memo โจ
this section is the official "what even is this doc" part ๐ The memo specifies an Internet standards track protocol for the Internet community, and it wants discussion and suggestions for improvements ๐ฌ. For the current standardization state and status, check the current edition of the "Internet Official Protocol Standards" ๐. And the distribution of this memo is unlimited, so share it with everyone ๐.
Abstract ๐ฆ
This document gives you the C language bindings for the Generic Security Service Application Program Interface (GSS-API) ๐. The GSS-API itself is described at a language-independent conceptual level in other documents, so this one is the C-specific version ๐ .
The GSS-API gives its callers security services ๐. It's built to sit on top of different underlying cryptographic mechanisms, which is so smart ๐. Usually the callers are application protocols, and they add security features by calling the services the GSS-API provides ๐ซถ. With it, a caller app can authenticate the principal identity tied to a peer app, delegate rights to that peer, and apply security services like confidentiality and integrity on a per-message basis ๐ฅ.
1. INTRODUCTION โจ
this is the big-picture intro and it's giving "how it all works" energy ๐ The Generic Security Service Application Programming Interface [1] gives security services to calling apps ๐ธ. A communicating app can authenticate the user behind another app, delegate rights to that other app, and apply security services like confidentiality and integrity on a per-message basis ๐ฆ.
Using the GSSAPI happens in four stages, okay? ๐
- (a) First, the app gets a set of credentials so it can prove its identity to other processes ๐ชช. These credentials vouch for its global identity, which might or might not be connected to the local username it runs under ๐ง.
- (b) Next, two communicating apps set up a joint security context using their credentials ๐ค. The security context is a pair of GSSAPI data structures holding shared state, and that state is needed so per-message security services can work ๐. While the context is being set up, the context initiator gets authenticated to the responder, and the responder can require that it gets authenticated back โจ. The initiator can also optionally give the responder the right to start more security contexts ๐. This transfer of rights is called delegation, and it works by making a set of credentials that's similar to the originating app's, but the responder is the one who can use them ๐. To set up and keep the shared info that makes the security context, certain GSSAPI calls return a token data structure. It's cryptographically protected and it's an opaque data type ๐. The caller of one of these routines has to pass the token to the peer app, and the peer should then hand it to a matching GSSAPI routine that decodes it and pulls out the info ๐ .
- (c) Per-message services get invoked to apply either:
- (i) integrity and data origin authentication, or
- (ii) confidentiality, integrity and data origin authentication
to application data ๐ฆ. The GSSAPI treats that data as arbitrary octet-strings ๐งฉ. A sending app that wants to protect a message calls the right GSSAPI routine (sign or seal) to apply the protection, names the right security context, and sends the result to the receiving app ๐จ. The receiver passes the incoming data to the matching decoding routine (verify or unseal), which removes the protection and validates the data โ .
- (d) When a communications session ends (and it can stretch across several connections), the peer apps call GSSAPI routines to delete the security context ๐งน. Multiple contexts can also get used, either one after another or at the same time, within a single communications association ๐.
2. GSSAPI Routines ๐
This section lists what each GSSAPI routine does and talks about its major parameters, including how they get passed to the routines ๐. The routines are listed in figure 4-1 โจ.
Figure 4-1 GSSAPI Routines
Routine Function
gss_acquire_cred Assume a global identity
gss_release_cred Discard credentials
gss_init_sec_context Initiate a security context
with a peer application
gss_accept_sec_context Accept a security context
initiated by a peer
application
gss_process_context_token Process a token on a security
context from a peer
application
gss_delete_sec_context Discard a security context
gss_context_time Determine for how long a
context will remain valid
gss_sign Sign a message; integrity
service
gss_verify Check signature on a message
gss_seal Sign (optionally encrypt) a
message; confidentiality
service
gss_unseal Verify (optionally decrypt)
message
gss_display_status Convert an API status code
to text
gss_indicate_mechs Determine underlying
authentication mechanism
gss_compare_name Compare two internal-form
names
gss_display_name Convert opaque name to text
gss_import_name Convert a textual name to
internal-form
gss_release_name Discard an internal-form
name
gss_release_buffer Discard a buffer
gss_release_oid_set Discard a set of object
identifiers
gss_inquire_cred Determine information about
a credential
Individual GSSAPI implementations can add to these routines with extra mechanism-specific routines, but only if the functionality they need isn't available from the generic forms ๐งฐ. Apps are encouraged to use the generic routines wherever they can, for portability reasons ๐ธ.
2.1. Data Types and Calling Conventions ๐
Here are the conventions the GSSAPI uses ๐:
2.1.1. Structured data types ๐งฑ
Wherever these GSSAPI C-bindings describe structured data, only the fields that every GSSAPI implementation must provide get documented ๐. Individual implementations can also provide additional fields, either for internal use inside GSSAPI routines or for use by non-portable apps ๐ง.
2.1.2. Integer types ๐ข
The GSSAPI defines this integer data type:
OM_uint32: 32-bit unsigned integer
When a guaranteed minimum bit-count matters, the GSSAPI routine definitions use this portable data type ๐ฏ. Individual GSSAPI implementations include appropriate typedef definitions that map this type onto a built-in data type ๐ฆ.
2.1.3. String and similar data ๐งต
Lots of GSSAPI routines take arguments and return values that describe contiguous multiple-byte data ๐ฆ. All of that data gets passed between the GSSAPI and the caller using the gss_buffer_t data type ๐.
This data type is a pointer to a buffer descriptor. The descriptor has a length field, which holds the total number of bytes in the datum, and a value field, which holds a pointer to the actual datum ๐:
typedef struct gss_buffer_desc_struct {
size_t length;
void *value;
} gss_buffer_desc, *gss_buffer_t;
storage alert ๐จ When a GSSAPI routine hands data to the app using thegss_buffer_tconventions, the GSSAPI routine is the one that allocates the storage. The app can free that storage by invoking thegss_release_bufferroutine ๐งน. Allocating thegss_buffer_descobject is always the app's responsibility ๐ . Unusedgss_buffer_descobjects may be initialized to the valueGSS_C_EMPTY_BUFFERโจ.
2.1.3.1. Opaque data types ๐
Some multiple-word data items count as opaque data types at the GSSAPI, because their internal structure doesn't matter to either the GSSAPI or the caller ๐ซฅ. Two examples: the input_token parameter to gss_init_sec_context (which is opaque to the caller), and the input_message parameter to gss_seal (which is opaque to the GSSAPI) ๐. Opaque data gets passed between the GSSAPI and the app using the gss_buffer_t datatype ๐.
2.1.3.2. Character strings ๐ค
Some multiple-word data items can be treated as simple ISO Latin-1 character strings ๐. The input_name_buffer parameter to gss_import_name is one example. A few GSSAPI routines also return character strings ๐ซ. Character strings get passed between the app and the GSSAPI using the gss_buffer_t datatype, which we defined earlier ๐ฆ.
2.1.4. Object Identifiers โจ
2.1.4. Object Identifiers ๐ฆ
okay so some GSSAPI procedures take a gss_OID (Object Identifier) parameter ๐ It's a type holding ISO-defined, tree-structured values, and the caller uses it to pick which underlying security mechanism to use ๐ณ Here's what the struct looks like:
typedef struct gss_OID_desc_struct {
OM_uint32 length;
void *elements;
} gss_OID_desc, *gss_OID;
The elements field points to the first byte of an octet string holding the ASN.1 BER encoding of the OID's value, and length tells you how many bytes that value takes up ๐ง For example, the gss_OID for {iso(1) identified- oganization(3) icd-ecma(12) member-company(2) dec(1011) cryptoAlgorithms(7) SPX(5)}, which is SPX (Digital's X.509 authentication mechanism), has a length of 7, and its elements points at seven octets with the octal values 53, 14, 2, 207, 163, 7, 5. Iconic, right? ๐ญ
GSSAPI implementations should give you constant gss_OID values so you can ask for any supported mechanism ๐ That said, applications are encouraged to accept the default mechanism for portability reasons, so it's giving "keep it simple, bestie" ๐
gss_OID values should also be provided so applications can name particular name types (see section 2.1.10) ๐ Also, treat any gss_OID_desc values the GSSAPI hands back as read-only. Don't try to deallocate them, no cap ๐
โโ๏ธ
The gss_OID_desc datatype is equivalent to the X/Open OM_object_identifier datatype [2] ๐
2.1.5. Object Identifier Sets ๐
Some GSSAPI procedures take a gss_OID_set parameter. This is one or more object identifiers (section 2.1.4) bundled together ๐ซถ Here's the struct:
typedef struct gss_OID_set_desc_struct {
int count;
gss_OID elements;
} gss_OID_set_desc, *gss_OID_set;
count is how many OIDs are in the set, and elements is a pointer to an array of gss_OID_desc objects, one for each OID ๐ง gss_OID_set values are used to list the mechanisms the GSSAPI supports, to request specific mechanisms, and to show which mechanisms a given credential supports ๐ฅ Any storage behind a gss_OID_set the GSSAPI returns to you can be freed with the gss_release_oid_set routine โจ
2.1.6. Credentials ๐
A credential handle is a caller-opaque atomic datum that points at a GSSAPI credential data structure ๐ฆ It's typed as the caller-opaque gss_cred_id_t, which can be an arithmetic or a pointer type. Credentials describe a principal and let whoever holds them act as that principal ๐ But the GSSAPI never hands the actual credentials to applications! Instead, you get a handle that identifies a credential held internally by the GSSAPI or the underlying mechanism ๐ Which means the handle has no security-relevant information in it and doesn't need special protection from your app, literally so chill ๐ซง
Depending on the implementation, the same handle can refer to different credentials when different callers present it to the GSSAPI ๐ธ Each GSSAPI implementation should define both the scope of a credential handle and the scope of the credential itself, and the credential's scope has to be at least as wide as the handle's. Possible handle scopes include the process that acquired the handle, the acquiring process and its children, or all processes sharing some local identification information (for example, a UID) ๐ง If no handles exist that can reach a given credential, the GSSAPI may delete that credential ๐
Some routines let you leave out the credential handle parameter to mean "use the default credential" ๐ How a default credential gets established and what its scope is should be defined by the individual GSSAPI implementation โจ
2.1.7. Contexts ๐ท
The gss_ctx_id_t data type is a caller-opaque atomic value that identifies one end of a GSSAPI security context ๐ It can be an arithmetic or a pointer type. Depending on the implementation, the same gss_ctx_id_t value may refer to different GSSAPI security contexts when different callers present it ๐ A security context holds the state for each end of a peer communication, including the cryptographic state ๐ Each GSSAPI implementation should define the scope of a context. There's no way to get a new gss_ctx_id_t value for an existing context, so the context's scope should be the same as the scope of a gss_ctx_id_t ๐
2.1.8. Authentication tokens ๐ซ
A token is a caller-opaque type the GSSAPI uses to keep the context data structures at each end of a GSSAPI security context in sync ๐ซถ It's a cryptographically protected bit-string, generated by the underlying mechanism at one end for the peer mechanism at the other end to use ๐ฆ Encapsulating the token (if needed) and getting it from one place to the other is the job of the peer applications ๐ Tokens move between the GSSAPI and the application using the gss_buffer_t conventions ๐
2.1.9. Status values ๐ฆ
Every GSSAPI routine returns one or more status codes. There are two distinct sorts: GSS status codes and Mechanism status codes ๐
2.1.9.1. GSS status codes ๐
GSSAPI routines return GSS status codes as their OM_uint32 function value ๐ฅ These codes flag errors that don't depend on the underlying mechanism providing the security service. The errors you can get this way are either generic API routine errors (defined in the GSSAPI specification) or calling errors (specific to these bindings) ๐ง
A GSS status code can report one fatal generic API error from the routine and one calling error ๐ซ On top of that, supplementary status information can be flagged by setting bits in the supplementary info field of a GSS status code โจ
Here's how these errors get packed into the 32-bit GSS status code:
MSB LSB
|------------------------------------------------------------|
| Calling Error | Routine Error | Supplementary Info |
|------------------------------------------------------------|
Bit 31 24 23 16 15 0
So, if a GSSAPI routine returns a GSS status code with a non-zero value in its upper 16 bits, the call failed ๐ If the calling error field is non-zero, the application's call to the routine was erroneous, and calling errors are listed in Table 5-1 below ๐ If the routine error field is non-zero, the routine failed for one of the routine-specific reasons in Table 5-2 ๐ธ Whether the upper 16 bits signal failure or success, the routine can also add extra info by setting bits in the supplementary info field, and what each bit means is in Table 5-3 ๐ง
Table 5-1 Calling Errors
Name Value in Meaning
Field
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 5-2 Routine Errors
Name Value in Meaning
Field
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_SIG 6 A token had an invalid
signature
GSS_S_NO_CRED 7 No credentials were supplied
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)
Table 5-3 Supplementary Status Bits
Name Bit Number Meaning
GSS_S_CONTINUE_NEEDED 0 (LSB) 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
The routine docs also use GSS_S_COMPLETE, which is a zero value meaning there are no API errors and no supplementary info bits set ๐
All GSS_S_xxx symbols are full OM_uint32 status codes, not bitfield values ๐ง For example, GSS_S_BAD_NAMETYPE (value 3 in the routine error field) is actually 3 << 16 ๐คฏ
There are macros to make your life easier: GSS_CALLING_ERROR(), GSS_ROUTINE_ERROR() and GSS_SUPPLEMENTARY_INFO(). Each one takes a GSS status code and strips out everything except the field it's named for ๐ For example, applying GSS_ROUTINE_ERROR to a status code removes the calling errors and supplementary info, leaving only the routine errors field ๐ The values these macros return can be compared directly with a GSS_S_xxx symbol of the matching type ๐ซถ There's also GSS_ERROR(), which returns a non-zero value if the status code flagged a calling or routine error, and zero otherwise ๐
A GSSAPI implementation may signal calling errors in a platform-specific way, either instead of or in addition to the routine value ๐ฅ๏ธ But routine errors and supplementary info should only be returned through routine status values ๐งก
2.1.9.2. Mechanism-specific status codes
okay so minor_status is the gossip column of GSSAPI routines ๐ซข it's where the underlying security mechanism whispers the specific error it ran into. it can hold a single mechanism-specific error, stored as an OM_uint32 value. main character energy ๐
the minor_status parameter is always set by a GSSAPI routine, even when the routine returns a calling error or one of the generic API errors listed above as fatal ๐ the other output parameters might stay unset in those cases though. bestie, that's the tea โ
output parameters that are supposed to hand back pointers to storage allocated by a routine must always set set by the routine, even when something went wrong ๐ซถ in an error case the routine can choose to set that returned pointer to NULL to say "no storage was actually allocated." any length field tied to those pointers (like the one in a gss_buffer_desc structure) should also be set to zero in those cases ๐ง
now the big one: GSS_S_FAILURE is the catch-all for when the mechanism hit an error that doesn't have its own GSS status code ๐ญ it's the "something broke and we don't have a name for it" code. the mechanism status code is where you'll find the juicy details ๐
2.1.10. Names
a name is how we identify a person or entity ๐ธ GSSAPI checks that the name and the entity claiming it actually belong together. no fake names allowed ๐ โโ๏ธ
there are two representations for names:
- (a) A printable form, for presentation to a user
- (b) An internal form, for presentation at the API
the printable syntax is defined by the GSSAPI implementation, and it can depend on local system configuration or individual user preference ๐ the internal form is the canonical version of the name, and it doesn't change with configuration. so consistent, so iconic โจ
one GSSAPI implementation can support names from multiple namespaces ๐ when that happens, the internal form has to include fields that say which namespace the name came from. the namespace of a printable name is specified by an accompanying object identifier ๐ฆ
the routines gss_import_name and gss_display_name convert names between their printable forms and the gss_name_t type ๐ gss_import_name can support several syntaxes for each supported namespace, so users get to pick the name format they like best. gss_display_name should use an implementation-chosen preferred syntax for each supported name-type ๐
to compare internal-form names, use the gss_compare_names routine ๐ this means the application doesn't have to understand the syntax of every printable name the implementation might support. honestly so freeing ๐ฎโ๐จ
storage gets allocated by any routine that returns a gss_name_t value ๐งบ to free the storage tied to a name, call gss_release_name ๐ซง
2.1.11. Channel Bindings
GSSAPI lets you use user-specified tags to identify a particular context to the peer application ๐ฆ those tags point at the exact communications channel carrying the context. the channel bindings get passed to GSSAPI using this 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 tell you what kind of addresses are inside 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 DARPA Internet address type
GSS_C_AF_IMPLINK ARPAnet IMP address type (eg IP)
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 (eg X.25)
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 X25
GSS_C_AF_NULLADDR No address specified
these are name address families, not specific addressing formats ๐ธ when a family has several alternative address forms, the initiator_address and acceptor_address fields must contain enough info to work out which form is being used. unless something says otherwise, addresses should be in network byte-order ๐ง
โ ๏ธ ngl this part is spicy: the GSSAPI basically mashes togetherinitiator_addrtype,initiator_address,acceptor_addrtype,acceptor_addressandapplication_datainto one octet string ๐ซฃ the mechanism signs that string and binds the signature to the context establishment token thatgss_init_sec_contextspits out. the acceptor passes in the same bindings togss_accept_sec_contextand calculates a signature the same way. if the signatures don't match,gss_accept_sec_contextreturnsGSS_S_BAD_BINDINGSand the context is NOT established ๐
some mechanisms might include the actual channel binding data in the token instead of just a signature ๐ so applications should not use confidential data as channel-binding components. and individual mechanisms can add their own rules about the addresses and address types that show up in channel bindings. for example, a mechanism might check that the initiator_address in the bindings given to gss_init_sec_context has the correct network address of the host system ๐
2.1.12. Optional parameters
some parameters are described as optional ๐ that means they follow a convention where you can ask for a default value. the conventions below are used for omitted parameters, and they only apply to parameters that are explicitly documented as optional ๐
2.1.12.1. gss_buffer_t types
specify GSS_C_NO_BUFFER as the value. for an input parameter, this means you want default behavior โจ for an output parameter, it means the application doesn't need the info that would've been returned through that parameter ๐ซถ
2.1.12.2. Integer types (input)
each parameter's documentation lists the values that mean "use the default action" ๐
2.1.12.3. Integer types (output)
specify NULL as the value for the pointer ๐
2.1.12.4. Pointer types
specify NULL as the value ๐ธ
2.1.12.5. Object IDs
specify GSS_C_NULL_OID as the value ๐ฆ
2.1.12.6. Object ID Sets
specify GSS_C_NULL_OID_SET as the value ๐งบ
2.1.12.7. Credentials
specify GSS_C_NO_CREDENTIAL to use the default credential handle ๐
2.1.12.8. Channel Bindings
specify GSS_C_NO_CHANNEL_BINDINGS to say that channel bindings are not to be used ๐
3. GSSAPI routine descriptions
2.1. gss_acquire_cred
OM_uint32 gss_acquire_cred (
OM_uint32 * minor_status,
gss_name_t desired_name,
OM_uint32 time_req,
gss_OID_set desired_mechs,
int cred_usage,
gss_cred_id_t * output_cred_handle,
gss_OID_set * actual_mechs,
OM_int32 * time_rec)
Purpose:
this routine lets an application grab a handle to a credential that already exists, by name ๐ GSSAPI implementations must put a local access-control policy on callers, so unauthorized callers can't get credentials they aren't entitled to ๐ซ this routine is NOT meant to be a "login to the network" function, since that would create brand-new credentials instead of just acquiring a handle to existing ones ๐ โโ๏ธ if you need a function like that, define it in implementation-specific extensions to the API โจ
if acquiring a credential is time-consuming for a mechanism, the mechanism may choose to delay the actual acquisition until the credential is needed (for example, by gss_init_sec_context or gss_accept_sec_context) ๐ข those mechanism-specific decisions should be invisible to the calling application. so a call to gss_inquire_cred right after gss_acquire_cred must return valid credential data, even if that means paying the overhead of a deferred acquisition ๐
Parameters:
desired_name gss_name_t, read
Name of principal whose credential
should be acquired
time_req integer, read
number of seconds that credentials
should remain valid
desired_mechs Set of Object IDs, read
set of underlying security mechanisms that
may be used. GSS_C_NULL_OID_SET may be used
to obtain an implementation-specific default.
cred_usage integer, read
GSS_C_BOTH - Credentials may be used
either to initiate or accept
security contexts.
GSS_C_INITIATE - Credentials will only be
used to initiate security
contexts.
GSS_C_ACCEPT - Credentials will only be used to
accept security contexts.
output_cred_handle gss_cred_id_t, modify
The returned credential handle.
actual_mechs Set of Object IDs, modify, optional
The set of mechanisms for which the
credential is valid. Specify NULL
if not required.
time_rec Integer, modify, optional
Actual number of seconds for which the
returned credentials will remain valid. If the
implementation does not support expiration of
credentials, the value GSS_C_INDEFINITE will
be returned. Specify NULL if not required
minor_status Integer, modify
Mechanism specific status code.
Function value:
GSS status code:
GSS_S_COMPLETE Successful completion
GSS_S_BAD_MECH Unavailable mechanism requested
GSS_S_BAD_NAMETYPE Type contained within desired_name parameter is
not supported
GSS_S_BAD_NAME Value supplied for desired_name parameter is
ill-formed.
GSS_S_FAILURE Unspecified failure. The minor_status parameter
contains more detailed information
3.2. gss_release_cred โจ
OM_uint32 gss_release_cred (
OM_uint32 * minor_status,
gss_cred_id_t * cred_handle)
Purpose:
Okay so this one is basically GSSAPI going "bestie, you can let go of this credential now" ๐ The process tells it that the credential handle isn't needed anymore. Once every process has released a credential, it gets deleted ๐ฅ
Parameters:
cred_handle(gss_cred_id_t, modify, optional): a buffer holding the opaque credential handle. IfGSS_C_NO_CREDENTIALis supplied, the default credential gets released ๐minor_status(integer, modify): a mechanism-specific status code ๐
Function value:
GSS status code:
GSS_S_COMPLETE: successful completion โGSS_S_NO_CRED: credentials could not be accessed. ๐ญ
3.3. gss_init_sec_context ๐ฆ
OM_uint32 gss_init_sec_context (
OM_uint32 * minor_status,
gss_cred_id_t claimant_cred_handle,
gss_ctx_id_t * context_handle,
gss_name_t target_name,
gss_OID mech_type,
int req_flags,
int time_req,
gss_channel_bindings_t
input_chan_bindings,
gss_buffer_t input_token
gss_OID * actual_mech_type,
gss_buffer_t output_token,
int * ret_flags,
OM_uint32 * time_rec )
Purpose:
This is the glow-up moment where the application and a remote peer start building a security context together โจ On the very first call, input_token should be set to GSS_C_NO_BUFFER, bestie.
The routine might hand back an output_token, which gets sent over to the peer application. The peer then passes it to gss_accept_sec_context ๐ซถ If nothing needs to be sent, gss_init_sec_context says so by setting the length field of output_token to zero.
To finish setting up the context, the peer might need to send back one or more reply tokens. If that happens, gss_init_sec_context returns GSS_S_CONTINUE_NEEDED, and you should call it again once the reply token shows up, passing that token in through input_token ๐
The values returned throughret_flagsandtime_recaren't defined unless the routine returnsGSS_S_COMPLETE. So don't go reading them early, periodt ๐
Parameters:
claimant_cred_handle(gss_cred_id_t, read, optional): handle for the credentials being claimed. SupplyGSS_C_NO_CREDENTIALto use the default credentials ๐งcontext_handle(gss_ctx_id_t, read/modify): the context handle for the new context. SupplyGSS_C_NO_CONTEXTon the first call, then use the value returned by that first call in continuation calls ๐ธtarget_name(gss_name_t, read): the name of the target ๐ฏmech_type(OID, read, optional): the Object ID of the desired mechanism. SupplyGSS_C_NULL_OIDto get an implementation-specific default ๐req_flags(bit-mask, read): this has four independent flags, each one requesting a specific service option. Each flag has a symbolic name, and you logically-OR the names of the flags you want together to build the bit-mask value ๐ The flags are:GSS_C_DELEG_FLAG- True: delegate credentials to the remote peer
- False: don't delegate
GSS_C_MUTUAL_FLAG- True: request that the remote peer authenticates itself
- False: authenticate yourself to the remote peer only
GSS_C_REPLAY_FLAG- True: enable replay detection for signed or sealed messages
- False: don't try to detect replayed messages
GSS_C_SEQUENCE_FLAG- True: enable detection of out-of-sequence signed or sealed messages
- False: don't try to detect out-of-sequence messages
time_req(integer, read): the desired number of seconds the context should stay valid. Supply 0 to ask for a default validity period โณinput_chan_bindings(channel bindings, read): application-specified bindings. These let the application securely bind channel identification information to the security context ๐input_token(buffer, opaque, read, optional (see text)): the token received from the peer application. SupplyGSS_C_NO_BUFFERon the initial call ๐ฉactual_mech_type(OID, modify): the actual mechanism that got used ๐ ๏ธoutput_token(buffer, opaque, modify): the token to be sent to the peer application. If the length field of the returned buffer is zero, no token needs to be sent to the peer application ๐คret_flags(bit-mask, modify): this has six independent flags, and each one tells you that the context supports a specific service option. Each flag has a symbolic name, and you logically-AND the names of the flags with theret_flagsvalue to check whether an option is supported by the context ๐ The flags are:GSS_C_DELEG_FLAG- True: credentials were delegated to the remote peer
- False: no credentials were delegated
GSS_C_MUTUAL_FLAG- True: the remote peer has been asked to authenticate itself
- False: the remote peer has not been asked to authenticate itself
GSS_C_REPLAY_FLAG- True: replay of signed or sealed messages will be detected
- False: replayed messages will not be detected
GSS_C_SEQUENCE_FLAG- True: out-of-sequence signed or sealed messages will be detected
- False: out-of-sequence messages will not be detected
GSS_C_CONF_FLAG- True: the confidentiality service may be invoked by calling the seal routine ๐
- False: no confidentiality service (via seal) is available. seal will only provide message encapsulation, data-origin authentication and integrity services
GSS_C_INTEG_FLAG- True: the integrity service may be invoked by calling either gss_sign or gss_seal routines โ
- False: per-message integrity service is unavailable
time_rec(integer, modify, optional): the number of seconds the context will remain valid. If the implementation doesn't support credential expiration,GSS_C_INDEFINITEgets returned. SpecifyNULLif you don't need it โminor_status(integer, modify): a mechanism-specific status code ๐
Function value:
GSS status code:
GSS_S_COMPLETE: successful completion ๐GSS_S_CONTINUE_NEEDED: a token from the peer application is needed to complete the context, andgss_init_sec_contextmust be called again with that token ๐GSS_S_DEFECTIVE_TOKEN: consistency checks performed on theinput_tokenfailed ๐GSS_S_DEFECTIVE_CREDENTIAL: consistency checks performed on the credential failed ๐GSS_S_NO_CRED: the supplied credentials were not valid for context initiation, or the credential handle didn't reference any credentials ๐ซGSS_S_CREDENTIALS_EXPIRED: the referenced credentials have expired โฐGSS_S_BAD_BINDINGS: theinput_tokencontains different channel bindings than the ones specified through theinput_chan_bindingsparameter ๐งฉGSS_S_BAD_SIG: theinput_tokencontains an invalid signature, or a signature that couldn't be verified ๐ฉGSS_S_OLD_TOKEN: theinput_tokenwas too old. This is a fatal error during context establishment ๐GSS_S_DUPLICATE_TOKEN: theinput_tokenis valid, but it's a duplicate of a token that was already processed. This is a fatal error during context establishment ๐ฏGSS_S_NO_CONTEXT: the supplied context handle didn't refer to a valid context ๐ซฅGSS_S_BAD_NAMETYPE: the providedtarget_nameparameter contained an invalid or unsupported type of name ๐ท๏ธGSS_S_BAD_NAME: the providedtarget_nameparameter was ill-formed ๐ฅดGSS_S_FAILURE: failure. Seeminor_statusfor more information ๐ต
3.4. gss_accept_sec_context โจ
okay bestie, this is the routine the accepting side calls ๐ it's how a context gets set up when a remote app starts the conversation with you. the signature, exactly as it is in the spec:
OM_uint32 gss_accept_sec_context (
OM_uint32 * minor_status,
gss_ctx_id_t * context_handle,
gss_cred_id_t verifier_cred_handle,
gss_buffer_t input_token_buffer
gss_channel_bindings_t
input_chan_bindings,
gss_name_t * src_name,
gss_OID * mech_type,
gss_buffer_t output_token,
int * ret_flags,
OM_uint32 * time_rec,
gss_cred_id_t * delegated_cred_handle)
Purpose:
so this one lets a remotely started security context get established between your app and a remote peer ๐ฆ it might hand back an output_token that you send to the peer app, and the peer will then give it to gss_init_sec_context. if no token needs to go back, it tells you that by setting the length field of output_token to zero ๐
sometimes the context needs one or more reply tokens from the peer first. when that happens you get the status flag GSS_S_CONTINUE_NEEDED, and you call it again once the reply token shows up, passing that token in through the input_token parameters. (the input_token_buffer argument is the one in the signature, fyi ๐)
the values that come back through src_name, ret_flags, time_rec, and delegated_cred_handle are only defined if the routine returns GSS_S_COMPLETE. so don't go reading them early, bestie ๐ซ
Parameters:
context_handle(gss_ctx_id_t, read/modify): the context handle for the new context โจ passGSS_C_NO_CONTEXTon the first call, then use the value returned by the previous calls.verifier_cred_handle(gss_cred_id_t, read, optional): the credential handle claimed by the context acceptor ๐ you can specifyGSS_C_NO_CREDENTIALto use default credentials. if you do that but the caller has no default credentials established, an implementation-defined default credential may be used.input_token_buffer(buffer, opaque, read): the token you got from the remote application ๐input_chan_bindings(channel bindings, read): application-specified bindings ๐ this lets the app securely tie channel identification info to the security context.src_name(gss_name_t, modify, optional): the authenticated name of the context initiator ๐ง after you're done with it, deallocate it by passing it togss_release_name. if you don't need it, specify NULL.mech_type(Object ID, modify): the security mechanism that got used ๐ the returned OID value is a pointer into static storage, so the caller should treat it as read-only. hands off, bestie.output_token(buffer, opaque, modify): the token to pass to the peer application ๐ธ if the length field of the returned token buffer is 0, then no token needs to be passed to the peer app.ret_flags(bit-mask, modify): this one is giving main character energy โจ it has six independent flags, and each one says the context supports a specific service option. each flag has its own symbolic name, and you logically-AND the symbolic names for the required flags withret_flagsto check whether an option is supported. the flags are:GSS_C_DELEG_FLAG- True: delegated credentials are available via the
delegated_cred_handleparameter ๐ - False: no credentials were delegated
- True: delegated credentials are available via the
GSS_C_MUTUAL_FLAG- True: the remote peer asked for mutual authentication ๐ซถ
- False: the remote peer did not ask for mutual authentication
GSS_C_REPLAY_FLAG- True: replay of signed or sealed messages will be detected ๐ฅ
- False: replayed messages will not be detected
GSS_C_SEQUENCE_FLAG- True: out-of-sequence signed or sealed messages will be detected ๐
- False: out-of-sequence messages will not be detected
GSS_C_CONF_FLAG- True: the confidentiality service may be invoked by calling the seal routine ๐
- False: no confidentiality service (via seal) is available. seal will only provide message encapsulation, data-origin authentication and integrity services โญ
GSS_C_INTEG_FLAG- True: the integrity service may be invoked by calling either
gss_signorgss_sealroutines ๐ - False: per-message integrity service is unavailable
- True: the integrity service may be invoked by calling either
time_rec(integer, modify, optional): the number of seconds for which the context will remain valid โณ specify NULL if you don't need it.delegated_cred_handle(gss_cred_id_t, modify): the credential handle for credentials received from the context initiator ๐ only valid if deleg_flag inret_flagsis true.minor_status(integer, modify): the mechanism-specific status code ๐งช
Function value:
GSS status code:
GSS_S_COMPLETE: successful completion ๐GSS_S_CONTINUE_NEEDED: a token from the peer application is required to complete the context, andgss_accept_sec_contextmust be called again with that token ๐GSS_S_DEFECTIVE_TOKEN: the consistency checks performed on theinput_tokenfailed ๐GSS_S_DEFECTIVE_CREDENTIAL: the consistency checks performed on the credential failed ๐GSS_S_NO_CRED: the supplied credentials were not valid for context acceptance, or the credential handle didn't reference any credentials ๐GSS_S_CREDENTIALS_EXPIRED: the referenced credentials have expired โGSS_S_BAD_BINDINGS: theinput_tokencontains different channel bindings than the ones specified via theinput_chan_bindingsparameter ๐ฉGSS_S_NO_CONTEXT: the supplied context handle did not refer to a valid context ๐ปGSS_S_BAD_SIG: theinput_tokencontains an invalid signature ๐จGSS_S_OLD_TOKEN: theinput_tokenwas too old. this is a fatal error during context establishment ๐GSS_S_DUPLICATE_TOKEN: theinput_tokenis valid, but it's a duplicate of a token that was already processed. this is also a fatal error during context establishment ๐ญGSS_S_FAILURE: failure. seeminor_statusfor more information ๐ฅฒ
3.5. gss_process_context_token ๐
okay so this is the routine for passing a token to the security service ๐ง usually tokens belong to either context establishment (where they'd go to gss_init_sec_context or gss_accept_sec_context) or per-message security (where they'd go to gss_verify or gss_unseal). every now and then, though, a token shows up at some other time, and gss_process_context_token is how you hand those to the underlying security service. right now, these extra tokens can only be generated by gss_delete_sec_context โจ a GSSAPI implementation may use this service to implement deleting the security context. so cute, right? ๐
the signature:
OM_uint32 gss_process_context_token (
OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
gss_buffer_t token_buffer)
Parameters:
context_handle(gss_ctx_id_t, read): the context handle of the context the token is to be processed on ๐ฆtoken_buffer(buffer, opaque, read): a pointer to the first byte of the token to process ๐minor_status(integer, modify): the implementation-specific status code ๐งช
Function value:
GSS status code:
GSS_S_COMPLETE: successful completion ๐GSS_S_DEFECTIVE_TOKEN: the consistency checks performed on the token failed ๐GSS_S_FAILURE: failure. seeminor_statusfor more information ๐ฅฒGSS_S_NO_CONTEXT: thecontext_handledid not refer to a valid context ๐ป
3.6. gss_delete_sec_context ๐ฆ
and the closing-up routine ๐ธ gss_delete_sec_context deletes the local data structures for a given security context, and it generates an output_token. when you pass that token to the peer's gss_process_context_token, it tells the peer to do the same thing ๐
after this, no further security services can be obtained using the context specified by context_handle. bye bye, context ๐
the signature:
OM_uint32 gss_delete_sec_context (
OM_uint32 * minor_status,
gss_ctx_id_t * context_handle,
gss_buffer_t output_token)
Parameters:
minor_status(integer, modify): the mechanism-specific status code ๐งชcontext_handle(gss_ctx_id_t, modify): the context handle identifying the context to delete ๐๏ธoutput_token(buffer, opaque, modify): the token to send to the remote application, telling it to also delete the context ๐ซถ
Function value:
GSS status code:
GSS_S_COMPLETE: successful completion ๐GSS_S_FAILURE: failure. seeminor_statusfor more information ๐ฅฒGSS_S_NO_CONTEXT: no valid context was supplied ๐ป
3.7. gss_context_time โณ
OM_uint32 gss_context_time (
OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
OM_uint32 * time_rec)
Purpose: okay so this one is the countdown timer ๐ It tells you how many seconds the context is still good for. If the context has already expired, you get zero back. Bestie, that's so clean.
Parameters:
minor_status(integer, modify): an implementation specific status code.context_handle(gss_ctx_id_t, read): the context you want to check up on.time_rec(integer, modify): the number of seconds the context will remain valid. If the context has already expired, zero is returned.
Function value: the GSS status code comes back as one of these:
GSS_S_COMPLETE: successful completion ๐GSS_S_CONTEXT_EXPIRED: the context has already expired ๐GSS_S_CREDENTIALS_EXPIRED: the context is recognized, but its associated credentials have expired ๐ฅฒGSS_S_NO_CONTEXT: thecontext_handleparameter didn't identify a valid context ๐
3.8. gss_sign ๐๏ธ
OM_uint32 gss_sign (
OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
int qop_req,
gss_buffer_t message_buffer,
gss_buffer_t msg_token)
Purpose: this one makes a cryptographic signature for your message and tucks it into a token so your bestie's app can check it. The qop_req parameter lets you pick between several cryptographic algorithms, as long as the mechanism you picked supports them. Iconic choice energy โจ
Parameters:
minor_status(integer, modify): an implementation specific status code.context_handle(gss_ctx_id_t, read): identifies the context the message will be sent on.qop_req(integer, read, optional): the requested quality of protection. Callers are encouraged, for portability reasons, to accept the default quality of protection the chosen mechanism offers, which you can ask for withGSS_C_QOP_DEFAULT. If you request a protection strength that isn't supported,gss_signreturns amajor_statusofGSS_S_FAILURE๐message_buffer(buffer, opaque, read): the message to be signed.msg_token(buffer, opaque, modify): the buffer that receives the token.
Function value: the GSS status code is one of these:
GSS_S_COMPLETE: successful completion โGSS_S_CONTEXT_EXPIRED: the context has already expired ๐GSS_S_CREDENTIALS_EXPIRED: the context is recognized, but its associated credentials have expired ๐ฅฒGSS_S_NO_CONTEXT: thecontext_handleparameter didn't identify a valid context ๐GSS_S_FAILURE: failure. Checkminor_statusfor more info ๐ญ
3.9. gss_verify ๐
OM_uint32 gss_verify (
OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
gss_buffer_t message_buffer,
gss_buffer_t token_buffer,
int * qop_state)
Purpose: this is the detective ๐ต๏ธโโ๏ธ It checks that the cryptographic signature in the token parameter actually fits the message you were given. The qop_state parameter tells the recipient how strong the protection on that message was.
Parameters:
minor_status(integer, modify): a mechanism specific status code.context_handle(gss_ctx_id_t, read): identifies the context the message arrived on.message_buffer(buffer, opaque, read): the message to be verified.token_buffer(buffer, opaque, read): the token associated with the message.qop_state(integer, modify): the quality of protection gained from the signature.
Function value: the GSS status code is one of these:
GSS_S_COMPLETE: successful completion โจGSS_S_DEFECTIVE_TOKEN: the token failed its consistency checks ๐ซGSS_S_BAD_SIG: the signature was incorrect ๐ซGSS_S_DUPLICATE_TOKEN: the token was valid and had a correct signature for the message, but it had already been processed. Dรฉjร vu, but make it a security issue ๐GSS_S_OLD_TOKEN: the token was valid and had a correct signature for the message, but it's too old ๐ฐ๏ธGSS_S_UNSEQ_TOKEN: the token was valid and had a correct signature for the message, but it was verified out of sequence. An earlier token was signed or sealed by the remote application but hasn't been processed locally yet ๐งฉGSS_S_CONTEXT_EXPIRED: the context has already expired ๐GSS_S_CREDENTIALS_EXPIRED: the context is recognized, but its associated credentials have expired ๐ฅฒGSS_S_NO_CONTEXT: thecontext_handleparameter didn't identify a valid context ๐GSS_S_FAILURE: failure. Checkminor_statusfor more info ๐ญ
3.10. gss_seal ๐
OM_uint32 gss_seal (
OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
int conf_req_flag,
int qop_req
gss_buffer_t input_message_buffer,
int * conf_state,
gss_buffer_t output_message_buffer)
Purpose: this one signs your message and, if you ask, encrypts it too ๐ซถ The output_message holds both the signature and the message. Like gss_sign, the qop_req parameter lets you pick between several cryptographic algorithms if the mechanism supports them.
Parameters:
minor_status(integer, modify): a mechanism specific status code.context_handle(gss_ctx_id_t, read): identifies the context the message will be sent on.conf_req_flag(boolean, read):- True: both confidentiality and integrity services are requested ๐
- False: only the integrity service is requested
qop_req(integer, read, optional): the required quality of protection. Settingqop_reqtoGSS_C_QOP_DEFAULTasks for the mechanism's own default. If you request a protection strength that isn't supported,gss_sealreturns amajor_statusofGSS_S_FAILURE๐input_message_buffer(buffer, opaque, read): the message to be sealed.conf_state(boolean, modify):- True: confidentiality, data origin authentication and integrity services have been applied ๐
- False: only the integrity and data origin services have been applied
output_message_buffer(buffer, opaque, modify): the buffer that receives the sealed message.
Function value: the GSS status code is one of these:
GSS_S_COMPLETE: successful completion โGSS_S_CONTEXT_EXPIRED: the context has already expired ๐GSS_S_CREDENTIALS_EXPIRED: the context is recognized, but its associated credentials have expired ๐ฅฒGSS_S_NO_CONTEXT: thecontext_handleparameter didn't identify a valid context ๐GSS_S_FAILURE: failure. Checkminor_statusfor more info ๐ญ
3.11. gss_unseal ๐
OM_uint32 gss_unseal (
OM_uint32 * minor_status,
gss_ctx_id_t context_handle,
gss_buffer_t input_message_buffer,
gss_buffer_t output_message_buffer,
int * conf_state,
int * qop_state)
Purpose: the reverse of gss_seal ๐ช It turns a previously sealed message back into something usable, and checks the signature baked into it along the way. The conf_state parameter tells you whether the message was encrypted, and the qop_state parameter tells you how strong the protection was for the confidentiality and integrity services.
Parameters:
minor_status(integer, modify): a mechanism specific status code.context_handle(gss_ctx_id_t, read): identifies the context the message arrived on.input_message_buffer(buffer, opaque, read): the sealed message.output_message_buffer(buffer, opaque, modify): the buffer that receives the unsealed message.conf_state(boolean, modify):- True: confidentiality and integrity protection were used ๐
- False:
Inteegrity service only was used(yes, that's how the original spells it, typo and all ๐)
qop_state(integer, modify): the quality of protection gained from the signature.
Function value: the GSS status code is one of these:
GSS_S_COMPLETE: successful completion โจGSS_S_DEFECTIVE_TOKEN: the token failed its consistency checks ๐ซGSS_S_BAD_SIG: the signature was incorrect ๐ซGSS_S_DUPLICATE_TOKEN: the token was valid and had a correct signature for the message, but it had already been processed ๐GSS_S_OLD_TOKEN: the token was valid and had a correct signature for the message, but it's too old ๐ฐ๏ธGSS_S_UNSEQ_TOKEN: the token was valid and had a correct signature for the message, but it was verified out of sequence. An earlier token was signed or sealed by the remote application but hasn't been processed locally yet ๐งฉGSS_S_CONTEXT_EXPIRED: the context has already expired ๐GSS_S_CREDENTIALS_EXPIRED: the context is recognized, but its associated credentials have expired ๐ฅฒGSS_S_NO_CONTEXT: thecontext_handleparameter didn't identify a valid context ๐GSS_S_FAILURE: failure. Checkminor_statusfor more info ๐ญ
3.12. gss_display_status ๐
OM_uint32 gss_display_status (
OM_uint32 * minor_status,
int status_value,
int status_type,
gss_OID mech_type,
int * message_context,
gss_buffer_t status_string)
Purpose: okay so this one lets an app turn a GSSAPI status code into readable text ๐ so it can show the user or drop it in a log. Some status values can hide more than one error ๐, so you might have to call gss_display_status a bunch of times, and each call gives you one text string. message_context is how you keep track of which error message you're on. Set it to 0 at the start, and gss_display_status will hand back a non-zero value if there are more messages still waiting to be pulled out ๐.
Parameters:
minor_status: integer, modify. Mechanism specific status code.status_value: integer, read. The status value to be converted.status_type: integer, read.GSS_C_GSS_CODEmeansstatus_valueis a GSS status code.GSS_C_MECH_CODEmeansstatus_valueis a mechanism status code.mech_type: Object ID, read, optional. The underlying mechanism, which is used to interpret a minor status value. SupplyGSS_C_NULL_OIDto get the system default ๐ง.message_context: integer, read/modify. The caller should set this to zero on the first call. If more messages are instatus_value,message_contextcomes back non-zero, and you pass that value into the next calls, along with the samestatus_value,status_typeandmech_type๐.status_string: buffer, character string, modify. The textual interpretation ofstatus_value๐.
Function value (GSS status code):
GSS_S_COMPLETE: successful completion โจ.GSS_S_BAD_MECH: you asked for a translation under a mechanism type that isn't supported ๐ โโ๏ธ.GSS_S_BAD_STATUS: the status value wasn't recognised, or the status type was neitherGSS_C_GSS_CODEnorGSS_C_MECH_CODE๐.
3.13. gss_indicate_mechs ๐ฆ
OM_uint32 gss_indicate_mechs (
OM_uint32 * minor_status,
gss_OID_set * mech_set)
Purpose: this lets an app find out which underlying security mechanisms are available on its end ๐. It's the "what do I have to work with" check, bestie.
Parameters:
minor_status: integer, modify. Mechanism specific status code.mech_set: set of Object IDs, modify. The set of mechanisms the implementation supports. The returnedgss_OID_setvalue is a pointer into static storage, so treat it as read-only, no touching ๐.
Function value (GSS status code):
GSS_S_COMPLETE: successful completion ๐.
3.14. gss_compare_name ๐ฏ
OM_uint32 gss_compare_name (
OM_uint32 * minor_status,
gss_name_t name1,
gss_name_t name2,
int * name_equal)
Purpose: lets an app compare two internal-form names and figure out if they point at the same entity ๐ซถ.
Parameters:
minor_status: integer, modify. Mechanism specific status code.name1: gss_name_t, read. An internal-form name.name2: gss_name_t, read. An internal-form name.name_equal: boolean, modify. True means the names refer to the same entity. False means the names refer to different entities. Strictly speaking, that means the names aren't known to refer to the same identity, so it's not a 100% "they're different people" answer ๐ค.
Function value (GSS status code):
GSS_S_COMPLETE: successful completion โจ.GSS_S_BAD_NAMETYPE: the type inname1orname2wasn't recognised, or the names were of types that can't be compared ๐ซ.GSS_S_BAD_NAME: one or both ofname1orname2was ill-formed ๐ญ.
3.15. gss_display_name ๐ท๏ธ
OM_uint32 gss_display_name (
OM_uint32 * minor_status,
gss_name_t input_name,
gss_buffer_t output_name_buffer,
gss_OID * output_name_type)
Purpose: this turns an opaque internal-form name into text you can actually display ๐. The syntax of a printable name is up to the GSSAPI implementation to define, so it's not one universal format ๐ธ.
Parameters:
minor_status: integer, modify. Mechanism specific status code.input_name: gss_name_t, read. The name to be displayed.output_name_buffer: buffer, character-string, modify. The buffer that receives the textual name string.output_name_type: Object ID, modify. The type of the returned name. The returnedgss_OIDis a pointer into static storage, so treat it as read-only by the caller ๐.
Function value (GSS status code):
GSS_S_COMPLETE: successful completion ๐ .GSS_S_BAD_NAMETYPE: the type ofinput_namewasn't recognised ๐.GSS_S_BAD_NAME:input_namewas ill-formed ๐.
3.16. gss_import_name ๐ฅ
OM_uint32 gss_import_name (
OM_uint32 * minor_status,
gss_buffer_t input_name_buffer,
gss_OID input_name_type,
gss_name_t * output_name)
Purpose: this converts a printable name into internal form ๐. Basically the "make this name app-ready" move.
Parameters:
minor_status: integer, modify. Mechanism specific status code.input_name_buffer: buffer, character-string, read. The buffer holding the printable name to convert.input_name_type: Object ID, read, optional. This is the Object ID that specifies what type of printable name you've got. You can passGSS_C_NULL_OIDto use a local, system-specific printable syntax. Or you can use an OID that the GSSAPI implementation registered to name a particular namespace ๐ชช.output_name: gss_name_t, modify. The returned name, now in internal form โจ.
Function value (GSS status code):
GSS_S_COMPLETE: successful completion ๐.GSS_S_BAD_NAMETYPE: theinput_name_typewasn't recognised ๐ฌ.GSS_S_BAD_NAME: theinput_nameparameter couldn't be read as a name of the specified type ๐.
3.17. gss_release_name ๐๏ธ
OM_uint32 gss_release_name (
OM_uint32 * minor_status,
gss_name_t * name)
Purpose: frees the GSSAPI-allocated storage tied to an internal form name ๐งน. Clean up after yourself, periodt.
Parameters:
minor_status: integer, modify. Mechanism specific status code.name: gss_name_t, modify. The name to be deleted.
Function value (GSS status code):
GSS_S_COMPLETE: successful completion ๐.GSS_S_BAD_NAME: thenameparameter didn't contain a valid name ๐ต.
3.18. gss_release_buffer ๐งบ
OM_uint32 gss_release_buffer (
OM_uint32 * minor_status,
gss_buffer_t buffer)
Purpose: frees the storage linked to a buffer. The storage has to have been allocated by a GSSAPI routine ๐ฆ. Along with freeing it, this routine zeroes the length field in the buffer parameter 0๏ธโฃ.
Parameters:
minor_status: integer, modify. Mechanism specific status code.buffer: buffer, modify. The storage tied to the buffer gets deleted. Thegss_buffer_descobject itself won't be freed, but its length field will be zeroed ๐ซง.
Function value (GSS status code):
GSS_S_COMPLETE: successful completion ๐.
3.19. gss_release_oid_set ๐งพ
OM_uint32 gss_release_oid_set (
OM_uint32 * minor_status,
gss_OID_set * set)
Purpose: frees the storage tied to a gss_OID_set object. That storage has to have been allocated by a GSSAPI routine ๐ท.
Parameters:
minor_status: integer, modify. Mechanism specific status code.set: set of Object IDs, modify. The storage tied to thegss_OID_setgets deleted.
Function value (GSS status code):
GSS_S_COMPLETE: successful completion ๐.
3.20. gss_inquire_cred ๐ชช
OM_uint32 gss_inquire_cred (
OM_uint32 * minor_status,
gss_cred_id_t cred_handle,
gss_name_t * name,
OM_uint32 * lifetime,
int * cred_usage,
gss_OID_set * mechanisms )
Purpose: this gets you info about a credential ๐. You need to already have a handle that refers to the credential first, so this is a follow-up move, not a starting one.
Parameters:
minor_status: integer, modify. Mechanism specific status code.cred_handle: gss_cred_id_t, read. A handle that refers to the target credential. SpecifyGSS_C_NO_CREDENTIALto ask about the default credential ๐ฏ.name: gss_name_t, modify. The name whose identity the credential asserts. Specify NULL if you don't need it.lifetime: integer, modify. The number of seconds the credential will stay valid. If the credential has expired, this gets set to zero โณ. If the implementation doesn't support credential expiration, the valueGSS_C_INDEFINITEis returned. Specify NULL if you don't need it.cred_usage: integer, modify. How the credential may be used. It's one of the following:GSS_C_INITIATE,GSS_C_ACCEPT, orGSS_C_BOTH. Specify NULL if you don't need it ๐ญ.mechanisms: gss_OID_set, modify. The set of mechanisms the credential supports. Specify NULL if you don't need it ๐งฉ.
Function value (GSS status code):
GSS_S_COMPLETE: successful completion ๐.GSS_S_NO_CRED: the referenced credentials couldn't be accessed ๐ช.GSS_S_DEFECTIVE_CREDENTIAL: the referenced credentials were invalid ๐.
GSS_S_CREDENTIALS_EXPIRED means the referenced credentials have expired ๐. If the lifetime parameter wasn't passed as NULL, it gets set to 0 โฐ. Okay, now the big C header, which is basically the GSSAPI's official outfit ๐โจ
#ifndef GSSAPI_H_
#define GSSAPI_H_
/*
* First, define the platform-dependent types.
*/
typedef <platform-specific> OM_uint32;
typedef <platform-specific> gss_ctx_id_t;
typedef <platform-specific> gss_cred_id_t;
typedef <platform-specific> gss_name_t;
/*
* Note that a platform supporting the xom.h X/Open header file
* may make use of that header for the definitions of OM_uint32
* and the structure to which gss_OID_desc equates.
*/
typedef struct gss_OID_desc_struct {
OM_uint32 length;
void *elements;
} gss_OID_desc, *gss_OID;
typedef struct gss_OID_set_desc_struct {
int count;
gss_OID elements;
} gss_OID_set_desc, *gss_OID_set;
typedef struct gss_buffer_desc_struct {
size_t length;
void *value;
} gss_buffer_desc, *gss_buffer_t;
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;
/*
* Six independent flags each of which indicates that a context
* supports a specific service option.
*/
#define GSS_C_DELEG_FLAG 1
#define GSS_C_MUTUAL_FLAG 2
#define GSS_C_REPLAY_FLAG 4
#define GSS_C_SEQUENCE_FLAG 8
#define GSS_C_CONF_FLAG 16
#define GSS_C_INTEG_FLAG 32
/*
* Credential usage options
*/
#define GSS_C_BOTH 0
#define GSS_C_INITIATE 1
#define GSS_C_ACCEPT 2
/*
* Status code types for gss_display_status
*/
#define GSS_C_GSS_CODE 1
#define GSS_C_MECH_CODE 2
/*
* The constant definitions for channel-bindings address families
*/
#define GSS_C_AF_UNSPEC 0;
#define GSS_C_AF_LOCAL 1;
#define GSS_C_AF_INET 2;
#define GSS_C_AF_IMPLINK 3;
#define GSS_C_AF_PUP 4;
#define GSS_C_AF_CHAOS 5;
#define GSS_C_AF_NS 6;
#define GSS_C_AF_NBS 7;
#define GSS_C_AF_ECMA 8;
#define GSS_C_AF_DATAKIT 9;
#define GSS_C_AF_CCITT 10;
#define GSS_C_AF_SNA 11;
#define GSS_C_AF_DECnet 12;
#define GSS_C_AF_DLI 13;
#define GSS_C_AF_LAT 14;
#define GSS_C_AF_HYLINK 15;
#define GSS_C_AF_APPLETALK 16;
#define GSS_C_AF_BSC 17;
#define GSS_C_AF_DSS 18;
#define GSS_C_AF_OSI 19;
#define GSS_C_AF_X25 21;
#define GSS_C_AF_NULLADDR 255;
#define GSS_C_NO_BUFFER ((gss_buffer_t) 0)
#define GSS_C_NULL_OID ((gss_OID) 0)
#define GSS_C_NULL_OID_SET ((gss_OID_set) 0)
#define GSS_C_NO_CONTEXT ((gss_ctx_id_t) 0)
#define GSS_C_NO_CREDENTIAL ((gss_cred_id_t) 0)
#define GSS_C_NO_CHANNEL_BINDINGS ((gss_channel_bindings_t) 0)
#define GSS_C_EMPTY_BUFFER {0, NULL}
/*
* Define the default Quality of Protection for per-message
* services. Note that an implementation that offers multiple
* levels of QOP may either reserve a value (for example zero,
* as assumed here) to mean "default protection", or alternatively
* may simply equate GSS_C_QOP_DEFAULT to a specific explicit QOP
* value.
*/
#define GSS_C_QOP_DEFAULT 0
/*
* Expiration time of 2^32-1 seconds means infinite lifetime for a
* credential or security context
*/
#define GSS_C_INDEFINITE 0xfffffffful
/* Major status codes */
#define GSS_S_COMPLETE 0
/*
* Some "helper" definitions to make the status code macros obvious.
*/
#define GSS_C_CALLING_ERROR_OFFSET 24
#define GSS_C_ROUTINE_ERROR_OFFSET 16
#define GSS_C_SUPPLEMENTARY_OFFSET 0
#define GSS_C_CALLING_ERROR_MASK 0377ul
#define GSS_C_ROUTINE_ERROR_MASK 0377ul
#define GSS_C_SUPPLEMENTARY_MASK 0177777ul
/*
* The macros that test status codes for error conditions
*/
#define GSS_CALLING_ERROR(x) \
(x & (GSS_C_CALLING_ERROR_MASK << GSS_C_CALLING_ERROR_OFFSET))
#define GSS_ROUTINE_ERROR(x) \
(x & (GSS_C_ROUTINE_ERROR_MASK << GSS_C_ROUTINE_ERROR_OFFSET))
#define GSS_SUPPLEMENTARY_INFO(x) \
(x & (GSS_C_SUPPLEMENTARY_MASK << GSS_C_SUPPLEMENTARY_OFFSET))
#define GSS_ERROR(x) \
((GSS_CALLING_ERROR(x) != 0) || (GSS_ROUTINE_ERROR(x) != 0))
/*
* Now the actual status code definitions
*/
/*
* Calling errors:
*/
#define GSS_S_CALL_INACCESSIBLE_READ \
(1ul << GSS_C_CALLING_ERROR_OFFSET)
#define GSS_S_CALL_INACCESSIBLE_WRITE \
(2ul << GSS_C_CALLING_ERROR_OFFSET)
#define GSS_S_CALL_BAD_STRUCTURE \
(3ul << GSS_C_CALLING_ERROR_OFFSET)
/*
* Routine errors:
*/
#define GSS_S_BAD_MECH (1ul << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_BAD_NAME (2ul << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_BAD_NAMETYPE (3ul << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_BAD_BINDINGS (4ul << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_BAD_STATUS (5ul << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_BAD_SIG (6ul << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_NO_CRED (7ul << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_NO_CONTEXT (8ul << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_DEFECTIVE_TOKEN (9ul << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_DEFECTIVE_CREDENTIAL (10ul << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_CREDENTIALS_EXPIRED (11ul << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_CONTEXT_EXPIRED (12ul << GSS_C_ROUTINE_ERROR_OFFSET)
#define GSS_S_FAILURE (13ul << GSS_C_ROUTINE_ERROR_OFFSET)
/*
* Supplementary info bits:
*/
#define GSS_S_CONTINUE_NEEDED (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 0))
#define GSS_S_DUPLICATE_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 1))
#define GSS_S_OLD_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 2))
#define GSS_S_UNSEQ_TOKEN (1ul << (GSS_C_SUPPLEMENTARY_OFFSET + 3))
/*
* Finally, function prototypes for the GSSAPI routines.
*/
OM_uint32 gss_acquire_cred
(OM_uint32*, /* minor_status */
gss_name_t, /* desired_name */
OM_uint32, /* time_req */
gss_OID_set, /* desired_mechs */
int, /* cred_usage */
gss_cred_id_t*, /* output_cred_handle */
gss_OID_set*, /* actual_mechs */
OM_uint32* /* time_rec */
);
OM_uint32 gss_release_cred,
(OM_uint32*, /* minor_status */
gss_cred_id_t* /* cred_handle */
);
OM_uint32 gss_init_sec_context
(OM_uint32*, /* minor_status */
gss_cred_id_t, /* claimant_cred_handle */
gss_ctx_id_t*, /* context_handle */
gss_name_t, /* target_name */
gss_OID, /* mech_type */
int, /* req_flags */
OM_uint32, /* time_req */
gss_channel_bindings_t,
/* input_chan_bindings */
gss_buffer_t, /* input_token */
gss_OID*, /* actual_mech_type */
gss_buffer_t, /* output_token */
int*, /* ret_flags */
OM_uint32* /* time_rec */
);
OM_uint32 gss_accept_sec_context
(OM_uint32*, /* minor_status */
gss_ctx_id_t*, /* context_handle */
gss_cred_id_t, /* verifier_cred_handle */
gss_buffer_t, /* input_token_buffer */
gss_channel_bindings_t,
/* input_chan_bindings */
gss_name_t*, /* src_name */
gss_OID*, /* mech_type */
gss_buffer_t, /* output_token */
int*, /* ret_flags */
OM_uint32*, /* time_rec */
gss_cred_id_t* /* delegated_cred_handle */
);
OM_uint32 gss_process_context_token
(OM_uint32*, /* minor_status */
gss_ctx_id_t, /* context_handle */
gss_buffer_t /* token_buffer */
);
OM_uint32 gss_delete_sec_context
(OM_uint32*, /* minor_status */
gss_ctx_id_t*, /* context_handle */
gss_buffer_t /* output_token */
);
OM_uint32 gss_context_time
(OM_uint32*, /* minor_status */
gss_ctx_id_t, /* context_handle */
OM_uint32* /* time_rec */
);
OM_uint32 gss_sign
(OM_uint32*, /* minor_status */
gss_ctx_id_t, /* context_handle */
int, /* qop_req */
gss_buffer_t, /* message_buffer */
gss_buffer_t /* message_token */
);
OM_uitn32 gss_verify
(OM_uint32*, /* minor_status */
gss_ctx_id_t, /* context_handle */
gss_buffer_t, /* message_buffer */
gss_buffer_t, /* token_buffer */
int* /* qop_state */
);
OM_uint32 gss_seal
(OM_uint32*, /* minor_status */
gss_ctx_id_t, /* context_handle */
int, /* conf_req_flag */
int, /* qop_req */
gss_buffer_t, /* input_message_buffer */
int*, /* conf_state */
gss_buffer_t /* output_message_buffer */
);
OM_uint32 gss_unseal
(OM_uint32*, /* minor_status */
gss_ctx_id_t, /* context_handle */
gss_buffer_t, /* input_message_buffer */
gss_buffer_t, /* output_message_buffer */
int*, /* conf_state */
int* /* qop_state */
);
OM_uint32 gss_display_status
(OM_uint32*, /* minor_status */
OM_uint32, /* status_value */
int, /* status_type */
gss_OID, /* mech_type */
int*, /* message_context */
gss_buffer_t /* status_string */
);
OM_uint32 gss_indicate_mechs
(OM_uint32*, /* minor_status */
gss_OID_set* /* mech_set */
);
OM_uint32 gss_compare_name
(OM_uint32*, /* minor_status */
gss_name_t, /* name1 */
gss_name_t, /* name2 */
int* /* name_equal */
);
OM_uint32 gss_display_name,
(OM_uint32*, /* minor_status */
gss_name_t, /* input_name */
gss_buffer_t, /* output_name_buffer */
gss_OID* /* output_name_type */
);
OM_uint32 gss_import_name
(OM_uint32*, /* minor_status */
gss_buffer_t, /* input_name_buffer */
gss_OID, /* input_name_type */
gss_name_t* /* output_name */
);
OM_uint32 gss_release_name
(OM_uint32*, /* minor_status */
gss_name_t* /* input_name */
);
OM_uint32 gss_release_buffer
(OM_uint32*, /* minor_status */
gss_buffer_t /* buffer */
);
OM_uint32 gss_release_oid_set
(OM_uint32*, /* minor_status */
gss_OID_set* /* set */
);
Here's the end of the gss_inquire_cred signature, plus the closing header guard ๐
OM_uint32 gss_inquire_cred
(OM_uint32 *, /* minor_status */
gss_cred_id_t, /* cred_handle */
gss_name_t *, /* name */
OM_uint32 *, /* lifetime */
int *, /* cred_usage */
gss_OID_set * /* mechanisms */
);
#endif /* GSSAPI_H_ */
References โจ
[1] Linn, J., "Generic Security Service Application Program Interface", RFC 1508, Geer Zolot Associate, September 1993. ๐
[2] "OSI Object Management API Specification, Version 2.0 t", X.400 API Association & X/Open Company Limited, August 24, 1990. Specification of datatypes and routines for manipulating information objects. ๐ง
Security Considerations ๐
Security issues are discussed throughout this memo. Bestie, this is the part you cannot skip ๐ญ The whole thing is about keeping things safe, so go back and read the rest with that in mind ๐
Author's Address ๐ฆ
John Wray
Digital Equipment Corporation
550 King Street, LKG2-2/AA6
Littleton, MA 01460
USA
Phone: +1-508-486-5210
EMail: Wray@tuxedo.enet.dec.com
๐ฆ where this page comes from
- ietf: rfc1509 1993-09
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms