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