RFC 7635
Session Traversal Utilities for NAT (STUN) Extension for Third-Party Authorization
RFC 7635: Session Traversal Utilities for NAT (STUN) Extension for Third-Party Authorization π
Okay so, this one is a Standards Track doc from the IETF, which means it's an official Internet standard π It was written by T. Reddy, P. Patil, and R. Ravindranath from Cisco, plus J. Uberti from Google. It's dated August 2015 and sits under ISSN 2070-1721 β¨ The header doesn't list anything it obsoletes or updates, so it's just a fresh addition to the STUN family π¦
Abstract β¨
Okay so this doc suggests using OAuth 2.0 to get and check ephemeral tokens for Session Traversal Utilities for NAT (STUN) authentication π Because the tokens are ephemeral, a STUN server can still keep access locked down even if a token gets compromised. That's the main character energy we need π
Status of This Memo π
This is an Internet Standards Track document.
This document is a product of the Internet Engineering Task Force (IETF). It represents the consensus of the IETF community. It has received public review and has been approved for publication by the Internet Engineering Steering Group (IESG). Further information on Internet Standards is available in Section 2 of RFC 5741.
Information about the current status of this document, any errata, and how to provide feedback on it may be obtained at http://www.rfc-editor.org/info/rfc7635.
Copyright Notice βοΈ
Copyright (c) 2015 IETF Trust and the persons identified as the document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (http://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.
Table of Contents ποΈ
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2
2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 3
3. Solution Overview . . . . . . . . . . . . . . . . . . . . . . 3
3.1. Usage with TURN . . . . . . . . . . . . . . . . . . . . . 4
4. Obtaining a Token Using OAuth . . . . . . . . . . . . . . . . 7
4.1. Key Establishment . . . . . . . . . . . . . . . . . . . . 8
4.1.1. HTTP Interactions . . . . . . . . . . . . . . . . . . 8
4.1.2. Manual Provisioning . . . . . . . . . . . . . . . . . 10
5. Forming a Request . . . . . . . . . . . . . . . . . . . . . . 10
6. STUN Attributes . . . . . . . . . . . . . . . . . . . . . . . 10
6.1. THIRD-PARTY-AUTHORIZATION . . . . . . . . . . . . . . . . 10
6.2. ACCESS-TOKEN . . . . . . . . . . . . . . . . . . . . . . 11
7. STUN Server Behavior . . . . . . . . . . . . . . . . . . . . 13
8. STUN Client Behavior . . . . . . . . . . . . . . . . . . . . 14
9. TURN Client and Server Behavior . . . . . . . . . . . . . . . 14
10. Operational Considerations . . . . . . . . . . . . . . . . . 15
11. Security Considerations . . . . . . . . . . . . . . . . . . . 15
12. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 16
12.1. Well-Known 'stun-key' URI . . . . . . . . . . . . . . . 16
13. References . . . . . . . . . . . . . . . . . . . . . . . . . 16
13.1. Normative References . . . . . . . . . . . . . . . . . . 16
13.2. Informative References . . . . . . . . . . . . . . . . . 17
Appendix A. Sample Tickets . . . . . . . . . . . . . . . . . . . 20
Appendix B. Interaction between the Client and Authorization
Server . . . . . . . . . . . . . . . . . . . . . . . 22
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 24
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 24
1. Introduction πΈ
Okay so Session Traversal Utilities for NAT (STUN) [RFC5389] gives you a way to control access using 'long-term' username/password credentials that come as part of the STUN protocol. These credentials are supposed to stay secret π€« If they leak, the STUN server could get used by unauthorized users or applications, which is a whole disaster π In web apps like WebRTC [WEBRTC], where JavaScript uses the browser to make real-time audio and/or video calls, run web conferencing, and do direct data transfer, keeping that secret is typically not possible π
To tackle this problem, and the ones described in [RFC7376], this doc proposes third-party authorization using OAuth 2.0 [RFC6749] for STUN π¦ With OAuth 2.0, a client grabs an ephemeral token from an authorization server (for example, a WebRTC server), and then the token gets presented to the STUN server instead of the usual username/password credentials. The STUN server checks that the token is legit and then provides the required services β¨ This third-party authorization approach for STUN can also be used with Traversal Using Relays around NAT (TURN) [RFC5766] π§
2. Terminology π
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119] π
This document uses the following abbreviations:
- WebRTC Server: A web server that supports WebRTC [WEBRTC].
- Access Token: OAuth 2.0 access token.
mac_key: The session key generated by the authorization server. This session key has a lifetime that corresponds to the lifetime of the access token, is generated by the authorization server, and is bound to the access token.kid: An ephemeral and unique key identifier. Thekidalso allows the resource server to select the appropriate keying material for decryption.- AS: Authorization server.
- RS: Resource server.
Some sections in this specification show the WebRTC server as the authorization server and the client as the WebRTC client. However, WebRTC is intended to be used for illustrative purpose only π
3. Solution Overview π₯
Here's how it goes: the STUN client knows it can use OAuth 2.0 with the target STUN server either through configuration, or when it receives the new STUN attribute THIRD-PARTY-AUTHORIZATION in the error response with an error code of 401 (Unauthorized) π
This spec uses the token type 'Assertion' (a.k.a. self-contained token) described in [RFC6819], where all the info needed to check that the token is valid is inside the token itself π§ This is a big win because it avoids needing a protocol between the STUN server and the authorization server for token validation, which means less latency β‘ The content of the token is opaque to the client. The client then embeds the token within a STUN request sent to the STUN server. Once the STUN server decides the token is valid, its services are offered for a determined period of time π«Ά The access token issued by the authorization server is explained in Section 6.2. OAuth 2.0 in [RFC6749] defines four grant types. This specification uses the OAuth 2.0 grant type 'Implicit', as explained in Section 1.3.2 of [RFC6749], where the client is issued an access token directly. The string stun is defined by this specification for use as the OAuth scope parameter (see Section 3.3 of [RFC6749]) for the OAuth token π
The exact mechanism a client uses to obtain a token, plus other OAuth 2.0 parameters like token type, mac_key, token lifetime, and kid, is outside the scope of this document π Appendix B gives an example deployment scenario of the interaction between the client and authorization server to get a token and other OAuth 2.0 parameters π¦
Section 3.1 illustrates the use of OAuth 2.0 to achieve third-party authorization for TURN π
3.1. Usage with TURN π
okay so TURN is an extension to the STUN protocol, and it's basically the go-to for boosting connectivity in peer-to-peer (P2P) apps π¦ TURN makes sure a connection can still happen even when one or both sides can't do a direct P2P connection. BUT (and this is a big but) it's a relay service, so it costs the provider real money to run πΈ That's why access to a TURN service is almost always locked down π To get third-party authorization, a resource owner (say, a WebRTC server) authorizes a TURN client to access resources on the TURN server. β¨
So in this example, the WebRTC server is the resource owner, and it's the one giving a TURN client permission to use resources on a TURN server. The mapping between OAuth 2.0 terms and WebRTC terms looks like this:
+----------------------+----------------------------+
| OAuth 2.0 | WebRTC |
+======================+============================+
| Client | WebRTC client |
+----------------------+----------------------------+
| Resource owner | WebRTC server |
+----------------------+----------------------------+
| Authorization server | Authorization server |
+----------------------+----------------------------+
| Resource server | TURN server |
+----------------------+----------------------------+
Figure 1: OAuth Terminology Mapped to WebRTC Terminology
Using the OAuth 2.0 authorization framework, a WebRTC client (the third-party application) gets limited access to a TURN server (the resource server) on behalf of the WebRTC server (the resource owner or authorization server) π The WebRTC client asks for access to resources that the resource owner (WebRTC server) controls and the resource server (TURN server) hosts. The WebRTC client gets the access token, lifetime, session key, and kid. Then the TURN client passes the access token and the other OAuth 2.0 parameters it learned from the authorization server over to the TURN server. The TURN server pulls the session key out of the access token, validates the token, computes the message integrity of the request, and then takes the right action, i.e., lets the TURN client create allocations. π§ Here's the abstract version in Figure 2:
+---------------+
| +<******+
+------------->| Authorization | *
| | server | *
| +----------|(WebRTC server)| * AS-RS,
| | | | * AUTH keys
(1) | | +---------------+ * (0)
Access | | (2) *
Token | | Access Token *
request | | + *
| | Session Key *
| | *
| V V
+-------+---+ +-+----=-----+
| | (3) | |
| | TURN request + Access | |
| WebRTC | Token | TURN |
| client |---------------------->| server |
| (Alice) | Allocate response (4) | |
| |<----------------------| |
+-----------+ +------------+
User: Alice
****: Out-of-Band Long-Term Symmetric Key Establishment
Figure 2: Interactions
Now here's the vibe check π In the figure below, the TURN client sends an Allocate request to the TURN server with no credentials at all. Since the TURN server requires that every request be authenticated using OAuth 2.0, it rejects the request with a 401 (Unauthorized) error code and the STUN attribute THIRD-PARTY-AUTHORIZATION. Then the WebRTC client gets an access token from the WebRTC server, hands it to the TURN client, and the TURN client tries again, this time with the access token included in the Allocate request. This time the TURN server validates the token, accepts the Allocate request, and sends back an Allocate success response. That response includes (among other things) the relayed transport address assigned to the allocation. The glow-up is complete π
+-------------------+ +--------+ +---------+
| ......... TURN | | TURN | | WebRTC |
| .WebRTC . client | | | | |
| .client . | | server | | server |
| ......... | | | | |
+-------------------+ +--------+ +---------+
| | Allocate request | |
| |------------------------------------------>| |
| | | |
| | Allocate error response | |
| | (401 Unauthorized) | |
| |<------------------------------------------| |
| | THIRD-PARTY-AUTHORIZATION | |
| | | |
| | | |
| | HTTP request for token | |
|------------------------------------------------------------>|
| | HTTP response with token parameters | |
|<------------------------------------------------------------|
|OAuth 2.0 | |
attributes | |
|------>| | |
| | Allocate request ACCESS-TOKEN | |
| |------------------------------------------>| |
| | | |
| | Allocate success response | |
| |<------------------------------------------| |
| | TURN messages | |
| | ////// integrity protected ////// | |
| | ////// integrity protected ////// | |
| | ////// integrity protected ////// | |
Figure 3: TURN Third-Party Authorization
4. Obtaining a Token Using OAuth π
okay so before a STUN client sends anything, it needs to know whether the STUN server can even do third-party authorization π So the client starts out by making a request with no authorization at all. If the STUN server supports third-party authorization, it sends back an error saying the client can authorize to the STUN server with an OAuth 2.0 access token. That error carries an ERROR-CODE attribute with the value 401 (Unauthorized), a nonce value in a NONCE attribute, and a SOFTWARE attribute that tells you about the STUN server's software. The server also throws in the extra STUN attribute THIRD-PARTY-AUTHORIZATION, which lets the STUN client know that the server supports third-party authorization. Iconic β¨
Note: An implementation may choose to contact the authorization server to get a token even before it makes a STUN request, as long as it already knows the server details. For example, once a client has learned from an authorization server that a STUN server supports third-party authorization, it can grab the token before making any later STUN requests. Smart and efficient π§
4.1. Key Establishment ποΈ
In this model, the STUN server doesn't authenticate the client itself. Instead, it checks whether the client knows the session key tied to a specific access token. You can find an example of this approach in the OAuth 2.0 Proof-of-Possession (PoP) Security Architecture [POP-ARCH]. The authorization server shares a long-term secret (K) with the STUN server. When the client asks for an access token, the authorization server makes a fresh, unique session key (mac_key) and puts it into the token, encrypted with the long-term secret. Symmetric cryptography MUST be chosen so the encrypted token stays small. Asymmetric cryptography would produce large encrypted tokens, which might not fit into a single STUN message. π«
The STUN server and the authorization server can set up a long-term symmetric key (K) and a certain authenticated encryption algorithm through an out-of-band mechanism. The STUN and authorization servers MUST establish K over an authenticated secure channel. If authenticated encryption with AES-CBC and HMAC-SHA (defined in [ENCRYPT]) is used, then the AS-RS and AUTH keys are derived from K. The AS-RS key encrypts the self-contained token, and the message integrity of the encrypted token is calculated using the AUTH key. If the Authenticated Encryption with Associated Data (AEAD) algorithm defined in [RFC5116] is used, there's no need to generate the AUTH key, and the AS-RS key has the same value as K. π
How the long-term symmetric key gets established is outside the scope of this specification, and this specification doesn't mandate support for any particular mechanism. Sections 4.1.1 and 4.1.2 show examples of mechanisms that can be used. πΈ
4.1.1. HTTP Interactions π
The STUN and AS servers could use a Representational State Transfer (REST) API over HTTPS to establish a long-term symmetric key. HTTPS MUST be used for data confidentiality, and TLS based on a client certificate MUST be used for mutual authentication. To get a new long-term symmetric key, the STUN server makes an HTTP GET request to the authorization server. The request specifies STUN as the service that the long-term symmetric keys are allocated for, and it specifies the name of the STUN server. The response comes back with content-type application/json and contains a JavaScript Object Notation (JSON) [RFC7159] object that holds the long-term symmetric key.
Request
service - specifies the desired service (TURN)
name - STUN server name associated with the key
example:
GET https://www.example.com/.well-known/stun-key?service=stun
&name=turn1@example.com
Response
k - long-term symmetric key
exp - identifies the time after which the key expires
example:
{
"k" :
"ESIzRFVmd4iZABEiM0RVZgKn6WjLaTC1FXAghRMVTzkBGNaaN496523WIISKerLi",
"exp" : 1300819380,
"kid" :"22BIjxU93h/IgwEb"
"enc" : A256GCM
}
The authorization server must also signal kid to the STUN server, which uses it to pick the right keying material for decryption. ποΈ The parameter k is defined in Section 6.4.1 of [RFC7518], enc is defined in Section 4.1.2 of [RFC7516], kid is defined in Section 4.1.4 of [RFC7515], and exp is defined in Section 4.1.4 of [RFC7519]. A256GCM and other authenticated encryption algorithms are defined in Section 5.1 of [RFC7518]. A STUN server and authorization server implementation MUST support A256GCM as the authenticated encryption algorithm. π
If A256CBC-HS512 as defined in [RFC7518] is used, then the AS-RS and AUTH keys are derived from K using the mechanism explained in Section 5.2.2.1 of [RFC7518]. In this case, the AS-RS key length must be 256 bits and the AUTH key length must be 256 bits (Section 2.6 of [RFC4868]). π
4.1.2. Manual Provisioning β¨
okay so the STUN and AS servers can be manually set up with a long-term symmetric key, an authenticated encryption algorithm, and a kid π
Note: The mechanism specified in this section requires configuration to change the long-term symmetric key and/or authenticated encryption algorithm. Hence, a STUN server and authorization server implementation SHOULD support REST as explained in Section 4.1.1. π«Ά
5. Forming a Request π
when a STUN server replies that third-party authorization is required, the STUN client tries the request again, this time with the access token and kid values in the ACCESS-TOKEN and USERNAME STUN attributes π the client also adds a MESSAGE-INTEGRITY attribute as the last attribute in the message, computed over the contents of the STUN message. the HMAC for it is worked out as described in Section 15.4 of [RFC5389], and the mac_key is the input key for that HMAC computation. the STUN client and server both use the mac_key to compute the message integrity, and they do not do an MD5 hash on the credentials. no MD5 drama here, bestie π ββοΈ
6. STUN Attributes π¦
these are the new STUN attributes this specification brings in so third-party authorization can happen π§
6.1. THIRD-PARTY-AUTHORIZATION
this attribute is how the STUN server tells the client that it supports third-party authorization π its value holds the STUN server name. the authorization server might have tie ups with multiple STUN servers (and the other way around), so the client MUST give the STUN server name to the authorization server. that way the AS can pick the right keying material to make the self-contained token. if the authorization server does not have a tie up with the STUN server, it sends back an error to the client π¬ if the client doesn't support third-party authorization or isn't capable of doing it, it falls back to first-party authentication. the THIRD-PARTY-AUTHORIZATION attribute is a comprehension-optional attribute (see Section 15 from [RFC5389]). if the client can comprehend THIRD-PARTY-AUTHORIZATION, it MUST make sure that third-party authorization takes precedence over first-party authentication (as explained in Section 10 of [RFC5389]). main character energy for third-party auth, periodt π
6.2. ACCESS-TOKEN
the access token is issued by the authorization server π OAuth 2.0 doesn't put any limit on how long the access token can be, but if the path MTU is unknown, STUN messages over IPv4 would need to be less than 548 bytes (Section 7.1 of [RFC5389]). so the access token length has to be restricted to fit within the maximum STUN message size π also, the self-contained token is opaque to the client, and the client MUST NOT examine the token π the ACCESS-TOKEN attribute is a comprehension-required attribute (see Section 15 from [RFC5389]).
the token is structured like this:
struct {
uint16_t nonce_length;
opaque nonce[nonce_length];
opaque {
uint16_t key_length;
opaque mac_key[key_length];
uint64_t timestamp;
uint32_t lifetime;
} encrypted_block;
} token;
Figure 4: Self-Contained Token Format
Note: uintN_t means an unsigned integer of exactly N bits. Single-byte entities containing uninterpreted data are of type 'opaque'. All values in the token are stored in network byte order. π€
the fields work like this:
nonce_length: the length of the nonce field. the length of nonce for AEAD algorithms is explained in [RFC5116].Nonce: nonce (N) formation is explained in Section 3.2 of [RFC5116].key_length: the length of the session key in octets. a 160-bit key length MUST be supported (meaning only the 160-bit key is used by HMAC-SHA-1 for message integrity of STUN messages). the key length also makes the hash agility plan from Section 16.3 of [RFC5389] work π§©mac_key: the session key generated by the authorization server. ποΈtimestamp: a 64-bit unsigned integer containing a timestamp. it's the time since January 1, 1970, 00:00 UTC, in a fixed-point format. the integer number of seconds lives in the first 48 bits of the field, and the remaining 16 bits are the number of 1/64000 fractions of a second (Native format - Unix). β°lifetime: the lifetime of the access token, in seconds. so 3600 means one hour. the lifetime value MUST be greater than or equal to the 'expires_in' parameter defined in Section 4.2.2 of [RFC6749]. otherwise the resource server could revoke the token, but the client would think the token hasn't expired and wouldn't refresh it πencrypted_block: the encrypted_block (P) is encrypted and authenticated using the long-term symmetric key that's set up between the STUN server and the authorization server π
the AEAD encryption operation has four inputs: K, N, A, and P, as defined in Section 2.1 of [RFC5116]. it gives back one output, either the ciphertext C or an indication that the encryption couldn't be done π«§
the associated data (A) MUST be the STUN server name. this keeps the client from using the same token to sneak into other STUN servers run by the same administrative domain. that matters when several STUN servers in one domain share the same long-term symmetric key with an authorization server π«
if authenticated encryption with AES-CBC and HMAC-SHA (explained in Section 2.1 of [ENCRYPT]) is used, the encryption goes like this. the ciphertext is the string S with the string T appended to it. C and A stand for the ciphertext and the STUN server name. the octet string AL (Section 2.1 of [ENCRYPT]) is the number of bits in A, written as a 64-bit unsigned big-endian integer. π§
AUTH = initial authentication key length octets of K,AS-RS = final encryption key length octets of K,S = CBC-PKCS7-ENC(AS-RS, encrypted_block),- the Initialization Vector is set to zero, because the encrypted_block in each access token won't be identical, so it won't produce identical ciphertext π§
mac = MAC(AUTH, A || S || AL),T = initial T_LEN octets of mac,C = S || T.
the entire token (the 'encrypted_block') is base64 encoded (see Section 4 of [RFC4648]), and the resulting access token is sent to the client π
7. STUN Server Behavior π§ββοΈ
when the STUN server gets a request with the ACCESS-TOKEN attribute, it does the checks listed in Section 10.2.2 of [RFC5389], plus these steps to make sure the access token is valid π
- the STUN server picks the keying material based on the kid signaled in the USERNAME attribute.
- the AEAD decryption operation has four inputs: K, N, A, and C, as defined in Section 2.2 of [RFC5116]. it gives back a single output, either a plaintext or a special symbol FAIL meaning the inputs aren't authentic. if the authenticated decrypt operation returns FAIL, the STUN server rejects the request with an error response 401 (Unauthorized). π¨
- if AES_CBC_HMAC_SHA2 is used, the final T_LEN octets are stripped from C. the server then checks token message integrity by computing an HMAC over the STUN server name, the encrypted portion of the self-contained token, and the AL, using the AUTH key. if the result doesn't match the mac field in the self-contained token, it rejects the request with an error response 401 (Unauthorized). π ββοΈ
- the STUN server gets the mac_key by pulling out the content of the access token (which needs the self-contained token decrypted with the AS-RS key). π
- the STUN server checks for replay with this check:
- the access token is accepted if the timestamp field (TS) in the self-contained token is shortly before the reception time of the STUN request (RDnew). the formula is:
lifetime + Delta > abs(RDnew - TS)
the RECOMMENDED value for the allowed Delta is 5 seconds. if the timestamp is not within the boundaries, the STUN server discards the request with error response 401 (Unauthorized). β³
- the STUN server uses the mac_key to compute the message integrity over the request. if the result doesn't match the contents of the MESSAGE-INTEGRITY attribute, it rejects the request with an error response 401 (Unauthorized). π
- if all the checks pass, the STUN server keeps processing the request. β
- any response the server generates MUST include the MESSAGE-INTEGRITY attribute, computed using the mac_key. π«Ά
if a STUN server gets an ACCESS-TOKEN attribute unexpectedly (because it never sent out a THIRD-PARTY-AUTHORIZATION), it responds with an error code of 420 (Unknown Attribute), as specified in Section 7.3.1 of [RFC5389]. π€·ββοΈ
8. STUN Client Behavior π
- the client looks for the MESSAGE-INTEGRITY attribute in the response. if MESSAGE-INTEGRITY is absent, or the value computed for message integrity using mac_key doesn't match the contents of the MESSAGE-INTEGRITY attribute, the response MUST be discarded. ποΈ
- if the access token expires, the client MUST get a new token from the authorization server and use it for new STUN requests. π
9. TURN Client and Server Behavior πΈ
changes specific to TURN are listed below π¦
- the access token can be reused for multiple Allocate requests to the same TURN server. the TURN client MUST include the ACCESS-TOKEN attribute only in Allocate and Refresh requests. since the access token is valid for a specific period of time, the TURN server can cache it. then it can check whether the access token in a new allocation request matches one of the cached tokens, and skip decrypting the token π§
- the lifetime the TURN server provides in the Allocate and Refresh responses MUST be less than or equal to the lifetime of the token. it's RECOMMENDED that the TURN server work out the maximum allowed lifetime value with this formula:
lifetime + Delta - abs(RDnew - TS)
the RECOMMENDED value for the allowed Delta is 5 seconds. β±οΈ
- if the access token expires, the client MUST get a new token from the authorization server and use it for new allocations. the client MUST use the new token to refresh existing allocations. this way, the client only has to keep one token per TURN server π
10. Operational Considerations β¨
Okay, time to talk about the stuff you need to set up in the real world π οΈ. Here are the operational considerations to keep in mind:
- Each authorization server should keep a list of the STUN servers it will hand tokens out for, plus the long-term secret it shares with each one π.
- If you go with manual configuration (Section 4.1.2) to set up long-term symmetric keys, you have to configure the long-term secret (K) and the authenticated encryption algorithm on every authorization server and every STUN server, for each kid. The client gets the session key and HMAC algorithm from the authorization server along with the token π.
- When a STUN client asks for access to a particular STUN server (S), the authorization server must make sure it picks the right kid and access token for server S π―.
11. Security Considerations π¨π
Okay, this section is the serious one, bestie, so read it carefully π₯Ή. When OAuth 2.0 is in play, the conversation between the client and the authorization server needs Transport Layer Security (TLS) with a ciphersuite that gives confidentiality protection, and you have to follow the guidance in [RFC7525] to dodge attacks on TLS. The session key MUST NOT be sent in the clear, because that would totally wreck the security benefits of this scheme π. An attacker who tries to replay a message carrying the ACCESS-TOKEN attribute can be shut down by changing the nonce often, as talked about in Section 10.2 of [RFC5389] π. The client might know some (but not all) of the token fields, which are encrypted with a secret key nobody outside knows, and the token can be hit with known-plaintext attacks. Good news though: AES is secure against this attack π‘οΈ.
Watch out for this one π: an attacker could strip the THIRD-PARTY-AUTHORIZATION STUN attribute out of the error message, which forces the client to fall back to first-party authentication. You can help mitigate this by using TLS [RFC5246] or Datagram Transport Layer Security (DTLS) [RFC6347] as the transport protocol for STUN, as defined in [RFC5389]and [RFC7350] π§±.
Also make sure you take into account the threat mitigation discussed in Section 5 of [POP-ARCH], plus the security considerations in [RFC5389] π.
12. IANA Considerations π
This document defines the THIRD-PARTY-AUTHORIZATION STUN attribute, which you can read about in Section 6. IANA has given this attribute the comprehension-optional codepoint 0x802E π.
This document also defines the ACCESS-TOKEN STUN attribute, described in Section 6. IANA has given this one the comprehension-required codepoint 0x001B π.
12.1. Well-Known 'stun-key' URI π
This memo registers the 'stun-key' well-known URI in the Well-Known URIs registry, as defined by [RFC5785] π. Here's what goes in the registry:
URI suffix: stun-key
Change controller: IETF
Specification document(s): This RFC
Related information: None
13. References π
13.1. Normative References
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<http://www.rfc-editor.org/info/rfc2119>.
[RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data
Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006,
<http://www.rfc-editor.org/info/rfc4648>.
[RFC4868] Kelly, S. and S. Frankel, "Using HMAC-SHA-256,
HMAC-SHA-384, and HMAC-SHA-512 with IPsec", RFC 4868,
DOI 10.17487/RFC4868, May 2007,
<http://www.rfc-editor.org/info/rfc4868>.
[RFC5116] McGrew, D., "An Interface and Algorithms for Authenticated
Encryption", RFC 5116, DOI 10.17487/RFC5116, January 2008,
<http://www.rfc-editor.org/info/rfc5116>.
[RFC5389] Rosenberg, J., Mahy, R., Matthews, P., and D. Wing,
"Session Traversal Utilities for NAT (STUN)", RFC 5389,
DOI 10.17487/RFC5389, October 2008,
<http://www.rfc-editor.org/info/rfc5389>.
[RFC6749] Hardt, D., Ed., "The OAuth 2.0 Authorization Framework",
RFC 6749, DOI 10.17487/RFC6749, October 2012,
<http://www.rfc-editor.org/info/rfc6749>.
[RFC7518] Jones, M., "JSON Web Algorithms (JWA)", RFC 7518,
DOI 10.17487/RFC7518, May 2015,
<http://www.rfc-editor.org/info/rfc7518>.
13.2. Informative References
[ENCRYPT] McGrew, D., Foley, J., and K. Paterson, "Authenticated
Encryption with AES-CBC and HMAC-SHA", Work in Progress,
draft-mcgrew-aead-aes-cbc-hmac-sha2-05, July 2014.
[POP-ARCH] Hunt, P., Richer, J., Mills, W., Mishra, P., and H.
Tschofenig, "OAuth 2.0 Proof-of-Possession (PoP) Security
Architecture", Work in Progress,
draft-ietf-oauth-pop-architecture-02, July 2015.
[POP-KEY-DIST]
Bradley, J., Hunt, P., Jones, M., and H. Tschofenig,
"OAuth 2.0 Proof-of-Possession: Authorization Server to
Client Key Distribution", Work in Progress,
draft-ietf-oauth-pop-key-distribution-01, March 2015.
[RFC5246] Dierks, T. and E. Rescorla, "The Transport Layer Security
(TLS) Protocol Version 1.2", RFC 5246,
DOI 10.17487/RFC5246, August 2008,
<http://www.rfc-editor.org/info/rfc5246>.
[RFC5766] Mahy, R., Matthews, P., and J. Rosenberg, "Traversal Using
Relays around NAT (TURN): Relay Extensions to Session
Traversal Utilities for NAT (STUN)", RFC 5766,
DOI 10.17487/RFC5766, April 2010,
<http://www.rfc-editor.org/info/rfc5766>.
[RFC5785] Nottingham, M. and E. Hammer-Lahav, "Defining Well-Known
Uniform Resource Identifiers (URIs)", RFC 5785,
DOI 10.17487/RFC5785, April 2010,
<http://www.rfc-editor.org/info/rfc5785>.
[RFC6347] Rescorla, E. and N. Modadugu, "Datagram Transport Layer
Security Version 1.2", RFC 6347, DOI 10.17487/RFC6347,
January 2012, <http://www.rfc-editor.org/info/rfc6347>.
[RFC6819] Lodderstedt, T., Ed., McGloin, M., and P. Hunt, "OAuth 2.0
Threat Model and Security Considerations", RFC 6819,
DOI 10.17487/RFC6819, January 2013,
<http://www.rfc-editor.org/info/rfc6819>.
[RFC7159] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data
Interchange Format", RFC 7159, DOI 10.17487/RFC7159, March
2014, <http://www.rfc-editor.org/info/rfc7159>.
[RFC7350] Petit-Huguenin, M. and G. Salgueiro, "Datagram Transport
Layer Security (DTLS) as Transport for Session Traversal
Utilities for NAT (STUN)", RFC 7350, DOI 10.17487/RFC7350,
August 2014, <http://www.rfc-editor.org/info/rfc7350>.
[RFC7376] Reddy, T., Ravindranath, R., Perumal, M., and A. Yegin,
"Problems with Session Traversal Utilities for NAT (STUN)
Long-Term Authentication for Traversal Using Relays around
NAT (TURN)", RFC 7376, DOI 10.17487/RFC7376, September
2014, <http://www.rfc-editor.org/info/rfc7376>.
[RFC7515] Jones, M., Bradley, J., and N. Sakimura, "JSON Web
Signature (JWS)", RFC 7515, DOI 10.17487/RFC7515, May
2015, <http://www.rfc-editor.org/info/rfc7515>.
[RFC7516] Jones, M. and J. Hildebrand, "JSON Web Encryption (JWE)",
RFC 7516, DOI 10.17487/RFC7516, May 2015,
<http://www.rfc-editor.org/info/rfc7516>.
[RFC7519] Jones, M., Bradley, J., and N. Sakimura, "JSON Web Token
(JWT)", RFC 7519, DOI 10.17487/RFC7519, May 2015,
<http://www.rfc-editor.org/info/rfc7519>.
[RFC7525] Sheffer, Y., Holz, R., and P. Saint-Andre,
"Recommendations for Secure Use of Transport Layer
Security (TLS) and Datagram Transport Layer Security
(DTLS)", BCP 195, RFC 7525, DOI 10.17487/RFC7525, May
2015, <http://www.rfc-editor.org/info/rfc7525>.
[STUN] Petit-Huguenin, M., Salgueiro, G., Rosenberg, J., Wing,
D., Mahy, R., and P. Matthews, "Session Traversal
Utilities for NAT (STUN)", Work in Progress,
draft-ietf-tram-stunbis-04, March 2015.
[WEBRTC] Alvestrand, H., "Overview: Real Time Protocols for
Browser-based Applications", Work in Progress, draft-ietf-
rtcweb-overview-14, June 2015.
Appendix A. Sample Tickets ποΈβ¨
Here's the input data, which is the same for all of the samples below π :
//STUN SERVER NAME
server_name = "blackdow.carleon.gov";
//Shared key between AS and RS
long_term_key = \x48\x47\x6b\x6a\x33\x32\x4b\x4a\x47\x69\x75\x79
\x30\x39\x38\x73\x64\x66\x61\x71\x62\x4e\x6a\x4f
\x69\x61\x7a\x37\x31\x39\x32\x33
//MAC key of the session (included in the token)
mac_key = \x5a\x6b\x73\x6a\x70\x77\x65\x6f\x69\x78\x58\x6d\x76\x6e
\x36\x37\x35\x33\x34\x6d;
//length of the MAC key
mac_key_length = 20;
//The timestamp field in the token
token_timestamp = 92470300704768;
//The lifetime of the token
token_lifetime = 3600;
//nonce for AEAD
aead_nonce = \x68\x34\x6a\x33\x6b\x32\x6c\x32\x6e\x34\x62\x35;
Now for the samples π¦.
1) token encryption algorithm = AEAD_AES_256_GCM
Encrypted token (64 bytes = 2 + 12 + 34 + 16) =
\x00\x0c\x68\x34\x6a\x33\x6b\x32\x6c\x32\x6e\x34\x62
\x35\x61\x7e\xf1\x34\xa3\xd5\xe4\x4e\x9a\x19\xcc\x7d
\xc1\x04\xb0\xc0\x3d\x03\xb2\xa5\x51\xd8\xfd\xf5\xcd
\x3b\x6d\xca\x6f\x10\xcf\xb7\x7e\x5b\x2d\xde\xc8\x4d
\x29\x3a\x5c\x50\x49\x93\x59\xf0\xc2\xe2\x6f\x76
2) token encryption algorithm = AEAD_AES_128_GCM
Encrypted token (64 bytes = 2 + 12 + 34 + 16) =
\x00\x0c\x68\x34\x6a\x33\x6b\x32\x6c\x32\x6e\x34\x62
\x35\x7f\xb9\xe9\x9f\x08\x27\xbe\x3d\xf1\xe1\xbd\x65
\x14\x93\xd3\x03\x1d\x36\xdf\x57\x07\x97\x84\xae\xe5
\xea\xcb\x65\xfa\xd4\xf2\x7f\xab\x1a\x3f\x97\x97\x4b
\x69\xf8\x51\xb2\x4b\xf5\xaf\x09\xed\xa3\x57\xe0
Two quick notes on the code side π§βπ»:
- [1] After
EVP_EncryptFinal_exencrypts the final data, you have to callEVP_CIPHER_CTX_ctrlto stick the authentication tag onto the ciphertext://EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, taglen, tag); - [2] Before calling
EVP_DecryptFinal, you must invokeEVP_CIPHER_CTX_ctrlto set the authentication tag://EVP_CIPHER_CTX_ctrl (&ctx, EVP_CTRL_GCM_SET_TAG, taglen, tag);
Figure 5: Sample Tickets πΈ
Appendix B. Interaction between the Client and Authorization Server β¨
okay so this appendix is about how the client actually gets its STUN token from an authorization server π the client sends an HTTP request to the auth server to grab a token it can use for STUN services, and the token comes back as JSON [RFC7159] π along with the other OAuth 2.0 parameters, like token type, key, token lifetime, and kid, all defined in [POP-KEY-DIST] π¦
+-------------------+ +--------+ +---------+
| ......... STUN | | STUN | | WebRTC |
| .WebRTC . client | | | | |
| .client . | | server | | server |
| ......... | | | | |
+-------------------+ +--------+ +---------+
| | STUN request | |
| |------------------------------------------>| |
| | | |
| | STUN error response | |
| | (401 Unauthorized) | |
| |<------------------------------------------| |
| | THIRD-PARTY-AUTHORIZATION | |
| | | |
| | | |
| | HTTP request for token | |
|------------------------------------------------------------>|
| | HTTP response with token parameters | |
|<------------------------------------------------------------|
|OAuth 2.0 | |
attributes | |
|------>| | |
| | STUN request with ACCESS-TOKEN | |
| |------------------------------------------>| |
| | | |
| | STUN success response | |
| |<------------------------------------------| |
| | STUN messages | |
| | ////// integrity protected ////// | |
| | ////// integrity protected ////// | |
| | ////// integrity protected ////// | |
Figure 6: STUN Third-Party Authorization π
[POP-KEY-DIST] is the doc that explains the whole client-to-auth-server chat π for example, the client learns the STUN server name "stun1@example.com" from the THIRD-PARTY-AUTHORIZATION attribute value π§ then it makes this HTTP request for the access token over TLS (the extra line breaks are just there so it's easier to read, they aren't part of the real thing) π«Ά
HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded
aud=stun1@example.com
timestamp=1361471629
grant_type=implicit
token_type=pop
alg=HMAC-SHA-256-128
Figure 7: Request π
okay now the hash agility part is β¨iconicβ¨ π₯ [STUN] supports hash agility, and it pulls that off by computing message integrity with both HMAC-SHA-1 and HMAC-SHA-256-128 π the client tells the auth server which algorithm it supports using the 'alg' parameter from [POP-KEY-DIST] π¦ then the auth server works out how long the mac_key needs to be based on the HMAC algorithm the client sent πΈ
and here's the lowkey clever bit π§ if the client supports both HMAC-SHA-1 and HMAC-SHA-256-128, it signals HMAC-SHA-256-128, gets a 256-bit key back from the auth server, and then calculates a 160-bit key for HMAC-SHA-1 by running SHA1 over that 256-bit key as input π main character energy, fr fr π
if the client is authorized, the auth server issues an access token π here's what a successful response looks like:
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
{
"access_token":
"U2FsdGVkX18qJK/kkWmRcnfHglrVTJSpS6yU32kmHmOrfGyI3m1gQj1jRPsr0uBb
HctuycAgsfRX7nJW2BdukGyKMXSiNGNnBzigkAofP6+Z3vkJ1Q5pWbfSRroOkWBn",
"token_type":"pop",
"expires_in":1800,
"kid":"22BIjxU93h/IgwEb",
"key":"v51N62OM65kyMvfTI08O"
"alg":HMAC-SHA-256-128
}
Figure 8: Response π
Acknowledgements π«Ά
the authors want to thank Dan Wing, Pal Martinsen, Oleg Moskalenko, Charles Eckel, Spencer Dawkins, Hannes Tschofenig, Yaron Sheffer, Tom Taylor, Christer Holmberg, Pete Resnick, Kathleen Moriarty, Richard Barnes, Stephen Farrell, Alissa Cooper, and Rich Salz for their comments and review π they also want to give a special shoutout to Brandon Williams for his help π
and thank you to Oleg Moskalenko for providing the token samples in Appendix A π§β¨
Authors' Addresses πΈ
Tirumaleswar Reddy Cisco Systems, Inc. Cessna Business Park, Varthur Hobli Sarjapur Marathalli Outer Ring Road Bangalore, Karnataka 560103 India Email: tireddy@cisco.com
Prashanth Patil Cisco Systems, Inc. Bangalore India Email: praspati@cisco.com
Ram Mohan Ravindranath Cisco Systems, Inc. Cessna Business Park, Kadabeesanahalli Village, Varthur Hobli, Sarjapur-Marathahalli Outer Ring Road Bangalore, Karnataka 560103 India Email: rmohanr@cisco.com
Justin Uberti Google 747 6th Ave S. Kirkland, WA 98033 United States Email: justin@uberti.name
π¦ where this page comes from
- ietf: rfc7635 2015-08
- π girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms