< draft-ietf-tram-turn-third-party-authz-14.txt   draft-ietf-tram-turn-third-party-authz-15.txt >
TRAM T. Reddy TRAM T. Reddy
Internet-Draft P. Patil Internet-Draft P. Patil
Intended status: Standards Track R. Ravindranath Intended status: Standards Track R. Ravindranath
Expires: October 17, 2015 Cisco Expires: October 23, 2015 Cisco
J. Uberti J. Uberti
Google Google
April 15, 2015 April 21, 2015
Session Traversal Utilities for NAT (STUN) Extension for Third Party Session Traversal Utilities for NAT (STUN) Extension for Third Party
Authorization Authorization
draft-ietf-tram-turn-third-party-authz-14 draft-ietf-tram-turn-third-party-authz-15
Abstract Abstract
This document proposes the use of OAuth 2.0 to obtain and validate This document proposes the use of OAuth 2.0 to obtain and validate
ephemeral tokens that can be used for Session Traversal Utilities for ephemeral tokens that can be used for Session Traversal Utilities for
NAT (STUN) authentication. The usage of ephemeral tokens ensures NAT (STUN) authentication. The usage of ephemeral tokens ensures
that access to a STUN server can be controlled even if the tokens are that access to a STUN server can be controlled even if the tokens are
compromised. compromised.
Status of This Memo Status of This Memo
skipping to change at page 1, line 38 skipping to change at page 1, line 38
Internet-Drafts are working documents of the Internet Engineering Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet- working documents as Internet-Drafts. The list of current Internet-
Drafts is at http://datatracker.ietf.org/drafts/current/. Drafts is at http://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress." material or to cite them other than as "work in progress."
This Internet-Draft will expire on October 17, 2015. This Internet-Draft will expire on October 23, 2015.
Copyright Notice Copyright Notice
Copyright (c) 2015 IETF Trust and the persons identified as the Copyright (c) 2015 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents Provisions Relating to IETF Documents
(http://trustee.ietf.org/license-info) in effect on the date of (http://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents publication of this document. Please review these documents
skipping to change at page 2, line 14 skipping to change at page 2, line 14
to this document. Code Components extracted from this document must to this document. Code Components extracted from this document must
include Simplified BSD License text as described in Section 4.e of include Simplified BSD License text as described in Section 4.e of
the Trust Legal Provisions and are provided without warranty as the Trust Legal Provisions and are provided without warranty as
described in the Simplified BSD License. described in the Simplified BSD License.
Table of Contents Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2
2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 3 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 3
3. Solution Overview . . . . . . . . . . . . . . . . . . . . . . 3 3. Solution Overview . . . . . . . . . . . . . . . . . . . . . . 3
4. Obtaining a Token Using OAuth . . . . . . . . . . . . . . . . 4 3.1. TURN . . . . . . . . . . . . . . . . . . . . . . . . . . 4
4.1. Key Establishment . . . . . . . . . . . . . . . . . . . . 4 4. Obtaining a Token Using OAuth . . . . . . . . . . . . . . . . 7
4.1.1. HTTP interactions . . . . . . . . . . . . . . . . . . 5 4.1. Key Establishment . . . . . . . . . . . . . . . . . . . . 8
4.1.2. Manual provisioning . . . . . . . . . . . . . . . . . 7 4.1.1. HTTP interactions . . . . . . . . . . . . . . . . . . 8
5. Forming a Request . . . . . . . . . . . . . . . . . . . . . . 7 4.1.2. Manual provisioning . . . . . . . . . . . . . . . . . 10
6. STUN Attributes . . . . . . . . . . . . . . . . . . . . . . . 7 5. Forming a Request . . . . . . . . . . . . . . . . . . . . . . 10
6.1. THIRD-PARTY-AUTHORIZATION . . . . . . . . . . . . . . . . 7 6. STUN Attributes . . . . . . . . . . . . . . . . . . . . . . . 10
6.2. ACCESS-TOKEN . . . . . . . . . . . . . . . . . . . . . . 8 6.1. THIRD-PARTY-AUTHORIZATION . . . . . . . . . . . . . . . . 10
7. STUN Server Behaviour . . . . . . . . . . . . . . . . . . . . 10 6.2. ACCESS-TOKEN . . . . . . . . . . . . . . . . . . . . . . 11
8. STUN Client Behaviour . . . . . . . . . . . . . . . . . . . . 11 7. STUN Server Behaviour . . . . . . . . . . . . . . . . . . . . 13
9. Usage with TURN . . . . . . . . . . . . . . . . . . . . . . . 11 8. STUN client behaviour . . . . . . . . . . . . . . . . . . . . 14
9. TURN client and server behaviour . . . . . . . . . . . . . . 14
10. Operational Considerations . . . . . . . . . . . . . . . . . 15 10. Operational Considerations . . . . . . . . . . . . . . . . . 15
11. Security Considerations . . . . . . . . . . . . . . . . . . . 15 11. Security Considerations . . . . . . . . . . . . . . . . . . . 15
12. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 16 12. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 16
13. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 16 13. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 16
14. References . . . . . . . . . . . . . . . . . . . . . . . . . 16 14. References . . . . . . . . . . . . . . . . . . . . . . . . . 16
14.1. Normative References . . . . . . . . . . . . . . . . . . 17 14.1. Normative References . . . . . . . . . . . . . . . . . . 16
14.2. Informative References . . . . . . . . . . . . . . . . . 17 14.2. Informative References . . . . . . . . . . . . . . . . . 17
Appendix A. Sample tickets . . . . . . . . . . . . . . . . . . . 19 Appendix A. C Snippet to encrypt/decrypt token . . . . . . . . . 19
Appendix B. Interaction between client and authorization server 20 Appendix B. Interaction between client and authorization server 26
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 22 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 28
1. Introduction 1. Introduction
Session Traversal Utilities for NAT (STUN) [RFC5389] provides a Session Traversal Utilities for NAT (STUN) [RFC5389] provides a
mechanism to control access via "long-term" username/ password mechanism to control access via "long-term" username/ password
credentials that are provided as part of the STUN protocol. It is credentials that are provided as part of the STUN protocol. It is
expected that these credentials will be kept secret; if the expected that these credentials will be kept secret; if the
credentials are discovered, the STUN server could be used by credentials are discovered, the STUN server could be used by
unauthorized users or applications. However, in web applications unauthorized users or applications. However, in web applications
like WebRTC [I-D.ietf-rtcweb-overview] where JavaScript uses the like WebRTC [I-D.ietf-rtcweb-overview] where JavaScript uses the
skipping to change at page 3, line 18 skipping to change at page 3, line 19
services. Third party authorization using OAuth 2.0 for STUN services. Third party authorization using OAuth 2.0 for STUN
explained in this specification can also be used with Traversal Using explained in this specification can also be used with Traversal Using
Relays around NAT (TURN) [RFC5766]. Relays around NAT (TURN) [RFC5766].
2. Terminology 2. Terminology
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in [RFC2119]. document are to be interpreted as described in [RFC2119].
This document uses the following abbreviations:
o WebRTC Server: A web server that supports WebRTC o WebRTC Server: A web server that supports WebRTC
[I-D.ietf-rtcweb-overview]. [I-D.ietf-rtcweb-overview].
o Access Token: OAuth 2.0 access token. o Access Token: OAuth 2.0 access token.
o mac_key: The session key generated by the authorization server. o mac_key: The session key generated by the authorization server.
This session key has a lifetime that corresponds to the lifetime This session key has a lifetime that corresponds to the lifetime
of the access token, is generated by the authorization server and of the access token, is generated by the authorization server and
bound to the access token. bound to the access token.
o kid: An ephemeral and unique key identifier. The kid also allows o kid: An ephemeral and unique key identifier. The kid also allows
the resource server to select the appropriate keying material for the resource server to select the appropriate keying material for
decryption. decryption.
o AS: Authorization server
Some sections in this specification show WebRTC server as the Some sections in this specification show WebRTC server as the
authorization server and client as the WebRTC client, however WebRTC authorization server and client as the WebRTC client, however WebRTC
is intended to be used for illustrative purpose only. is intended to be used for illustrative purpose only.
3. Solution Overview 3. Solution Overview
STUN client knows that it can use OAuth 2.0 with the target STUN STUN client knows that it can use OAuth 2.0 with the target STUN
server either through configuration or when it receives the new STUN server either through configuration or when it receives the new STUN
attribute THIRD-PARTY-AUTHORIZATION in the error response with an attribute THIRD-PARTY-AUTHORIZATION in the error response with an
error code of 401(Unauthorized). error code of 401(Unauthorized).
skipping to change at page 4, line 12 skipping to change at page 4, line 17
request sent to the STUN server. Once the STUN server has determined request sent to the STUN server. Once the STUN server has determined
the token is valid, its services are offered for a determined period the token is valid, its services are offered for a determined period
of time. Access token issued by the authorization server is of time. Access token issued by the authorization server is
explained in Section 6.2. OAuth 2.0 in [RFC6749] defines four grant explained in Section 6.2. OAuth 2.0 in [RFC6749] defines four grant
types. This specification uses the OAuth 2.0 grant type "Implicit" types. This specification uses the OAuth 2.0 grant type "Implicit"
explained in section 1.3.2 of [RFC6749] where the client is issued an explained in section 1.3.2 of [RFC6749] where the client is issued an
access token directly. The string 'stun' is defined by this access token directly. The string 'stun' is defined by this
specification for use as the OAuth scope parameter (see section 3.3 specification for use as the OAuth scope parameter (see section 3.3
of [RFC6749]) for the OAuth token. of [RFC6749]) for the OAuth token.
The exact mechanism used by a client to obtain a token from the OAuth The exact mechanism used by a client to obtain a token and other
2.0 authorization server is outside the scope of this document. OAuth 2.0 parameters like token type, mac_key, token lifetime and kid
Appendix B provides an example deployment scenario of interaction is outside the scope of this document. Appendix B provides an
between the client and authorization server to obtain a token. example deployment scenario of interaction between the client and
authorization server to obtain a token and other OAuth 2.0
parameters.
Consider the following example that illustrates the use of OAuth 2.0
to achieve third party authorization for Traversal Using Relay NAT
(TURN) [RFC5766] .
3.1. TURN
TURN an extension to the STUN protocol is often used to improve the
connectivity of P2P applications. TURN ensures that a connection can
be established even when one or both sides is incapable of a direct
P2P connection. However, as a relay service, it imposes a nontrivial
cost on the service provider. Therefore, access to a TURN service is
almost always access-controlled. In order to achieve third party
authorization, a resource owner e.g. WebRTC server, authorizes a
TURN client to access resources on the TURN server.
In this example, a resource owner i.e., WebRTC server, authorizes a
TURN client to access resources on a TURN server.
+----------------------+----------------------------+
| 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 (third-
party application) obtains limited access to a TURN (resource server)
on behalf of the WebRTC server (resource owner or authorization
server). The WebRTC client requests access to resources controlled
by the resource owner (WebRTC server) and hosted by the resource
server (TURN server). The WebRTC client obtains access token,
lifetime, session key and kid. The TURN client conveys the access
token and other OAuth 2.0 parameters learnt from the authorization
server to the TURN server. The TURN server obtains the session key
from the access token. The TURN server validates the token, computes
the message integrity of the request and takes appropriate action
i.e, permits the TURN client to create allocations. This is shown in
an abstract way in Figure 2.
+---------------+
| +<******+
+------------->| Authorization | *
| | Server | *
| +----------|(WebRTC Server)| * AS-RS,
| | | | * AUTH keys
(2) | | +---------------+ * (1)
Access | | (3) *
Token | | Access Token *
Request | | + *
| | Session Key *
| | *
| V V
+-------+---+ +-+----=-----+
| | (4) | |
| | TURN Request + Access | |
| WebRTC | Token | TURN |
| Client |---------------------->| Server |
| (Alice) | Allocate Response (5) | |
| |<----------------------| |
+-----------+ +------------+
User : Alice
****: Out-of-Band Long-Term Key Establishment
Figure 2: Interactions
In the below figure, the client sends an Allocate request to the
server without credentials. Since the server requires that all
requests be authenticated using OAuth 2.0, the server rejects the
request with a 401 (Unauthorized) error code and STUN attribute
THIRD-PARTY-AUTHORIZATION. The WebRTC client obtains access token
from the WebRTC server and then tries again, this time including
access token. This time, the server validates the token, accepts the
Allocate request and returns an Allocate success response containing
(amongst other things) the relayed transport address assigned to the
allocation.
+-------------------+ +--------+ +---------+
| ......... 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 4. Obtaining a Token Using OAuth
A STUN client needs to know the authentication capability of the STUN A STUN client needs to know the authentication capability of the STUN
server before deciding to use third party authorization. A STUN server before deciding to use third party authorization. A STUN
client initially makes a request without any authorization. If the client initially makes a request without any authorization. If the
STUN server supports third party authorization, it will return an STUN server supports third party authorization, it will return an
error message indicating that the client can authorize to the STUN error message indicating that the client can authorize to the STUN
server using an OAuth 2.0 access token. The STUN server includes an server using an OAuth 2.0 access token. The STUN server includes an
ERROR-CODE attribute with a value of 401 (Unauthorized), a nonce ERROR-CODE attribute with a value of 401 (Unauthorized), a nonce
skipping to change at page 6, line 25 skipping to change at page 9, line 29
k - Long-term key (K) k - Long-term key (K)
exp - identifies the time after which the key expires. exp - identifies the time after which the key expires.
example: example:
{ {
"k" : "k" :
"ESIzRFVmd4iZABEiM0RVZgKn6WjLaTC1FXAghRMVTzkBGNaaN496523WIISKerLi", "ESIzRFVmd4iZABEiM0RVZgKn6WjLaTC1FXAghRMVTzkBGNaaN496523WIISKerLi",
"exp" : 1300819380, "exp" : 1300819380,
"kid" :"22BIjxU93h/IgwEb" "kid" :"22BIjxU93h/IgwEb"
"enc" : A256GCMKW "enc" : A256GCM
} }
The authorization server must also signal kid to the STUN server The authorization server must also signal kid to the STUN server
which will be used to select the appropriate keying material for which will be used to select the appropriate keying material for
decryption. The parameter "k" is defined in Section 6.4.1 of decryption. The parameter "k" is defined in Section 6.4.1 of
[I-D.ietf-jose-json-web-algorithms], "enc" is defined in [I-D.ietf-jose-json-web-algorithms], "enc" is defined in
Section 4.1.2 of [I-D.ietf-jose-json-web-encryption], "kid" is Section 4.1.2 of [I-D.ietf-jose-json-web-encryption], "kid" is
defined in Section 4.1.4 of [I-D.ietf-jose-json-web-signature] and defined in Section 4.1.4 of [I-D.ietf-jose-json-web-signature] and
"exp" is defined in Section 4.1.4 of [I-D.ietf-oauth-json-web-token]. "exp" is defined in Section 4.1.4 of [I-D.ietf-oauth-json-web-token].
A256GCMKW and other authenticated encryption algorithms are defined A256GCM and other authenticated encryption algorithms are defined in
in [I-D.ietf-jose-json-web-algorithms]. A STUN server and section 5.1 of [I-D.ietf-jose-json-web-algorithms]. A STUN server
authorization server implementation MUST support A256GCMKW as the and authorization server implementation MUST support A256GCM as the
authenticated encryption algorithm. authenticated encryption algorithm.
If A256CBC-HS512 defined in [I-D.ietf-jose-json-web-algorithms] is If A256CBC-HS512 defined in [I-D.ietf-jose-json-web-algorithms] is
used then the AS-RS and AUTH keys are derived from K using the used then the AS-RS and AUTH keys are derived from K using the
mechanism explained in section 5.2.2.1 of mechanism explained in section 5.2.2.1 of
[I-D.ietf-jose-json-web-algorithms]. In this case AS-RS key length [I-D.ietf-jose-json-web-algorithms]. In this case AS-RS key length
must be 256-bit, AUTH key length must be 256-bit (section 2.6 of must be 256-bit, AUTH key length must be 256-bit (section 2.6 of
[RFC4868]). [RFC4868]).
4.1.2. Manual provisioning 4.1.2. Manual provisioning
skipping to change at page 8, line 29 skipping to change at page 11, line 29
uint16_t nonce_length; uint16_t nonce_length;
opaque nonce[nonce_length]; opaque nonce[nonce_length];
opaque { opaque {
uint16_t key_length; uint16_t key_length;
opaque mac_key[key_length]; opaque mac_key[key_length];
uint64_t timestamp; uint64_t timestamp;
uint32_t lifetime; uint32_t lifetime;
} encrypted_block; } encrypted_block;
} token; } token;
Figure 1: Self-contained token format Figure 4: Self-contained token format
Note: uintN_t means an unsigned integer of exactly N bits. Single- Note: uintN_t means an unsigned integer of exactly N bits. Single-
byte entities containing uninterpreted data are of type opaque. All byte entities containing uninterpreted data are of type opaque. All
values in the token are stored in network byte order. values in the token are stored in network byte order.
The associated data (A) MUST be the STUN server name. This ensures The associated data (A) MUST be the STUN server name. This ensures
that the client does not use the same token to gain illegal access to that the client does not use the same token to gain illegal access to
other STUN servers provided by the same administrative domain i.e., other STUN servers provided by the same administrative domain i.e.,
when multiple STUN servers in a single administrative domain share when multiple STUN servers in a single administrative domain share
the same symmetric key with an authorization server. the same symmetric key with an authorization server.
skipping to change at page 9, line 44 skipping to change at page 12, line 44
process is illustrated below. The ciphertext consists of the string process is illustrated below. The ciphertext consists of the string
S, with the string T appended to it. Here C and A denote Ciphertext S, with the string T appended to it. Here C and A denote Ciphertext
and STUN server name respectively. The octet string AL (section 2.1 and STUN server name respectively. The octet string AL (section 2.1
of [I-D.mcgrew-aead-aes-cbc-hmac-sha2]) is equal to the number of of [I-D.mcgrew-aead-aes-cbc-hmac-sha2]) is equal to the number of
bits in A expressed as a 64-bit unsigned big endian integer. bits in A expressed as a 64-bit unsigned big endian integer.
o AUTH = initial authentication key length octets of K, o AUTH = initial authentication key length octets of K,
o AS-RS = final encryption key length octets of K, o AS-RS = final encryption key length octets of K,
o S = CBC-PKCS5-ENC(AS-RS, encrypted_block), o S = CBC-PKCS7-ENC(AS-RS, encrypted_block),
* Initialization vector is set to zero because the * Initialization vector is set to zero because the
encrypted_block in each access token will not be identical and encrypted_block in each access token will not be identical and
hence will not result in generation of identical ciphertext. hence will not result in generation of identical ciphertext.
o mac = MAC(AUTH, A || S || AL), o mac = MAC(AUTH, A || S || AL),
o T = initial T_LEN octets of mac, o T = initial T_LEN octets of mac,
o C = S || T. o C = S || T.
skipping to change at page 11, line 19 skipping to change at page 14, line 19
o If all the checks pass, the STUN server continues to process the o If all the checks pass, the STUN server continues to process the
request. Any response generated by the server MUST include the request. Any response generated by the server MUST include the
MESSAGE-INTEGRITY attribute, computed using the mac_key. MESSAGE-INTEGRITY attribute, computed using the mac_key.
If a STUN server receives an ACCESS-TOKEN attribute unexpectedly If a STUN server receives an ACCESS-TOKEN attribute unexpectedly
(because it had not previously sent out a THIRD-PARTY-AUTHORIZATION), (because it had not previously sent out a THIRD-PARTY-AUTHORIZATION),
it will respond with an error code of 420 (Unknown Attribute) as it will respond with an error code of 420 (Unknown Attribute) as
specified in Section 7.3.1 of [RFC5389]. specified in Section 7.3.1 of [RFC5389].
8. STUN Client Behaviour 8. STUN client behaviour
o The client looks for the MESSAGE-INTEGRITY attribute in the o The client looks for the MESSAGE-INTEGRITY attribute in the
response. If MESSAGE-INTEGRITY is absent or the value computed response. If MESSAGE-INTEGRITY is absent or the value computed
for message integrity using mac_key does not match the contents of for message integrity using mac_key does not match the contents of
the MESSAGE-INTEGRITY attribute then the response MUST be the MESSAGE-INTEGRITY attribute then the response MUST be
discarded. discarded.
o If the access token expires then the client MUST obtain a new o If the access token expires then the client MUST obtain a new
token from the authorization server and use it for new STUN token from the authorization server and use it for new STUN
requests. requests.
9. Usage with TURN 9. TURN client and server behaviour
Traversal Using Relay NAT (TURN) [RFC5766] an extension to the STUN
protocol is often used to improve the connectivity of P2P
applications. TURN ensures that a connection can be established even
when one or both sides is incapable of a direct P2P connection.
However, as a relay service, it imposes a nontrivial cost on the
service provider. Therefore, access to a TURN service is almost
always access-controlled. In order to achieve third party
authorization, a resource owner e.g. WebRTC server, authorizes a
TURN client to access resources on the TURN server.
Consider the following example that illustrates the use of OAuth 2.0
to achieve third party authorization for TURN. In this example, a
resource owner i.e., WebRTC server, authorizes a TURN client to
access resources on a TURN server.
+----------------------+----------------------------+
| OAuth 2.0 | WebRTC |
+======================+============================+
| Client | WebRTC client |
+----------------------+----------------------------+
| Resource owner | WebRTC server |
+----------------------+----------------------------+
| Authorization server | Authorization server |
+----------------------+----------------------------+
| Resource server | TURN Server |
+----------------------+----------------------------+
Figure 2: OAuth terminology mapped to WebRTC terminology
Using the OAuth 2.0 authorization framework, a WebRTC client (third-
party application) obtains limited access to a TURN (resource server)
on behalf of the WebRTC server (resource owner or authorization
server). The WebRTC client requests access to resources controlled
by the resource owner (WebRTC server) and hosted by the resource
server (TURN server). The WebRTC client obtains access token,
lifetime, session key and kid. The TURN client conveys the access
token and other OAuth 2.0 parameters learnt from the authorization
server to the TURN server. The TURN server obtains the session key
from the access token. The TURN server validates the token, computes
the message integrity of the request and takes appropriate action
i.e, permits the TURN client to create allocations. This is shown in
an abstract way in Figure 3.
+---------------+
| +<******+
+------------->| Authorization | *
| | Server | *
| +----------|(WebRTC Server)| * AS-RS,
| | | | * AUTH keys
(2) | | +---------------+ * (1)
Access | | (3) *
Token | | Access Token *
Request | | + *
| | Session Key *
| | *
| V V
+-------+---+ +-+----=-----+
| | (4) | |
| | TURN Request + Access | |
| WebRTC | Token | TURN |
| Client |---------------------->| Server |
| (Alice) | Allocate Response (5) | |
| |<----------------------| |
+-----------+ +------------+
User : Alice
****: Out-of-Band Long-Term Key Establishment
Figure 3: Interactions
In the below figure, the client sends an Allocate request to the
server without credentials. Since the server requires that all
requests be authenticated using OAuth 2.0, the server rejects the
request with a 401 (Unauthorized) error code and STUN attribute
THIRD-PARTY-AUTHORIZATION. The WebRTC client obtains access token
from the WebRTC server and then tries again, this time including
access token. This time, the server validates the token, accepts the
Allocate request and returns an Allocate success response containing
(amongst other things) the relayed transport address assigned to the
allocation.
+-------------------+ +--------+ +---------+
| ......... 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 4: TURN Third Party Authorization
Changes specific to TURN are listed below: Changes specific to TURN are listed below:
o The access token can be reused for multiple Allocate requests to o The access token can be reused for multiple Allocate requests to
the same TURN server. The TURN client MUST include the ACCESS- the same TURN server. The TURN client MUST include the ACCESS-
TOKEN attribute only in Allocate and Refresh requests. Since the TOKEN attribute only in Allocate and Refresh requests. Since the
access token is valid for a specific period of time, the TURN access token is valid for a specific period of time, the TURN
server can cache it so that it can check if the access token in a server can cache it so that it can check if the access token in a
new allocation request matches one of the cached tokens and avoids new allocation request matches one of the cached tokens and avoids
the need to decrypt the token. the need to decrypt the token.
skipping to change at page 16, line 40 skipping to change at page 16, line 36
This document defines the ACCESS-TOKEN STUN attribute, described in This document defines the ACCESS-TOKEN STUN attribute, described in
Section 6. IANA has allocated the comprehension-required codepoint Section 6. IANA has allocated the comprehension-required codepoint
TBD for this attribute. TBD for this attribute.
13. Acknowledgements 13. Acknowledgements
Authors would like to thank Dan Wing, Pal Martinsen, Oleg Moskalenko, Authors would like to thank Dan Wing, Pal Martinsen, Oleg Moskalenko,
Charles Eckel, Spencer Dawkins, Hannes Tschofenig, Yaron Sheffer, Tom Charles Eckel, Spencer Dawkins, Hannes Tschofenig, Yaron Sheffer, Tom
Taylor, Christer Holmberg, Pete Resnick, Kathleen Moriarty, Richard Taylor, Christer Holmberg, Pete Resnick, Kathleen Moriarty, Richard
Barnes, Stephen Farrell and Alissa Cooper for comments and review. Barnes, Stephen Farrell, Alissa Cooper and Rich Salz for comments and
The authors would like to give special thanks to Brandon Williams for review. The authors would like to give special thanks to Brandon
his help. Williams for his help.
Thanks to Oleg Moskalenko for providing token samples in the Thanks to Oleg Moskalenko for providing code snippent in the
Appendix section. Appendix section.
14. References 14. References
14.1. Normative References 14.1. Normative References
[I-D.ietf-jose-json-web-algorithms] [I-D.ietf-jose-json-web-algorithms]
Jones, M., "JSON Web Algorithms (JWA)", draft-ietf-jose- Jones, M., "JSON Web Algorithms (JWA)", draft-ietf-jose-
json-web-algorithms-40 (work in progress), January 2015. json-web-algorithms-40 (work in progress), January 2015.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, March 1997. Requirement Levels", BCP 14, RFC 2119, March 1997.
[RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data
skipping to change at page 19, line 17 skipping to change at page 19, line 10
[RFC7350] Petit-Huguenin, M. and G. Salgueiro, "Datagram Transport [RFC7350] Petit-Huguenin, M. and G. Salgueiro, "Datagram Transport
Layer Security (DTLS) as Transport for Session Traversal Layer Security (DTLS) as Transport for Session Traversal
Utilities for NAT (STUN)", RFC 7350, August 2014. Utilities for NAT (STUN)", RFC 7350, August 2014.
[RFC7376] Reddy, T., Ravindranath, R., Perumal, M., and A. Yegin, [RFC7376] Reddy, T., Ravindranath, R., Perumal, M., and A. Yegin,
"Problems with Session Traversal Utilities for NAT (STUN) "Problems with Session Traversal Utilities for NAT (STUN)
Long-Term Authentication for Traversal Using Relays around Long-Term Authentication for Traversal Using Relays around
NAT (TURN)", RFC 7376, September 2014. NAT (TURN)", RFC 7376, September 2014.
Appendix A. Sample tickets Appendix A. C Snippet to encrypt/decrypt token
<CODE BEGINS>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <strings.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <openssl/ssl.h>
#include <openssl/evp.h>
#define OAUTH_GCM_NONCE_SIZE (12)
#define OAUTH_GCM_TAG_SIZE (16)
#define MAX_NONCE_LENGTH (128)
#define MAX_MAC_KEY_LENGTH (128)
#define MAX_ENCODED_OAUTH_TOKEN_SIZE (1024)
struct _oauth_token {
uint16_t nonce_length;
uint8_t nonce[MAX_NONCE_LENGTH];
uint16_t mac_key_length;
uint8_t mac_key[MAX_MAC_KEY_LENGTH];
uint64_t timestamp;
uint32_t lifetime;
};
typedef struct _oauth_token oauth_token_t;
static int my_EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *outl, const uint8_t *in, int inl)
{
int cycle = 0;
int out_len = 0;
while((out_len<inl)&&(++cycle<128)) {
int tmp_outl=0;
unsigned char *ptr = NULL;
if(out)
ptr = out+out_len;
int ret = EVP_EncryptUpdate(ctx, ptr, &tmp_outl, in+out_len, inl-out_len);
out_len += tmp_outl;
if(ret<1)
return ret;
}
*outl = out_len;
return 1;
}
static int my_EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out,
int *outl, const uint8_t *in, int inl)
{
int cycle = 0;
int out_len = 0;
while((out_len<inl)&&(++cycle<128)) {
int tmp_outl=0;
unsigned char *ptr = NULL;
if(out)
ptr = out+out_len;
int ret = EVP_DecryptUpdate(ctx, ptr, &tmp_outl, in+out_len, inl-out_len);
out_len += tmp_outl;
if(ret<1)
return ret;
}
*outl = out_len;
return 1;
}
static inline uint64_t ntohll(uint64_t v)
{
#if BYTE_ORDER == LITTLE_ENDIAN
uint8_t *src = (uint8_t*) &v;
uint8_t* dst = src + 7;
while (src < dst) {
uint8_t vdst = *dst;
*(dst--) = *src;
*(src++) = vdst;
}
#elif BYTE_ORDER == BIG_ENDIAN
/* OK */
#else
#error WRONG BYTE_ORDER SETTING
#endif
return v;
}
static int encode_oauth_token_gcm(const uint8_t *server_name, const uint8_t *key,
const oauth_token_t *oauth_token,
uint8_t *encoded_buffer) {
int ret = -1;
if(server_name && key && oauth_token && encoded_buffer) {
uint8_t orig_field[MAX_ENCODED_OAUTH_TOKEN_SIZE];
bzero(orig_field,sizeof(orig_field));
size_t len = 0;
*((uint16_t*)(orig_field+len)) = ntohs(oauth_token->nonce_length);
len +=2;
bcopy(oauth_token->nonce,orig_field+len,oauth_token->nonce_length);
len += oauth_token->nonce_length;
*((uint16_t*)(orig_field+len)) = ntohs(oauth_token->mac_key_length);
len +=2;
bcopy(oauth_token->mac_key,orig_field+len,oauth_token->mac_key_length);
len += oauth_token->mac_key_length;
*((uint64_t*)(orig_field+len)) = ntohll(oauth_token->timestamp);
len += 8;
*((uint32_t*)(orig_field+len)) = ntohl(oauth_token->lifetime);
len += 4;
const EVP_CIPHER * cipher = EVP_aes_256_gcm();
if(!cipher)
return -1;
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
/* Initialize the encryption operation. */
if(1 != EVP_EncryptInit_ex(&ctx, cipher, NULL, NULL, NULL))
return -1;
EVP_CIPHER_CTX_set_padding(&ctx,1);
/* Set IV length if default 12 bytes (96 bits) is not appropriate */
if(1 != EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, oauth_token->nonce_length, NULL))
return -1;
/* Initialize key and IV */
if(1 != EVP_EncryptInit_ex(&ctx, NULL, NULL, key, oauth_token->nonce))
return -1;
int outl=0;
size_t sn_len = strlen((const char*)server_name);
/* Provide any AAD data. This can be called zero or more times as
* required
*/
if(1 != my_EVP_EncryptUpdate(&ctx, NULL, &outl, server_name, (int)sn_len))
return -1;
outl=0;
bcopy(orig_field,encoded_buffer,oauth_token->nonce_length + 2);
encoded_buffer += oauth_token->nonce_length + 2;
uint8_t *start_field = orig_field + oauth_token->nonce_length + 2;
len -= oauth_token->nonce_length + 2;
if(1 != my_EVP_EncryptUpdate(&ctx, encoded_buffer, &outl, start_field, (int)len))
return -1;
int tmp_outl = 0;
EVP_EncryptFinal_ex(&ctx, encoded_buffer + outl, &tmp_outl);
outl += tmp_outl;
EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_GET_TAG, OAUTH_GCM_TAG_SIZE, encoded_buffer + outl);
outl += OAUTH_GCM_TAG_SIZE;
ret = (int)(2 + oauth_token->nonce_length + outl);
EVP_CIPHER_CTX_cleanup(&ctx);
}
return ret;
}
static int decode_oauth_token_gcm(const uint8_t *server_name, const uint8_t *key,
oauth_token_t *oauth_token,
const uint8_t *encoded_buffer, size_t encoded_buffer_size)
{
int ret = -1;
if(server_name && key && oauth_token && encoded_buffer) {
oauth_token->nonce_length = ntohs(*((const uint16_t*)encoded_buffer));
bcopy(encoded_buffer+2,oauth_token->nonce,oauth_token->nonce_length);
const uint8_t* encrypted_field = (const uint8_t*)(encoded_buffer + oauth_token->nonce_length + 2);
size_t encrypted_field_size = (size_t)(encoded_buffer_size - oauth_token->nonce_length - 2 - OAUTH_GCM_TAG_SIZE);
uint8_t tag[OAUTH_GCM_TAG_SIZE];
bcopy(encrypted_field + encrypted_field_size, tag ,sizeof(tag));
uint8_t decoded_field[MAX_ENCODED_OAUTH_TOKEN_SIZE];
const EVP_CIPHER * cipher = EVP_aes_256_gcm();
if(!cipher) {
return -1;
}
EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
/* Initialize the decryption operation. */
if(1 != EVP_DecryptInit_ex(&ctx, cipher, NULL, NULL, NULL)) {
return -1;
}
/* Set IV length if default 12 bytes (96 bits) is not appropriate */
if(1 != EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_GCM_SET_IVLEN, oauth_token->nonce_length, NULL)) {
return -1;
}
/* Initialize key and IV */
if(1 != EVP_DecryptInit_ex(&ctx, NULL, NULL, (const unsigned char *)key, oauth_token->nonce)) {
return -1;
}
/* Set expected tag value. A restriction in OpenSSL 1.0.1c and earlier
+ * required the tag before any AAD or ciphertext */
EVP_CIPHER_CTX_ctrl (&ctx, EVP_CTRL_GCM_SET_TAG, OAUTH_GCM_TAG_SIZE, tag);
int outl=0;
size_t sn_len = strlen((const char*)server_name);
/* Provide any AAD data. This can be called zero or more times as
* required
*/
if(1 != my_EVP_DecryptUpdate(&ctx, NULL, &outl, server_name, (int)sn_len)) {
return -1;
}
if(1 != my_EVP_DecryptUpdate(&ctx, decoded_field, &outl, encrypted_field, (int)encrypted_field_size)) {
return -1;
}
int tmp_outl = 0;
if(EVP_DecryptFinal_ex(&ctx, decoded_field + outl, &tmp_outl)<1) {
EVP_CIPHER_CTX_cleanup(&ctx);
return -1;
}
outl += tmp_outl;
EVP_CIPHER_CTX_cleanup(&ctx);
size_t len = 0;
oauth_token->mac_key_length = ntohs(*((uint16_t*)(decoded_field+len)));
len += 2;
bcopy(decoded_field+len,oauth_token->mac_key,oauth_token->mac_key_length);
len += oauth_token->mac_key_length;
oauth_token->timestamp = ntohll(*((uint64_t*)(decoded_field+len)));
len += 8;
oauth_token->lifetime = ntohl(*((uint32_t*)(decoded_field+len)));
len += 4;
ret = len;
}
return ret;
}
int main() {
SSL_load_error_strings();
OpenSSL_add_ssl_algorithms();
oauth_token_t oauth_token = { OAUTH_GCM_NONCE_SIZE, "h4j3k2l2n4b5",
20, "ZksjpweoixXmvn67534m",
(uint64_t)(92470300704768LL), 3600
};
const char server_name[33] = "blackdow.carleon.gov";
const char key[33] = "HGkj32KJGiuy098sdfaqbNjOiaz71923";
uint8_t encoded_buffer[MAX_ENCODED_OAUTH_TOKEN_SIZE];
int len = encode_oauth_token_gcm((const uint8_t *)server_name, (const uint8_t *)key,
&oauth_token,
encoded_buffer);
if(len<0) {
fprintf(stderr,"Cannot encode token\n");
exit(-1);
}
oauth_token_t oauth_token_decoded;
len = decode_oauth_token_gcm((const uint8_t *)server_name, (const uint8_t *)key,
&oauth_token_decoded,
encoded_buffer, (size_t)len);
if(len<0) {
fprintf(stderr,"Cannot decode token\n");
exit(-1);
}
if(
(oauth_token.nonce_length != oauth_token_decoded.nonce_length) ||
(bcmp(oauth_token.nonce,oauth_token_decoded.nonce,oauth_token.nonce_length)!=0) ||
(oauth_token.mac_key_length != oauth_token_decoded.mac_key_length) ||
(bcmp(oauth_token.mac_key,oauth_token_decoded.mac_key,oauth_token.mac_key_length)!=0) ||
(oauth_token.timestamp != oauth_token_decoded.timestamp) ||
(oauth_token.lifetime != oauth_token_decoded.lifetime)) {
fprintf(stderr,"Incorrectly decoded token\n");
exit(-1);
}
fprintf(stdout,"SUCCESS !\n");
return 0;
}
<CODE ENDS>
Input data (same for all samples below): Input data (same for all samples below):
//STUN SERVER NAME //STUN SERVER NAME
server_name = "blackdow.carleon.gov"; server_name = "blackdow.carleon.gov";
//Shared key between AS and RS //Shared key between AS and RS
long_term_key = \x48\x47\x6b\x6a\x33\x32\x4b\x4a\x47\x69\x75\x79 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 \x30\x39\x38\x73\x64\x66\x61\x71\x62\x4e\x6a\x4f
skipping to change at page 19, line 43 skipping to change at page 26, line 9
//length of the MAC key //length of the MAC key
mac_key_length = 20; mac_key_length = 20;
//The timestamp field in the token //The timestamp field in the token
token_timestamp = 92470300704768; token_timestamp = 92470300704768;
//The lifetime of the token //The lifetime of the token
token_lifetime = 3600; token_lifetime = 3600;
//nonce for AEAD when AEAD is used //nonce for AEAD
aead_nonce = \x68\x34\x6a\x33\x6b\x32\x6c\x32\x6e\x34\x62\x35; aead_nonce = \x68\x34\x6a\x33\x6b\x32\x6c\x32\x6e\x34\x62\x35;
Sample: Samples:
1) 1) token encryption algorithm = AEAD_AES_256_GCM
token encryption algorithm = AEAD_AES_256_GCM Encrypted token (64 bytes = 2 + 12 +34 + 16) =
token auth algorithm = N/A
Result:
AS_RS key (32 bytes) =
\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
AUTH key = N/A \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
Encrypted token (62 bytes = 34 + 16 + 12) = 2) token encryption algorithm = AEAD_AES_128_GCM
\xd4\x86\x5c\x5d\x59\xfb\x3f\xe3\xf6\xf1\xd8\xc3\x22\xc2\x22\x26\x8d Encrypted token (64 bytes = 2 + 12 +34 + 16) =
\x2e\xf0\xbe\x2\x5b\xbd\x13\x49\x89\x6e\xa5\xc5\x51\xee\xee\x7f\xd9
\xe4\x41\xd7\xcb\x51\x20\x40\xcc\xc5\x53\x90\x2f\xdc\xbb\x8d\x53\x68
\x34\x6a\x33\x6b\x32\x6c\x32\x6e\x34\x62\x35
Figure 5: Sample tickets \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
Figure 5: Sample code
Appendix B. Interaction between client and authorization server Appendix B. Interaction between client and authorization server
Client makes an HTTP request to an authorization server to obtain a Client makes an HTTP request to an authorization server to obtain a
token that can be used to avail itself of STUN services. The STUN token that can be used to avail itself of STUN services. The STUN
token is returned in JSON syntax [RFC7159], along with other OAuth token is returned in JSON syntax [RFC7159], along with other OAuth
2.0 parameters like token type, key, token lifetime and kid defined 2.0 parameters like token type, key, token lifetime and kid defined
in [I-D.ietf-oauth-pop-key-distribution]. in [I-D.ietf-oauth-pop-key-distribution].
+-------------------+ +--------+ +---------+ +-------------------+ +--------+ +---------+
skipping to change at page 22, line 12 skipping to change at page 28, line 12
request for the access token using transport-layer security (with request for the access token using transport-layer security (with
extra line breaks for display purposes only): extra line breaks for display purposes only):
HTTP/1.1 HTTP/1.1
Host: server.example.com Host: server.example.com
Content-Type: application/x-www-form-urlencoded Content-Type: application/x-www-form-urlencoded
aud=stun1@example.com aud=stun1@example.com
timestamp=1361471629 timestamp=1361471629
grant_type=implicit grant_type=implicit
token_type=pop token_type=pop
alg=HMAC-SHA-1 HMAC-SHA-256-128 alg=HMAC-SHA-256-128
Figure 7: Request Figure 7: Request
[I-D.ietf-tram-stunbis] will support hash agility and accomplish this [I-D.ietf-tram-stunbis] supports hash agility and accomplish this
agility by conveying the HMAC algorithms supported by the STUN server agility by computing message integrity using both HMAC-SHA-1 and
along with a STUN error message to the client. The client then HMAC-SHA-256-128. The client signals the algorithm supported by it
signals the intersection-set of algorithms supported by it and the to the authorization server in the 'alg' parameter defined in
STUN server to the authorization server in the 'alg' parameter [I-D.ietf-oauth-pop-key-distribution]. The authorization determines
defined in [I-D.ietf-oauth-pop-key-distribution]. The authorization length of the mac_key based on the HMAC algorithm conveyed by the
server selects an HMAC algorithm from the list of algorithms the client. If the client supports both HMAC-SHA-1 and HMAC-SHA-256-128
client provided and determines length of the mac_key based on the then it signals HMAC-SHA-256-128 to the authorization server, gets
selected HMAC algorithm. Note that until STUN supports hash agility 256-bit key from the authorization server and calculates 160-bit key
HMAC-SHA1 is the only valid hash algorithm that the client can signal for HMAC-SHA-1 using SHA1 taking the 256-bit key as input.
to the authorization server and vice-versa.
If the client is authorized then the authorization server issues an If the client is authorized then the authorization server issues an
access token. An example of successful response: access token. An example of successful response:
HTTP/1.1 200 OK HTTP/1.1 200 OK
Content-Type: application/json Content-Type: application/json
Cache-Control: no-store Cache-Control: no-store
{ {
"access_token": "access_token":
 End of changes. 30 change blocks. 
180 lines changed or deleted 501 lines changed or added

This html diff was produced by rfcdiff 1.42. The latest version is available from http://tools.ietf.org/tools/rfcdiff/
X-Generator: pyht 0.35