Re: [OAUTH-WG] Proof-Of-Possession Semantics for JSON Web Tokens (JWTs)

John Bradley <ve7jtb@ve7jtb.com> Sun, 13 April 2014 20:00 UTC

Return-Path: <ve7jtb@ve7jtb.com>
X-Original-To: oauth@ietfa.amsl.com
Delivered-To: oauth@ietfa.amsl.com
Received: from localhost (ietfa.amsl.com [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 6BBCD1A0221 for <oauth@ietfa.amsl.com>; Sun, 13 Apr 2014 13:00:08 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.9
X-Spam-Level:
X-Spam-Status: No, score=-1.9 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001] autolearn=ham
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id SuHmRIKadfsG for <oauth@ietfa.amsl.com>; Sun, 13 Apr 2014 13:00:03 -0700 (PDT)
Received: from mail-qg0-f48.google.com (mail-qg0-f48.google.com [209.85.192.48]) by ietfa.amsl.com (Postfix) with ESMTP id 04FCA1A021D for <oauth@ietf.org>; Sun, 13 Apr 2014 13:00:02 -0700 (PDT)
Received: by mail-qg0-f48.google.com with SMTP id z60so488395qgd.7 for <oauth@ietf.org>; Sun, 13 Apr 2014 13:00:00 -0700 (PDT)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:content-type:mime-version:subject:from :in-reply-to:date:cc:message-id:references:to; bh=UHQnk0yiuQmJeKgfwgMlqwjHxdCzY8450WrPY1rddGE=; b=P7lvnjL0mZ2YpsNormNLczsrht8Dl6wYEIQv+IGYx5+Fqn/dGmzSQR+dASNockCITq gVifz0s8wsnc4wuQzLZuBwV/JOFQ1BxaSKnSD6zK2CoNBqQHxjDRXqRMS52QJTJ4Boyy jn2j9ZpuoEsAPkDIlExEVo/e7pyh5S0leyjjxQUyzjhsMlF8eoUN+OouY9ReNHqVaALi TBlEE9q8oXzTOW5d63suDrKKExMQUY8W97aPFL2kOA+sxkF/e6vCTP4S68kPNmdh6Chw 8JEIfYa7zskgSr3qM7R/nuu32ac5V4ZV9axoCV5R6Q/o/jdNFIv3RY4Q27ValFMVQ3Ex QP6Q==
X-Gm-Message-State: ALoCoQnvPrlkGXPVFChVlvnR/+jZTj4vRU50ww968u4zO48tzZ4qyxxOHAUvhWVNt5oTnGLh8zai
X-Received: by 10.224.119.141 with SMTP id z13mr14420100qaq.48.1397419200427; Sun, 13 Apr 2014 13:00:00 -0700 (PDT)
Received: from [192.168.1.216] ([190.22.32.162]) by mx.google.com with ESMTPSA id c61sm17685581qgf.15.2014.04.13.12.58.58 for <multiple recipients> (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 13 Apr 2014 13:00:00 -0700 (PDT)
Content-Type: multipart/alternative; boundary="Apple-Mail=_DF0562C2-38EA-4C5A-B0B4-E6933DFFE11A"
Mime-Version: 1.0 (Mac OS X Mail 7.2 \(1874\))
From: John Bradley <ve7jtb@ve7jtb.com>
In-Reply-To: <CA+wnMn9xB94kf-mncv7a7Q6GB8W6GTvyq_+LXUyMhN6kAqDbmg@mail.gmail.com>
Date: Sun, 13 Apr 2014 16:57:50 -0300
Message-Id: <222ED748-B291-4E1F-BF26-54072EAF696F@ve7jtb.com>
References: <4E1F6AAD24975D4BA5B16804296739439A132083@TK5EX14MBXC286.redmond.corp.microsoft.com> <CA+wnMn_LBojNz+LCTTQN62P_U7Rag0rot715c7XCOcXAQJmEhA@mail.gmail.com> <4E1F6AAD24975D4BA5B16804296739439A155FFB@TK5EX14MBXC286.redmond.corp.microsoft.com> <CA+wnMn-Dto7ySgNgMu5rkqyzfok1BWdS7WxB18ep+Uv0sFRsuw@mail.gmail.com> <4E1F6AAD24975D4BA5B16804296739439A15609B@TK5EX14MBXC286.redmond.corp.microsoft.com> <C782E37A-A38D-4C12-8029-B5934ADA3977@ve7jtb.com> <CA+wnMn_LyO4wmhfuPYnNO87sq8c-p4zgpKbNqUnEYhJzvCpmhg@mail.gmail.com> <CA+wnMn9xB94kf-mncv7a7Q6GB8W6GTvyq_+LXUyMhN6kAqDbmg@mail.gmail.com>
To: Chuck Mortimore <cmortimore@salesforce.com>
X-Mailer: Apple Mail (2.1874)
Archived-At: http://mailarchive.ietf.org/arch/msg/oauth/EBhE4CQlyBan1bYomKttlDrGV_A
Cc: "oauth@ietf.org" <oauth@ietf.org>
Subject: Re: [OAUTH-WG] Proof-Of-Possession Semantics for JSON Web Tokens (JWTs)
X-BeenThere: oauth@ietf.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: OAUTH WG <oauth.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/oauth>, <mailto:oauth-request@ietf.org?subject=unsubscribe>
List-Archive: <http://www.ietf.org/mail-archive/web/oauth/>
List-Post: <mailto:oauth@ietf.org>
List-Help: <mailto:oauth-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/oauth>, <mailto:oauth-request@ietf.org?subject=subscribe>
X-List-Received-Date: Sun, 13 Apr 2014 20:00:08 -0000

That is one way it might be done.

Sending the thumbprint in the authorization request is similar to sec 2.2 https://tools.ietf.org/html/draft-sakimura-oauth-tcse-02

I have always thought of that spec as wanting to be a a proof of possession for code.

So in the case where the AS and the token endpoint are in the same security domain this is really just a code flow with the thumbprint in "code_challenge" or "jkt"
Then uses the assertion flow to authenticate as you describe.

For native apps this avoids per instance registration and gets you almost all the benefits of a private client.

Nothing stops you from making code a JWT and passing the thumbprint to the Token endpoint statelesly.  
The token endpoint can then use the same pattern for generating the refresh token and on down to the access token.

We want to separate the logical parts to document:
1  the format of the JWT itself
2 Getting a pop token and key establishment
3 using a PoP token at a RS
4 PoP presentment at the token endpoint for code and refresh. (I think it is important, but some think it is low priority,  In OAuth people have mostly been thinking about PoP at the RS)

As you point out with the JWT assertion flow PoP is posable for clients that are otherwise public with a bit of profiling.

The format you propose is similar to http://tools.ietf.org/html/draft-jones-oauth-token-exchange-00  If you mix in PoP.  

Perhaps it is just a "urn:ietf:params:oauth:grant-type:jwt-pop" grant_type where code is used as the pop value in your example.  
If we were talking about Connect then yes we might use the id_token returned, but for the id_token with the client as the aud I hope we can eventually have the user agent provide a proof key once we have web crypto available.  So overloading the id_token may not be as simple as just treating the value of code as an assertion that can be a JWT/SAML/or reference.

John B.


On Apr 13, 2014, at 3:05 PM, Chuck Mortimore <cmortimore@salesforce.com> wrote

> Was also trying to work through what this would look like with thumbnails.    Does this sounds right?
> 
> 
> 1) Client generates a private / public key
> 
> 2) Client calculates a public key thumbprint like this:  http://tools.ietf.org/html/draft-jones-jose-jwk-thumbprint-00
> 
> For example for this key
> 
> {"e":"AQAB","kty":"RSA","n":"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2
> 
>      aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCi
>      FV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65Y
>      GjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n
> 
>      91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_x
>      BniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw"}
> 
>  You’d arrive  at: NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs
> 
> 3)  Client passes the thumbprint in an oauth authorization request as a parameter “jkt=NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs”
> 
> 4) Authorization server constructs an id_token like this:
> 
> {
>      "iss": "https://login.salesforce.com",
>      "sub": "https://login.salesforce.com/id/00D30000001bZxaEAE/00530000009UVC0AAO"
>      "aud": "3MVG99OxTyEMCQ3gXuX31lysX3RQP4.Vj3EVzlMsVbxFvUe7VjZ0WcjWvGlAU7BPJFZBSyBGPiGyHhojZ2BE3",
>      "exp": 1397352138,
>      "iat": 1397352018,
>      "nbf": 1397352018,
>      "cnf":{
> 	    "jwk":{
>                            "jkt": “NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs”
>  }
> 	 }
> } 
> 
> 
> 5) This ID Token can then be passed by the client or a delegate with the key to the token endpoint via JWT bearer flow and prove possession by constructing a JWT that looks like this:
> 
> {"alg":"RS256"}
> .
> {
>      "jwk":{
> 	"kty": "RSA",
> 	"n": "0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2
> 
>      aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCi
>      FV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65Y
>      GjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n
> 
>      91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_x
>      BniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw",
> 	"e": "AQAB"
>      }
>      "pop": "base64url encoded id token",
> }
> .
> signture with private key
> 
> When this is posted as a JWT bearer assertion, the token endpoint 
> 
> a) verifies that the outer signature matches the public key, b) that the public key matches the thumbprint signed into the inner id token, and c) that the signature on the id token is valid.   It can than act as then issue a token response for the sub of the inner id token
> 
> Look correct?
> 
> -cmort
> 
> 
> 
> On Sun, Apr 13, 2014 at 9:31 AM, Chuck Mortimore <cmortimore@salesforce.com> wrote:
> Yes - sounds about what I'm looking at
> 
> For the scenario, we'd have a client talking to our authorization server that is also paired with it's own cloud backend.   The cloud would have a certificate pre-reigstered with our authorization server, and the client would dynamically generate it's own public/private key.    Both would be able to prove possession using their own keys without sharing.    So to answer mike's data structure question, it would looks something like this
> 
> 1) Client requests id token and in the authorization request it passes in its newly minted public key ( or perhaps a thumbprint but not covering that here) 
> 
> 2) Authorization server authorizes, and mints new id token as jwk set containing both the dynamically generated client key and also the cert for its server:
> 
> {
>      "iss": "https://login.salesforce.com",
>      "sub": "https://login.salesforce.com/id/00D30000001bZxaEAE/00530000009UVC0AAO"
>      "aud": "3MVG99OxTyEMCQ3gXuX31lysX3RQP4.Vj3EVzlMsVbxFvUe7VjZ0WcjWvGlAU7BPJFZBSyBGPiGyHhojZ2BE3",
>      "exp": 1397352138,
>      "iat": 1397352018,
>      "cnf":
> 	 	{
> 			"keys":[
> 				{
> 					"kty": "RSA",
> 					"n": "AKPBc9I142dEc-Srdk5sz9MVaJH_k....",
> 					"e": "AQAB",
> 					"alg": "RS256"
> 				},
> 				{
> 					"x5c":["MIIDQjCCAi...."]  			     
> 				}
> 			]
> 		}
> } 
> 
> 
> The id token can then be presented to something like our oauth token endpoint as an assertion by either the client application such as a mobile app, or the server infrastructure it's paired with.   The client's key is client specific.   The server's key is global for the application.  No need to share between them, and the capabilities of the grant could vary.
> 
> Proof would simply be constructing a JWT that signs the id token with the required key: outerheader.base64url(innerheader.body.innersignature).outersignature
> 
> -cmort
> 
> 
> 
> On Sun, Apr 13, 2014 at 8:34 AM, John Bradley <ve7jtb@ve7jtb.com> wrote:
> I think Chuck is largely referring to the scenario that Connect supports for issuing id_tokens for 3rd parties but where the 3rd party also wants a access token to access the API.
> 
> This is similar to the Google Play / NAAPS use case, but with access tokens using PoP back to the 1st party RS.
> 
> Now using bearer tokens the native app can just pass the AT to a backend server hand have it make calls to the RS.  The AS is no wiser to the activity.
> However PoP is designed to stop this sort of thing.
> 
> As I think Chuck intimated, you could share the private key between the app and the backend, but giving your servers private key to a app seems like a good way to loose it.
> 
> The alternatives are:
> 1 share keys (bad)
> 2 put multiple proof keys in the token (needs the keys to be pre registered and ads complexity for symmetric keys.
> 3 Give client an assertion that can be used by the related backend to get it's own AT, allowing the clients to have different client_id and proof keys. (builds on Connect id_token used in jwt assertion flow)
> 
> John B.
> 
> On Apr 13, 2014, at 1:17 AM, Mike Jones <Michael.Jones@microsoft.com> wrote:
> 
>> Can you sketch out what data structures you’d ideally use for your scenario and what the elements mean?
>>  
>> From: Chuck Mortimore [mailto:cmortimore@salesforce.com] 
>> Sent: Saturday, April 12, 2014 8:39 PM
>> To: Mike Jones
>> Cc: oauth@ietf.org
>> Subject: Re: [OAUTH-WG] Proof-Of-Possession Semantics for JSON Web Tokens (JWTs)
>>  
>> Not sure it it's common yet.   The scenario I'm exploring is a client that is paired with a server.     For example, a mobile app that's an OpenID Connect client that is sharing it's ID Token with the server.   Both the client and server want to be able to prove possession without sharing a private key.   
>>  
>> -cmort 
>>  
>> 
>> On Sat, Apr 12, 2014 at 8:32 PM, Mike Jones <Michael.Jones@microsoft.com> wrote:
>> Is having multiple confirmation keys a common case?  I’d rather we “make simple things simple” than build the most general solution possible.  If an application really needs multiple confirmation keys, it can always defined a “jwks” element and the handling rules for it, and go for it…
>>  
>>                                                             -- Mike
>>  
>> From: Chuck Mortimore [mailto:cmortimore@salesforce.com] 
>> Sent: Saturday, April 12, 2014 6:12 PM
>> To: Mike Jones
>> 
>> Cc: oauth@ietf.org
>> Subject: Re: [OAUTH-WG] Proof-Of-Possession Semantics for JSON Web Tokens (JWTs)
>>  
>> Good start here Mike!
>>  
>> One quick question - I see the "cnf" member is defined as a JWK.  Why not a JWK Set?    I could see use-cases for binding in multiple keys.
>>  
>> -cmort
>>  
>>  
>>  
>> 
>> On Tue, Apr 1, 2014 at 8:36 PM, Mike Jones <Michael.Jones@microsoft.com> wrote:
>> I’ve written a concise Internet-Draft on proof-of-possession for JWTs with John Bradley and Hannes Tschofenig.  Quoting from the abstract:
>>  
>> This specification defines how to express a declaration in a JSON Web Token (JWT) that the presenter of the JWT possesses a particular key and that the recipient can cryptographically confirm proof-of-possession of the key by the presenter. This property is also sometimes described as the presenter being a holder-of-key.
>>  
>> This specification intentionally does not specify the means of communicating the proof-of-possession JWT, nor the messages used to exercise the proof key, as these are necessarily application-specific.  Rather, this specification defines a proof-of-possession JWT data structure to be used by other specifications that do define those things.
>>  
>> The specification is available at:
>> ·        http://tools.ietf.org/html/draft-jones-oauth-proof-of-possession-00
>> 
>>  
>> An HTML formatted version is available at:
>> ·        http://self-issued.info/docs/draft-jones-oauth-proof-of-possession-00.html
>> 
>>  
>>                                                             -- Mike
>>  
>> P.S.  This note was also posted at http://self-issued.info/?p=1210 and as @selfissued.
>>  
>> 
>> _______________________________________________
>> OAuth mailing list
>> OAuth@ietf.org
>> https://www.ietf.org/mailman/listinfo/oauth
>> 
>>  
>>  
>> _______________________________________________
>> OAuth mailing list
>> OAuth@ietf.org
>> https://www.ietf.org/mailman/listinfo/oauth
> 
> 
>