Subject: [MMUSIC] RTSP 2.0: Client Authentication

From: Magnus Westerlund <[email-masked]>
Date: Fri, 30 Aug 2013 17:37:30 +0200

WG,

As part of Robert's comments is this minor comment:

>
>> As written, a client and server can use HTTP Basic authentication over
>> TCP that is not protected with TLS. Consider restricting it's use to TLS
>> only. Are you sure you don't need to say anything RTSP specific about
>> DIGEST computations (I don't think you need to go as far as SIP did
>> talking about DIGEST, but I'm surprised you haven't run into issues
>> relying only on 2617 literally.
> Are you referring to Section 19.1 here?
Yes
>
> Yes, I would not have any issue with requiring Basic to be combined with
> TLS. I think that is appropriate.
>
> When it comes to DIGEST, are you referring to section 22.4 in RFC 3261?
Yes
>
> That section indicates that some clarifications are likely needed.

This actually resulted in finding a bit more shortcomings around the
client authentication. The high level summary of what my proposal for
fixing this is:

- Mandate TLS for basic authentication.
- Added the missing Authentication-Info and Proxy-Authentication-Info
- Corrected ABNF that was missing basic
- Written an equivalent of the RFC 2617 clarification section of
  RFC 3261.
- Tried to press on the hop-by-hop nature of proxy-authorization
- Put up a warning flag for server to client requests lack authentication.

This massive amount obviously needs review.

The resulting relevant text sections are:

18 Header tables:

   +------------------+-------+-----+----+-----+-----+-----+-----+-----+
   | Header           | Where | Pro | DE | OPT | STP | PLY | PSE | TRD |
   |                  |       | xy  | S  |     |     |     |     |     |
   +------------------+-------+-----+----+-----+-----+-----+-----+-----+

   | Authentication-I | r     |     | o  | o   | o   | o   | o   | o/- |
   | nfo              |       |     |    |     |     |     |     |     |

   | Authorization    | R     |     | o  | o   | o   | o   | o   | o   |

   | Proxy-           | 407     | amr | m  | m  | m  | m   | m   | m   |
   | Authenticate     |         |     |    |    |    |     |     |     |
   |                  |         |     |    |    |    |     |     |     |
   | Proxy-Authentica | r       | amd | o  | o  | o  | o   | o   | o/- |
   | tion-Info        |         | r   |    |    |    |     |     |     |
   |                  |         |     |    |    |    |     |     |     |
   | Proxy-           | R       | rd  | o  | o  | o  | o   | o   | o   |
   | Authorization    |         |     |    |    |    |     |     |     |

   |                  |         |     |    |    |    |     |     |     |
   | WWW-             | 401     |     | m  | m  | m  | m   | m   | m   |
   | Authenticate     |         |     |    |    |    |     |     |     |
   +------------------+---------+-----+----+----+----+-----+-----+-----+

   +-------------------------+---------+-------+-----+-----+-----+-----+
   | Header                  | Where   | Proxy | GPR | SPR | RDR | PNY |
   +-------------------------+---------+-------+-----+-----+-----+-----+
   | Authentication-Info     | r       |       | o/- | o/- | -   | -   |
   |                         |         |       |     |     |     |     |
   | Authorization           | R       |       | o   | o   | o   | -   |
   |                         |         |       |     |     |     |     |
   | Proxy-Authenticate      | 407     | amdr  | m   | m   | m   | -   |
   |                         |         |       |     |     |     |     |
   | Proxy-Authentication-In | r       | amdr  | o/- | o/- | -   | -   |
   | fo                      |         |       |     |     |     |     |
   |                         |         |       |     |     |     |     |
   | Proxy-Authorization     | R       | amdr  | o   | o   | o   | -   |

      +------------------+---------+-------+-----+-----+-----+-----+
      | Header           | Where   | Proxy | GPR | SPR | RDR | PNY |
      +------------------+---------+-------+-----+-----+-----+-----+

      |                  |         |       |     |     |     |     |
      | WWW-Authenticate | 401     |       | m   | m   | m   | -   |
      +------------------+---------+-------+-----+-----+-----+-----+

18.7.  Authentication-Info

   The Authentication-Info header is used by the server to communicate
   some information regarding the successful authentication in the
   response message.  This usage of this header is specified in
   [RFC2617] with some RTSP clarification in Section 19.1.  This header
   MUST only be used in response messages related to client to server
   requests.

18.8.  Authorization

   An RTSP client that wishes to authenticate itself with a server using
   authentication mechanism from HTTP [RFC2617] , usually, but not
   necessarily, after receiving a 401 response, does so by including an
   Authorization request-header field with the request.  The
   Authorization field value consists of credentials containing the
   authentication information of the user agent for the realm of the
   resource being requested.  This header MUST only be used in client to
   server requests.

   If a request is authenticated and a realm specified, the same
   credentials SHOULD be valid for all other requests within this realm
   (assuming that the authentication scheme itself does not require
   otherwise, such as credentials that vary according to a challenge
   value or using synchronized clocks).

   When a shared cache (see Section 16) receives a request containing an
   Authorization field, it MUST NOT return the corresponding response as
   a reply to any other request, unless one of the following specific
   exceptions holds:

   1.  If the response includes the "max-age" cache-control directive,
       the cache MAY use that response in replying to a subsequent
       request.  But (if the specified maximum age has passed) a proxy
       cache MUST first revalidate it with the origin server, using the
       request-headers from the new request to allow the origin server
       to authenticate the new request.  (This is the defined behavior
       for max-age.)  If the response includes "max-age=0", the proxy
       MUST always revalidate it before re-using it.

   2.  If the response includes the "must-revalidate" cache-control
       directive, the cache MAY use that response in replying to a
       subsequent request.  But if the response is stale, all caches
       MUST first revalidate it with the origin server, using the
       request-headers from the new request to allow the origin server
       to authenticate the new request.

   3.  If the response includes the "public" cache-control directive, it
       MAY be returned in reply to any subsequent request.

18.34.  Proxy-Authenticate

   The Proxy-Authenticate response-header field MUST be included as part
   of a 407 (Proxy Authentication Required) response.  The field value
   consists of a challenge that indicates the authentication scheme and
   parameters applicable to the proxy for this Request-URI.

   The HTTP access authentication process is described in [RFC2617].
   Unlike WWW-Authenticate, the Proxy-Authenticate header field applies
   only to the current connection and SHOULD NOT be passed on to
   downstream agents.  This header MUST only be used in response
   messages related to client to server requests.

18.35.  Proxy-Authentication-Info

   The Proxy-Authentication-Info header is used by the proxy to
   communicate some information regarding the successful authentication
   to the proxy in the message response.  The content and usage of this
   header is described in the HTTP access authentication [RFC2617] that
   is also used by RTSP and clarified in Section 19.1.  This header MUST
   only be used in response messages related to client to server
   requests.  This header has hop by hop scope.

18.36.  Proxy-Authorization

   The Proxy-Authorization request-header field allows the client to
   identify itself (or its user) to a proxy which requires
   authentication.  The Proxy-Authorization field value consists of
   credentials containing the authentication information of the user
   agent for the proxy and/or realm of the resource being requested.

   The HTTP access authentication process is described in [RFC2617].
   Unlike Authorization, the Proxy-Authorization header field applies
   only to the next hop proxy.  This header MUST only be used in client
   to server requests.

18.58.  WWW-Authenticate

   The WWW-Authenticate response-header field MUST be included in 401
   (Unauthorized) response messages.  The field value consists of at
   least one challenge that indicates the authentication scheme(s) and
   parameters applicable to the Request-URI.  This header MUST only be
   used in response messages related to client to server requests.

   The HTTP access authentication process is described in [RFC2617] with
   some clarification in Section 19.1.  User agents are advised to take
   special care in parsing the WWW- Authenticate field value as it might
   contain more than one challenge, or if more than one WWW-Authenticate
   header field is provided, the contents of a challenge itself can
   contain a comma-separated list of authentication parameters.

19.1.  RTSP and HTTP Authentication

   RTSP and HTTP share common authentication schemes, and thus follow
   the same usage guidelines as specified in [RFC2617] with the
   additions for digest specified below in Section 19.1.1.  Servers
   SHOULD implement both basic and digest [RFC2617] authentication.
   Clients MUST implement both basic and digest authentication [RFC2617]
   so that a server that requires the client to authenticate can trust
   that the capability is present.

   It should be stressed that using the HTTP authentication alone does
   not provide full control message security.  Therefore, in
   environments requiring tighter security for the control messages, TLS
   SHOULD be used, see Section 19.2.  Any RTSP message containing an
   Authorization header containg a basic authorization MUST be using a
   TLS connection with confidentiality protection enabled, i.e. no NULL
   encryption.

   In cases where there is a chain of proxies between the client and the
   server, each proxy may individually request the client or previous
   proxy to authenticate itself.  This is done using the Proxy-
   Authenticate (Section 18.34), the Proxy-Authorization (Section 18.36)
   and the Proxy-Authentication-Info (Section 18.35) headers.  These
   headers are hop-by-hop headers and have only scope for the current
   connection.  Thus if a chain exist, the proxy connecting to another
   proxy will have to act as a client to authorize itself towards the
   next proxy.  The WWW-Authenticate (Section 18.58), Authorization
   (Section 18.8) and Authentication-Info (Section 18.7) headers are
   end-to-end and must not be modified by proxies.

   This authentication mechanism works only for client to server
   requests as currently defined.  This leaves server to client request
   outside of the context of TLS based communication more vulnerable to
   message injection attacks on the client.  Based on the server to
   client methods that exist, the potential risks are various; hijacking
   (REDIRECT), denial of service (TEARDOWN and PLAY_NOTIFY) or attacks
   with uncertain results (SET_PARAMETER).

19.1.1.  Digest Authentication

   This section describes the modifications and clarifications required
   to apply the HTTP Digest authentication scheme to RTSP.  The RTSP
   scheme usage is almost completely identical to that for HTTP
   [RFC2617].  These are based on the procedures defined for SIP 2.0
   [RFC3261].

   The rules for Digest authentication follow those defined in
   [RFC2617], with "HTTP/1.1" replaced by "RTSP/2.0" in addition to the
   following differences:

   1.  Use the ABNF specified in this document, rather than the one in
       [RFC2617].  That way the following is assured:

       *  Using the right RTSP URIs allowed in the challenge as well as
          in the digest.

       *  Resolved the error in the "uri" parameter of the Authorization
          header in [RFC2617].

   2.  If MTags are used then the example procedure for choosing a nonce
       based on Etag can work based on replacing ETag with the MTag.

   3.  As a clarification to the calculation of the A2 value for message
       integrity assurance in the Digest authentication scheme,
       implementers should assume, when the entity-body is empty (that
       is, when the RTSP messages have no message body) that the hash of
       the message-body resolves to the MD5 hash of an empty string, or:
       H(entity-body) = MD5("") = "d41d8cd98f00b204e9800998ecf8427e".

   4.  RFC 2617 notes that a cnonce value MUST NOT be sent in an
       Authorization (and by extension Proxy-Authorization) header field
       if no qop directive has been sent.  Therefore, any algorithms
       that have a dependency on the cnonce (including "MD5-Sess")
       require that the qop directive be sent.  Use of the "qop"
       parameter is optional in RFC 2617 for the purposes of backwards
       compatibility with RFC 2069; since this specification defines
       RTSP 2.0 there is no backwards compatibilit issue with mandating.
       Thus, all RTSP agents MUST implement qop-options.

   Authentication-Info = "Authentication-Info" HCOLON auth-info
   auth-info         = auth-info-entry *(COMMA auth-info-entry)
   auth-info-entry   = nextnonce
                     / message-qop
                     / response-auth
                     / cnonce
                     / nonce-count
   nextnonce         = "nextnonce" "=" nonce-value
   response-auth     = "rspauth" "=" response-digest
   response-digest   = DQ *LHEX DQ
   Authorization     =  "Authorization" HCOLON credentials
   credentials       =  basic-credential
                     /  digest-credential
                     /  other-response
   basic-credential  = "Basic" LWS basic-credentials
   basic-credentials = base64 ; Base64 encoding of user-password
   user-password     = basic-username ":" password
   basic-username    = *CF-TEXT
   CF-TEXT           = %x20-39 / %x3B-7E / %x80-FF ; TEXT without :
   password          = *TEXT
   digest-credential = ("Digest" LWS digest-response)
   digest-response   =  dig-resp *(COMMA dig-resp)
   dig-resp          =  username / realm / nonce / digest-uri
                     /  dresponse / algorithm / cnonce
                     /  opaque / message-qop
                     /  nonce-count / auth-param
   username          =  "username" EQUAL username-value
   username-value    =  quoted-string
   digest-uri        =  "uri" EQUAL LDQUOT digest-uri-value RDQUOT
   digest-uri-value  =  RTSP-REQ-URI
   message-qop       =  "qop" EQUAL qop-value
   cnonce            =  "cnonce" EQUAL cnonce-value
   cnonce-value      =  nonce-value
   nonce-count       =  "nc" EQUAL nc-value
   nc-value          =  8LHEX
   dresponse         =  "response" EQUAL request-digest
   request-digest    =  LDQUOT 32LHEX RDQUOT
   auth-param        =  auth-param-name EQUAL
                        ( token / quoted-string )
   auth-param-name   =  token
   other-response    =  auth-scheme LWS auth-param
                        *(COMMA auth-param)
   auth-scheme       =  token

   Proxy-Authenticate =  "Proxy-Authenticate" HCOLON challenge-list
   challenge-list     =  challenge *(COMMA challenge)
   challenge          =  ("Digest" LWS digest-cln *(COMMA digest-cln))
                      /  ("Basic" LWS realm)
                      /  other-challenge
   other-challenge    =  auth-scheme LWS auth-param
                         *(COMMA auth-param)
   digest-cln         =  realm / domain / nonce
                      /  opaque / stale / algorithm
                      /  qop-options / auth-param
   realm              =  "realm" EQUAL realm-value
   realm-value        =  quoted-string
   domain             =  "domain" EQUAL LDQUOT RTSP-REQ-Ref
                         *(1*SP RTSP-REQ-Ref ) RDQUOT
   nonce              =  "nonce" EQUAL nonce-value
   nonce-value        =  quoted-string
   opaque             =  "opaque" EQUAL quoted-string
   stale              =  "stale" EQUAL ( "true" / "false" )
   algorithm          =  "algorithm" EQUAL ("MD5" / "MD5-sess" / token)
   qop-options        =  "qop" EQUAL LDQUOT qop-value
                         *("," qop-value) RDQUOT
   qop-value          =  "auth" / "auth-int" / token

   Proxy-Auth-Info    = "Proxy-Authentication-Info" HCOLON auth-info
   Proxy-Authorization = "Proxy-Authorization" HCOLON credentials

   WWW-Authenticate  = "WWW-Authenticate" HCOLON challenge-list
-- 

Magnus Westerlund

----------------------------------------------------------------------
Multimedia Technologies, Ericsson Research EAB/TVM
----------------------------------------------------------------------
Ericsson AB                | Phone  +46 10 7148287
Färögatan 6                | Mobile +46 73 0949079
SE-164 80 Stockholm, Sweden| mailto: [email-masked]
----------------------------------------------------------------------