<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!ENTITY RFC2119 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY RFC3552 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3552.xml">
<!ENTITY RFC2818 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2818.xml">
<!ENTITY RFC3261 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3261.xml">
<!ENTITY RFC5479 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5479.xml">
<!ENTITY RFC4347 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.4347.xml">
<!ENTITY RFC4568 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.4568.xml">
<!ENTITY RFC5763 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5763.xml">
<!ENTITY RFC4251 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.4251.xml">
<!ENTITY RFC3760 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3760.xml">
<!ENTITY RFC6189 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6189.xml">
<!ENTITY RFC5245 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5245.xml">
<!ENTITY RFC6454 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6454.xml">
<!ENTITY RFC4627 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.4627.xml">

<!ENTITY I-D.ietf-rtcweb-security-arch SYSTEM "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.ietf-rtcweb-security-arch">
<!ENTITY I-D.ietf-hybi-thewebsocketprotocol SYSTEM "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.ietf-hybi-thewebsocketprotocol">
<!ENTITY I-D.kaufman-rtcweb-security-ui SYSTEM "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.kaufman-rtcweb-security-ui">
<!ENTITY I-D.ietf-rtcweb-security SYSTEM "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.ietf-rtcweb-security">

]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<?rfc toc="yes" ?>
<?rfc symrefs="yes" ?>
<?rfc strict="yes" ?>
<?rfc compact="yes" ?>
<?rfc sortrefs="yes" ?>
<?rfc colonspace="yes" ?>
<?rfc rfcedstyle="no" ?>
<!-- Don't change this. It breaks stuff -->
<?rfc tocdepth="4"?>
<rfc category="std" docName="draft-rescorla-rtcweb-generic-idp-01"
     ipr="pre5378Trust200902">
  <front>
    <title abbrev="RTCWEB IdP">RTCWEB Generic Identity Provider Interface</title>

    <author fullname="Eric Rescorla" initials="E.K." surname="Rescorla">
      <organization>RTFM, Inc.</organization>

      <address>
        <postal>
          <street>2064 Edgewood Drive</street>

          <city>Palo Alto</city>

          <region>CA</region>

          <code>94303</code>

          <country>USA</country>
        </postal>

        <phone>+1 650 678 2350</phone>

        <email>ekr@rtfm.com</email>
      </address>
    </author>

    <date day="12" month="March" year="2012" />

    <area>RAI</area>

    <workgroup>RTCWEB</workgroup>

    <abstract>
      <t>
	Security for RTCWEB communications requires that the
 communicating endpoints be able to authenticate each 
 other. While authentication may be mediated by the 
 calling service, there are settings in which this is
 undesirable. This document describes a generic mechanism
 for leveraging existing identity providers
 (IdPs) such as BrowserID or OAuth to provide this
 authentication service.
      </t>
    </abstract>
    <note title="Legal">
      <t>THIS DOCUMENT AND THE INFORMATION CONTAINED THEREIN ARE PROVIDED ON
      AN &ldquo;AS IS&rdquo; BASIS AND THE CONTRIBUTOR, THE ORGANIZATION
      HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY, THE
      IETF TRUST, AND THE INTERNET ENGINEERING TASK FORCE, DISCLAIM ALL
      WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY
      WARRANTY THAT THE USE OF THE INFORMATION THEREIN WILL NOT INFRINGE ANY
      RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
      PARTICULAR PURPOSE.</t>
    </note>
  </front>

  <middle>
    <section title="Introduction" anchor="sec.introduction">
      <t>
	Security for RTCWEB communications requires that the
	communicating endpoints be able to authenticate each other. While
	authentication may be mediated by the calling service, there are
	settings in which this is undesirable. This document describes a
	mechanism for leveraging existing identity providers (IdPs) such as
	BrowserID or OAuth to provide this authentication service.
      </t>
      <t>
	Specifically, Alice and Bob have relationships with some
	Identity Provider (IdP) that supports a protocol such OpenID or
	BrowserID) that can be used to attest to their identity. While
	they are making calls through the signaling service, their
	identities (and the cryptographic keying material used to make
	the call) is authenticated via the IdP.
	This separation isn't particularly important in "closed world"
	cases where Alice and Bob are users on the same social network, have
	identities based on that network, and are calling using that
	network's signaling service. However, there are important
	settings where that is not the case, such as
	federation (calls from one network to another) and
	calling on untrusted sites, such as where two users who have
	a relationship via a given social network want to call each
	other on another, untrusted, site, such as a poker site. 
      </t>

      <figure title="A call with IdP-based identity" anchor="fig.proposal.idp">
	<artwork><![CDATA[
                            +----------------+
                            |                |
                            |     Signaling  |
			    |     Server     |
                            |                |
                            +----------------+
                                ^        ^
                               /          \
                       HTTPS  /            \   HTTPS
                             /              \                               
                            /                \                               
                           v                  v
                        JS API              JS API
                  +-----------+            +-----------+
                  |           |    Media   |           |
            Alice |  Browser  |<---------->|  Browser  | Bob
                  |           | (DTLS-SRTP)|           |
                  +-----------+            +-----------+
                        ^      ^--+     +--^     ^		        
                        |         |     |        |
			v         |     |        v
                  +-----------+   |     |  +-----------+
                  |           |<--------+  |           |
		  |   IdP A   |   |        |   IdP B   |
                  |           |   +------->|           |
                  +-----------+            +-----------+
 	]]></artwork>
      </figure>
      <t>
	<xref target="fig.proposal.idp"/> shows the basic topology. Alice
	and Bob are on the same signaling server, but they additionally
	have relationships with their own IdPs. Alice has registered with
	IdP A and Bob has registered with IdP B. Note that nothing
	stops these IdPs from being the same, or indeed from being
	the same as the signaling server, but they can also be totally
	distinct. In particular, Alice and Bob need not have
	identities from the same IdP. 
      </t>
      <t>
	Starting from this point, the mechanisms described in this
	document allow Alice and Bob to establish a mutually authenticated
	phone call. In the interest of clarity the remainder of 
	this section provides a brief overview of how these mechanisms
	fit into the bigger RTCWEB calling picture. For a detailed description of the relevant protocol elements
	and their interaction with the larger signaling protocol
	see <xref target="I-D.ietf-rtcweb-security"/>. 
	When Alice goes to call Bob, her browser (specifically
	her PeerConnection object) contacts her IdP on her behalf and
	obtains an assertion of her identity bound to her certificate
	fingerprint. This assertion is carried with her signaling
	messages to the signaling server and then down to Bob.
	Bob's browser verifies the assertion, possibly with the 
	cooperation of the IdP, and can then display Alice's
	identity to Bob in a trusted user interface element.
	If Alice is in Bob's address book,
	then this interface might also include her real name, a picture, etc.
      </t>
      <t>
	When/If Bob agrees to answer the call, his browser contacts his
	IdP and gets a similar assertion. This assertion is sent to
	the signaling server as part of Bob's answer which is then
	forwarded to Alice. Alice's browser verifies
	Bob's identity and can display the result in a trusted
	UI element. At this point Alice and Bob know each other's
	fingerprints and so they can transitively verify the 
	keys used to authenticate the DTLS-SRTP handshake and
	hence the security of the media.
      </t>
      <t>
	The mechanisms in this
	document do not require the browser to implement any 
	particular identity protocol or to support any particular
	IdP. Instead, this document provides a generic interface
	which any IdP can implement. Thus, new IdPs and protocols
	can be introduced without change to either the browser or the
	calling service. This avoids the need to make a commitment
	to any particular identity protocol, although browsers
	may opt to directly implement some identity protocols in
	order to provide superior performance or UI properties.
      </t>
    </section>

    <section anchor="sec-term" title="Terminology">
      <t>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 <xref
      target="RFC2119">RFC 2119</xref>.</t>
    </section>

    <section title="Trust Relationships: IdPs, APs, and RPs" anchor="sec.trust-relationships">
      <t>
	Any authentication protocol has three major participants:
      </t>
      <t>
	<list style="hanging">
	  <t hangText="Authenticating Party (AP):">The entity which is
	  trying to establish its identity.</t>
	  <t></t>

	  <t hangText="Identity Provider (IdP):">The entity which is
	  vouching for the AP's identity.</t>
	  
	  <t></t>

	  <t hangText="Relying Party (RP):">The entity which is trying
	  to verify the AP's identity.</t>
	</list>
      </t>
      <t>
	The AP and the IdP have an account relationship of some kind: the
	AP registers with the IdP and is able to subsequently authenticate
	directly to the IdP (e.g., with a password). This means that the
	browser must somehow know which IdP(s) the user has 
	an account relationship with. 
	This can either be something that the user configures into
	the browser or that is configured at the calling site and
	then provided to the PeerConnection by the calling site.
      </t>
      <t>
	At a high level there are two kinds of IdPs:
      </t>
      <t>
	<list style="hanging">
	  <t hangText="Authoritative: ">IdPs which have verifiable control 
	  of some section of the identity space. For instance, in the
	  realm of e-mail, the operator of "example.com" has complete control of the
	  namespace ending in "@example.com". Thus, "alice@example.com"
	  is whoever the operator says it is. Examples of systems with
	  authoritative identity providers include DNSSEC, 
	  RFC 4474, and Facebook Connect (Facebook identities only
	  make sense within the context of the Facebook system).
	  </t>

	  <t></t>
	  <t hangText="Third-Party: ">IdPs which don't have control of 
	  their section of the identity space but instead verify 
	  user's identities via some unspecified mechanism and then
	  attest to it. Because the IdP doesn't actually control
	  the namespace, RPs need to trust that the
	  IdP is correctly verifying AP identities, and there
	  can potentially be multiple IdPs attesting to the same
	  section of the identity space. Probably the best-known example
	  of a third-party identity provider is SSL certificates,
	  where there are a large number of CAs all of whom can
	  attest to any domain name.
	  </t>
	</list>
      </t>

      <t>
	If an AP is authenticating via an authoritative IdP, then 
	the RP does not need to explicitly trust the IdP at all:
	as long as the RP knows how to verify that the IdP 
	indeed made the relevant identity assertion (a function
	provided by the mechanisms in this document), then
	any assertion it makes about an identity for which 
	it is authoritative is directly verifiable.
      </t>
      <t>
	By contrast, if an AP is authenticating via a third-party
	IdP, the RP needs to explicitly trust that IdP
	(hence the need for an explicit trust anchor list
	in PKI-based SSL/TLS clients). The list of trustable
	IdPs needs to be configured directly into the
	browser, either by the user or potentially by the
	browser manufacturer. This is a significant advantage
	of authoritative IdPs and implies that if third-party
	IdPs are to be supported, the potential number needs
	to be fairly small. 
      </t>
    </section>
      
    <section title="Overview of Operation" anchor="sec.overview">
      <t>
	In order to provide security without trusting the calling
	site, the PeerConnection component of the browser must
	interact directly with the IdP. In this section, we
	describe a standalone mechanism based on IFRAMEs
	and postMessage(), however, most likely this will
	eventually be superceded by WebIntents
	<eref target="http://www.webintents.com/"/>.
	[[ 
	OPEN ISSUE: 
	I've been looking at WebIntents and I believe that it
	can be made to work but may require some modifications.
	I am currently studying the problem.
	More analysis to come.]]
	]].
      </t>
      <figure>
 <artwork><![CDATA[
      +------------------------------------+
      |  https://calling-site.example.com  |
      |                                    |
      |                                    |
      |                                    |
      |         Calling JS Code            |
      |                ^                   |
      |                | API Calls         |
      |                v                   |
      |         PeerConnection             |
      |                ^                   |
      |                | postMessage()     |
      |                v                   |
      |    +-------------------------+     |     +---------------+
      |    | https://idp.example.org |     |     |               |
      |    |                         |<--------->|   Identity    |   
      |    |        IdP JS           |     |     |   Provider    |
      |    |                         |     |     |               |
      |    +-------------------------+     |     +---------------+
      |                                    |
      +------------------------------------+
  ]]></artwork>
      </figure>
      <t>
	When the PeerConnection object wants to interact with the
	IdP, the sequence of events is as follows:
      </t>
      <t>
	<list style="numbers">
	  <t>The browser (the PeerConnection component)
	  instantiates an IdP proxy (typically a hidden
	  IFRAME) with its source at the IdP. This allows the 
	  IdP to load whatever JS is necessary into the
	  proxy, which runs in the IdP's security context.</t>
	  <t>If the user is not already logged in, the
	  IdP does whatever is required to log them in,
	  such as soliciting a username and password.</t>
	  <t>Once the user is logged in, the IdP proxy
	  notifies the browser (via postMessage()) that
	  it is ready.</t>
	  <t>The browser and the IdP proxy communicate
	  via a standardized series of messages
	  delivered via postMessage. For instance,
	  the browser might request the IdP proxy to
	  sign or verify a given identity assertion.</t>
	</list>
      </t>
      <t>
	This approach allows us to decouple the browser from
	any particular identity provider; the browser need
	only know how to load the IdP's JavaScript--which
	is deterministic from the IdP's identity--and
	the generic protocol for requesting and verifying
	assertions. The IdP provides whatever logic
	is necessary to bridge the generic protocol to
	the IdP's specific requirements. Thus, a single
	browser can support any number of identity protocols,
	including being forward compatible with IdPs which
	did not exist at the time the browser was written.
      </t>
    </section>
    <section title="Protocol Details" anchor="sec.protocol-details">
      <section title="General Message Structure">
	<t>
	  Messages between the PeerConnection object and the
	  IdP proxy are formatted using JSON <xref target="RFC4627"/>.
	  For instance, the PeerConnection would request a 
	  signature with the following "SIGN" message:
	</t>
	<figure>
	  <artwork><![CDATA[
 { 
   "type":"SIGN",
   "id": "1",
   "message":"012345678abcdefghijkl"
 }
 ]]></artwork>
	</figure>
	<t>
	  All messages MUST contain a "type" field which indicates
	  the general meaning of the message.
	</t>
	<t>
	  All requests from the PeerConnection object MUST contain
	  an "id" field which MUST be unique for that PeerConnection
	  object. Any responses from the IdP proxy MUST contain
	  the same id in response, which allows the PeerConnection
	  to correlate requests and responses.
	</t>
	<t>
	  Any message-specific data is carried in a "message"
	  field. Depending on the message type, this may
	  either be a string or a richer JSON object.
	</t>
	<section title="Errors">
	  <t>
	    If an error occurs, the IdP sends a message of
	    type "ERROR". The message MAY have an
	    "error" field containing freeform
	    text data which containing additional
	    information about what happened. For instance:
	  </t>
 <figure title="Example error" anchor="fig.example-error">
 <artwork><![CDATA[
        {
          "type":"ERROR",
          "error":"Signature verification failed"
        }
 ]]></artwork>
 </figure>
 </section>
      </section>
      
      <section title="IdP Proxy Setup" anchor="sec.iframe-setup">
	<t>
	  In order to perform an identity transaction, the PeerConnection
	  must first create the IdP proxy. While the specific technical
	  mechanism used is left up to the implementation, the
	  following requirements MUST be met for security and
	  interoperability.
	</t>
	<t>
	  <list style="symbols">
	    <t>Any JS MUST run in the IdP's security context.</t>
	    <t>The usual browser sandbox isolation mechanisms MUST
	    be enforced with respect to the IdP proxy.</t>
	    <t>JS running in the IdP proxy MUST be able to
	    send and receive messages to the PeerConnection
	    object using postMessage.</t>
	    <t>Either window.parent or window.opener MUST
	    be set such that messages sent with postMessage()
	    arrive at the PeerConnection object. If both
	    variables are set, they MUST be the same.</t>
	    <t>Messages sent by the PeerConnection object
	    MUST have their .origin value set to "rtcweb:://idp-interface".
	    [TBD]</t>
	  </list>
	</t>
	<t>
	  One mechanism for implementing the IdP proxy is as a hidden
	  (CSS "display=none") IFRAME with a URI as determined in <xref
	  target="sec.idp-uri"/>. The PeerConnection component 
	  will of course need to specially arrange for the 
	  origin value to be set correctly; as dicussed in
	  <xref target="sec.sec-cons"/>, the fact that ordinary
	  Web pages cannot set their origins to "rtcweb://..."
	  is an essential security feature.
	</t>

	<t>
	  Initially the IdP proxy is in an unready state; the 
	  IdP JS must be loaded and there may be several round 
	  trips to the IdP server, for instance to log the user
	  in. Thus, the IFRAME's "onready" property is not a reliable
	  indicator of when the IdP IFRAME is ready to receive commands.
	  Instead, when the IdP proxy is ready to receive commands,
	  it delivers a "ready" message via postMessage(). As this
	  message is unsolicited, it simply contains:
	</t>
      <figure>
 <artwork><![CDATA[
        { "type":"READY" }
  ]]></artwork>
      </figure>
      <t>
	Once the PeerConnection object receives the ready message,
	it can send commands to the IdP proxy.
      </t>
      <section title="Determining the IdP URI" anchor="sec.idp-uri">
	<t>
	  Each IdP proxy instance is associated with two values:
	</t>
	<t>
	  <list style="hanging">
	    <t hangText="domain name:">The IdP's domain name</t>
	    <t hangText="protocol:">The specific IdP protocol
	    which the IdP is using. This is a completely IdP-specific
	    string, but allows an IdP to implement two protocols
	    in parallel. This value may be the empty string.</t>
	  </list>
	</t>
	<t>
	  Each IdP MUST serve its initial entry page
	  (i.e., the one loaded by the IdP proxy) from
	  the well-known URI specified in 
	  "/.well-known/idp-proxy/&lt;protocol&gt;" on
	  the IdP's web site. This URI MUST be loaded
	  via HTTPS <xref target="RFC2818"/>.
	  For example, for the IdP "identity.example.com"
	  and the protocol "example", the URL
	  would be:
	</t>
	<figure>
 <artwork><![CDATA[
 https://example.com/.well-known/idp-proxy/example
  ]]></artwork>
	</figure>
	<section title="Authenticating Party">
	  <t>
	    How an AP determines the appropriate IdP domain is
	    out of scope of this specification. In general, 
	    however, the AP has some actual account relationship 
	    with the IdP, as this identity is what the IdP is 
	    attesting to. Thus, the AP somehow supplies the
	    IdP information to the browser. Some potential
	    mechanisms include:
	  </t>
	  <t>
	    <list style="symbols">
	      <t>Provided by the user directly.</t>
	      <t>Selected from some set of IdPs known to the calling site.
	      E.g., a button that shows "Authenticate via Facebook Connect"</t>
	    </list>
	  </t>
	</section>
	<section title="Relying Party">
	  <t>
	    Unlike the AP, the RP need not have any particular
	    relationship with the IdP. Rather, it needs to be able
	    to process whatever assertion is provided by the AP.
	    As the assertion contains the IdP's identity,
	    the URI can be constructed directly from the 
	    assertion, and thus the RP can directly verify
	    the technical validity of the assertion with no user 
	    interaction. Authoritative assertions need only
	    be verifiable. Third-party assertions also MUST be
	    verified against local policy, as described in
	    <xref target="sec.id-format"/>.
	  </t>
	</section>
      </section>
      </section>
      <section title="Requesting Assertions" anchor="sec.request-assert">
	<t>
	  In order to request an assertion, the PeerConnection
	  sends a "SIGN" message. Aside from the mandatory fields,
	  this message has a "message" field containing a string.
	  The contents of this string are defined in 
	  <xref target="I-D.ietf-rtcweb-security"/>, but are
	  opaque from the perspective of this protocol.
	</t>
	<t>
	  A successful response to a "SIGN" message contains
	  a message field which is a JS dictionary 
	  dictionary consisting of two fields:
	</t>
	<t>
	  <list style="hanging">
	    <t hangText="idp:">A dictionary containing the domain name of the provider
	    and the protocol string</t>
	    <t hangText="assertion:">An opaque field containing the
	    assertion itself. This is only interpretable by the
	    idp or its proxy.</t>
	  </list>
	</t>
	<t>
	  <xref target="fig.assert-request"/> shows an
	  example transaction, with the message 
	  "abcde..." being signed and bound to identity
	  "ekr@example.org". In this case, the message has presumably
	  been
	  digitally signed/MACed in some way that the IdP can
	  later verify it, but this is an implementation detail
	  and out of scope of this document. Line breaks are inserted
	  solely for readability.
	</t>
 
      <figure title="Example assertion request" anchor="fig.assert-request">
 <artwork><![CDATA[
    PeerConnection -> IdP proxy:
      {
        "type":"SIGN",
         "id":1,
         "message":"abcdefghijklmnopqrstuvwyz"
      }
      
    IdPProxy -> PeerConnection:
      {
        "type":"SUCCESS",
        "id":1,
        "message": {
	  "idp":{
	    "domain": "example.org"
	    "protocol": "bogus"
 	  },
	  "assertion":\"{\"identity\":\"bob@example.org\",
	                 \"contents\":\"abcdefghijklmnopqrstuvwyz\",
                         \"signature\":\"010203040506\"}"
        }
      }
  ]]>
 </artwork>
      </figure>

      </section>

      <section title="Verifying Assertions" anchor="sec.verify-assert">
	<t>
	  In order to verify an assertion, an RP sends a "VERIFY"
	  message to the IdP proxy containing the assertion 
	  supplied by the AP in the "message" field.
	</t>
	<t>
	  The IdP proxy verifies the assertion. Depending on the
	  identity protocol, this may require one or more round
	  trips to the IdP. For instance, an OAuth-based protocol
	  will likely require using the IdP as an oracle,
	  whereas with BrowserID the IdP proxy can likely
	  verify the signature on the assertion without
	  contacting the IdP, provided that it has cached
	  the IdP's public key.
	</t>
	<t>
	  Regardless of the mechanism,
	  if verification succeeds, a successful response from
	  the IdP proxy MUST contain a message field consisting
	  of a dictionary/hash with the following fields:
	</t>
	<t>
	  <list style="hanging">
	    <t hangText="identity">The identity of the AP from the
	    IdP's perspective. Details of this are provided in
	    <xref target="sec.id-format"/></t>
	    <t hangText="contents">The original unmodified string
	    provided by the AP in the original SIGN request.
	    </t>
	  </list>
	</t>
	<t>
	  <xref target="fig.verify-request"/> shows
	  an example transaction. Line breaks are inserted
	  solely for readability. 
	</t>

 <figure title="Example assertion request" anchor="fig.verify-request">
 <artwork><![CDATA[
      PeerConnection -> IdP Proxy:
        {
          "type":"VERIFY",
          "id":2,
	  "message":\"{\"identity\":\"bob@example.org\",
	               \"contents\":\"abcdefghijklmnopqrstuvwyz\",
                       \"signature\":\"010203040506\"}"
        }

      IdP Proxy -> PeerConnection:
        {
         "type":"SUCCESS",
         "id":2,
         "message": {
	   "identity" : {
	     "name" : "bob@example.org",
	     "displayname" : "Bob"
	   },
	   "contents":"abcdefghijklmnopqrstuvwyz"
	 }
        }
  ]]>
 </artwork>
      </figure>

      <section title="Identity Formats" anchor="sec.id-format">
	<t>
	  Identities passed from the IdP proxy to the PeerConnection
	  are structured as JSON dictionaries with one mandatory
	  field: "name". This field MUST consist of an
	  RFC822-formatted string representing the user's identity.
	  [[ OPEN ISSUE: Would it be better to have a typed field? ]]
	  The PeerConnection API MUST check this string as
	  follows:
	</t>
	<t>
	  <list style="numbers">
	    <t>If the RHS of the string is equal to the domain name
	    of the IdP proxy, then the assertion is valid,
	    as the IdP is authoritative for this domain.</t>
	    <t>If the RHS of the string is not equal to the domain
	    name of the IdP proxy, then the PeerConnection object
	    MUST reject the assertion unless (a) the 
	    IdP domain is listed as an acceptable third-party
	    IdP and (b) local policy is configured to trust
	    this IdP domain for the RHS of the identity string.
	    </t>
	  </list>
	</t>
	<t>
	  Sites which have identities that do not fit
	  into the RFC822 style (for instance, Facebook
	  ids are simple numeric values) SHOULD 
	  convert them to this form by appending their
	  IdP domain (e.g., 12345@identity.facebook.com),
	  thus ensuring that they are authoritative for
	  the identity.
	</t>
	<t>
	  The IdP proxy MAY also include a "displayname" field
	  which contains a more user-friendly identity assertion.
	  Browsers SHOULD take care in the UI to distinguish the
	  "name" assertion which is verifiable directly from the
	  "displayname" which cannot be verified and thus
	  relies on trust in the IdP. In future,
	  we may define other fields to allow the IdP to
	  provide more information to the browser.
	</t>
      </section>
      <section title="PostMessage Checks" anchor="sec.postmessage">
	<t>
	  Because the PeerConnect object and the IdP proxy communicate
	  via postMessage(), it is essential to verify that the
	  origin of any message (contained in the event.origin
	  property) and source (contained in the event.source)
	  property are as expected:
	</t>
	<t>
	  <list style="symbols">
	    <t>
	      For messages from the PeerConnection object, the
	      IdP proxy MUST verify that the origin is
	      "rtcweb://idp-interface" and that the source
	      matches either window.opener or window.parent.
	      If both are non-falsey, they MUST be equal.
	      If any of these checks fail, the message MUST
	      be rejected.
	      [[ OPEN ISSUE: An alternate (more generic) design would be to not
	      check the origin here but rather to include the origin 
	      in the assertion and have it checked at the RP. Comments? ]]
	    </t>
	    <t>
	      For messages from the IdP proxy, the PeerConnection
	      object MUST verify that the origin matches
	      the IdP's origin and that the source matches
	      the window/IFRAME opened for the IdP proxy.
	    </t>
	  </list>
	</t>
	<t>
	  If any of these checks fail, the message MUST
	  be rejected. In general, mismatches SHOULD NOT
	  cause transaction failure, since malicious
	  JS might use bogus messages as a form of DoS
	  attack.
	</t>
      </section>
      <section title="PeerConnection API Extensions" anchor="sec.pc-api">
	<section title="Authenticating Party">
	<t>
	  As discussed in <xref target="sec.trust-relationships"/>, 
	  the AP's IdP can either be configured directly into the
	  browser or selected from a list known to the calling
	  site. We anticipate that some browsers will allow
	  configuration of IdPs in the browser UI but allow the
	  calling application to provide new candidate IdPs or 
	  to direct the selection of a known one. Thus, one
	  model would be:
	</t>
	<t>
	  <list style="symbols">
	    <t>If a IdP is provided by the calling application use that.</t>
	    <t>If no IdP is provided, and one is configured, use that.</t>
	    <t>If no IdP is provided or configured, do nothing.</t>
	  </list>
	</t>
	<t>
	  Implementations MAY also wish to have configuration settings
	  override the calling application's preferences.
	</t>
	<t>
	  APIs for PeerConnection configuration are as-yet unsettled, but
	  it MUST be possible to specify the following parameters to the
	  PeerConnection.
	</t>
	<t>
	  <list style="symbols">
	    <t>The IdP domain.</t>
	    <t>The users expected identity (if known) [this allows selection
	    between multiple candidate identities with the same IdP.]</t>
	  </list>
	</t>
	</section>
	<section title="Relying Party">
	  <t>
	    Because the browser UI must be responsible for displaying
	    the user's identity, it isn't strictly necessary to
	    have new JS interfaces on the relying party side. However, 
	    two new interfaces are RECOMMENDED.
	  </t>
	  <t>
	    When a message is provided to the PeerConnection API with
	    processSignalingMessage() with an assertion that cannot
	    be verified, there is a need for some sort of error
	    indicating verification failure. [Note: I don't
	    see an interface for any other kind of parse error,
	    so I'm not sure what to imitate here.]
	  </t>
	  <t>
	    A new attribute should be added to indicate the verification
	    status. For instance:
 <figure>
 <artwork><![CDATA[
   readonly attribute DOMString verifiedIdentity;
  ]]>
 </artwork>
 </figure>
            The attribute value should be a JS dictionary indicating the identity
	    and the domain name of the IdP, such as:
	  </t>
 <figure>
 <artwork><![CDATA[
 {
   "identity" : "ekr@example.org",
   "idp": "example.org"
 }
  ]]>
 </artwork>
 </figure>
	</section>
      </section>
    </section>
    
    <section title="Example Bindings to Specific Protocols">
      <t>
	This section provides some examples of how the
	mechanisms described in this document could be used
	with existing authentication protocols such as
	BrowserID or OAuth. Note that this does not
	require browser-level support for either protocol.
	Rather, the protocols can be fit into the generic
	framework. (Though BrowserID in particular works
	better with some client side support).
      </t>
	<section title="BrowserID">
	  <t>
	    BrowserID [https://browserid.org/] is a technology which 
	    allows a user with a verified email address to generate
	    an assertion (authenticated by their identity provider) 
	    attesting to their identity (phrased as an email address).
	    The way that this is used in practice is that the relying
	    party embeds JS in their site which talks to the BrowserID
	    code (either hosted on a trusted intermediary or embedded
	    in the browser). That code generates the assertion which is
	    passed back to the relying party for verification.
	    The assertion can be verified directly or with a Web
	    service provided by the identity provider.
	    It's relatively easy to extend this functionality to 
	    authenticate RTCWEB calls, as shown below.
	  </t>
      <figure>
	<artwork><![CDATA[
+----------------------+                     +----------------------+
|                      |                     |                      |
|    Alice's Browser   |                     |     Bob's Browser    |
|                      | OFFER ------------> |                      |
|   Calling JS Code    |                     |    Calling JS Code   |
|          ^           |                     |          ^           |
|          |           |                     |          |           |
|          v           |                     |          v           |
|    PeerConnection    |                     |    PeerConnection    |			       
|       |      ^       |                     |       |      ^       |			       
| Finger|      |Signed |	             |Signed |      |       |
| print |      |Finger |                     |Finger |      |"Alice"|
|       |      |print  |	    	     |print  |      |       |
|       v      |       |	    	     |       v      |       |
|   +--------------+   |	    	     |   +---------------+  |
|   |  IdP Proxy   |   |                     |   |  IdP Proxy    |  |
|   |     to       |   |                     |   |     to        |  |
|   |  BrowserID   |   |	    	     |   |  BrowserID    |  |
|   |  Signer      |   |	    	     |   |  Verifier     |  |
|   +--------------+   |	    	     |   +---------------+  | 
|           ^          |	    	     |          ^           |
+-----------|----------+                     +----------|-----------+
            |                                           |
            | Get certificate                           |
	    v                                           | Check 
+----------------------+                                | certificate
|                      |                                |
|       Identity       |/-------------------------------+
|       Provider       |
|                      |
+----------------------+            
 	]]></artwork>
      </figure>
      <t>
	The way this mechanism works is as follows. On Alice's side, Alice
	goes to initiate a call.
      </t>
      <t><list style="numbers">
	<t>The calling JS instantiates a PeerConnection
	and tells it that it is interested in having it authenticated 
	via BrowserID (i.e., it provides "browserid.org" as the
	IdP name.)</t>
	<t>The PeerConnection instantiates the BrowserID signer in
	the IdP proxy
	</t>
	<t>The BrowserID signer contacts Alice's identity provider,
	authenticating as Alice (likely via a cookie).</t>
	<t>The identity provider returns a short-term certificate
	attesting to Alice's identity and her short-term public key.</t>
	<t>The Browser-ID code signs the fingerprint and returns the
	signed assertion + certificate to the PeerConnection. </t>
	<t>The PeerConnection returns the signed information to the
	calling JS code.</t>
	<t>The signed assertion gets sent over the wire to Bob's
	browser (via the signaling service) as part of the call setup.</t>
      </list>
      </t>
      <t>
	Obviously, the format of the signed assertion varies depending
	on what signaling style the WG ultimately adopts. However, for
	concreteness, if something like ROAP were adopted, then the
	entire message might look like:
      </t>
      <figure>
	<artwork><![CDATA[
   {
     "messageType":"OFFER",
     "callerSessionId":"13456789ABCDEF",
     "seq": 1
     "sdp":"
   v=0\n
   o=- 2890844526 2890842807 IN IP4 192.0.2.1\n
   s= \n
   c=IN IP4 192.0.2.1\n
   t=2873397496 2873404696\n
   m=audio 49170 RTP/AVP 0\n
   a=fingerprint: SHA-1 \
   4A:AD:B9:B1:3F:82:18:3B:54:02:12:DF:3E:5D:49:6B:19:E5:7C:AB\n",
    "identity":{
         "idp":{     // Standardized
	    "domain":"browserid.org",
	    "method":"default"
         },
	 "assertion":   // Contents are browserid-specific
	   "\"assertion\": {
             \"digest\":\"<hash of the contents from the browser>\",
             \"audience\": \"[TBD]\"
             \"valid-until\": 1308859352261,
            }, 
            \"certificate\": {
              \"email\": \"rescorla@example.org\",
              \"public-key\": \"<ekrs-public-key>\",
              \"valid-until\": 1308860561861,
            }" // certificate is signed by example.org
	 }
   }
 	]]></artwork>
      </figure>
      <t>
	<!-- [TODO: Need to talk about Audience a bit.] -->
	Note that while the IdP here is specified as "browserid.org",
	the actual certificate is signed by example.org. This is because
	BrowserID is a combined authoritative/third-party system in
	which browserid.org delegates the right to be authoritative
	(what BrowserID calls primary) to individual domains.
      </t>
      <t>
	On Bob's side, he receives the signed assertion as part of the call
	setup message and a similar procedure happens to verify it.
      </t>
      <t><list style="numbers">
	<t>The calling JS instantiates a PeerConnection
	and provides it the relevant signaling information, including the
	signed assertion.</t>
	<t>The PeerConnection instantiates the IdP proxy which examines 
	the IdP name and brings up the BrowserID verification code.</t>
	<t>The BrowserID verifier contacts the identity provider to
	verify the certificate and then uses the key to verify the
	signed fingerprint.</t>
	<t>Alice's verified identity is returned to the PeerConnection
	(it already has the fingerprint).</t>
	<t>At this point, Bob's browser can display a trusted UI indication
	that Alice is on the other end of the call.</t>
      </list>
      </t>
      <t>
	When Bob returns his answer, he follows the converse procedure, which
	provides Alice with a signed assertion of Bob's identity and keying
	material.
      </t>
      </section>

	<section title="OAuth">
	  <t>
	    While OAuth is not directly designed for user-to-user authentication,
	    with a little lateral thinking it can be made to serve. We use the
	    following mapping of OAuth concepts to RTCWEB concepts:
	  </t>
	    <texttable anchor="oauth-rtcweb">
	      <ttcol align="left">OAuth</ttcol>
	      <ttcol align="left">RTCWEB</ttcol>
	      <c>Client</c><c>Relying party</c>
	      <c>Resource owner</c><c>Authenticating party</c>
	      <c>Authorization server</c><c>Identity service</c>
	      <c>Resource server</c><c>Identity service</c>
	    </texttable>
	  <t>
	    The idea here is that when Alice wants to authenticate to Bob (i.e., for
	    Bob to be aware that she is calling). In order to do this, she allows
	    Bob to see a resource on the identity provider that is bound to the
	    call, her identity, and her public key. Then Bob retrieves the resource
	    from the identity provider, thus verifying the binding between Alice
	    and the call.
	  </t>
      <figure>
	<artwork><![CDATA[
	Alice                       IdP                       Bob
	---------------------------------------------------------
        Call-Id, Fingerprint  ------->
        <------------------- Auth Code
	Auth Code ---------------------------------------------->
  	                             <----- Get Token + Auth Code
				     Token --------------------->
				     <------------- Get call-info 
				     Call-Id, Fingerprint ------>
 	]]></artwork>
      </figure>
      <t>
	This is a modified version of a common OAuth flow, but
	omits the redirects required to have the client point the
	resource owner to the IdP, which is acting as both 
	the resource server and the authorization server, since
	Alice already has a handle to the IdP.
      </t>
      <t>
	Above, we have referred to "Alice", but really what we mean
	is the PeerConnection. Specifically, the PeerConnection will
	instantiate an IFRAME with JS from the IdP and will use
	that IFRAME to communicate with the IdP, authenticating
	with Alice's identity (e.g., cookie). Similarly, Bob's
	PeerConnection instantiates an IFRAME to talk to the IdP.
      </t>
      </section>
    </section>
    <section title="Security Considerations" anchor="sec.sec-cons">
      <t>
	This mechanism relies for its security on the IdP and on
	the PeerConnection correctly enforcing the security 
	invariants described above. At a high level, the IdP
	is attesting that the user identified in the assertion
	wishes to be associated with the assertion. Thus,
	it must not be possible for arbitrary third parties to
	get assertions tied to a user or to produce assertions
	that RPs will accept.
      </t>

      <section title="PeerConnection Origin Check" anchor="sec.pc-origin">
	<t>
	  Fundamentally, the IdP proxy is just a piece of HTML and JS
	  loaded by the browser, so nothing stops a Web attacker o
	  from creating their own IFRAME, loading the IdP proxy HTML/JS,
	  and requesting a signature. In order to prevent this attack,
	  we require that all signatures be tied to a specific 
	  origin ("rtcweb://...") which cannot be produced by
	  a page tied to a Web attacker. Thus, while an attacker
	  can instantiate the IdP proxy, they cannot send messages
	  from an appropriate origin and so cannot create acceptable
	  assertions. [[OPEN ISSUE: Where is this enforced? ]]
	</t>
      </section>

      <section title="IdP Well-known URI" anchor="sec.sec-idp-uri">
	<t>
	  As described in <xref target="sec.idp-uri"/> the IdP proxy
	  HTML/JS landing page is located at a well-known URI based on
	  the IdP's domain name. This requirement prevents an attacker
	  who can write some resources at the IdP (e.g., on one's
	  Facebook wall) from being able to impersonate the IdP.
	</t>
      </section>

      <section title="Security of Third-Party IdPs" anchor="sec.sec-third-party">
	<t>
	  As discussed above, each third-party IdP represents a new universal trust
	  point and therefore the number of these IdPs needs to be 
	  quite limited. Most IdPs, even those which issue unqualified
	  identities such as Facebook, can be recast as authoritative
	  IdPs (e.g., 123456@facebook.com). However, in such cases,
	  the user interface implications are not entirely desirable.
	  One intermediate approach is to have special (potentially user
	  configurable) UI for large authoritative IdPs, thus allowing
	  the user to instantly grasp that the call is being authenticated
	  by Facebook, Google, etc.
	</t>
      </section>
    </section>

    <section title="Web Security Feature Interactions">
	<t>
	  A number of optional Web security features have the potential
	  to cause issues for this mechanism, as discussed below.
	</t>
	<section title="Popup Blocking" anchor="sec.popup-blocking">
	  <t>
	    If the user is not already logged into the IdP, the 
	    IdP proxy may need to pop up a top level window in order
	    to prompt the user for their authentication information
	    (it is bad practice to do this in an IFRAME inside the
	    window because then users have no way to determine the
	    destination for their password). If the user's browser
	    is configured to prevent popups, this may fail
	    (depending on the exact algorithm that the popup blocker
	    uses to suppress popups). It may be necessary to provide
	    a standardized mechanism to allow the IdP proxy to
	    request popping of a login window. Note that
	    care must be taken here to avoid PeerConnection becoming
	    a general escape hatch from popup blocking. One possibility
	    would be to only allow popups when the user has explicitly
	    registered a given IdP as one of theirs (this is only relevant
	    at the AP side in any case). This is what WebIntents does, and
	    the problem would go away if WebIntents is used.
	  </t>
	</section>

	<section title="Third Party Cookies" anchor="sec.3rd-party-cookies">
	  <t>
	    Some browsers allow users to block third party cookies (cookies associated
	    with origins other than the top level page) for privacy reasons.
	    Any IdP which uses cookies to persist logins will be broken
	    by third-party cookie blocking. One option is to accept this
	    as a limitation; another is to have the PeerConnection object
	    disable third-party cookie blocking for the IdP proxy.
	  </t>
	</section>

      </section>
    </section>
  </middle>

  <back>


    <references title="Normative References">
      &RFC2119;      
      &RFC2818;      
      &I-D.ietf-rtcweb-security;
      &I-D.ietf-rtcweb-security-arch;
      
      &RFC4627;
    </references>
    <references title="Informative References">
      &RFC6454;
    </references>
  </back>
</rfc>

