Imported Upstream version 1.20.1
[platform/upstream/krb5.git] / doc / html / _sources / appdev / gssapi.rst.txt
1 Developing with GSSAPI
2 ======================
3
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.
9
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
12 server program.
13
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.
17
18
19 Name types
20 ----------
21
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:
25
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.
30
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.
34
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.
41
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).
46
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
50   principal name.
51
52 * **GSS_C_NT_STRING_UID_NAME**: As above, but the value is a decimal
53   string representation of the uid.
54
55 * **GSS_C_NT_EXPORT_NAME**: The value must be the result of a
56   gss_export_name_ call.
57
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
62   release 1.17.)
63
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
68   1.19.)
69
70
71 Initiator credentials
72 ---------------------
73
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.
82
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
89 :ref:`libdefaults`.
90
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.
98
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.
103
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.
114
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
119 contains tickets.
120
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.
124
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.
129
130
131 Acceptor names
132 --------------
133
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.
139
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
145 contrary.
146
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.
152
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.
162
163 .. note::
164
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`.
169
170 .. note::
171
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.
175
176 .. note::
177
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().
183
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.
187
188
189 Name Attributes
190 ---------------
191
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:
197
198 .. _gssapi_authind_attr:
199
200 * "auth-indicators" attribute:
201
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.)
207
208
209 Credential store extensions
210 ---------------------------
211
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::
215
216     struct gss_key_value_element_struct {
217         const char *key;
218         const char *value;
219     };
220     typedef struct gss_key_value_element_struct gss_key_value_element_desc;
221
222     struct gss_key_value_set_struct {
223         OM_uint32 count;
224         gss_key_value_element_desc *elements;
225     };
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;
228
229     OM_uint32 gss_acquire_cred_from(OM_uint32 *minor_status,
230                                     const gss_name_t desired_name,
231                                     OM_uint32 time_req,
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);
238
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);
248
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:
252
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).
257
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.
261
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.
267
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.)
273
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.)
277
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.)
285
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
293 selected cache.
294
295
296 Importing and exporting credentials
297 -----------------------------------
298
299 The following GSSAPI extensions can be used to import and export
300 credentials (declared in ``<gssapi/gssapi_ext.h>``)::
301
302     OM_uint32 gss_export_cred(OM_uint32 *minor_status,
303                               gss_cred_id_t cred_handle,
304                               gss_buffer_t token);
305
306     OM_uint32 gss_import_cred(OM_uint32 *minor_status,
307                               gss_buffer_t token,
308                               gss_cred_id_t *cred_handle);
309
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.
318
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.
324
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
334 the originator.
335
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.
342
343
344 Constrained delegation (S4U)
345 ----------------------------
346
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.
351
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.
361
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*.
372
373 To acquire a proxy credential using an S4U2Self request, the service
374 can use the following GSSAPI extension::
375
376     OM_uint32 gss_acquire_cred_impersonate_name(OM_uint32 *minor_status,
377                                                 gss_cred_id_t icred,
378                                                 gss_name_t desired_name,
379                                                 OM_uint32 time_req,
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);
385
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.)
396
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
405 service.
406
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>``)::
413
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);
418
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**.
425
426
427 AEAD message wrapping
428 ---------------------
429
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::
434
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,
440                             int *conf_state,
441                             gss_buffer_t output_message_buffer);
442
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,
448                               int *conf_state,
449                               gss_qop_t *qop_state);
450
451 Wrap tokens created with gss_wrap_aead will successfully unwrap only
452 if the same *input_assoc_buffer* contents are presented to
453 gss_unwrap_aead.
454
455
456 IOV message wrapping
457 --------------------
458
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
462 RPC::
463
464     typedef struct gss_iov_buffer_desc_struct {
465         OM_uint32 type;
466         gss_buffer_desc buffer;
467     } gss_iov_buffer_desc, *gss_iov_buffer_t;
468
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,
472                            int *conf_state,
473                            gss_iov_buffer_desc *iov, int iov_count);
474
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);
479
480     OM_uint32 gss_wrap_iov_length(OM_uint32 *minor_status,
481                                   gss_ctx_id_t context_handle,
482                                   int conf_req_flag,
483                                   gss_qop_t qop_req, int *conf_state,
484                                   gss_iov_buffer_desc *iov,
485                                   int iov_count);
486
487     OM_uint32 gss_release_iov_buffer(OM_uint32 *minor_status,
488                                      gss_iov_buffer_desc *iov,
489                                      int iov_count);
490
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.
493 Valid types include:
494
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.
498
499 * **GSS_C_BUFFER_TYPE_HEADER**: The GSSAPI wrap token header and
500   underlying cryptographic header.
501
502 * **GSS_C_BUFFER_TYPE_TRAILER**: The cryptographic trailer, if one is
503   required.
504
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.)
509
510 * **GSS_C_BUFFER_TYPE_STREAM**: For unwrapping only, a buffer
511   containing a complete wrap token in standard format to be unwrapped.
512
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.
516
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.
523
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)::
532
533     OM_uint32 major, minor;
534     gss_iov_buffer_desc iov[4];
535     char str[] = "message";
536
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;
543
544     major = gss_wrap_iov(&minor, ctx, 1, GSS_C_QOP_DEFAULT, NULL,
545                          iov, 4);
546     if (GSS_ERROR(major))
547         handle_error(major, minor);
548
549     /* Transmit or otherwise use resulting buffers. */
550
551     (void)gss_release_iov_buffer(&minor, iov, 4);
552
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::
559
560     OM_uint32 major, minor;
561     gss_iov_buffer_desc iov[4];
562     char str[1024] = "message", *ptr;
563
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);
568
569     iov[2].type = GSS_IOV_BUFFER_TYPE_PADDING;
570     iov[3].type = GSS_IOV_BUFFER_TYPE_TRAILER;
571
572     major = gss_wrap_iov_length(&minor, ctx, 1, GSS_C_QOP_DEFAULT,
573                                 NULL, iov, 4);
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;
585
586     major = gss_wrap_iov(&minor, ctx, 1, GSS_C_QOP_DEFAULT, NULL,
587                          iov, 4);
588     if (GSS_ERROR(major))
589         handle_error(major, minor);
590
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.
598
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
602 modified.
603
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)::
613
614     OM_uint32 major, minor;
615     gss_iov_buffer_desc iov[2];
616
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);
624
625     /* Decrypted data is in iov[1].buffer, pointing to a subregion of
626      * token. */
627
628 .. _gssapi_mic_token:
629
630 IOV MIC tokens
631 --------------
632
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
635 using an IOV list::
636
637     OM_uint32 gss_get_mic_iov(OM_uint32 *minor_status,
638                               gss_ctx_id_t context_handle,
639                               gss_qop_t qop_req,
640                               gss_iov_buffer_desc *iov,
641                               int iov_count);
642
643     OM_uint32 gss_get_mic_iov_length(OM_uint32 *minor_status,
644                                      gss_ctx_id_t context_handle,
645                                      gss_qop_t qop_req,
646                                      gss_iov_buffer_desc *iov,
647                                      iov_count);
648
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,
653                                  int iov_count);
654
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.
657 Valid types include:
658
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.
662
663 * **GSS_C_BUFFER_TYPE_MIC_TOKEN**: The GSSAPI MIC token.
664
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
673 gss_ctx_id_t)::
674
675     OM_uint32 major, minor;
676     gss_iov_buffer_desc iov[3];
677
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;
685
686     major = gss_get_mic_iov(&minor, ctx, GSS_C_QOP_DEFAULT, iov, 3);
687     if (GSS_ERROR(major))
688         handle_error(major, minor);
689
690     /* Transmit or otherwise use iov[2].buffer. */
691
692     (void)gss_release_iov_buffer(&minor, iov, 3);
693
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::
698
699     OM_uint32 major, minor;
700     gss_iov_buffer_desc iov[2];
701     char data[1024];
702
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;
707
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;
714
715     major = gss_get_mic_iov(&minor, ctx, GSS_C_QOP_DEFAULT, iov, 2);
716     if (GSS_ERROR(major))
717         handle_error(major, minor);
718
719
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