idnits 2.17.1 draft-ietf-kitten-gss-loop-03.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- ** The document seems to lack an IANA Considerations section. (See Section 2.2 of https://www.ietf.org/id-info/checklist for how to handle the case when there are no actions for IANA.) Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (December 31, 2014) is 3404 days in the past. Is this intentional? -- Found something which looks like a code comment -- if you have code sections in the document, please surround them with '' and '' lines. Checking references for intended status: Informational ---------------------------------------------------------------------------- -- Duplicate reference: RFC2743, mentioned in 'RFC2743E4151', was also mentioned in 'RFC2743'. Summary: 1 error (**), 0 flaws (~~), 1 warning (==), 3 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Network Working Group B. Kaduk 3 Internet-Draft MIT 4 Intended status: Informational December 31, 2014 5 Expires: July 4, 2015 7 Structure of the GSS Negotiation Loop 8 draft-ietf-kitten-gss-loop-03 10 Abstract 12 This document specifies the generic structure of the negotiation loop 13 to establish a GSS security context between initiator and acceptor. 14 The control flow of the loop is indicated for both parties, including 15 error conditions, and indications are given for where application- 16 specific behavior must be specified. 18 Status of This Memo 20 This Internet-Draft is submitted in full conformance with the 21 provisions of BCP 78 and BCP 79. 23 Internet-Drafts are working documents of the Internet Engineering 24 Task Force (IETF). Note that other groups may also distribute 25 working documents as Internet-Drafts. The list of current Internet- 26 Drafts is at http://datatracker.ietf.org/drafts/current/. 28 Internet-Drafts are draft documents valid for a maximum of six months 29 and may be updated, replaced, or obsoleted by other documents at any 30 time. It is inappropriate to use Internet-Drafts as reference 31 material or to cite them other than as "work in progress." 33 This Internet-Draft will expire on July 4, 2015. 35 Copyright Notice 37 Copyright (c) 2014 IETF Trust and the persons identified as the 38 document authors. All rights reserved. 40 This document is subject to BCP 78 and the IETF Trust's Legal 41 Provisions Relating to IETF Documents 42 (http://trustee.ietf.org/license-info) in effect on the date of 43 publication of this document. Please review these documents 44 carefully, as they describe your rights and restrictions with respect 45 to this document. Code Components extracted from this document must 46 include Simplified BSD License text as described in Section 4.e of 47 the Trust Legal Provisions and are provided without warranty as 48 described in the Simplified BSD License. 50 Table of Contents 52 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 53 2. Application Protocol Requirements . . . . . . . . . . . . . . 3 54 3. Loop Structure . . . . . . . . . . . . . . . . . . . . . . . 4 55 3.1. Anonymous Initiators . . . . . . . . . . . . . . . . . . 4 56 3.2. GSS_Init_sec_context . . . . . . . . . . . . . . . . . . 5 57 3.3. Sending from Initiator to Acceptor . . . . . . . . . . . 5 58 3.4. Acceptor Sanity Checking . . . . . . . . . . . . . . . . 6 59 3.5. GSS_Accept_sec_context . . . . . . . . . . . . . . . . . 7 60 3.6. Sending from Acceptor to Initiator . . . . . . . . . . . 8 61 3.7. Initiator input validation . . . . . . . . . . . . . . . 8 62 3.8. Continue the Loop . . . . . . . . . . . . . . . . . . . . 9 63 4. After Security Context Negotiation . . . . . . . . . . . . . 9 64 4.1. Authorization Checks . . . . . . . . . . . . . . . . . . 10 65 4.2. Using Partially Complete Security Contexts . . . . . . . 10 66 4.3. Additional Context Tokens . . . . . . . . . . . . . . . . 10 67 5. Sample Code . . . . . . . . . . . . . . . . . . . . . . . . . 11 68 5.1. GSS Application Sample Code . . . . . . . . . . . . . . . 12 69 6. Security Considerations . . . . . . . . . . . . . . . . . . . 18 70 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 19 71 7.1. Normative References . . . . . . . . . . . . . . . . . . 19 72 7.2. Informational References . . . . . . . . . . . . . . . . 19 73 Appendix A. Acknowledgements . . . . . . . . . . . . . . . . . . 20 74 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 20 76 1. Introduction 78 The Generic Security Service Application Program Interface version 2 79 [RFC2743] provides a generic interface for security services, in the 80 form of an abstraction layer over the underlying security mechanisms 81 that an application may use. A GSS initiator and acceptor exchange 82 messages, called tokens, until a security context is established. 83 Such a security context allows for each party to authenticate the 84 other, the passing of confidential and/or integrity-protected 85 messages between the initiator and acceptor, the generation of 86 identical pseudo-random bit strings by both participants [RFC4401], 87 and more. 89 During context establishment, security context tokens are exchanged 90 synchronously, one at a time; the initiator sends the first context 91 token. The number of tokens which must be exchanged between 92 initiator and acceptor in order to establish the security context is 93 dependent on the underlying mechanism as well as the desired 94 properties of the security context, and is in general not known to 95 the application. Accordingly, the application's control flow must 96 include a loop within which GSS security context tokens are 97 exchanged, which terminates upon successful establishment of a 98 security context or an error condition. The GSS-API, together with 99 its security mechanisms, specifies the format and encoding of the 100 context tokens themselves, but the application protocol must specify 101 the necessary framing for the application to determine what octet 102 strings constitute GSS security context tokens and pass them into the 103 GSS-API implementation as appropriate. 105 The GSS-API C bindings [RFC2744] provide some example code for such a 106 negotiation loop, but this code does not specify the application's 107 behavior on unexpected or error conditions. As such, individual 108 application protocol specifications have had to specify the structure 109 of their GSS negotiation loops, including error handling, on a per- 110 protocol basis. [RFC4462], [RFC3645], [RFC5801], [RFC4752], 111 [RFC2203] This represents a substantial duplication of effort, and 112 the various specifications go into different levels of detail and 113 describe different possible error conditions. It is therefore 114 preferable to have the structure of the GSS negotiation loop, 115 including error conditions and token passing, described in a single 116 specification, which can then be referred to from other documents in 117 lieu of repeating the structure of the loop each time. This document 118 will perform that role. 120 The necessary requirements for correctly performing a GSS negotiation 121 loop are essentially all included in [RFC2743], but they are 122 scattered in many different places. This document brings all the 123 requirements together into one place for the convenience of 124 implementors, even though the normative requirements remain in 125 [RFC2743]. In a few places, this document notes additional behavior 126 which is useful for applications but is not mandated by [RFC2743]. 128 2. Application Protocol Requirements 130 Part of the purpose of this document is to guide the development of 131 new application protocols using the GSS-API, as well as the 132 development of new application software using such protocols. The 133 following list is features which are necessary or useful in such an 134 application protocol: 136 o A way to frame and identify security context negotiation tokens in 137 the loop. 139 o Error tokens should generally also get special framing, as the 140 recipient may have no other way to distinguish unexpected error 141 context tokens from per-message tokens. 143 o Failing that, a way to indicate error status from one peer to the 144 other, possibly accompanied by a descriptive string. 146 o A protocol may use the negotiated GSS security context for per- 147 message operations; in such cases, the protocol will need a way to 148 frame and identify those per-message tokens and the nature of 149 their contents. For example, a protocol message may be 150 accompanied by the output of GSS_GetMIC() over that message; the 151 protocol must identify the location and size of that MIC token, 152 and indicate that it is a MIC token and what cleartext it 153 corresponds to. 155 o Applications are responsible for authorization of the 156 authenticated peer principal names which are supplied by the GSS- 157 API. Such names are mechanism-specific, and may come from a 158 different portion of a federated identity scheme. Application 159 protocols may need to supply additional information to support the 160 authorization of access to a given resource, such as the SSHv2 161 "username" parameter. 163 3. Loop Structure 165 The loop is begun by the appropriately named initiator, which calls 166 GSS_Init_sec_context() with an empty (zero-length) input_token and a 167 fixed set of input flags containing the desired attributes for the 168 security context. The initiator should not change any of the input 169 parameters to GSS_Init_sec_context() between calls to it during the 170 loop, with the exception of the input_token parameter, which will 171 contain a message from the acceptor after the initial call, and the 172 input_context_handle, which must be the result returned in the 173 output_context_handle of the previous call to GSS_Init_sec_context() 174 (GSS_C_NO_CONTEXT for the first call). (In the C bindings, there is 175 only a single read/modify context_handle argument, so the same 176 variable should be passed for each call in the loop.) RFC 2743 only 177 requires that the claimant_cred_handle argument remain constant over 178 all calls in the loop, but the other non-excepted arguments should 179 also remain fixed for reliable operation. 181 The following subsections will describe the various steps of the 182 loop, without special consideration to whether a call to 183 GSS_Init_sec_context() or GSS_Accept_sec_context() is the first such 184 call in the loop. 186 3.1. Anonymous Initiators 188 If the initiator is requesting anonymity by setting the anon_req_flag 189 input to GSS_Init_sec_context(), then on non-error returns from 190 GSS_Init_sec_context() (that is, when the major status is 191 GSS_S_COMPLETE or GSS_S_CONTINUE_NEEDED), the initiator must verify 192 that the output value of anon_state from GSS_Init_sec_context() is 193 true before sending the security context token to the acceptor. 195 Failing to perform this check could cause the initiator to lose 196 anonymity. 198 3.2. GSS_Init_sec_context 200 The initiator calls GSS_Init_sec_context(), using the 201 input_context_handle for the current proto-security-context and its 202 fixed set of input parameters, and the input_token received from the 203 acceptor (if not the first iteration of the loop). The presence or 204 absence of a nonempty output_token and the value of the major status 205 code are the indicators for how to proceed: 207 o If the major status code is GSS_S_COMPLETE and the output_token is 208 empty, then the context negotiation is fully complete and ready 209 for use by the initiator with no further actions. 211 o If the major status code is GSS_S_COMPLETE and the output_token is 212 nonempty, then the initiator's portion of the security context 213 negotiation is complete but the acceptor's is not. The initiator 214 must send the output_token to the acceptor so that the acceptor 215 can establish its half of the security context. 217 o If the major status code is GSS_S_CONTINUE_NEEDED and the 218 output_token is nonempty, the context negotiation is incomplete. 219 The initiator must send the output_token to the acceptor and await 220 another input_token from the acceptor. 222 o If the major status code is GSS_S_CONTINUE_NEEDED and the 223 output_token is empty, the mechanism has produced an output which 224 is not compliant with [RFC2743]. However, there are some known 225 implementations of certain mechanisms which do produce empty 226 context negotiation tokens. For maximum interoperability, 227 applications should be prepared to accept such tokens, and should 228 transmit them to the acceptor if they are generated. 230 o If the major status code is any other value, the context 231 negotiation has failed. If the output_token is nonempty, it is an 232 error token, and the initiator should send it to the acceptor. If 233 the output_token is empty, then the initiator should indicate the 234 failure to the acceptor if an appropriate application-protocol 235 channel to do so is available. 237 3.3. Sending from Initiator to Acceptor 239 The establishment of a GSS security context between initiator and 240 acceptor requires some communication channel by which to exchange the 241 context negotiation tokens. The nature of this channel is not 242 specified by the GSS specification -- it could be a dedicated TCP 243 channel, a UDP-based RPC protocol, or any other sort of channel. In 244 many cases, the channel will be multiplexed with non-GSS application 245 data; the application protocol must always provide some means by 246 which the GSS context tokens can be identified (e.g., length and 247 start location) and passed through to the mechanism accordingly. The 248 application protocol may also include a facility for indicating 249 errors from one party to the other, which can be used to convey 250 errors resulting from GSS-API calls, when appropriate (such as when 251 no error token was generated by the GSS-API implementation). Note 252 that GSS major and minor status codes are specified by language 253 bindings, not the abstract API; sending a major status code and 254 optionally the display form of the two error codes may be the best 255 that can be done in this case. 257 However, even the presence of a communication channel does not 258 necessarily indicate that it is appropriate for the initiator to 259 indicate such errors. For example, if the acceptor is a stateless or 260 near-stateless UDP server, there is probably no need for the 261 initiator to explicitly indicate its failure to the acceptor. 262 Conditions such as this can be treated in individual application 263 protocol specifications. 265 If a regular security context output_token is produced by the call to 266 GSS_Init_sec_context(), the initiator must transmit this token to the 267 acceptor over the application's communication channel. If the call 268 to GSS_Init_sec_context() returns an error token as output_token, it 269 is recommended that the initiator transmit this token to the acceptor 270 over the application's communication channel. 272 3.4. Acceptor Sanity Checking 274 The acceptor's half of the negotiation loop is triggered by the 275 receipt of a context token from the initiator. Before calling 276 GSS_Accept_sec_context(), the acceptor may find it useful to perform 277 some sanity checks on the state of the negotiation loop. 279 If the acceptor receives a context token but was not expecting such a 280 token (for example, if the acceptor's previous call to 281 GSS_Accept_sec_context() returned GSS_S_COMPLETE), this is probably 282 an error condition indicating that the initiator's state is invalid. 283 See Section 4.3 for some exceptional cases. It is likely appropriate 284 for the acceptor to report this error condition to the acceptor via 285 the application's communication channel. 287 If the acceptor is expecting a context token (e.g., if the previous 288 call to GSS_Accept_sec_context() returned GSS_S_CONTINUE_NEEDED), but 289 does not receive such a token within a reasonable amount of time 290 after transmitting the previous output_token to the initiator, the 291 acceptor should assume that the initiator's state is invalid (time 292 out) and fail the GSS negotiation. Again, it is likely appropriate 293 for the acceptor to report this error condition to the initiator via 294 the application's communication channel. 296 3.5. GSS_Accept_sec_context 298 The GSS acceptor responds to the actions of an initiator; as such, 299 there should always be a nonempty input_token to calls to 300 GSS_Accept_sec_context(). The input_context_handle parameter will 301 always be given as the output_context_handle from the previous call 302 to GSS_Accept_sec_context() in a given negotiation loop, or 303 GSS_C_NO_CONTEXT on the first call, but the acceptor_cred_handle and 304 chan_bindings arguments should remain fixed over the course of a 305 given GSS negotiation loop. [RFC2743] only requires that the 306 acceptor_cred_handle remain fixed throughout the loop, but the 307 chan_bindings argument should also remain fixed for reliable 308 operation. 310 The GSS acceptor calls GSS_Accept_sec_context(), using the 311 input_context_handle for the current proto-security-context and the 312 input_token received from the initiator. The presence or absence of 313 a nonempty output_token and the value of the major status code are 314 the indicators for how to proceed: 316 o If the major status code is GSS_S_COMPLETE and the output_token is 317 empty, then the context negotiation is fully complete and ready 318 for use by the acceptor with no further actions. 320 o If the major status code is GSS_S_COMPLETE and the output_token is 321 nonempty, then the acceptor's portion of the security context 322 negotiation is complete but the initiator's is not. The acceptor 323 must send the output_token to the initiator so that the initiator 324 can establish its half of the security context. 326 o If the major status code is GSS_S_CONTINUE_NEEDED and the 327 output_token is nonempty, the context negotiation is incomplete. 328 The acceptor must send the output_token to the initiator and await 329 another input_token from the initiator. 331 o If the major status code is GSS_S_CONTINUE_NEEDED and the 332 output_token is empty, the mechanism has produced an output which 333 is not compliant with [RFC2743]. However, there are some known 334 implementations of certain mechanisms which do produce empty 335 context negotiation tokens. For maximum interoperability, 336 applications should be prepared to accept such tokens, and should 337 transmit them to the initiator if they are generated. 339 o If the major status code is any other value, the context 340 negotiation has failed. If the output_token is nonempty, it is an 341 error token, and the acceptor should send it to the initiator. If 342 the output_token is empty, then the acceptor should indicate the 343 failure to the initiator if an appropriate application-protocol 344 channel to do so is available. 346 3.6. Sending from Acceptor to Initiator 348 The mechanism for sending the context token from acceptor to 349 initiator will depend on the nature of the communication channel 350 between the two parties. For a synchronous bidirectional channel, it 351 can be just another piece of data sent over the link, but for a 352 stateless UDP RPC acceptor, the token will probably end up being sent 353 as an RPC output parameter. Application protocol specifications will 354 need to specify the nature of this behavior. 356 If the application protocol has the initiator driving the 357 application's control flow, it is particularly helpful for the 358 acceptor to indicate a failure to the initiator, as mentioned in some 359 of the above cases conditional on "an appropriate application- 360 protocol channel to do so". 362 If a regular security context output_token is produced by the call to 363 GSS_Accept_sec_context(), the acceptor must transmit this token to 364 the initiator over the application's communication channel. If the 365 call to GSS_Accept_sec_context() returns an error token as 366 output_token, it is recommended that the acceptor transmit this token 367 to the initiator over the application's communication channel. 369 3.7. Initiator input validation 371 The initiator's half of the negotiation loop is triggered (after the 372 first call) by receipt of a context token from the acceptor. Before 373 calling GSS_Init_sec_context(), the initiator may find it useful to 374 perform some sanity checks on the state of the negotiation loop. 376 If the initiator receives a context token but was not expecting such 377 a token (for example, if the initiator's previous call to 378 GSS_Init_sec_context() returned GSS_S_COMPLETE), this is probably an 379 error condition indicating that the acceptor's state is invalid. See 380 Section 4.3 for some exceptional cases. It may be appropriate for 381 the initiator to report this error condition to the acceptor via the 382 application's communication channel. 384 If the initiator is expecting a context token (that is, the previous 385 call to GSS_Init_sec_context() returned GSS_S_CONTINUE_NEEDED), but 386 does not receive such a token within a reasonable amount of time 387 after transmitting the previous output_token to the acceptor, the 388 initiator should assume that the acceptor's state is invalid and fail 389 the GSS negotiation. Again, it may be appropriate for the initiator 390 to report this error condition to the acceptor via the application's 391 communication channel. 393 3.8. Continue the Loop 395 If the loop is in neither a success or failure condition, then the 396 loop must continue. Control flow returns to Section 3.2. 398 4. After Security Context Negotiation 400 Once a party has completed its half of the security context and 401 fulfilled its obligations to the other party, the context is 402 complete, but it is not necessarily ready and appropriate for use. 403 In particular, the security context flags may not be appropriate for 404 the given application's use. In some cases the context may be ready 405 for use before the negotiation is complete, see Section 4.2. 407 The initiator specifies as part of its fixed set of inputs to 408 GSS_Init_sec_context() values for all defined request flag booleans, 409 among them: deleg_req_flag, mutual_req_flag, replay_det_req_flag, 410 sequence_req_flag, conf_req_flag, and integ_req_flag. Upon 411 completion of the security context negotiation, the initiator must 412 verify that the values of the deleg_state, mutual_state, 413 replay_det_state, sequence_state, conf_avail, and integ_avail (and 414 any additional flags added by extensions) from the last call to 415 GSS_Init_sec_context() correspond to the requested flags. If a flag 416 was requested but is not available, and that feature is necessary for 417 the appplication protocol, the initiator must destroy the security 418 context and not use the security context for application traffic. 420 Application protocol specifications citing this document should 421 indicate which context flags are required for their application 422 protocol. 424 The acceptor receives as output the following booleans: deleg_state, 425 mutual_state, replay_det_state, sequence_state, anon_state, 426 trans_state, conf_avail, and integ_avail, and any additional flags 427 added by extensions to the GSS-API. The acceptor must verify that 428 any flags necessary for the application protocol are set. If a 429 necessary flag is not set, the acceptor must destroy the security 430 context and not use the security context for application traffic. 432 4.1. Authorization Checks 434 The acceptor receives as one of the outputs of 435 GSS_Accept_sec_context() the name of the initiator which has 436 authenticated during the security context negotiation. Applications 437 need to implement authorization checks on this received name 438 ('client_name' in the sample code) before providing access to 439 restricted resources. In particular, security context negotiation 440 can be successful when the client is anonymous or is from a different 441 identity realm than the acceptor, depending on the details of the 442 mechanism used by the GSS-API to establish the security context. 443 Acceptor applications can check which target name was used by the 444 initiator, but the details are out of scope for this document. See 445 [RFC2743] sections 2.2.6 and 1.1.5. Additional information can be 446 available in GSS-API Naming Extensions, [RFC6680]. 448 4.2. Using Partially Complete Security Contexts 450 For mechanism/flag combinations that require multiple token 451 exchanges, the GSS-API specification [RFC2743] provides a 452 prot_ready_state output value from GSS_Init_sec_context() and 453 GSS_Accept_sec_context(), which indicates when per-message operations 454 are available. However, many mechanism implementations do not 455 provide this functionality, and the analysis of the security 456 consequences of its use is rather complicated, so it is not expected 457 to be useful in most application protocols. 459 In particular, mutual authentication, replay protection, and other 460 services (if requested) are services which will be active when 461 GSS_S_COMPLETE is returned, but which are not necessarily active 462 before the security context is fully established. 464 4.3. Additional Context Tokens 466 Under some conditions, a context token will be received by a party to 467 a security context negotiation after that party has completed the 468 negotiation (i.e., after GSS_Init_sec_context() or 469 GSS_Accept_sec_context() has returned GSS_S_COMPLETE). Such tokens 470 must be passed to GSS_Process_context_token() for processing. It may 471 not always be necessary for a mechanism implementation to generate an 472 error token on the initiator side, or for an initiator application to 473 transmit that token to the acceptor; such decisions are out of scope 474 for this document. Both peers should always be prepared to process 475 such tokens, and application protocols should provide means by which 476 they can be transmitted. 478 Such tokens can be security context deletion tokens, emitted when the 479 remote party called GSS_Delete_sec_context() with a non-null 480 output_context_token parameter, or error tokens, emitted when the 481 remote party experiences an error processing the last token in a 482 security context negotiation exchange. Errors experienced when 483 processing tokens earlier in the negotiation would be transmitted as 484 normal security context tokens and processed by 485 GSS_Init_sec_context() or GSS_Accept_sec_context(), as appropriate. 486 With the GSS-API version 2, it is not recommended to use security 487 context deletion tokens, so error tokens are expected to be the most 488 common form of additional context token for new application 489 protocols. 491 GSS_Process_context_token() may indicate an error in its major_status 492 field if an error is encountered locally during token processing, or 493 to indicate that an error was encountered on the peer and conveyed in 494 an error token. [RFC2743E4151] Regardless of the major_status output 495 of GSS_Process_context_token(), GSS_Inquire_context() should be used 496 after processing the extra token, to query the status of the security 497 context and whether it can supply the features necessary for the 498 application protocol. 500 At present, all tokens which should be handled by 501 GSS_Process_context_token() will lead to the security context being 502 effectively unusable. Future extensions to the GSS-API may allow for 503 applications to continue to function after a call to 504 GSS_Process_context_token(), and it is expected that the outputs of 505 GSS_Inquire_context() will indicate whether it is safe to do so. 506 However, since there are no such extensions at present (error tokens 507 and deletion tokens both result in the security context being 508 essentially unusable), there is no guidance to give to applications 509 regarding this possibility at this time. 511 Even if GSS_Process_context_token() processes an error or deletion 512 token which renders the context essentially unusable, the resources 513 associated with the context must eventually be freed with a call to 514 GSS_Delete_sec_context(), just as would be needed if 515 GSS_Init_sec_context() or GSS_Accept_sec_context() had returned an 516 error while processing an input context token and the 517 input_context_handle was not GSS_C_NO_CONTEXT. RFC 2743 has some 518 text which is slightly ambiguous in this regard, but the best 519 practice is to always call GSS_Delete_sec_context(). 521 5. Sample Code 523 This section gives sample code for the GSS negotiation loop, both for 524 a regular application and for an application where the initiator 525 wishes to remain anonymous. Since the code for the two cases is very 526 similar, the anonymous-specific additions are wrapped in a 527 conditional check; that check and the conditional code may be ignored 528 if anonymous processing is not needed. 530 Since the communication channel between the initiator and acceptor is 531 a matter for individual application protocols, it is inherently 532 unspecified at the GSS-API level, which can lead to examples that are 533 less satisfying than may be desired. For example, the sample code in 534 [RFC2744] uses an unspecified send_token_to_peer() routine. Fully 535 correct and general code to frame and transmit tokens requires a 536 substantial amount of error checking and would detract from the core 537 purpose of this document, so we only present the function signature 538 for one example of what such functions might be, and leave some 539 comments in the otherwise-empty function bodies. 541 This sample code is written in C, using the GSS-API C bindings 542 [RFC2744]. It uses the macro GSS_ERROR() to help unpack the various 543 sorts of information which can be stored in the major status field; 544 supplementary information does not necessarily indicate an error. 545 Applications written in other languages will need to exercise care 546 that checks against the major status value are written correctly. 548 This sample code should be compilable as a standalone program, linked 549 against a GSS-API library. In addition to supplying implementations 550 for the token transmission/receipt routines, in order for the program 551 to successfully run when linked against most GSS-API libraries, the 552 initiator will need to specify an explicit target name for the 553 acceptor, which must match the credentials available to the acceptor. 554 A skeleton for how this may be done is provided, using a dummy name. 556 This sample code assumes v2 of the GSS-API. Applications wishing to 557 remain compatible with v1 of the GSS-API may need to perform 558 additional checks in some locations. 560 5.1. GSS Application Sample Code 562 #include 563 #include 564 #include 565 #include 566 #include 567 #include 569 /* 570 * This helper is used only on buffers that we allocate ourselves (e.g., 571 * from receive_token()). Buffers allocated by GSS routines must use 572 * gss_release_buffer(). 573 */ 574 static void 575 release_buffer(gss_buffer_t buf) 576 { 577 free(buf->value); 578 buf->value = NULL; 579 buf->length = 0; 580 } 582 /* 583 * Helper to send a token on the specified fd. 584 * 585 * If errors are encountered, this routine must not directly cause 586 * termination of the process, because compliant GSS applications 587 * must release resources allocated by the GSS library before 588 * exiting. 589 */ 590 static int 591 send_token(int fd, gss_buffer_t token) 592 { 593 /* 594 * Supply token framing and transmission code here. 595 * 596 * It is advisable for the application protocol to specify the 597 * length of the token being transmitted, unless the underlying 598 * transit does so implicitly. 599 * 600 * In addition to checking for error returns from whichever 601 * syscall(s) are used to send data, applications should have 602 * a loop to handle EINTR returns. 603 */ 604 return 1; 605 } 607 /* 608 * Helper to receive a token on the specified fd. 609 * 610 * If errors are encountered, this routine must not directly cause 611 * termination of the process, because compliant GSS applications 612 * must release resources allocated by the GSS library before 613 * exiting. 614 */ 615 static int 616 receive_token(int fd, gss_buffer_t token) 617 { 618 /* 619 * Supply token framing and transmission code here. 620 * 621 * In addition to checking for error returns from whichever 622 * syscall(s) are used to receive data, applications should have 623 * a loop to handle EINTR returns. 624 * 625 * This routine is assumed to allocate memory for the local copy 626 * of the received token, which must be freed with release_buffer(). 627 */ 628 return 1; 629 } 631 static void 632 do_initiator(int readfd, int writefd, int anon) 633 { 634 int initiator_established = 0, ret; 635 gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; 636 OM_uint32 major, minor, req_flags, ret_flags; 637 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; 638 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; 639 gss_buffer_desc name_buf = GSS_C_EMPTY_BUFFER; 640 gss_name_t target_name = GSS_C_NO_NAME; 642 /* Applications should set target_name to a real value. */ 643 name_buf.value = "@"; 644 name_buf.length = strlen(name_buf.value); 645 major = gss_import_name(&minor, &name_buf, 646 GSS_C_NT_HOSTBASED_SERVICE, &target_name); 647 if (GSS_ERROR(major)) { 648 warnx(1, "Could not import name\n"); 649 goto cleanup; 650 } 652 /* Mutual authentication will require a token from acceptor to 653 * initiator, and thus a second call to gss_init_sec_context(). */ 654 req_flags = GSS_C_MUTUAL_FLAG | GSS_C_CONF_FLAG | GSS_C_INTEG_FLAG; 655 if (anon) 656 req_flags |= GSS_C_ANON_FLAG; 658 while (!initiator_established) { 659 /* The initiator_cred_handle, mech_type, time_req, 660 * input_chan_bindings, actual_mech_type, and time_rec 661 * parameters are not needed in many cases. We pass 662 * GSS_C_NO_CREDENTIAL, GSS_C_NO_OID, 0, NULL, NULL, and NULL 663 * for them, respectively. */ 664 major = gss_init_sec_context(&minor, GSS_C_NO_CREDENTIAL, &ctx, 665 target_name, GSS_C_NO_OID, 666 req_flags, 0, NULL, &input_token, 667 NULL, &output_token, &ret_flags, 668 NULL); 669 /* This was allocated by receive_token() and is no longer 670 * needed. Free it now to avoid leaks if the loop continues. */ 672 release_buffer(&input_token); 673 if (anon) { 674 /* Initiators which wish to remain anonymous must check 675 * whether their request has been honored before sending 676 * each token. */ 677 if (!(ret_flags & GSS_C_ANON_FLAG)) { 678 warnx("Anonymous requested but not available\n"); 679 goto cleanup; 680 } 681 } 682 /* Always send a token if we are expecting another input token 683 * (GSS_S_CONTINUE_NEEDED is set) or if it is nonempty. */ 684 if ((major & GSS_S_CONTINUE_NEEDED) || 685 output_token.length > 0) { 686 ret = send_token(writefd, &output_token); 687 if (ret != 0) 688 goto cleanup; 689 } 690 /* Check for errors after sending the token so that we will send 691 * error tokens. */ 692 if (GSS_ERROR(major)) { 693 warnx("gss_init_sec_context() error major 0x%x\n", major); 694 goto cleanup; 695 } 696 /* Free the output token's storage; we don't need it anymore. 697 * gss_release_buffer() is safe to call on the output buffer 698 * from gss_int_sec_context(), even if there is no storage 699 * associated with that buffer. */ 700 (void)gss_release_buffer(&minor, &output_token); 702 if (major & GSS_S_CONTINUE_NEEDED) { 703 ret = receive_token(readfd, &input_token); 704 if (ret != 0) 705 goto cleanup; 706 } else if (major == GSS_S_COMPLETE) { 707 initiator_established = 1; 708 } else { 709 /* This situation is forbidden by RFC 2743. Bail out. */ 710 warnx("major not complete or continue but not error\n"); 711 goto cleanup; 712 } 713 } /* while (!initiator_established) */ 714 if ((ret_flags & req_flags) != req_flags) { 715 warnx("Negotiated context does not support requested flags\n"); 716 goto cleanup; 717 } 718 printf("Initiator's context negotiation successful\n"); 719 cleanup: 721 /* We are required to release storage for nonzero-length output 722 * tokens. gss_release_buffer() zeros the length, so we are 723 * will not attempt to release the same buffer twice. */ 724 if (output_token.length > 0) 725 (void)gss_release_buffer(&minor, &output_token); 726 /* Do not request a context deletion token; pass NULL. */ 727 (void)gss_delete_sec_context(&minor, &ctx, NULL); 728 (void)gss_release_name(&minor, &target_name); 729 } 731 /* 732 * Perform authorization checks on the initiator's GSS name object. 733 * 734 * Returns 0 on success (the initiator is authorized) and nonzero 735 * when the initiator is not authorized. 736 */ 737 static int 738 check_authz(gss_name_t client_name) 739 { 740 /* 741 * Supply authorization checking code here. 742 * 743 * Options include bitwise comparison of the exported name against 744 * a local database, and introspection against name attributes. 745 */ 746 return 0; 747 } 749 static void 750 do_acceptor(int readfd, int writefd) 751 { 752 int acceptor_established = 0, ret; 753 gss_ctx_id_t ctx = GSS_C_NO_CONTEXT; 754 OM_uint32 major, minor, ret_flags; 755 gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; 756 gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; 757 gss_name_t client_name; 759 major = GSS_S_CONTINUE_NEEDED; 761 while (!acceptor_established) { 762 if (major & GSS_S_CONTINUE_NEEDED) { 763 ret = receive_token(readfd, &input_token); 764 if (ret != 0) 765 goto cleanup; 766 } else if (major == GSS_S_COMPLETE) { 767 acceptor_established = 1; 768 break; 770 } else { 771 /* This situation is forbidden by RFC 2743. Bail out. */ 772 warnx("major not complete or continue but not error\n"); 773 goto cleanup; 774 } 775 /* We can use the default behavior or do not need the returned 776 * information for the parameters acceptor_cred_handle, 777 * input_chan_bindings, mech_type, time_rec, and 778 * delegated_cred_handle and pass the values 779 * GSS_C_NO_CREDENTIAL, NULL, NULL, NULL, and NULL, 780 * respectively. In some cases the src_name will not be 781 * needed, but most likely it will be needed for some 782 * authorization or logging functionality. */ 783 major = gss_accept_sec_context(&minor, &ctx, 784 GSS_C_NO_CREDENTIAL, 785 &input_token, NULL, 786 &client_name, NULL, 787 &output_token, &ret_flags, NULL, 788 NULL); 789 /* This was allocated by receive_token() and is no longer 790 * needed. Free it now to avoid leaks if the loop continues. */ 791 release_buffer(&input_token); 792 /* Always send a token if we are expecting another input token 793 * (GSS_S_CONTINUE_NEEDED is set) or if it is nonempty. */ 794 if ((major & GSS_S_CONTINUE_NEEDED) || 795 output_token.length > 0) { 796 ret = send_token(writefd, &output_token); 797 if (ret != 0) 798 goto cleanup; 799 } 800 /* Check for errors after sending the token so that we will send 801 * error tokens. */ 802 if (GSS_ERROR(major)) { 803 warnx("gss_accept_sec_context() error major 0x%x\n", major); 804 goto cleanup; 805 } 806 /* Free the output token's storage; we don't need it anymore. 807 * gss_release_buffer() is safe to call on the output buffer 808 * from gss_accept_sec_context(), even if there is no storage 809 * associated with that buffer. */ 810 (void)gss_release_buffer(&minor, &output_token); 811 } /* while (!acceptor_established) */ 812 if (!(ret_flags & GSS_C_INTEG_FLAG)) { 813 warnx("Negotiated context does not support integrity\n"); 814 goto cleanup; 815 } 816 printf("Acceptor's context negotiation successful\n"); 817 ret = check_authz(client_name); 818 if (ret != 0) 819 printf("Client is not authorized; rejecting access\n"); 820 cleanup: 821 release_buffer(&input_token); 822 /* We are required to release storage for nonzero-length output 823 * tokens. gss_release_buffer() zeros the length, so we are 824 * will not attempt to release the same buffer twice. */ 825 if (output_token.length > 0) 826 (void)gss_release_buffer(&minor, &output_token); 827 /* Do not request a context deletion token, pass NULL. */ 828 (void)gss_delete_sec_context(&minor, &ctx, NULL); 829 (void)gss_release_name(&minor, &client_name); 830 } 832 int 833 main(void) 834 { 835 pid_t pid; 836 int fd1 = -1, fd2 = -1; 838 /* Create fds for reading/writing here. */ 839 pid = fork(); 840 if (pid == 0) 841 do_initiator(fd1, fd2, 0); 842 else if (pid > 0) 843 do_acceptor(fd2, fd1); 844 else 845 err(1, "fork() failed\n"); 846 exit(0); 847 } 849 6. Security Considerations 851 This document provides a (reasonably) concise description and example 852 for correct construction of the GSS-API security context negotiation 853 loop. Since everything relating to the construction and use of a GSS 854 security context is security-related, there are security-relevant 855 considerations throughout the document. It is useful to call out a 856 few things in this section, though. 858 The GSS-API uses a request-and-check model for features. An 859 application using the GSS-API requests certain features 860 (confidentiality protection for messages, or anonymity), but such a 861 request does not require the GSS implementation to provide that 862 feature. The application must check the returned flags to verify 863 whether a requested feature is present; if the feature was non- 864 optional for the application, the application must generate an error. 866 Phrased differently, the GSS-API will not generate an error if it is 867 unable to satisfy the features requested by the application. 869 In many cases it is convenient for GSS acceptors to accept security 870 contexts using multiple acceptor names (such as by using the default 871 credential set, as happens when GSS_C_NO_CREDENTIAL is passed to 872 GSS_Accept_sec_context()). This allows acceptors to use any 873 credentials to which it has access for accepting security contexts, 874 which may not be the desired behavior for a given application. (For 875 example, sshd may only wish to accept only using GSS_C_NT_HOSTBASED 876 credentials of the form host@, and not nfs@.) 877 Acceptor applications can check which target name was used by the 878 initiator, but the details are out of scope for this document. See 879 [RFC2743] sections 2.2.6 and 1.1.5. 881 The C sample code uses the macro GSS_ERROR() to assess the return 882 value of gss_init_sec_context() and gss_accept_sec_context(). This 883 is done to indicate where checks are needed in writing code for other 884 languages and what the nature of those checks might be. The C code 885 could be made simpler by omitting that macro. In applications 886 expecting to receive protected octet streams, this macro should not 887 be used on the result of per-message operations, as it omits checking 888 for supplementary status values such as GSS_S_DUPLICATE_TOKEN, 889 GSS_S_OLD_TOKEN, etc.. Use of the GSS_ERROR() macro on the results 890 of GSS-API per-message operations has resulted in security 891 vulnerabilities in existing software! 893 The security considerations from RFCs 2743 and 2744 remain applicable 894 to consumers of this document. 896 7. References 898 7.1. Normative References 900 [RFC2743] Linn, J., "Generic Security Service Application Program 901 Interface Version 2, Update 1", RFC 2743, January 2000. 903 [RFC2744] Wray, J., "Generic Security Service API Version 2 : 904 C-bindings", RFC 2744, January 2000. 906 7.2. Informational References 908 [RFC4462] Hutzelman, J., Salowey, J., Galbraith, J., and V. Welch, 909 "Generic Security Service Application Program Interface 910 (GSS-API) Authentication and Key Exchange for the Secure 911 Shell (SSH) Protocol", RFC 4462, May 2006. 913 [RFC4401] Williams, N., "A Pseudo-Random Function (PRF) API 914 Extension for the Generic Security Service Application 915 Program Interface (GSS-API)", RFC 4401, February 2006. 917 [RFC3645] Kwan, S., Garg, P., Gilroy, J., Esibov, L., Westhead, J., 918 and R. Hall, "Generic Security Service Algorithm for 919 Secret Key Transaction Authentication for DNS (GSS-TSIG)", 920 RFC 3645, October 2003. 922 [RFC5801] Josefsson, S. and N. Williams, "Using Generic Security 923 Service Application Program Interface (GSS-API) Mechanisms 924 in Simple Authentication and Security Layer (SASL): The 925 GS2 Mechanism Family", RFC 5801, July 2010. 927 [RFC4752] Melnikov, A., "The Kerberos V5 ("GSSAPI") Simple 928 Authentication and Security Layer (SASL) Mechanism", RFC 929 4752, November 2006. 931 [RFC2203] Eisler, M., Chiu, A., and L. Ling, "RPCSEC_GSS Protocol 932 Specification", RFC 2203, September 1997. 934 [RFC6680] Williams, N., Johansson, L., Hartman, S., and S. 935 Josefsson, "Generic Security Service Application 936 Programming Interface (GSS-API) Naming Extensions", RFC 937 6680, August 2012. 939 [RFC2743E4151] 940 Williams, N., "RFC 2743 Errata 4151", November 2014. 942 Appendix A. Acknowledgements 944 Thanks to Nico Williams and Jeff Hutzleman for prompting me to write 945 this document. 947 Author's Address 949 Benjamin Kaduk 950 MIT Kerberos Consortium 952 Email: kaduk@mit.edu