<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Fri, Jul 4, 2014 at 4:33 AM, Shane Tomlinson <span dir="ltr"><<a href="mailto:stomlinson@mozilla.com" target="_blank">stomlinson@mozilla.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">IIUC, the core problem you are trying to solve arises because the user is being asked to grant the RP authorization to two distinct service providers in a single oauth transaction, and a single token would allow one service provider to masquerade as the user at the other service provider?<br>

</blockquote><div><br></div><div>Yes, as well as any middleman along the way who is able to see the token, such as if SSL isn't used or is cracked.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">



<br>
First off, what is the crypto being used for? I think the answer is this sentence:<br>
<br>
> The next step was to consider using a secret token to sign a request, so that the original token is never revealed.<br>
<br>
In step 4, the RP receives a token from the OAuth server. In step 5, the RP takes that code, creates a pub/priv keypair, creates a bundle with the pubkey, the code, and the client_secret, signs the bundle with the privkey and ships it to the OAuth server?</blockquote>

<div><br></div><div>Yep again.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> Does the RP then have to store the pub/priv key for this user/scope combination for all of eternity, or is this client side only?</blockquote>

<div><br></div><div>As long as the user has an account at the RP, and the OAuth server hasn't expired this "token". Similar to receiving a bearer token in typical OAuth2, you need to hold on to it as long as you wish to make requests on behalf of the user. Here, you'd just have 2 data pieces instead of one: public and private key. With ed25519, these keys are small, so it shouldn't affect storage much.<br>

</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> If the priv key is sent to the RP, what threats exist if their server is compromised?</blockquote>

<div><br></div><div>The private key shouldn't be sent anywhere: the RP should generate a keypair, and then guard the private key. If their server is compromised, the responsible thing to do would be to tell our OAuth server which "keys" to destroy. If it were a big enough RP that we'd notice, we could also destroy all "keys" associated with their client_id.<br>

</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"> What happens if the user is asked to re-authorize, is the same pub/priv key used, or is a new one generated?</blockquote>

<div><br></div><div>You should create a new keypair if re-authorizing with the OAuth server, such as to get additional scopes.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

 Can the OAuth provider masquerade as the user anywhere they like?<br></blockquote><div><br></div><div>The OAuth provider is the gatekeeper for the user. It has the power to say if a certain pubkey has scopes or not. Therefore, it could potentially create its own keypair and give itself any scopes it wanted; it's been empowered to act as the user already.<br>

</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
In step 6, what happens if the OAuth server already has a pubkey stored for the user/scope combination, does it reject the new one, clear the old one or store them both? If there are multiple keys stored, are old ones ever ejected?<br>

</blockquote><div><br></div><div>The OAuth server will accept the new pubkey. The RP could ask the OAuth server to destroy the old one. The old one might be cleaned up when it expires, but we haven't yet specified an expiration of tokens, just "codes".<br>

</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
In step 7, instead of passing the original token, the RP creates a new bundle that contains an encrypted/hashed version of the original token along with the scope? What info does the Profile server use to actually ensure the request is authorized? Does the Profile server need to share state with the OAuth server?<br>

</blockquote><div><br></div><div>The signature is created similar to Hawk; it's all information found in the request itself. Here's the info that's used to create the header: <br><div class="" id="LC58"><span class="">{</span></div>

<div class="" id="LC59">    <span class="">type</span><span class="">:</span> <span class="">'header'</span><span class="">,</span></div><div class="" id="LC60">    <span class="">pubkey</span><span class="">:</span> <span class="">fields</span><span class="">.</span><span class="">pubkey</span><span class="">,</span></div>

<div class="" id="LC61">    <span class="">ts</span><span class="">:</span> <span class="">fields</span><span class="">.</span><span class="">ts</span><span class="">,</span></div><div class="" id="LC62">    <span class="">nonce</span><span class="">:</span> <span class="">fields</span><span class="">.</span><span class="">nonce</span><span class="">,</span></div>

<div class="" id="LC63">    <span class="">method</span><span class="">:</span> <span class="">req</span><span class="">.</span><span class="">method</span><span class="">.</span><span class="">toUpperCase</span><span class="">(),</span></div>

<div class="" id="LC64">    <span class="">resource</span><span class="">:</span> <span class="">req</span><span class="">.</span><span class="">path</span><span class="">,</span></div><div class="" id="LC65">    <span class="">host</span><span class="">:</span> <span class="">req</span><span class="">.</span><span class="">hostname</span><span class="">,</span></div>

<div class="" id="LC66">    <span class="">port</span><span class="">:</span> <span class="">req</span><span class="">.</span><span class="">port</span> <span class="">||</span> <span class="">(</span><span class="">req</span><span class="">.</span><span class="">protocol</span> <span class="">===</span> <span class="">'https:'</span> <span class="">?</span> <span class="">443</span> <span class="">:</span> <span class="">80</span><span class="">),</span></div>

<div class="" id="LC67">    <span class="">payload</span><span class="">:</span> <span class="">req</span><span class="">.</span><span class="">payload</span> <span class="">?</span> <span class="">payloadHash</span><span class="">(</span><span class="">req</span><span class="">.</span><span class="">payload</span><span class="">,</span> <span class="">req</span><span class="">.</span><span class="">contentType</span><span class="">)</span> <span class="">:</span> <span class="">''</span></div>

<div class="" id="LC68">  <span class="">}<br><br></span></div><div class="" id="LC68"><span class="">The service provider, such as the Profile server, can decode the signature using the pubkey in the Authorization header, and compare with the info in the request. Once it's sure the signature is authentic (we can provide libraries to do this, such as the nodejs gryphon library already does), the service provider just needs to ask the OAuth server for the scopes permitted to that pubkey.<br>

</span></div></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
I'm going on to step 8 - requesting info from FoxCoin, is it a repeat of step 7, just with a different service provider?<br></blockquote><div><br></div><div>Yep, so the host, port, resource, timestamp, nonce, and payload would likely differ, creating a different signature.<br>

</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
<br>
Is there any notion of expiration? If my device has a magic priv key to FoxCoin, and then is stolen, will the thief forever have access to my FoxCoin account?<br></blockquote><div><br></div><div>The pubkey/token can be manually removed from OAuth via POST /v1/destroy. FoxCoin could notice and do this, or we also would like to have a dashboard that allows the user to see what apps have which scopes, and a button to revoke them.<br>

<br></div><div>Expiration after a certain time is possible, but hasn't yet been defined.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">


<br>
What new requirements are imposed on an RP that are not already imposed by OAuth? It sounds like a ed25519 library, and potentially storing pub/priv keys? Are vetted ed25519 libraries readily available for popular languages?<br>


<br></blockquote><div><br></div><div>That's it. Plus request signing instead of just passing a bearer token when asking for information. <br></div></div><br></div><div class="gmail_extra">A thorough and popular library that includes the ed25519 library is libsodium[1], which has bindings to many languages[2].<br>

<br>[1]: <a href="https://github.com/jedisct1/libsodium">https://github.com/jedisct1/libsodium</a><br>[2]: <a href="http://doc.libsodium.org/bindings_for_other_languages/README.html">http://doc.libsodium.org/bindings_for_other_languages/README.html</a><br>

</div></div>