W3C home > Mailing lists > Public > public-webrtc@w3.org > August 2016

Re: Issue 714: STUN/TURN OAuth token auth parameter handover

From: Mészáros Mihály <misi@niif.hu>
Date: Thu, 18 Aug 2016 16:45:06 +0200
To: public-webrtc@w3.org
Message-ID: <ca299da7-8d6d-220a-f360-99874e49466a@niif.hu>
Hi,

2016-08-15 19:46 keltezéssel, Bernard Aboba írta:
>
> https://github.com/w3c/webrtc-pc/issues/714
>
>  
>
> Today we have:
>
>  
>
> dictionary *RTCIceServer*{
>     required (DOMString or sequence<DOMString>)|urls|;
>              DOMString                          |username|
> <http://w3c.github.io/webrtc-pc/#dom-rtciceserver-username>;
>              DOMString                          |credential|
> <http://w3c.github.io/webrtc-pc/#dom-rtciceserver-credential>;
>              |RTCIceCredentialType|               |credentialType|= "password";
> };
>
>  
>
>  
>
> enum *RTCIceCredentialType*{
>     "password
> <http://w3c.github.io/webrtc-pc/#dom-rtcicecredentialtype-password>",
>     "token
> <http://w3c.github.io/webrtc-pc/#dom-rtcicecredentialtype-token>"
> };
>
>  
>
> This issue asks how (or if) this can be used to support RFC 7635
> <https://tools.ietf.org/html/rfc7635> (OAuth 2.0) when credentialType
> = “token”.
>
>  
>
> An example of an access token is given in RFC 7635, Appendix B:
>
_
___may I am only confused, but _I feel there is a misunderstanding
around the access-token definition.
_
This structure containing more information not only the access token,
and IETF access token definition is not this json structure.

This example contains the access token, _but_  also other mandatory
parameters like kid, key.
So it contains all the information that needed for the ICE agent need to
know to be able to auth.
The "alg" will be important later, when the implementation will support
more then the SHA1 HMAC alg.
>
>  
>
>         {
>           "access_token":
>    "U2FsdGVkX18qJK/kkWmRcnfHglrVTJSpS6yU32kmHmOrfGyI3m1gQj1jRPsr0uBb
>    HctuycAgsfRX7nJW2BdukGyKMXSiNGNnBzigkAofP6+Z3vkJ1Q5pWbfSRroOkWBn",
>           "token_type":"pop",
>           "expires_in":1800,
>           "kid":"22BIjxU93h/IgwEb",
>           "key":"v51N62OM65kyMvfTI08O"
>           "alg":HMAC-SHA-256-128
>         }
Or do you mean that we should pass the whole structure to the ICE agent
as credential?

If yes then I still fell misleading to reference to this structure as
access_token. Your W3C access token definition split apart from IETF,
and means then different thing then the one, defined in RFC7635.

To pass in RTCIceServer.credential cause other problems, that I will
explain later. So I am not sure that it is the right way...

When you wrote that it is "an example of an access token", for me at
least, added some confusion..
Rather it is the final response structure received by Client from the
Authorization Server (according the PoP key distribution).
It contains all the informations that needed for an ICE agent to auth
not only the access_token.

The Access Token structure is defined here:
https://tools.ietf.org/html/rfc7635#section-6.2
(Most part is encrypted and some is not.)

Please understand how it works, and why this structure is more then an
access_token, to understand why passing token as rtciseserver.credential
is not the right way.

AFAIU in nutshell (and so inexactly) the way how the token based auth works:
The TURN server and the Auth server establishing a "AS-RS Auth key".
That will be used by Auth server to encrypt access token.
Access Token is created by Auth server and contains encrypted form of
the new generated mac_key lets call it as simple "key" ~="the password".
That will be used by the ICE agent to create MESSAGE-INTEGRITY.
(The usage of the "key" is during TURN auth is the same as normal
password/credential is used in password auth/LTC/.)
The ICE agents after receiving nonce sends  ----{kid  in USERNAME,
access_token in ACCESS_TOKEN attribute, and based the "key" create the
MESSAGE-INTEGRITY}
The TURN server decrypts/opens the access token. 
(with a symmetric "AS-RS Auth key", the key that is "shared/established"
between the  Authorization Server and TURN server).
And finally this is the way TURN server get access to the clear text
"key"/password. And creates and verifies the message integrity against
the one it finds in the message MESSAGE-INTEGRITY attribute.
Because (We could use multiple AS-RS "shared/established" keys)The kid
that passed in USERNAME stun/turn attribute is used to select key that
is used to decrypt ACCESS-TOKEN. .


AFAIU, three attributes kid, key, and access_token are mandatory to have
for an ICE agent to Auth against a TURN server using OAuth!
alg will be important after ICE agent's will support other than SHA1
digest alg.
>
>  
>
> Rather than adding new attributes to RTCIceServer (as proposed in
> Issue 714), is there a reason why such a token couldn’t be passed in
> RTCIceServer.credential with RTCIceServer.credentialType = “token”?
>
Yes. We have at least three mandatory parameters, but actually two
fields are in the API.

I am confused, howto pass informations because the above JSON response
is not only containing, three information (the access-token but also the
key, and kid.), but the current webrtc-pc interface  RTCIceServer only
defines two fields: username, password, that are places for kid and key.

For me it is not fully clear how the current standard imagined the pass
in RTCIceServer.credential. Could you please explain it more?
So it would be better question to where to put and pass the
access_token, (alg, expiry)?

Pass the whole result structure of the PoP key response as
RTCIceServer.credential?
I guess this is what is meant.

But, well, I believe it is not good idea from implementation point of
view, because much better to put the right values the right variables
through the interface.
Especially if username and password handling is already implemented..
So better to put "kid" in "username" and "key" in "credential", to not
bother the actual implementations, and not forcing changes in
established implementations, that even if we pass an empty username, and
pass all information in credential, should anyway sort information
behind the scenes.
But even if we mess up the normal way, anyhow and anyway behind the
scenes the "kid" must treated in STUN client as username and put it in
USERNAME STUN attribute. So why not put it through the interface and
keep the current implementation untouched.
And also not mess up the credential implementation workflows the same way..
So I think it is not the right idea to go this way.

Or it is meant to add the "kid" to the "username" field and add other
parameters to the "key" and "access_token", "alg", "expiry" and
altogether packed in one, to the "credential" field?

But it is also not right because it is confusing from implementer points
of view. Mess up the existing credential usage.
One time we use credential to pass password, other time we use to pass
multiple parameters, and also it would be not clean interface, and as I
have explained earlier later the implementation need anyhow to assign
internally to the "credential" variable the "key" value. So I believe it
is also not ideal...

I pointed out already in the issue that

  * "kid" is used as "username"
      o No change needed in already implemented internal workflow.
  * "key" is used as "credential"
      o No change needed in already implemented internal workflow.
  * access_token is a new stun parameter that need to be passed.
  * (Expires is an optional but good to know information for the ICE agent)
  * (alg if multiple digest alg will be supported)

We have to pass three new parameters.

So there is place in *RTCIceServer*to pass username=kid  and password=key,

BUT not for the access_token (and the expiry date, and alg).





My proposals:

 1. Keep RTCIceServer as it is. (Not preferred by me)
      * Document that credential could be in case of token the result of
        PoP key distribution result json. (Let's call it something, and
        find it a less confusing name than "Access Token".)
      * Add to this sentence that only check it credentialType = "password" 
          o "If scheme name is |turn| or |turns|, and either of
            |server.username| or |server.credential| are omitted, then
            throw an |InvalidAccessError| and abort these steps."
    Pros&Cons:
      * + no interface change
      * -  not clean, dumb parameter handover
      * -  adds duty for implementation to sort values later internally.
      * -  mess up the already existing implementations username and
        password/credential internal workflows as I have explained
        earlier above.
      * -  Leaving empty RTCIceServer.username, but on other hand later
        on it should anyhow put kid internally to username, and handle
        as username.
          o The same is true for "credential" and "key"
 2. Pass in credential field the key and also the access_token packed in
    one. (It is also not preferred by me.)

    dictionary TokenCredential {
        required DOMString key;
        required DOMString access_token;
        required DOMString alg;
        DOMTimeStamp expiry;
    };


    dictionary RTCIceServer {
        required (DOMString or sequence<DOMString>) urls;
                 DOMString                          username;
                 (DOMString or TokenCredential)     credential;
                 RTCIceCredentialType               credentialType =
    "password";
    };


      * + Nearly zero change needed.
      * -  It adds a not clean and ugly parameter handover in the interface.
      * -  For implementers it is more complex and confusing that some
        time credential contains the password but other times it
        contains multiple values.
            It is more clean to assign credential=key as it is
        credential=password. So not bother existing implementation and
        leave and use as it is in password case.
            Documentation and example needed that if
        credentialType="token" then the credential looks like
            credential = {
                key="base64_encoded_key",
                access_token="base64_encoded_access_token"
                alg="HMAC-SHA-1-96"
                expiry="1471528540"
            }
 3. simply extend RTCIceServer with the plus two attributes as proposed.
    (Preferred)

    dictionary RTCIceServer {
        required (DOMString or sequence<DOMString>) urls;
                 DOMString                          username;
                 DOMString                          credential;
                 DOMString                          accesstoken;
                 DOMString                          alg;
                 DOMTimeStamp                       expiry;
                 RTCIceCredentialType               credentialType =
    "password";
    };

      * + Cleanly match and reuse fields
          o username=kid
              + So kid is used in username attribute, (following the
                existing normal STUN password workflow)
          o credential=key
              + key is used as credential (following the existing normal
                STUN password workflow)
      * + Slightly more easy the backward compatibility,
          o no change needed in existing implementation
            username/credential handling workflow.
      * -  Adding more and more attributes is not ideal
 4.

    Or be more exact and define a new dictionaries and change credential
    type to multiple sequence. (Preferred)

    dictionary TokenCredential {
        required DOMString    kid;
        required DOMString    key;
        required DOMString    access_token;
        required DOMString    alg;
        DOMTimeStamp          expiry;
    };

    dictionary LongTermCredential {
        required DOMString    username;
        required DOMString    password;
    };

    dictionary RTCIceServer {
        required (DOMString or sequence<DOMString>) urls;
                 (LongTermCredential or TokenCredential)    credential;
                 RTCIceCredentialType                      
    credentialType = "password";
    };

      * + It is the most exact, and (we don't need new attributes)
      * + More Future-proff.
      * -  More complicated but more clean vs. simple change (3.)
      * -  Bigger change, need more time to implement


Please comment and correct me if I am wrong...

Just my 2 cent..
Sorry for the long email..

I am looking forward hearing your thoughts and comments...

Thanks,
Misi
Received on Thursday, 18 August 2016 14:45:44 UTC

This archive was generated by hypermail 2.3.1 : Monday, 23 October 2017 15:19:49 UTC