RFC 3645

Generic Security Service Algorithm for Secret Key Transaction Authentication for DNS (GSS-TSIG)

πŸ“… published October 2003, from ietf

RFC 3645 ✨ GSS-TSIG: Generic Security Service Algorithm for Secret Key Transaction Authentication for DNS

okay bestie, let's get into this one πŸŽ€ It's RFC 3645, a Standards Track doc from October 2003, and it's written by S. Kwan, P. Garg, J. Gilroy, L. Esibov, and J. Westhead from Microsoft Corp., plus R. Hall from Lucent Technologies. It's a Network Working Group document. The big thing to know is that it updates RFC 2845. That's the TSIG spec, and this one adds a new algorithm to it, so it's basically a glow-up for TSIG πŸ’…

Status of This Memo

This document specifies an Internet standards track protocol for the Internet community, and requests discussion and suggestions for improvements. Please refer to the current edition of the "Internet Official Protocol Standards" (STD 1) for the standardization state and status of this protocol. Distribution of this memo is unlimited. πŸ“œ

Copyright (C) The Internet Society (2003). All Rights Reserved. 🌸

Abstract

okay so the Secret Key Transaction Authentication for DNS (TSIG) protocol gives you transaction level authentication for DNS πŸ” TSIG is extensible, which means you can define new algorithms for it, and this doc does exactly that with an algorithm built on the Generic Security Service Application Program Interface (GSS-API) (RFC2743). Also, this document updates RFC 2845 πŸ¦‹

Table of Contents

1.  Introduction . . . . . . . . . . . . . . . . . . . . . . . . .  2
2.  Algorithm Overview . . . . . . . . . . . . . . . . . . . . . .  3
    2.1.  GSS Details. . . . . . . . . . . . . . . . . . . . . . .  4
    2.2.  Modifications to the TSIG protocol (RFC 2845). . . . . .  4
3.  Client Protocol Details. . . . . . . . . . . . . . . . . . . .  5
    3.1.  Negotiating Context. . . . . . . . . . . . . . . . . . .  5
        3.1.1.  Call GSS_Init_sec_context. . . . . . . . . . . . .  6
        3.1.2.  Send TKEY Query to Server. . . . . . . . . . . . .  8
        3.1.3.  Receive TKEY Query-Response from Server. . . . . .  8
    3.2.  Context Established. . . . . . . . . . . . . . . . . . . 11
        3.2.1.  Terminating a Context. . . . . . . . . . . . . . . 11
4.  Server Protocol Details. . . . . . . . . . . . . . . . . . . . 12
    4.1.  Negotiating Context. . . . . . . . . . . . . . . . . . . 12
        4.1.1.  Receive TKEY Query from Client . . . . . . . . . . 12
        4.1.2.  Call GSS_Accept_sec_context. . . . . . . . . . . . 12
        4.1.3.  Send TKEY Query-Response to Client . . . . . . . . 13
    4.2.  Context Established. . . . . . . . . . . . . . . . . . . 15
        4.2.1.  Terminating a Context. . . . . . . . . . . . . . . 15
5.  Sending and Verifying Signed Messages. . . . . . . . . . . . . 15
    5.1.  Sending a Signed Message - Call GSS_GetMIC . . . . . . . 15
    5.2.  Verifying a Signed Message - Call GSS_VerifyMIC. . . . . 16
6.  Example usage of GSS-TSIG algorithm. . . . . . . . . . . . . . 18
7.  Security Considerations. . . . . . . . . . . . . . . . . . . . 22
8.  IANA Considerations. . . . . . . . . . . . . . . . . . . . . . 22
9.  Conformance. . . . . . . . . . . . . . . . . . . . . . . . . . 22
10. Intellectual Property Statement. . . . . . . . . . . . . . . . 23
11. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . 23
12. References . . . . . . . . . . . . . . . . . . . . . . . . . . 24
    12.1.  Normative References. . . . . . . . . . . . . . . . . . 24
    12.2.  Informative References. . . . . . . . . . . . . . . . . 24
13. Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . 25
14. Full Copyright Statement . . . . . . . . . . . . . . . . . . . 26

1. Introduction 🧚

okay so the Secret Key Transaction Authentication for DNS (TSIG) [RFC2845] protocol was built to give you lightweight authentication and integrity for messages between two DNS entities, like a client and a server, or a server and another server πŸ’– TSIG can protect dynamic update messages, authenticate regular messages, or take complicated DNSSEC [RFC2535] processing off a client and hand it to a server, while the client can still be sure the answers have integrity 🫢

The TSIG protocol [RFC2845] is extensible through new algorithms. This document specifies an algorithm based on the Generic Security Service Application Program Interface (GSS-API) [RFC2743]. GSS-API is a framework that gives the application protocol developer an abstraction of security πŸ”₯ The security services it can offer include authentication, integrity, and confidentiality.

The GSS-API framework has several benefits:

  • Mechanism and protocol independence. The underlying mechanisms that realize the security services can be negotiated on the fly and varied over time. For example, a client and server MAY use Kerberos [RFC1964] for one transaction, whereas that same server MAY use SPKM [RFC2025] with a different client. ✨
  • The protocol developer is removed from the responsibility of creating and managing a security infrastructure. For example, the developer does not need to create new key distribution or key management systems. Instead the developer relies on the security service mechanism to manage this on its behalf. πŸ’…

The scope of this document is limited to the description of an authentication mechanism only. It does not discuss and/or propose an authorization mechanism. Readers that are unfamiliar with GSS-API concepts are encouraged to read the characteristics and concepts section of [RFC2743] before examining this protocol in detail. It is also assumed that the reader is familiar with [RFC2845], [RFC2930], [RFC1034] and [RFC1035]. πŸ“š

The key words "MUST", "MUST NOT", "REQUIRED", "SHOULD", "SHOULD NOT", "RECOMMENDED", and "MAY" in this document are to be interpreted as described in BCP 14, RFC 2119 [RFC2119]. πŸŽ€

2. Algorithm Overview 🌈

In GSS, the client and server interact to create a "security context". The security context can be used to create and verify transaction signatures on messages between the two parties. A unique security context is required for each unique connection between client and server πŸ¦‹

Creating a security context involves a negotiation between client and server. Once a context has been established, it has a finite lifetime for which it can be used to secure messages. Thus there are three states of a context associated with a connection:

                          +----------+
                          |          |
                          V          |
                  +---------------+  |
                  | Uninitialized |  |
                  |               |  |
                  +---------------+  |
                          |          |
                          V          |
                  +---------------+  |
                  | Negotiating   |  |
                  | Context       |  |
                  +---------------+  |
                          |          |
                          V          |
                  +---------------+  |
                  | Context       |  |
                  | Established   |  |
                  +---------------+  |
                          |          |
                          +----------+

Every connection begins in the uninitialized state. 🌸

2.1. GSS Details πŸ“

Client and server MUST be locally authenticated and have acquired default credentials before using this protocol as specified in Section 1.1.1 "Credentials" in RFC 2743 [RFC2743]. no skipping this step, bestie πŸ™ˆ

The GSS-TSIG algorithm consists of two stages:

  • I. Establish security context. The Client and Server use the GSS_Init_sec_context and GSS_Accept_sec_context APIs to generate the tokens that they pass to each other using [RFC2930] as a transport mechanism. 🧚
  • II. Use the context to sign and verify. Once the security context is established it is used to generate and verify signatures using GSS_GetMIC and GSS_VerifyMIC APIs. These signatures are exchanged by the Client and Server as a part of the TSIG records exchanged in DNS messages sent between the Client and Server, as described in [RFC2845]. πŸ’œ

2.2. Modifications to the TSIG protocol (RFC 2845) πŸ’–

okay this part is the plot twist 😭 Modification to RFC 2845 allows use of TSIG through signing server's response in an explicitly specified place in multi message exchange between two DNS entities, even if client's request wasn't signed.

Specifically, Section 4.2 of RFC 2845 MUST be modified as follows:

Replace: "The server MUST not generate a signed response to an unsigned request." With: "The server MUST not generate a signed response to an unsigned request, except in case of response to client's unsigned TKEY query if secret key is established on server side after server processed client's query. Signing responses to unsigned TKEY queries MUST be explicitly specified in the description of an individual secret key establishment algorithm."

3. Client Protocol Details πŸ’…

A unique context is required for each server to which the client sends secure messages. A context is identified by a context handle. A client maintains a mapping of servers to handles:

   (target_name, key_name, context_handle)

The value key_name also identifies a context handle. The key_name is the owner name of the TKEY and TSIG records sent between a client and a server to indicate to each other which context MUST be used to process the current request. πŸ”‘

DNS client and server MAY use various underlying security mechanisms to establish security context as described in sections 3 and 4. At the same time, in order to guarantee interoperability between DNS clients and servers that support GSS-TSIG it is REQUIRED that security mechanism used by client enables use of Kerberos v5 (see Section 9 for more information). ✨ this is the key requirement, so don't sleep on it πŸ‘‘

3.1. Negotiating Context πŸ¦‹

In GSS, establishing a security context involves passing opaque tokens between the client and the server. The client generates the initial token and sends it to the server. The server processes the token and if necessary, returns a subsequent token to the client. The client processes this token, and so on, until the negotiation is complete. The number of times the client and server exchange tokens depends on the underlying security mechanism. A completed negotiation results in a context handle. 🌈

The TKEY resource record [RFC2930] is used as the vehicle to transfer tokens between client and server. The TKEY record is a general mechanism for establishing secret keys for use with TSIG. For more information, see [RFC2930]. πŸŽ€


more of this is coming, bestie πŸ’–πŸ§š

3.1.1. Call GSS_Init_sec_context ✨

okay bestie, first things first πŸ’… the client MUST call the GSS_Init_sec_context API to get the very first token that gets sent to a server πŸ¦‹ this is the moment it all starts!!

these input parameters MUST be used, and the outcome of the call shows up in the output values below. for the syntax definitions, check out Sections 2.2.1, "GSS_Init_sec_context call", of [RFC2743] πŸ“–

   INPUTS
     CREDENTIAL HANDLE claimant_cred_handle = NULL (NULL specifies "use
         default").  Client MAY instead specify some other valid
         handle to its credentials.
     CONTEXT HANDLE input_context_handle  = 0
     INTERNAL NAME  targ_name             = "DNS@<target_server_name>"
     OBJECT IDENTIFIER mech_type          = Underlying security
         mechanism chosen by implementers.  To guarantee
         interoperability of the implementations of the GSS-TSIG
         mechanism client MUST specify a valid underlying security
         mechanism that enables use of Kerberos v5 (see Section 9 for
         more information).
     OCTET STRING   input_token           = NULL
     BOOLEAN        replay_det_req_flag   = TRUE
     BOOLEAN        mutual_req_flag       = TRUE
     BOOLEAN        deleg_req_flag        = TRUE
     BOOLEAN        sequence_req_flag     = TRUE
     BOOLEAN        anon_req_flag         = FALSE
     BOOLEAN        integ_req_flag        = TRUE
     INTEGER        lifetime_req          = 0 (0 requests a default
         value).  Client MAY instead specify another upper bound for the
         lifetime of the context to be established in seconds.
     OCTET STRING   chan_bindings         = Any valid channel bindings
         as specified in Section 1.1.6 "Channel Bindings" in [RFC2743]

the OUTPUTS are these 🌸

   OUTPUTS
     INTEGER        major_status
     CONTEXT HANDLE output_context_handle
     OCTET STRING   output_token
     BOOLEAN        replay_det_state
     BOOLEAN        mutual_state
     INTEGER        minor_status
     OBJECT IDENTIFIER mech_type
     BOOLEAN        deleg_state
     BOOLEAN        sequence_state
     BOOLEAN        anon_state
     BOOLEAN        trans_state
     BOOLEAN        prot_ready_state
     BOOLEAN        conf_avail
     BOOLEAN        integ_avail
     INTEGER        lifetime_rec

now the important bit 🚨 if major_status comes back as one of these errors:

     GSS_S_DEFECTIVE_TOKEN
     GSS_S_DEFECTIVE_CREDENTIAL
     GSS_S_BAD_SIG (GSS_S_BAD_MIC)
     GSS_S_NO_CRED
     GSS_S_CREDENTIALS_EXPIRED
     GSS_S_BAD_BINDINGS
     GSS_S_OLD_TOKEN
     GSS_S_DUPLICATE_TOKEN
     GSS_S_NO_CONTEXT
     GSS_S_BAD_NAMETYPE
     GSS_S_BAD_NAME
     GSS_S_BAD_MECH
     GSS_S_FAILURE

then the client MUST abandon the algorithm and MUST NOT use the GSS-TSIG algorithm to establish this security context πŸ’€ this doc doesn't say which other mechanism could be used to set up a security context, so that's not on us. the next time the client needs a security context, it MAY use the GSS-TSIG algorithm again πŸ”„

the success values of major_status are GSS_S_CONTINUE_NEEDED and GSS_S_COMPLETE. the exact success code matters later in processing, so don't ignore it πŸ‘€

the replay_det_state and mutual_state values tell you whether the security package provides replay detection and mutual authentication. if major_status is GSS_S_COMPLETE and one or both of these values are FALSE, the client MUST abandon this algorithm. no exceptions, periodt πŸ™…β€β™€οΈ

the client's behavior MAY depend on other OUTPUT parameters, according to the policy local to the client. that's the client's call 🧚

finally, the output_context_handle is unique to this negotiation. it gets stored in the client's mapping table as the context_handle that maps to target_name πŸ—‚οΈ

3.1.2. Send TKEY Query to Server πŸš€

the opaque output_token that GSS_Init_sec_context returned gets sent to the server in a query request with QTYPE=TKEY. the token itself goes in a Key Data field of the RDATA field in the TKEY resource record, which lives in the additional records section of the query πŸŽ€

the owner name of the TKEY resource record set being queried for, and the owner name of the supplied TKEY resource record in the additional records section, MUST be the same. this name uniquely identifies the security context to both the client and the server, so the client SHOULD use a value that's globally unique, as described in [RFC2930]. to get that global uniqueness, the name MAY contain a UUID/GUID [ISO11578] 🌈

      TKEY Record
        NAME = client-generated globally unique domain name string
               (as described in [RFC2930])
        RDATA
           Algorithm Name      = gss-tsig
           Mode                = 3 (GSS-API negotiation - per [RFC2930])
           Key Size            = size of output_token in octets
           Key Data            = output_token

the remaining fields in the TKEY RDATA, which are Inception, Expiration, Error, Other Size and Data Fields, MUST be set according to [RFC2930] πŸ“‹

then the query gets transmitted to the server πŸ“¨

Note: if the original client call to GSS_Init_sec_context returned any major_status other than GSS_S_CONTINUE_NEEDED or GSS_S_COMPLETE, then the client MUST NOT send the TKEY query. the client's behavior in that case is described above in Section 3.1.1. don't skip this, it's a whole vibe check πŸ™…β€β™€οΈ

3.1.3. Receive TKEY Query-Response from Server πŸ“¬

when the DNS server gets the TKEY query, it MUST respond according to the description in Section 4. this section covers what the client does after it receives the matching response to its query πŸ’Œ

the next step depends on the value of major_status from the most recent call the client made to GSS_Init_sec_context. it's either GSS_S_COMPLETE or GSS_S_CONTINUE, so pay attention πŸ‘€

3.1.3.1. Value of major_status == GSS_S_COMPLETE βœ…

if the last call to GSS_Init_sec_context gave a major_status of GSS_S_COMPLETE and a non-NULL output_token was sent to the server, then the client side of the negotiation is done. the client is now just waiting for the server to confirm 🫢

the confirmation comes as a query response with RCODE=NOERROR and the last client-supplied TKEY record in the answer section. the response MUST be signed with a TSIG record. the server is allowed to sign a response to an unsigned client query because of the modification to RFC 2845 described in Section 2.2 above πŸ” the signature in the TSIG record MUST be verified using the procedure detailed in section 5, Sending and Verifying Signed Messages.

now, if the response is not signed, or if it's signed but the signature is invalid, then an attacker has tampered with the message in transit or is trying to feed the client a false response 😱 in that case the client MAY keep waiting for a response to its last TKEY query until the time period since the client sent that query runs out. how long that is depends on the policy local to the client. this is a new option that lets the DNS client accept multiple answers for one query ID and pick one (not necessarily the first one) based on some criteria. main character energy πŸ‘‘

if the signature checks out, the context state is advanced to Context Established. proceed to section 3.2 for usage of the security context πŸ₯³

3.1.3.2. Value of major_status == GSS_S_CONTINUE_NEEDED πŸ”

if the last call to GSS_Init_sec_context gave a major_status of GSS_S_CONTINUE_NEEDED, the negotiation isn't finished yet. the server will send back a query response with a TKEY record in the Answer section πŸ“¦

if the DNS message error is not NO_ERROR, or the error field in the TKEY record is not 0 (meaning there's an error), then the client MUST abandon this negotiation sequence. the client MUST delete an active context by calling GSS_Delete_sec_context with the associated context_handle πŸ—‘οΈ the client MAY repeat the negotiation sequence starting from the uninitialized state, as described in section 3.1. to prevent infinite looping, the number of attempts to establish a security context MUST be limited to ten or less πŸ›‘

if the DNS message error is NO_ERROR and the error field in the TKEY record is 0 (no error), then the client MUST pass a token from the Key Data field in the TKEY resource record to GSS_Init_sec_context. it uses the same parameter values as the previous call, except for the CONTEXT HANDLE input_context_handle and OCTET STRING input_token, which are set like this:

   INPUTS
     CONTEXT HANDLE input_context_handle  = context_handle (this is the
          context_handle corresponding to the key_name which is the
          owner name of the TKEY record in the answer section in the
          TKEY query response)

     OCTET STRING   input_token           = token from Key field of
                                            TKEY record

depending on these OUTPUT values of GSS_Init_sec_context:

        INTEGER        major_status
        OCTET STRING   output_token

the client MUST take one of the following actions 🎯

if OUTPUT major_status is set to one of these values:

        GSS_S_DEFECTIVE_TOKEN
        GSS_S_DEFECTIVE_CREDENTIAL
        GSS_S_BAD_SIG (GSS_S_BAD_MIC)
        GSS_S_NO_CRED
        GSS_S_CREDENTIALS_EXPIRED
        GSS_S_BAD_BINDINGS
        GSS_S_OLD_TOKEN
        GSS_S_DUPLICATE_TOKEN
        GSS_S_NO_CONTEXT
        GSS_S_BAD_NAMETYPE
        GSS_S_BAD_NAME
        GSS_S_BAD_MECH
        GSS_S_FAILURE

the client MUST abandon this negotiation sequence. that means the client MUST delete an active context by calling GSS_Delete_sec_context with the associated context_handle. the client MAY repeat the negotiation sequence starting from the uninitialized state, as described in section 3.1. to prevent infinite looping, the number of attempts to establish a security context MUST be limited to ten or less πŸ’”

if OUTPUT major_status is GSS_S_CONTINUE_NEEDED or GSS_S_COMPLETE, then the client MUST act as described below πŸ‘‡

if the response from the server was signed and OUTPUT major_status is GSS_S_COMPLETE, then the signature in the TSIG record MUST be verified using the procedure detailed in section 5, Sending and Verifying Signed Messages. if the signature is invalid, the client MUST abandon this negotiation sequence. that means the client MUST delete an active context by calling GSS_Delete_sec_context with the associated context_handle. the client MAY repeat the negotiation sequence starting from the uninitialized state, as described in section 3.1. to prevent infinite looping, the number of attempts to establish a security context MUST be limited to ten or less πŸ™ˆ

if major_status is GSS_S_CONTINUE_NEEDED, the negotiation isn't finished yet. the token output_token MUST be passed to the server in a TKEY record by repeating the negotiation sequence, beginning with section 3.1.2. the client MUST place a limit on the number of continuations in a context negotiation so it doesn't loop forever. that limit SHOULD NOT exceed a value of 10 πŸ”’

if major_status is GSS_S_COMPLETE and output_token is non-NULL, the client-side part of the negotiation is complete, but the token output_token MUST still be passed to the server by repeating the negotiation sequence, beginning with section 3.1.2 πŸ“€

if major_status is GSS_S_COMPLETE and output_token is NULL, the context negotiation is complete. the context state is advanced to Context Established. proceed to section 3.2 for usage of the security context πŸŽ‰

3.2. Context Established πŸ’œ

when context negotiation is complete, the handle context_handle MUST be used for generating and verifying transaction signatures ✍️

the procedures for sending and receiving signed messages are described in section 5, Sending and Verifying Signed Messages πŸ“œ

3.2.1. Terminating a Context 🫧

okay so if the client isn't planning to keep using the security context, it SHOULD delete the active one by calling GSS_Delete_sec_context with the matching context_handle 🧹 and it SHOULD also delete the established context on the DNS server by sending a TKEY RR with the Mode field set to 5, i.e., "key deletion" [RFC2930] πŸ’…

4. Server Protocol Details ✨

same as the client side, a successful context negotiation ends with a context handle that gets used to generate and verify the transaction signatures πŸ’œ

a server MAY be juggling several contexts with several clients 🧚 clients tell the server which context they mean by giving a key name in their request, so the server keeps a little mapping of key names to handles:

(key_name, context_handle)

4.1. Negotiating Context 🀝

a server MUST recognize TKEY queries as security context negotiation messages πŸ‘‘

4.1.1. Receive TKEY Query from Client πŸ“₯

when a query comes in with QTYPE = TKEY, the server MUST check whether the Mode and Algorithm Name fields of the TKEY record in the additional records section of the message contain the values 3 and gss-tsig, respectively πŸ” if they do, the server looks through its (key_name, context_handle) mapping table for a key_name that matches the owner name of that TKEY record in the query's additional records section. if the name is found and the security context for it is established and not expired, the server MUST respond to the query with BADNAME in the TKEY error field πŸ™ˆ if the name is found and the security context is not established yet, the matching context_handle gets used in the later GSS operations 🫢 if the name is found but the security context has expired, the server deletes that security context as described in Section 4.2.1, treats the query as the start of a new security context negotiation, and performs the operations described in Section 4.1.2 and 4.1.3 πŸ”„ and if the name isn't in the table at all, the server treats the query as the start of a new security context negotiation and performs the operations described in Section 4.1.2 and 4.1.3 🌈

4.1.2. Call GSS_Accept_sec_context πŸŽ€

this is the server's half of the context negotiation: it calls GSS_Accept_sec_context 🧁 the following input parameters MUST be used, and the outcome shows up in the output values below. for the syntax definitions, check Sections 2.2.2 "GSS_Accept_sec_context call" of the RFC 2743 [RFC2743] ✨

INPUTS
  CONTEXT HANDLE input_context_handle  = 0 if new negotiation,
                                         context_handle matching
                                      key_name if ongoing negotiation
  OCTET STRING   input_token           = token specified in the Key
        field from TKEY RR (from Additional records Section of
        the client's query)

  CREDENTIAL HANDLE acceptor_cred_handle = NULL (NULL specifies "use
        default").  Server MAY instead specify some other valid
        handle to its credentials.
  OCTET STRING   chan_bindings          = Any valid channel bindings
        as specified in Section 1.1.6 "Channel Bindings" in [RFC2743]

OUTPUTS
  INTEGER        major_status
  CONTEXT_HANDLE output_context_handle
  OCTET STRING   output_token
  INTEGER        minor_status
  INTERNAL NAME  src_name
  OBJECT IDENTIFIER  mech_type
  BOOLEAN        deleg_state
  BOOLEAN        mutual_state
  BOOLEAN        replay_det_state
  BOOLEAN        sequence_state
  BOOLEAN        anon_state
  BOOLEAN        trans_state
  BOOLEAN        prot_ready_state
  BOOLEAN        conf_avail
  BOOLEAN        integ_avail
  INTEGER        lifetime_rec
  CONTEXT_HANDLE delegated_cred_handle

if this is the very first GSS_Accept_sec_context call in a brand new negotiation, the output_context_handle gets saved in the server's key-mapping table as the context_handle that maps to the name of the TKEY record πŸ“

4.1.3. Send TKEY Query-Response to Client πŸ“¨

the server MUST answer the client with a TKEY query response that has RCODE = NOERROR and contains a TKEY record in the answer section πŸ’Œ

if OUTPUT major_status is one of the errors below, the error field in the TKEY record is set to BADKEY 😭

GSS_S_DEFECTIVE_TOKEN
GSS_S_DEFECTIVE_CREDENTIAL
GSS_S_BAD_SIG (GSS_S_BAD_MIC)
GSS_S_DUPLICATE_TOKEN
GSS_S_OLD_TOKEN
GSS_S_NO_CRED
GSS_S_CREDENTIALS_EXPIRED
GSS_S_BAD_BINDINGS
GSS_S_NO_CONTEXT
GSS_S_BAD_MECH
GSS_S_FAILURE

if OUTPUT major_status is set to GSS_S_COMPLETE or GSS_S_CONTINUE_NEEDED, then the server MUST act as described below πŸ‘€

if major_status is GSS_S_COMPLETE, the server's part of the negotiation is finished πŸŽ‰ if output_token is non-NULL, it MUST be returned to the client in a Key Data field of the RDATA in TKEY 🎁 the error field in the TKEY record is set to NOERROR βœ… the message MUST be signed with a TSIG record as described in section 5, Sending and Verifying Signed Messages πŸ” note that the server is allowed to sign a response to an unsigned client query, thanks to the modification to RFC 2845 in Section 2.2 above πŸ™Œ the context state advances to Context Established πŸ¦‹ and Section 4.2 talks about how to use the security context πŸ’œ

if major_status is GSS_S_COMPLETE and output_token is NULL, then the TKEY record the client sent MUST be returned in the Answer section of the response πŸ“¦ the message MUST be signed with a TSIG record as described in section 5, Sending and Verifying Signed Messages πŸ” same note as before: the server can sign a response to an unsigned client query because of the modification to RFC 2845 in section 2.2 above ✨ the context state advances to Context Established πŸ¦‹ and Section 4.2 discusses the usage of the security context πŸ’œ

if major_status is GSS_S_CONTINUE_NEEDED, the server's part of the negotiation isn't done yet ⏳ the server responds to the TKEY query with a standard query response, putting a TKEY record in the answer section that carries output_token in the Key Data RDATA field 🧩 the error field in the TKEY record is set to NOERROR πŸ™‚ the server MUST limit how many times a given context is allowed to repeat, so nothing loops forever πŸ” and that limit SHOULD NOT exceed the value of 10 πŸ›‘

in every case except when major_status is GSS_S_COMPLETE and output_token is NULL, the other TKEY record fields MUST contain these values:

NAME = key_name
RDATA
   Algorithm Name      = gss-tsig
   Mode                = 3 (GSS-API negotiation - per [RFC2930])
   Key Size            = size of output_token in octets

the remaining fields in the TKEY RDATA (Inception, Expiration, Error, Other Size and Data Fields) MUST be set according to [RFC2930] πŸ“‹

4.2. Context Established 🌸

once the context negotiation is complete, the handle context_handle is used to generate and verify transaction signatures πŸ–ŠοΈ the handle is only valid for a finite amount of time, and that time is decided by the underlying security mechanism ⏰ a server MAY unilaterally terminate a context at any time (see section 4.2.1) πŸšͺ

the server SHOULD limit how much memory it uses to cache established contexts 🧠

the procedures for sending and receiving signed messages are in section 5, Sending and Verifying Signed Messages πŸ“¬

4.2.1. Terminating a Context πŸ¦‹

a server can terminate any established context at any time πŸ’« the server MAY hint to the client that the context is being deleted by including a TKEY RR in a response with the Mode field set to 5, i.e., "key deletion" [RFC2930] πŸ‘‹ an active context gets deleted by calling GSS_Delete_sec_context with the associated context_handle πŸ—‘οΈ

5. Sending and Verifying Signed Messages πŸ”

5.1. Sending a Signed Message - Call GSS_GetMIC 🧾

the procedure for sending a signature-protected message is specified in [RFC2845] πŸ“œ the data passed to the signature routine includes the whole DNS message with specific TSIG variables appended 🧡 for the exact format, see [RFC2845] πŸ‘€ for this protocol, use these TSIG variable values:

TSIG Record
  NAME = key_name that identifies this context
  RDATA
     Algorithm Name = gss-tsig

assign the remaining fields in the TSIG RDATA appropriate values as described in [RFC2845] πŸŽ€

the signature is generated by calling GSS_GetMIC πŸ–‹οΈ the following input parameters MUST be used, and the outcome of the call is shown with the output values below 🌟 for the syntax definitions, check Sections 2.3.1 "GSS_GetMIC call" of the RFC 2743[RFC2743] πŸ“–

INPUTS
  CONTEXT HANDLE context_handle = context_handle for key_name
  OCTET STRING   message        = outgoing message plus TSIG
                                  variables (per [RFC2845])
  INTEGER qop_req               = 0 (0 requests a default
      value).  Caller MAY instead specify other valid value (for
      details see Section 1.2.4 in [RFC2743])

OUTPUTS
  INTEGER        major_status
  INTEGER        minor_status
  OCTET STRING   per_msg_token

if major_status is GSS_S_COMPLETE, the signature was generated successfully πŸŽ‰ the signature in per_msg_token goes into the Signature field of the TSIG RR, and then the message is sent πŸš€

if major_status is GSS_S_CONTEXT_EXPIRED, GSS_S_CREDENTIALS_EXPIRED or GSS_S_FAILURE, the caller MUST delete the security context, return to the uninitialized state, and SHOULD negotiate a new security context as described above in Section 3.1 πŸ”

if major_status is GSS_S_NO_CONTEXT, the caller MUST remove the entry for key_name from the (target_ name, key_name, context_handle) mapping table, return to the uninitialized state, and SHOULD negotiate a new security context as described above in Section 3.1 🫠

if major_status is GSS_S_BAD_QOP, the caller SHOULD repeat the GSS_GetMIC call with an allowed QOP value πŸ’– the number of these repetitions MUST be limited to prevent infinite loops πŸŒ€

5.2. Verifying a Signed Message - Call GSS_VerifyMIC πŸ”

Okay so checking a signed message is specified in [RFC2845], so we're basically following that recipe πŸ“

The NAME of the TSIG record tells you which context_handle maps to the context that MUST be used to verify the signature πŸ”‘. If that NAME doesn't map to an established context, the server MUST send a standard TSIG error response to the client, with BADKEY in the TSIG error field (as described in [RFC2845]). Not vibing πŸ’€

For the GSS algorithm, you verify a signature by calling GSS_VerifyMIC like this:

   INPUTS
     CONTEXT HANDLE context_handle = context_handle for key_name
     OCTET STRING   message        = incoming message plus TSIG
                                     variables (per [RFC2845])
     OCTET STRING   per_msg_token  = Signature field from TSIG RR

   OUTPUTS
     INTEGER        major_status
     INTEGER        minor_status
     INTEGER        qop_state

If major_status is GSS_S_COMPLETE, the signature is authentic and the message was delivered intact πŸ₯° Per [RFC2845], the timer values of the TSIG record MUST also be valid before you can treat the message as authentic ⏰ The caller MUST not act on the request or response in the message until these checks are verified πŸ™…β€β™€οΈ

When a server is processing a client request, the server MUST send a standard TSIG error response to the client indicating BADKEY in the TSIG error field (as described in [RFC2845]) if major_status is set to one of these values:

  • GSS_S_DEFECTIVE_TOKEN
  • GSS_S_BAD_SIG (GSS_S_BAD_MIC)
  • GSS_S_DUPLICATE_TOKEN
  • GSS_S_OLD_TOKEN
  • GSS_S_UNSEQ_TOKEN
  • GSS_S_GAP_TOKEN
  • GSS_S_CONTEXT_EXPIRED
  • GSS_S_NO_CONTEXT
  • GSS_S_FAILURE
If the timer values of the TSIG record are invalid, the message MUST NOT be considered authentic 🚫 And if this error checking fails while a server is processing a client request, the appropriate error response MUST be sent to the client according to [RFC2845]. No skipping this part, bestie 😭

6. Example usage of GSS-TSIG algorithm 🧚

Okay this section is the fun one πŸŽ€ It walks through an example where a Client, client.example.com, and a Server, server.example.com, set up a security context using the algorithm we just covered ✨

I. Client initializes security context negotiation 🌸

To establish a security context with a server, server.example.com, the Client calls GSS_Init_sec_context with these parameters. (Some INPUT and OUTPUT parameters that aren't critical for this algorithm are left out of this example, so don't stress about them πŸ’…)

     CONTEXT HANDLE input_context_handle  = 0
     INTERNAL NAME  targ_name             = "DNS@server.example.com"
     OCTET STRING   input_token           = NULL
     BOOLEAN        replay_det_req_flag   = TRUE
     BOOLEAN        mutual_req_flag       = TRUE

The OUTPUTS parameters returned by GSS_Init_sec_context include:

     INTEGER        major_status = GSS_S_CONTINUE_NEEDED
     CONTEXT HANDLE output_context_handle context_handle
     OCTET STRING   output_token output_token
     BOOLEAN        replay_det_state = TRUE
     BOOLEAN        mutual_state = TRUE

The client double-checks that replay_det_state and mutual_state are TRUE 🫢 Since major_status is GSS_S_CONTINUE_NEEDED, which counts as a success OUTPUT major_status value, the client stores the context_handle that maps to "DNS@server.example.com" and moves on to the next step πŸ¦‹

II. Client sends a query with QTYPE = TKEY to server πŸ’œ

The client sends a query with QTYPE = TKEY for a client-generated, globally unique domain name string, 789.client.example.com.server.example.com. The query carries a TKEY record in its Additional records section with these fields (fields that aren't specific to this algorithm are left unspecified):

     NAME = 789.client.example.com.server.example.com.
     RDATA
        Algorithm Name      = gss-tsig
        Mode                = 3 (GSS-API negotiation - per [RFC2930])
        Key Size            = size of output_token in octets
        Key Data            = output_token

Once the key_name 789.client.example.com.server.example.com. is generated, it gets stored in the client's (target_name, key_name, context_handle) mapping table πŸ—‚οΈ

III. Server receives a query with QTYPE = TKEY πŸ‘€

When the server receives a query with QTYPE = TKEY, it verifies that the Mode and Algorithm fields in the TKEY record (in the Additional records section of the query) are set to 3 and "gss-tsig" respectively. Then it finds that the key_name 789.client.example.com.server.example.com. is not listed in its (key_name, context_handle) mapping table πŸ€”

IV. Server calls GSS_Accept_sec_context πŸŽ€

To keep the security context negotiation going, the server calls GSS_Accept_sec_context with these parameters. (Again, some INPUT and OUTPUT parameters that aren't critical for this algorithm are left out here πŸ“)

   INPUTS
     CONTEXT HANDLE input_context_handle  = 0
     OCTET STRING   input_token           = token specified in the Key
                              field from TKEY RR (from Additional
                              records section of the client's query)

The OUTPUTS parameters returned by GSS_Accept_sec_context include:

     INTEGER        major_status = GSS_S_CONTINUE_NEEDED
     CONTEXT_HANDLE output_context_handle context_handle
     OCTET STRING   output_token output_token

The server stores the mapping of 789.client.example.com.server.example.com. to the OUTPUT context_handle in its (key_name, context_handle) mapping table πŸ“’

V. Server responds to the TKEY query πŸ’Œ

Since major_status = GSS_S_CONTINUE_NEEDED in the server's last call to GSS_Accept_sec_context, the server responds to the TKEY query. It places a TKEY record in the answer section, with output_token in the Key Data RDATA field. The error field in that TKEY record is set to 0, and the RCODE in the query response is set to NOERROR βœ…

VI. Client processes token returned by server πŸ”

When the client receives the TKEY query response from the server, it calls GSS_Init_sec_context with these parameters. (Some INPUT and OUTPUT parameters not critical for this algorithm are, once again, not described here πŸ’–)

     CONTEXT HANDLE input_context_handle  = the context_handle stored
          in the client's mapping table entry (DNS@server.example.com.,
          789.client.example.com.server.example.com., context_handle)
     INTERNAL NAME  targ_name             = "DNS@server.example.com"
     OCTET STRING   input_token           = token from Key field of TKEY
          record from the Answer section of the server's response
     BOOLEAN        replay_det_req_flag   = TRUE
     BOOLEAN        mutual_req_flag       = TRUE

The OUTPUTS parameters returned by GSS_Init_sec_context include:

     INTEGER        major_status = GSS_S_COMPLETE
     CONTEXT HANDLE output_context_handle = context_handle
     OCTET STRING   output_token = output_token
     BOOLEAN        replay_det_state = TRUE
     BOOLEAN        mutual_state = TRUE

Since major_status is GSS_S_COMPLETE, the client side security context is established πŸŽ‰ But because output_token is not NULL, the client MUST send a TKEY query to the server, as described below πŸ“¨

VII. Client sends a query with QTYPE = TKEY to server πŸ’«

The client sends the server a TKEY query for the 789.client.example.com.server.example.com. name. The query carries a TKEY record in its Additional records section with these fields (INPUT and OUTPUT parameters that aren't critical to this algorithm are left out, as usual 🌈):

     NAME = 789.client.example.com.server.example.com.
     RDATA
        Algorithm Name      = gss-tsig
        Mode                = 3 (GSS-API negotiation - per [RFC2930])
        Key Size            = size of output_token in octets
        Key Data            = output_token

VIII. Server receives a TKEY query πŸ₯Ή

When the server receives a TKEY query, it verifies that the Mode and Algorithm fields in the TKEY record (in the Additional records section of the query) are set to 3 and gss-tsig, respectively. It finds that the key_name 789.client.example.com.server.example.com. is listed in its (key_name, context_handle) mapping table ✨

IX. Server calls GSS_Accept_sec_context 🌟

To keep the negotiation going, the server calls GSS_Accept_sec_context with these parameters. (Some INPUT and OUTPUT parameters not critical for this algorithm are left out here too 🧁)

   INPUTS
     CONTEXT HANDLE input_context_handle  = context_handle from the
           (789.client.example.com.server.example.com., context_handle)
           entry in the server's mapping table
     OCTET STRING   input_token           = token specified in the Key
           field of TKEY RR (from Additional records Section of
           the client's query)

The OUTPUTS parameters returned by GSS_Accept_sec_context include:

     INTEGER        major_status = GSS_S_COMPLETE
     CONTEXT_HANDLE output_context_handle = context_handle
     OCTET STRING   output_token = NULL

Since major_status = GSS_S_COMPLETE, the security context on the server side is established πŸ™Œ The server still needs to respond to the client's TKEY query, though, as described below. The security context state is advanced to Context Established πŸ¦‹

X. Server responds to the TKEY query 🎁

Since major_status = GSS_S_COMPLETE in the server's last call to GSS_Accept_sec_context, and output_token is NULL, the server responds to the TKEY query. It places in the answer section a TKEY record that the client sent in the Additional records section of the client's latest TKEY query. On top of that, this server puts a TSIG record in the additional records section of its response πŸ’… The server calls GSS_GetMIC to generate a signature for the TSIG record, and it specifies these GSS_GetMIC INPUT parameters:

     CONTEXT HANDLE context_handle = context_handle from the
           (789.client.example.com.server.example.com., context_handle)
           entry in the server's mapping table
     OCTET STRING   message        = outgoing message plus TSIG
                                   variables (as described in [RFC2845])

The OUTPUTS parameters returned by GSS_GetMIC include:

     INTEGER        major_status = GSS_S_COMPLETE
     OCTET STRING   per_msg_token

The Signature field in the TSIG record is set to per_msg_token πŸ”

XI. Client processes token returned by server 🫧

The client receives the TKEY query response from the server. Since major_status was GSS_S_COMPLETE in the client's last call to GSS_Init_sec_context, the client verifies that the server's response is signed πŸ‘€ To validate that signature, the client calls GSS_VerifyMIC with these parameters:

   INPUTS
     CONTEXT HANDLE context_handle = context_handle for
                  789.client.example.com.server.example.com. key_name
     OCTET STRING   message        = incoming message plus TSIG
                                  variables (as described in [RFC2845])
     OCTET STRING   per_msg_token  = Signature field from TSIG RR
                  included in the server's query response

Since the OUTPUTS parameter major_status = GSS_S_COMPLETE, the signature is validated πŸ₯³ Security negotiation is complete, and the security context state is advanced to Context Established. From here, the client and server use that established security context to sign and validate the signatures on the packets they exchange with each other, until the context expires β³πŸ’œ

7. Security Considerations πŸ”

okay bestie, this part is serious 😭 This doc is a protocol for DNS security that uses GSS-API, and the security it gives you is only as strong as the security of the GSS mechanisms underneath it. no cap, if the bottom layer is weak, the whole thing is weak πŸ’€

Also, every security consideration from RFC 2845, RFC 2930 and RFC 2743 applies to this protocol too. Read those. Seriously. 🫢

8. IANA Considerations πŸŽ€

IANA has reserved the TSIG Algorithm name gss-tsig for use in the Algorithm fields of TKEY and TSIG resource records πŸ¦‹ That name points to the algorithm described in this document. The requirement to have the name registered with IANA is specified in RFC 2845, so go check there if you're wondering why.

9. Conformance πŸ’…

Okay, the GSS API using SPNEGO [RFC2478] is basically the most flexible option, because it lets you choose the underlying security mechanisms and negotiate security context on the fly ✨ Client and server can pick the mechanisms they want while they're talking, which is iconic.

To get that flexibility, DNS clients and servers SHOULD specify SPNEGO mech_type in their GSS API calls 🌸 BUT, and this is important, if you want DNS clients and servers that support GSS-TSIG to actually interoperate, these things are required:

  • DNS servers specify SPNEGO mech_type
  • GSS APIs called by DNS client support Kerberos v5
  • GSS APIs called by DNS server support SPNEGO [RFC2478] and Kerberos v5

On top of that, GSS APIs used by DNS client and server MAY also support other underlying security mechanisms 🌈 So you can add more if you want, but the list above is the floor.

10. Intellectual Property Statement βš–οΈ

The IETF doesn't take a position on whether any intellectual property rights claimed for this technology are valid, what their scope is, or whether licenses for them exist. It also doesn't say it has tried to find any such rights πŸ™ˆ If you want the IETF's rules on rights for standards-track and standards-related docs, check BCP-11. Claims of rights that were made available for publication, plus any promised licenses, or the results of attempts to get a general license for implementers or users, can be requested from the IETF Secretariat πŸ“¬

The IETF also invites anyone to flag any copyrights, patents, patent applications, or other proprietary rights that might cover technology needed to practise this standard. Send that info to the IETF Executive Director 🧚

11. Acknowledgements 🫢

The authors want to thank these people for their help with this spec: Chuck Chan, Mike Swift, Ram Viswanathan, Olafur Gudmundsson, Donald E. Eastlake, 3rd and Erik Nordmark. Legends, all of them πŸ‘‘

12. References πŸ“š

12.1. Normative References

[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
          Requirement Levels", BCP 14, RFC 2119, March 1997.

[RFC2478] Baize, E. and D. Pinkas, "The Simple and Protected GSS-API
          Negotiation Mechanism", RFC 2478, December 1998.

[RFC2743] Linn, J., "Generic Security Service Application Program
          Interface, Version 2 , Update 1", RFC 2743, January 2000.

[RFC2845] Vixie, P., Gudmundsson, O., Eastlake 3rd, D. and B.
          Wellington, "Secret Key Transaction Authentication for DNS
          (TSIG)", RFC 2845, May 2000.

[RFC2930] Eastlake 3rd, D., "Secret Key Establishment for DNS (TKEY
          RR)", RFC 2930, September 2000.

12.2. Informative References

[ISO11578] "Information technology", "Open Systems Interconnection",
           "Remote Procedure Call", ISO/IEC 11578:1996,
           http://www.iso.ch/cate/d2229.html.

[RFC1034] Mockapetris, P., "Domain Names - Concepts and Facilities",
          STD 13, RFC 1034, November 1987.

[RFC1035] Mockapetris, P., "Domain Names - Implementation and
          Specification", STD 13, RFC 1034, November 1987.

[RFC1964] Linn, J., "The Kerberos Version 5 GSS-API Mechanism", RFC
          1964, June 1996.

[RFC2025] Adams, C., "The Simple Public-Key GSS-API Mechanism
          (SPKM)", RFC 2025, October 1996.

[RFC2137] Eastlake 3rd, D., "Secure Domain Name System Dynamic
          Update", RFC 2137, April 1997.

[RFC2535] Eastlake 3rd, D., "Domain Name System Security Extensions",
          RFC 2535, March 1999.

13. Authors' Addresses πŸ—ΊοΈ

Here are the people who wrote this, with where to find them πŸ’Œ

Stuart Kwan
Microsoft Corporation
One Microsoft Way
Redmond, WA  98052
USA
EMail: skwan@microsoft.com

Praerit Garg
Microsoft Corporation
One Microsoft Way
Redmond, WA  98052
USA
EMail: praeritg@microsoft.com

James Gilroy
Microsoft Corporation
One Microsoft Way
Redmond, WA  98052
USA
EMail: jamesg@microsoft.com

Levon Esibov
Microsoft Corporation
One Microsoft Way
Redmond, WA  98052
USA
EMail: levone@microsoft.com

Randy Hall
Lucent Technologies
400 Lapp Road
Malvern PA 19355
USA
EMail: randyhall@lucent.com

Jeff Westhead
Microsoft Corporation
One Microsoft Way
Redmond, WA  98052
USA
EMail: jwesth@microsoft.com

The legal bit, kept word-for-word so nothing gets lost πŸ“œ

Copyright (C) The Internet Society (2003).  All Rights Reserved.

This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published
and distributed, in whole or in part, without restriction of any
kind, provided that the above copyright notice and this paragraph are
included on all such copies and derivative works.  However, this
document itself may not be modified in any way, such as by removing
the copyright notice or references to the Internet Society or other
Internet organizations, except as needed for the purpose of
developing Internet standards in which case the procedures for
copyrights defined in the Internet Standards process must be
followed, or as required to translate it into languages other than
English.

The limited permissions granted above are perpetual and will not be
revoked by the Internet Society or its successors or assignees.

This document and the information contained herein is provided on an
"AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.

Acknowledgement πŸ’œ

Funding for the RFC Editor function is currently provided by the Internet Society. Thank you for reading, bestie 🌸✨

πŸ“¦ where this page comes from