4 The GSSAPI (Generic Security Services API) allows applications to
5 communicate securely using Kerberos 5 or other security mechanisms.
6 We recommend using the GSSAPI (or a higher-level framework which
7 encompasses GSSAPI, such as SASL) for secure network communication
8 over using the libkrb5 API directly.
10 GSSAPIv2 is specified in :rfc:`2743` and :rfc:`2744`. Also see
11 :rfc:`7546` for a description of how to use the GSSAPI in a client or
14 This documentation will describe how various ways of using the
15 GSSAPI will behave with the krb5 mechanism as implemented in MIT krb5,
16 as well as krb5-specific extensions to the GSSAPI.
22 A GSSAPI application can name a local or remote entity by calling
23 gss_import_name_, specifying a name type and a value. The following
24 name types are supported by the krb5 mechanism:
26 * **GSS_C_NT_HOSTBASED_SERVICE**: The value should be a string of the
27 form ``service`` or ``service@hostname``. This is the most common
28 way to name target services when initiating a security context, and
29 is the most likely name type to work across multiple mechanisms.
31 * **GSS_KRB5_NT_PRINCIPAL_NAME**: The value should be a principal name
32 string. This name type only works with the krb5 mechanism, and is
33 defined in the ``<gssapi/gssapi_krb5.h>`` header.
35 * **GSS_C_NT_USER_NAME** or **GSS_C_NULL_OID**: The value is treated
36 as an unparsed principal name string, as above. These name types
37 may work with mechanisms other than krb5, but will have different
38 interpretations in those mechanisms. **GSS_C_NT_USER_NAME** is
39 intended to be used with a local username, which will parse into a
40 single-component principal in the default realm.
42 * **GSS_C_NT_ANONYMOUS**: The value is ignored. The anonymous
43 principal is used, allowing a client to authenticate to a server
44 without asserting a particular identity (which may or may not be
45 allowed by a particular server or Kerberos realm).
47 * **GSS_C_NT_MACHINE_UID_NAME**: The value is uid_t object. On
48 Unix-like systems, the username of the uid is looked up in the
49 system user database and the resulting username is parsed as a
52 * **GSS_C_NT_STRING_UID_NAME**: As above, but the value is a decimal
53 string representation of the uid.
55 * **GSS_C_NT_EXPORT_NAME**: The value must be the result of a
56 gss_export_name_ call.
58 * **GSS_KRB5_NT_ENTERPRISE_NAME**: The value should be a krb5
59 enterprise name string (see :rfc:`6806` section 5), in the form
60 ``user@suffix``. This name type is used to convey alias names, and
61 is defined in the ``<gssapi/gssapi_krb5.h>`` header. (New in
64 * **GSS_KRB5_NT_X509_CERT**: The value should be an X.509 certificate
65 encoded according to :rfc:`5280`. This name form can be used for
66 the desired_name parameter of gss_acquire_cred_impersonate_name(),
67 to identify the S4U2Self user by certificate. (New in release
74 A GSSAPI client application uses gss_init_sec_context_ to establish a
75 security context. The *initiator_cred_handle* parameter determines
76 what tickets are used to establish the connection. An application can
77 either pass **GSS_C_NO_CREDENTIAL** to use the default client
78 credential, or it can use gss_acquire_cred_ beforehand to acquire an
79 initiator credential. The call to gss_acquire_cred_ may include a
80 *desired_name* parameter, or it may pass **GSS_C_NO_NAME** if it does
81 not have a specific name preference.
83 If the desired name for a krb5 initiator credential is a host-based
84 name, it is converted to a principal name of the form
85 ``service/hostname`` in the local realm, where *hostname* is the local
86 hostname if not specified. The hostname will be canonicalized using
87 forward name resolution, and possibly also using reverse name
88 resolution depending on the value of the **rdns** variable in
91 If a desired name is specified in the call to gss_acquire_cred_, the
92 krb5 mechanism will attempt to find existing tickets for that client
93 principal name in the default credential cache or collection. If the
94 default cache type does not support a collection, and the default
95 cache contains credentials for a different principal than the desired
96 name, a **GSS_S_CRED_UNAVAIL** error will be returned with a minor
97 code indicating a mismatch.
99 If no existing tickets are available for the desired name, but the
100 name has an entry in the default client :ref:`keytab_definition`, the
101 krb5 mechanism will acquire initial tickets for the name using the
102 default client keytab.
104 If no desired name is specified, credential acquisition will be
105 deferred until the credential is used in a call to
106 gss_init_sec_context_ or gss_inquire_cred_. If the call is to
107 gss_init_sec_context_, the target name will be used to choose a client
108 principal name using the credential cache selection facility. (This
109 facility might, for instance, try to choose existing tickets for a
110 client principal in the same realm as the target service). If there
111 are no existing tickets for the chosen principal, but it is present in
112 the default client keytab, the krb5 mechanism will acquire initial
113 tickets using the keytab.
115 If the target name cannot be used to select a client principal
116 (because the credentials are used in a call to gss_inquire_cred_), or
117 if the credential cache selection facility cannot choose a principal
118 for it, the default credential cache will be selected if it exists and
121 If the default credential cache does not exist, but the default client
122 keytab does, the krb5 mechanism will try to acquire initial tickets
123 for the first principal in the default client keytab.
125 If the krb5 mechanism acquires initial tickets using the default
126 client keytab, the resulting tickets will be stored in the default
127 cache or collection, and will be refreshed by future calls to
128 gss_acquire_cred_ as they approach their expire time.
134 A GSSAPI server application uses gss_accept_sec_context_ to establish
135 a security context based on tokens provided by the client. The
136 *acceptor_cred_handle* parameter determines what
137 :ref:`keytab_definition` entries may be authenticated to by the
138 client, if the krb5 mechanism is used.
140 The simplest choice is to pass **GSS_C_NO_CREDENTIAL** as the acceptor
141 credential. In this case, clients may authenticate to any service
142 principal in the default keytab (typically |keytab|, or the value of
143 the **KRB5_KTNAME** environment variable). This is the recommended
144 approach if the server application has no specific requirements to the
147 A server may acquire an acceptor credential with gss_acquire_cred_ and
148 a *cred_usage* of **GSS_C_ACCEPT** or **GSS_C_BOTH**. If the
149 *desired_name* parameter is **GSS_C_NO_NAME**, then clients will be
150 allowed to authenticate to any service principal in the default
151 keytab, just as if no acceptor credential was supplied.
153 If a server wishes to specify a *desired_name* to gss_acquire_cred_,
154 the most common choice is a host-based name. If the host-based
155 *desired_name* contains just a *service*, then clients will be allowed
156 to authenticate to any host-based service principal (that is, a
157 principal of the form ``service/hostname@REALM``) for the named
158 service, regardless of hostname or realm, as long as it is present in
159 the default keytab. If the input name contains both a *service* and a
160 *hostname*, clients will be allowed to authenticate to any host-based
161 principal for the named service and hostname, regardless of realm.
165 If a *hostname* is specified, it will be canonicalized
166 using forward name resolution, and possibly also using
167 reverse name resolution depending on the value of the
168 **rdns** variable in :ref:`libdefaults`.
172 If the **ignore_acceptor_hostname** variable in
173 :ref:`libdefaults` is enabled, then *hostname* will be
174 ignored even if one is specified in the input name.
178 In MIT krb5 versions prior to 1.10, and in Heimdal's
179 implementation of the krb5 mechanism, an input name with
180 just a *service* is treated like an input name of
181 ``service@localhostname``, where *localhostname* is the
182 string returned by gethostname().
184 If the *desired_name* is a krb5 principal name or a local system name
185 type which is mapped to a krb5 principal name, clients will only be
186 allowed to authenticate to that principal in the default keytab.
192 In release 1.8 or later, the gss_inquire_name_ and
193 gss_get_name_attribute_ functions, specified in :rfc:`6680`, can be
194 used to retrieve name attributes from the *src_name* returned by
195 gss_accept_sec_context_. The following attributes are defined when
196 the krb5 mechanism is used:
198 .. _gssapi_authind_attr:
200 * "auth-indicators" attribute:
202 This attribute will be included in the gss_inquire_name_ output if the
203 ticket contains :ref:`authentication indicators <auth_indicator>`.
204 One indicator is returned per invocation of gss_get_name_attribute_,
205 so multiple invocations may be necessary to retrieve all of the
206 indicators from the ticket. (New in release 1.15.)
209 Credential store extensions
210 ---------------------------
212 Beginning with release 1.11, the following GSSAPI extensions declared
213 in ``<gssapi/gssapi_ext.h>`` can be used to specify how credentials
214 are acquired or stored::
216 struct gss_key_value_element_struct {
220 typedef struct gss_key_value_element_struct gss_key_value_element_desc;
222 struct gss_key_value_set_struct {
224 gss_key_value_element_desc *elements;
226 typedef const struct gss_key_value_set_struct gss_key_value_set_desc;
227 typedef const gss_key_value_set_desc *gss_const_key_value_set_t;
229 OM_uint32 gss_acquire_cred_from(OM_uint32 *minor_status,
230 const gss_name_t desired_name,
232 const gss_OID_set desired_mechs,
233 gss_cred_usage_t cred_usage,
234 gss_const_key_value_set_t cred_store,
235 gss_cred_id_t *output_cred_handle,
236 gss_OID_set *actual_mechs,
237 OM_uint32 *time_rec);
239 OM_uint32 gss_store_cred_into(OM_uint32 *minor_status,
240 gss_cred_id_t input_cred_handle,
241 gss_cred_usage_t cred_usage,
242 const gss_OID desired_mech,
243 OM_uint32 overwrite_cred,
244 OM_uint32 default_cred,
245 gss_const_key_value_set_t cred_store,
246 gss_OID_set *elements_stored,
247 gss_cred_usage_t *cred_usage_stored);
249 The additional *cred_store* parameter allows the caller to specify
250 information about how the credentials should be obtained and stored.
251 The following options are supported by the krb5 mechanism:
253 * **ccache**: For acquiring initiator credentials, the name of the
254 :ref:`credential cache <ccache_definition>` to which the handle will
255 refer. For storing credentials, the name of the cache or collection
256 where the credentials will be stored (see below).
258 * **client_keytab**: For acquiring initiator credentials, the name of
259 the :ref:`keytab <keytab_definition>` which will be used, if
260 necessary, to refresh the credentials in the cache.
262 * **keytab**: For acquiring acceptor credentials, the name of the
263 :ref:`keytab <keytab_definition>` to which the handle will refer.
264 In release 1.19 and later, this option also determines the keytab to
265 be used for verification when initiator credentials are acquired
266 using a password and verified.
268 * **password**: For acquiring initiator credentials, this option
269 instructs the mechanism to acquire fresh credentials into a unique
270 memory credential cache. This option may not be used with the
271 **ccache** or **client_keytab** options, and a *desired_name* must
272 be specified. (New in release 1.19.)
274 * **rcache**: For acquiring acceptor credentials, the name of the
275 :ref:`replay cache <rcache_definition>` to be used when processing
276 the initiator tokens. (New in release 1.13.)
278 * **verify**: For acquiring initiator credentials, this option
279 instructs the mechanism to verify the credentials by obtaining a
280 ticket to a service with a known key. The service key is obtained
281 from the keytab specified with the **keytab** option or the default
282 keytab. The value may be the name of a principal in the keytab, or
283 the empty string. If the empty string is given, any ``host``
284 service principal in the keytab may be used. (New in release 1.19.)
286 In release 1.20 or later, if a collection name is specified for
287 **cache** in a call to gss_store_cred_into(), an existing cache for
288 the client principal within the collection will be selected, or a new
289 cache will be created within the collection. If *overwrite_cred* is
290 false and the selected credential cache already exists, a
291 **GSS_S_DUPLICATE_ELEMENT** error will be returned. If *default_cred*
292 is true, the primary cache of the collection will be switched to the
296 Importing and exporting credentials
297 -----------------------------------
299 The following GSSAPI extensions can be used to import and export
300 credentials (declared in ``<gssapi/gssapi_ext.h>``)::
302 OM_uint32 gss_export_cred(OM_uint32 *minor_status,
303 gss_cred_id_t cred_handle,
306 OM_uint32 gss_import_cred(OM_uint32 *minor_status,
308 gss_cred_id_t *cred_handle);
310 The first function serializes a GSSAPI credential handle into a
311 buffer; the second unseralizes a buffer into a GSSAPI credential
312 handle. Serializing a credential does not destroy it. If any of the
313 mechanisms used in *cred_handle* do not support serialization,
314 gss_export_cred will return **GSS_S_UNAVAILABLE**. As with other
315 GSSAPI serialization functions, these extensions are only intended to
316 work with a matching implementation on the other side; they do not
317 serialize credentials in a standardized format.
319 A serialized credential may contain secret information such as ticket
320 session keys. The serialization format does not protect this
321 information from eavesdropping or tampering. The calling application
322 must take care to protect the serialized credential when communicating
323 it over an insecure channel or to an untrusted party.
325 A krb5 GSSAPI credential may contain references to a credential cache,
326 a client keytab, an acceptor keytab, and a replay cache. These
327 resources are normally serialized as references to their external
328 locations (such as the filename of the credential cache). Because of
329 this, a serialized krb5 credential can only be imported by a process
330 with similar privileges to the exporter. A serialized credential
331 should not be trusted if it originates from a source with lower
332 privileges than the importer, as it may contain references to external
333 credential cache, keytab, or replay cache resources not accessible to
336 An exception to the above rule applies when a krb5 GSSAPI credential
337 refers to a memory credential cache, as is normally the case for
338 delegated credentials received by gss_accept_sec_context_. In this
339 case, the contents of the credential cache are serialized, so that the
340 resulting token may be imported even if the original memory credential
341 cache no longer exists.
344 Constrained delegation (S4U)
345 ----------------------------
347 The Microsoft S4U2Self and S4U2Proxy Kerberos protocol extensions
348 allow an intermediate service to acquire credentials from a client to
349 a target service without requiring the client to delegate a
350 ticket-granting ticket, if the KDC is configured to allow it.
352 To perform a constrained delegation operation, the intermediate
353 service must submit to the KDC an "evidence ticket" from the client to
354 the intermediate service. An evidence ticket can be acquired when the
355 client authenticates to the intermediate service with Kerberos, or
356 with an S4U2Self request if the KDC allows it. The MIT krb5 GSSAPI
357 library represents an evidence ticket using a "proxy credential",
358 which is a special kind of gss_cred_id_t object whose underlying
359 credential cache contains the evidence ticket and a krbtgt ticket for
360 the intermediate service.
362 To acquire a proxy credential during client authentication, the
363 service should first create an acceptor credential using the
364 **GSS_C_BOTH** usage. The application should then pass this
365 credential as the *acceptor_cred_handle* to gss_accept_sec_context_,
366 and also pass a *delegated_cred_handle* output parameter to receive a
367 proxy credential containing the evidence ticket. The output value of
368 *delegated_cred_handle* may be a delegated ticket-granting ticket if
369 the client sent one, or a proxy credential if not. If the library can
370 determine that the client's ticket is not a valid evidence ticket, it
371 will place **GSS_C_NO_CREDENTIAL** in *delegated_cred_handle*.
373 To acquire a proxy credential using an S4U2Self request, the service
374 can use the following GSSAPI extension::
376 OM_uint32 gss_acquire_cred_impersonate_name(OM_uint32 *minor_status,
378 gss_name_t desired_name,
380 gss_OID_set desired_mechs,
381 gss_cred_usage_t cred_usage,
382 gss_cred_id_t *output_cred,
383 gss_OID_set *actual_mechs,
384 OM_uint32 *time_rec);
386 The parameters to this function are similar to those of
387 gss_acquire_cred_, except that *icred* is used to make an S4U2Self
388 request to the KDC for a ticket from *desired_name* to the
389 intermediate service. Both *icred* and *desired_name* are required
390 for this function; passing **GSS_C_NO_CREDENTIAL** or
391 **GSS_C_NO_NAME** will cause the call to fail. *icred* must contain a
392 krbtgt ticket for the intermediate service. The result of this
393 operation is a proxy credential. (Prior to release 1.18, the result
394 of this operation may be a regular credential for *desired_name*, if
395 the KDC issues a non-forwardable ticket.)
397 Once the intermediate service has a proxy credential, it can simply
398 pass it to gss_init_sec_context_ as the *initiator_cred_handle*
399 parameter, and the desired service as the *target_name* parameter.
400 The GSSAPI library will present the krbtgt ticket and evidence ticket
401 in the proxy credential to the KDC in an S4U2Proxy request; if the
402 intermediate service has the appropriate permissions, the KDC will
403 issue a ticket from the client to the target service. The GSSAPI
404 library will then use this ticket to authenticate to the target
407 If an application needs to find out whether a credential it holds is a
408 proxy credential and the name of the intermediate service, it can
409 query the credential with the **GSS_KRB5_GET_CRED_IMPERSONATOR** OID
410 (new in release 1.16, declared in ``<gssapi/gssapi_krb5.h>``) using
411 the gss_inquire_cred_by_oid extension (declared in
412 ``<gssapi/gssapi_ext.h>``)::
414 OM_uint32 gss_inquire_cred_by_oid(OM_uint32 *minor_status,
415 const gss_cred_id_t cred_handle,
416 gss_OID desired_object,
417 gss_buffer_set_t *data_set);
419 If the call succeeds and *cred_handle* is a proxy credential,
420 *data_set* will be set to a single-element buffer set containing the
421 unparsed principal name of the intermediate service. If *cred_handle*
422 is not a proxy credential, *data_set* will be set to an empty buffer
423 set. If the library does not support the query,
424 gss_inquire_cred_by_oid will return **GSS_S_UNAVAILABLE**.
427 AEAD message wrapping
428 ---------------------
430 The following GSSAPI extensions (declared in
431 ``<gssapi/gssapi_ext.h>``) can be used to wrap and unwrap messages
432 with additional "associated data" which is integrity-checked but is
433 not included in the output buffer::
435 OM_uint32 gss_wrap_aead(OM_uint32 *minor_status,
436 gss_ctx_id_t context_handle,
437 int conf_req_flag, gss_qop_t qop_req,
438 gss_buffer_t input_assoc_buffer,
439 gss_buffer_t input_payload_buffer,
441 gss_buffer_t output_message_buffer);
443 OM_uint32 gss_unwrap_aead(OM_uint32 *minor_status,
444 gss_ctx_id_t context_handle,
445 gss_buffer_t input_message_buffer,
446 gss_buffer_t input_assoc_buffer,
447 gss_buffer_t output_payload_buffer,
449 gss_qop_t *qop_state);
451 Wrap tokens created with gss_wrap_aead will successfully unwrap only
452 if the same *input_assoc_buffer* contents are presented to
459 The following extensions (declared in ``<gssapi/gssapi_ext.h>``) can
460 be used for in-place encryption, fine-grained control over wrap token
461 layout, and for constructing wrap tokens compatible with Microsoft DCE
464 typedef struct gss_iov_buffer_desc_struct {
466 gss_buffer_desc buffer;
467 } gss_iov_buffer_desc, *gss_iov_buffer_t;
469 OM_uint32 gss_wrap_iov(OM_uint32 *minor_status,
470 gss_ctx_id_t context_handle,
471 int conf_req_flag, gss_qop_t qop_req,
473 gss_iov_buffer_desc *iov, int iov_count);
475 OM_uint32 gss_unwrap_iov(OM_uint32 *minor_status,
476 gss_ctx_id_t context_handle,
477 int *conf_state, gss_qop_t *qop_state,
478 gss_iov_buffer_desc *iov, int iov_count);
480 OM_uint32 gss_wrap_iov_length(OM_uint32 *minor_status,
481 gss_ctx_id_t context_handle,
483 gss_qop_t qop_req, int *conf_state,
484 gss_iov_buffer_desc *iov,
487 OM_uint32 gss_release_iov_buffer(OM_uint32 *minor_status,
488 gss_iov_buffer_desc *iov,
491 The caller of gss_wrap_iov provides an array of gss_iov_buffer_desc
492 structures, each containing a type and a gss_buffer_desc structure.
495 * **GSS_C_BUFFER_TYPE_DATA**: A data buffer to be included in the
496 token, and to be encrypted or decrypted in-place if the token is
497 confidentiality-protected.
499 * **GSS_C_BUFFER_TYPE_HEADER**: The GSSAPI wrap token header and
500 underlying cryptographic header.
502 * **GSS_C_BUFFER_TYPE_TRAILER**: The cryptographic trailer, if one is
505 * **GSS_C_BUFFER_TYPE_PADDING**: Padding to be combined with the data
506 during encryption and decryption. (The implementation may choose to
507 place padding in the trailer buffer, in which case it will set the
508 padding buffer length to 0.)
510 * **GSS_C_BUFFER_TYPE_STREAM**: For unwrapping only, a buffer
511 containing a complete wrap token in standard format to be unwrapped.
513 * **GSS_C_BUFFER_TYPE_SIGN_ONLY**: A buffer to be included in the
514 token's integrity protection checksum, but not to be encrypted or
515 included in the token itself.
517 For gss_wrap_iov, the IOV list should contain one HEADER buffer,
518 followed by zero or more SIGN_ONLY buffers, followed by one or more
519 DATA buffers, followed by a TRAILER buffer. The memory pointed to by
520 the buffers is not required to be contiguous or in any particular
521 order. If *conf_req_flag* is true, DATA buffers will be encrypted
522 in-place, while SIGN_ONLY buffers will not be modified.
524 The type of an output buffer may be combined with
525 **GSS_C_BUFFER_FLAG_ALLOCATE** to request that gss_wrap_iov allocate
526 the buffer contents. If gss_wrap_iov allocates a buffer, it sets the
527 **GSS_C_BUFFER_FLAG_ALLOCATED** flag on the buffer type.
528 gss_release_iov_buffer can be used to release all allocated buffers
529 within an iov list and unset their allocated flags. Here is an
530 example of how gss_wrap_iov can be used with allocation requested
531 (*ctx* is assumed to be a previously established gss_ctx_id_t)::
533 OM_uint32 major, minor;
534 gss_iov_buffer_desc iov[4];
535 char str[] = "message";
537 iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER | GSS_IOV_BUFFER_FLAG_ALLOCATE;
538 iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
539 iov[1].buffer.value = str;
540 iov[1].buffer.length = strlen(str);
541 iov[2].type = GSS_IOV_BUFFER_TYPE_PADDING | GSS_IOV_BUFFER_FLAG_ALLOCATE;
542 iov[3].type = GSS_IOV_BUFFER_TYPE_TRAILER | GSS_IOV_BUFFER_FLAG_ALLOCATE;
544 major = gss_wrap_iov(&minor, ctx, 1, GSS_C_QOP_DEFAULT, NULL,
546 if (GSS_ERROR(major))
547 handle_error(major, minor);
549 /* Transmit or otherwise use resulting buffers. */
551 (void)gss_release_iov_buffer(&minor, iov, 4);
553 If the caller does not choose to request buffer allocation by
554 gss_wrap_iov, it should first call gss_wrap_iov_length to query the
555 lengths of the HEADER, PADDING, and TRAILER buffers. DATA buffers
556 must be provided in the iov list so that padding length can be
557 computed correctly, but the output buffers need not be initialized.
558 Here is an example of using gss_wrap_iov_length and gss_wrap_iov::
560 OM_uint32 major, minor;
561 gss_iov_buffer_desc iov[4];
562 char str[1024] = "message", *ptr;
564 iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER;
565 iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
566 iov[1].buffer.value = str;
567 iov[1].buffer.length = strlen(str);
569 iov[2].type = GSS_IOV_BUFFER_TYPE_PADDING;
570 iov[3].type = GSS_IOV_BUFFER_TYPE_TRAILER;
572 major = gss_wrap_iov_length(&minor, ctx, 1, GSS_C_QOP_DEFAULT,
574 if (GSS_ERROR(major))
575 handle_error(major, minor);
576 if (strlen(str) + iov[0].buffer.length + iov[2].buffer.length +
577 iov[3].buffer.length > sizeof(str))
578 handle_out_of_space_error();
579 ptr = str + strlen(str);
580 iov[0].buffer.value = ptr;
581 ptr += iov[0].buffer.length;
582 iov[2].buffer.value = ptr;
583 ptr += iov[2].buffer.length;
584 iov[3].buffer.value = ptr;
586 major = gss_wrap_iov(&minor, ctx, 1, GSS_C_QOP_DEFAULT, NULL,
588 if (GSS_ERROR(major))
589 handle_error(major, minor);
591 If the context was established using the **GSS_C_DCE_STYLE** flag
592 (described in :rfc:`4757`), wrap tokens compatible with Microsoft DCE
593 RPC can be constructed. In this case, the IOV list must include a
594 SIGN_ONLY buffer, a DATA buffer, a second SIGN_ONLY buffer, and a
595 HEADER buffer in that order (the order of the buffer contents remains
596 arbitrary). The application must pad the DATA buffer to a multiple of
597 16 bytes as no padding or trailer buffer is used.
599 gss_unwrap_iov may be called with an IOV list just like one which
600 would be provided to gss_wrap_iov. DATA buffers will be decrypted
601 in-place if they were encrypted, and SIGN_ONLY buffers will not be
604 Alternatively, gss_unwrap_iov may be called with a single STREAM
605 buffer, zero or more SIGN_ONLY buffers, and a single DATA buffer. The
606 STREAM buffer is interpreted as a complete wrap token. The STREAM
607 buffer will be modified in-place to decrypt its contents. The DATA
608 buffer will be initialized to point to the decrypted data within the
609 STREAM buffer, unless it has the **GSS_C_BUFFER_FLAG_ALLOCATE** flag
610 set, in which case it will be initialized with a copy of the decrypted
611 data. Here is an example (*token* and *token_len* are assumed to be a
612 pre-existing pointer and length for a modifiable region of data)::
614 OM_uint32 major, minor;
615 gss_iov_buffer_desc iov[2];
617 iov[0].type = GSS_IOV_BUFFER_TYPE_STREAM;
618 iov[0].buffer.value = token;
619 iov[0].buffer.length = token_len;
620 iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
621 major = gss_unwrap_iov(&minor, ctx, NULL, NULL, iov, 2);
622 if (GSS_ERROR(major))
623 handle_error(major, minor);
625 /* Decrypted data is in iov[1].buffer, pointing to a subregion of
628 .. _gssapi_mic_token:
633 The following extensions (declared in ``<gssapi/gssapi_ext.h>``) can
634 be used in release 1.12 or later to construct and verify MIC tokens
637 OM_uint32 gss_get_mic_iov(OM_uint32 *minor_status,
638 gss_ctx_id_t context_handle,
640 gss_iov_buffer_desc *iov,
643 OM_uint32 gss_get_mic_iov_length(OM_uint32 *minor_status,
644 gss_ctx_id_t context_handle,
646 gss_iov_buffer_desc *iov,
649 OM_uint32 gss_verify_mic_iov(OM_uint32 *minor_status,
650 gss_ctx_id_t context_handle,
651 gss_qop_t *qop_state,
652 gss_iov_buffer_desc *iov,
655 The caller of gss_get_mic_iov provides an array of gss_iov_buffer_desc
656 structures, each containing a type and a gss_buffer_desc structure.
659 * **GSS_C_BUFFER_TYPE_DATA** and **GSS_C_BUFFER_TYPE_SIGN_ONLY**: The
660 corresponding buffer for each of these types will be signed for the
661 MIC token, in the order provided.
663 * **GSS_C_BUFFER_TYPE_MIC_TOKEN**: The GSSAPI MIC token.
665 The type of the MIC_TOKEN buffer may be combined with
666 **GSS_C_BUFFER_FLAG_ALLOCATE** to request that gss_get_mic_iov
667 allocate the buffer contents. If gss_get_mic_iov allocates the
668 buffer, it sets the **GSS_C_BUFFER_FLAG_ALLOCATED** flag on the buffer
669 type. gss_release_iov_buffer can be used to release all allocated
670 buffers within an iov list and unset their allocated flags. Here is
671 an example of how gss_get_mic_iov can be used with allocation
672 requested (*ctx* is assumed to be a previously established
675 OM_uint32 major, minor;
676 gss_iov_buffer_desc iov[3];
678 iov[0].type = GSS_IOV_BUFFER_TYPE_DATA;
679 iov[0].buffer.value = "sign1";
680 iov[0].buffer.length = 5;
681 iov[1].type = GSS_IOV_BUFFER_TYPE_SIGN_ONLY;
682 iov[1].buffer.value = "sign2";
683 iov[1].buffer.length = 5;
684 iov[2].type = GSS_IOV_BUFFER_TYPE_MIC_TOKEN | GSS_IOV_BUFFER_FLAG_ALLOCATE;
686 major = gss_get_mic_iov(&minor, ctx, GSS_C_QOP_DEFAULT, iov, 3);
687 if (GSS_ERROR(major))
688 handle_error(major, minor);
690 /* Transmit or otherwise use iov[2].buffer. */
692 (void)gss_release_iov_buffer(&minor, iov, 3);
694 If the caller does not choose to request buffer allocation by
695 gss_get_mic_iov, it should first call gss_get_mic_iov_length to query
696 the length of the MIC_TOKEN buffer. Here is an example of using
697 gss_get_mic_iov_length and gss_get_mic_iov::
699 OM_uint32 major, minor;
700 gss_iov_buffer_desc iov[2];
703 iov[0].type = GSS_IOV_BUFFER_TYPE_MIC_TOKEN;
704 iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
705 iov[1].buffer.value = "message";
706 iov[1].buffer.length = 7;
708 major = gss_get_mic_iov_length(&minor, ctx, GSS_C_QOP_DEFAULT, iov, 2);
709 if (GSS_ERROR(major))
710 handle_error(major, minor);
711 if (iov[0].buffer.length > sizeof(data))
712 handle_out_of_space_error();
713 iov[0].buffer.value = data;
715 major = gss_get_mic_iov(&minor, ctx, GSS_C_QOP_DEFAULT, iov, 2);
716 if (GSS_ERROR(major))
717 handle_error(major, minor);
720 .. _gss_accept_sec_context: https://tools.ietf.org/html/rfc2744.html#section-5.1
721 .. _gss_acquire_cred: https://tools.ietf.org/html/rfc2744.html#section-5.2
722 .. _gss_export_name: https://tools.ietf.org/html/rfc2744.html#section-5.13
723 .. _gss_get_name_attribute: https://tools.ietf.org/html/6680.html#section-7.5
724 .. _gss_import_name: https://tools.ietf.org/html/rfc2744.html#section-5.16
725 .. _gss_init_sec_context: https://tools.ietf.org/html/rfc2744.html#section-5.19
726 .. _gss_inquire_name: https://tools.ietf.org/html/rfc6680.txt#section-7.4
727 .. _gss_inquire_cred: https://tools.ietf.org/html/rfc2744.html#section-5.21