idnits 2.17.1 draft-ietf-oauth-spop-11.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- No issues found here. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (May 17, 2015) is 3265 days in the past. Is this intentional? Checking references for intended status: Proposed Standard ---------------------------------------------------------------------------- (See RFCs 3967 and 4897 for information about using normative references to lower-maturity documents in RFCs) == Missing Reference: 'A-Z' is mentioned on line 269, but not defined == Missing Reference: '0-9' is mentioned on line 269, but not defined == Missing Reference: 'RFC5226' is mentioned on line 428, but not defined ** Obsolete undefined reference: RFC 5226 (Obsoleted by RFC 8126) ** Obsolete normative reference: RFC 7525 (ref. 'BCP195') (Obsoleted by RFC 9325) ** Downref: Normative reference to an Informational RFC: RFC 6234 Summary: 3 errors (**), 0 flaws (~~), 4 warnings (==), 1 comment (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 OAuth Working Group N. Sakimura, Ed. 3 Internet-Draft Nomura Research Institute 4 Intended status: Standards Track J. Bradley 5 Expires: November 18, 2015 Ping Identity 6 N. Agarwal 7 Google 8 May 17, 2015 10 Proof Key for Code Exchange by OAuth Public Clients 11 draft-ietf-oauth-spop-11 13 Abstract 15 OAuth 2.0 public clients utilizing the Authorization Code Grant are 16 susceptible to the authorization code interception attack. This 17 specification describes the attack as well as a technique to mitigate 18 against the threat. 20 Status of This Memo 22 This Internet-Draft is submitted in full conformance with the 23 provisions of BCP 78 and BCP 79. 25 Internet-Drafts are working documents of the Internet Engineering 26 Task Force (IETF). Note that other groups may also distribute 27 working documents as Internet-Drafts. The list of current Internet- 28 Drafts is at http://datatracker.ietf.org/drafts/current/. 30 Internet-Drafts are draft documents valid for a maximum of six months 31 and may be updated, replaced, or obsoleted by other documents at any 32 time. It is inappropriate to use Internet-Drafts as reference 33 material or to cite them other than as "work in progress." 35 This Internet-Draft will expire on November 18, 2015. 37 Copyright Notice 39 Copyright (c) 2015 IETF Trust and the persons identified as the 40 document authors. All rights reserved. 42 This document is subject to BCP 78 and the IETF Trust's Legal 43 Provisions Relating to IETF Documents 44 (http://trustee.ietf.org/license-info) in effect on the date of 45 publication of this document. Please review these documents 46 carefully, as they describe your rights and restrictions with respect 47 to this document. Code Components extracted from this document must 48 include Simplified BSD License text as described in Section 4.e of 49 the Trust Legal Provisions and are provided without warranty as 50 described in the Simplified BSD License. 52 Table of Contents 54 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 55 1.1. Protocol Flow . . . . . . . . . . . . . . . . . . . . . . 4 56 2. Notational Conventions . . . . . . . . . . . . . . . . . . . 5 57 3. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 6 58 4. Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . 6 59 4.1. Client creates a code verifier . . . . . . . . . . . . . 6 60 4.2. Client creates the code challenge . . . . . . . . . . . . 7 61 4.3. Client sends the code challenge with the authorization 62 request . . . . . . . . . . . . . . . . . . . . . . . . . 7 63 4.4. Server returns the code . . . . . . . . . . . . . . . . . 7 64 4.4.1. Error Response . . . . . . . . . . . . . . . . . . . 8 65 4.5. Client sends the code and the secret to the token 66 endpoint . . . . . . . . . . . . . . . . . . . . . . . . 8 67 4.6. Server verifies code_verifier before returning the tokens 8 68 5. Compatibility . . . . . . . . . . . . . . . . . . . . . . . . 9 69 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 9 70 6.1. OAuth Parameters Registry . . . . . . . . . . . . . . . . 9 71 6.2. PKCE Code Challenge Method Registry . . . . . . . . . . . 10 72 6.2.1. Registration Template . . . . . . . . . . . . . . . . 10 73 6.2.2. Initial Registry Contents . . . . . . . . . . . . . . 11 74 7. Security Considerations . . . . . . . . . . . . . . . . . . . 11 75 7.1. Entropy of the code verifier . . . . . . . . . . . . . . 11 76 7.2. Protection against eavesdroppers . . . . . . . . . . . . 11 77 7.3. Entropy of the code_verifier . . . . . . . . . . . . . . 12 78 7.4. OAuth security considerations . . . . . . . . . . . . . . 12 79 7.5. TLS security considerations . . . . . . . . . . . . . . . 12 80 8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 12 81 9. Revision History . . . . . . . . . . . . . . . . . . . . . . 13 82 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 15 83 10.1. Normative References . . . . . . . . . . . . . . . . . . 15 84 10.2. Informative References . . . . . . . . . . . . . . . . . 16 85 Appendix A. Notes on implementing base64url encoding without 86 padding . . . . . . . . . . . . . . . . . . . . . . 16 87 Appendix B. Example for the S256 code_challenge_method . . . . . 16 88 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 17 90 1. Introduction 92 OAuth 2.0 [RFC6749] public clients are susceptible to the 93 authorization "code" interception attack. 95 The attacker thereby intercepts the authorization code returned from 96 the authorization endpoint within communication path not protected by 97 TLS, such as inter-app communication within the operating system of 98 the client. 100 Once the attacker has gained access to the authorization code it can 101 use it to obtain the access token. 103 Figure 1 shows the attack graphically. In step (1) the native app 104 running on the end device, such as a smart phone, issues an 105 authorization request via the browser/operating system, which then 106 gets forwarded to the OAuth 2.0 authorization server in step (2). 107 The authorization server returns the authorization code in step (3). 108 The malicious app is able to observe the authorization code in step 109 (4) since it is registered to the custom URI scheme used by the 110 legitimate app. This allows the attacker to reguest and obtain an 111 access token in step (5) and step (6), respectively. 113 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ 114 | End Device (e.g., Smart Phone) | 115 | | 116 | +-------------+ +----------+ | (6) Access Token +----------+ 117 | |Legitimate | | Malicious|<--------------------| | 118 | |OAuth 2.0 App| | App |-------------------->| | 119 | +-------------+ +----------+ | (5) Authorization | | 120 | | ^ ^ | Grant | | 121 | | \ | | | | 122 | | \ (4) | | | | 123 | (1) | \ Authz| | | | 124 | Authz| \ Code | | | Authz | 125 | Request| \ | | | Server | 126 | | \ | | | | 127 | | \ | | | | 128 | v \ | | | | 129 | +----------------------------+ | | | 130 | | | | (3) Authz Code | | 131 | | Operating System/ |<--------------------| | 132 | | Browser |-------------------->| | 133 | | | | (2) Authz Request | | 134 | +----------------------------+ | +----------+ 135 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ 137 Figure 1: Authorization Code Interception Attack. 139 A number of pre-conditions need to hold in order for this attack to 140 work: 142 1) The attacker manages to register a malicious application on the 143 client device and registers a custom URI scheme that is also used 144 by another application. 146 The operating systems must allow a custom URI schemes to be 147 registered by multiple applications. 148 2) The OAuth 2.0 authorization code grant is used. 149 3) The attacker has access to the client id. All native app client- 150 instances use the same client id. No client secret is used (since 151 public clients cannot keep their secrets confidential.) 152 4) The attacker (via the installed app) is able to observe responses 153 from the authorization endpoint. As a more sophisticated attack 154 scenario the attacker is also able to observe requests (in 155 addition to responses) to the authorization endpoint. The 156 attacker is, however, not able to act as a man-in-the-middle. 158 While this is a long list of pre-conditions the described attack has 159 been observed in the wild and has to be considered in OAuth 2.0 160 deployments. 161 While the OAuth 2.0 Threat Model Section 4.4.1 [RFC6819] describes 162 mitigation techniques they are, unfortunately, not applicable since 163 they rely on a per-client instance secret or aper client instance 164 redirect URI. 166 To mitigate this attack, this extension utilizes a dynamically 167 created cryptographically random key called 'code verifier'. A 168 unique code verifier is created for every authorization request and 169 its transformed value, called 'code challenge', is sent to the 170 authorization server to obtain the authorization code. The 171 authorization "code" obtained is then sent to the token endpoint with 172 the 'code verifier' and the server compares it with the previously 173 received request code so that it can perform the proof of possession 174 of the 'code verifier' by the client. This works as the mitigation 175 since the attacker would not know this one-time key. 177 1.1. Protocol Flow 178 +-------------------+ 179 | Authz Server | 180 +--------+ | +---------------+ | 181 | |--(A)- Authorization Request ---->| | | 182 | | + t(code_verifier), t | | Authorization | | 183 | | | | Endpoint | | 184 | |<-(B)---- Authorization Code -----| | | 185 | | | +---------------+ | 186 | Client | | | 187 | | | +---------------+ | 188 | |--(C)-- Access Token Request ---->| | | 189 | | + code_verifier | | Token | | 190 | | | | Endpoint | | 191 | |<-(D)------ Access Token ---------| | | 192 +--------+ | +---------------+ | 193 +-------------------+ 195 Figure 2: Abstract Protocol Flow 197 This specification adds additional parameters to the OAuth 2.0 198 Authorization and Access Token Requests, shown in abstract form in 199 Figure 1. 201 A. The client creates and records a secret named the "code_verifier", 202 and derives a transformed version "t(code_verifier)" (referred to 203 as the "code_challenge") which is sent in the OAuth 2.0 204 Authorization Request, along with the transformation method "t". 205 B. The Authorization Endpoint responds as usual, but records 206 "t(code_verifier)" and the transformation method. 207 C. The client then sends the code in the Access Token Request as 208 usual, but includes the "code_verifier" secret generated at (A). 209 D. The authorization server transforms "code_verifier" and compares 210 it to "t(code_verifier)" from (B). Access is denied if they are 211 not equal. 213 An attacker who intercepts the Authorization Grant at (B) is unable 214 to redeem it for an Access Token, as they are not in possession of 215 the "code_verifier" secret. 217 2. Notational Conventions 219 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 220 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 221 "OPTIONAL" in this document are to be interpreted as described in Key 222 words for use in RFCs to Indicate Requirement Levels [RFC2119]. If 223 these words are used without being spelled in uppercase then they are 224 to be interpreted with their normal natural language meanings. 226 This specification uses the Augmented Backus-Naur Form (ABNF) 227 notation of [RFC5234]. 229 STRING denotes a sequence of zero or more ASCII [RFC0020] characters. 231 OCTETS denotes a sequence of zero or more octets. 233 ASCII(STRING) denotes the octets of the ASCII [RFC0020] 234 representation of STRING where STRING is a sequence of zero or more 235 ASCII characters. 237 BASE64URL-ENCODE(OCTETS) denotes the base64url encoding of OCTETS, 238 per Section 3 producing a STRING. 240 BASE64URL-DECODE(STRING) denotes the base64url decoding of STRING, 241 per Section 3, producing a sequence of octets. 243 SHA256(OCTETS) denotes a SHA2 256bit hash [RFC6234] of OCTETS. 245 3. Terminology 247 In addition to the terms defined in OAuth 2.0 [RFC6749], this 248 specification defines the following terms: 250 code verifier A cryptographically random string that is used to 251 correlate the authorization request to the token request. 252 code challenge A challenge derived from the code verifier that is 253 sent in the authorization request, to be verified against later. 254 Base64url Encoding Base64 encoding using the URL- and filename-safe 255 character set defined in Section 5 of [RFC4648], with all trailing 256 '=' characters omitted (as permitted by Section 3.2 of [RFC4648]) 257 and without the inclusion of any line breaks, whitespace, or other 258 additional characters. (See Appendix A for notes on implementing 259 base64url encoding without padding.) 261 4. Protocol 263 4.1. Client creates a code verifier 265 The client first creates a code verifier, "code_verifier", for each 266 OAuth 2.0 [RFC6749] Authorization Request, in the following manner: 268 code_verifier = high entropy cryptographic random STRING using the 269 Unreserved Characters [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~" 270 from Sec 2.3 of [RFC3986], with a minimum length of 43 characters and 271 a maximum length of 128 characters. 273 ABNF for "code_verifier" is as follows. 275 code-verifier = 43*128unreserved 276 unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" 277 ALPHA = %x41-5A / %x61-7A 278 DIGIT = %x30-39 280 NOTE: code verifier SHOULD have enough entropy to make it impractical 281 to guess the value. It is RECOMMENDED that the output of a suitable 282 random number generator be used to create a 32-octet sequence. The 283 Octet sequence is then base64url encoded to produce a 43-octet URL 284 safe string to use as the code verifier. 286 4.2. Client creates the code challenge 288 The client then creates a code challenge, "code_challenge", derived 289 from the "code_verifier" by using one of the following 290 transformations on the "code_verifier": 292 plain "code_challenge" = "code_verifier" 293 S256 "code_challenge" = BASE64URL- 294 ENCODE(SHA256(ASCII("code_verifier"))) 296 It is RECOMMENDED to use the S256 transformation when possible. 298 ABNF for "code_challenge" is as follows. 300 code-challenge = 43*128unreserved 301 unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" 302 ALPHA = %x41-5A / %x61-7A 303 DIGIT = %x30-39 305 4.3. Client sends the code challenge with the authorization request 307 The client sends the code challenge as part of the OAuth 2.0 308 Authorization Request (Section 4.1.1 of [RFC6749].) using the 309 following additional parameters: 311 code_challenge REQUIRED. Code challenge. 313 code_challenge_method OPTIONAL, defaults to "plain". Code verifier 314 transformation method, "S256" or "plain". 316 4.4. Server returns the code 318 When the server issues the "code" in the Authorization Response, it 319 MUST associate the "code_challenge" and "code_challenge_method" 320 values with the "code" so it can be verified later. 322 Typically, the "code_challenge" and "code_challenge_method" values 323 are stored in encrypted form in the "code" itself, but could 324 alternatively be stored on the server, associated with the code. The 325 server MUST NOT include the "code_challenge" value in client requests 326 in a form that other entities can extract. 328 The exact method that the server uses to associate the 329 "code_challenge" with the issued "code" is out of scope for this 330 specification. 332 4.4.1. Error Response 334 If the server requires PKCE, and the client does not send the 335 "code_challenge" in the request, the authorization endpoint MUST 336 return the authorization error response with "error" value set to 337 "invalid_request". The "error_description" or the response of 338 "error_uri" SHOULD explain the nature of error, e.g., code challenge 339 required. 341 If the server supporting PKCE does not support the requested 342 transform, the authorization endpoint MUST return the authorization 343 error response with "error" value set to "invalid_request". The 344 "error_description" or the response of "error_uri" SHOULD explain the 345 nature of error, e.g., transform algorithm not supported. 347 If the client is capable of using "S256", it MUST use "S256", as 348 "S256" is Mandatory To Implement (MTI) on the server. Clients MAY 349 use "plain" only if they cannot support "S256" for some technical 350 reason and knows that the server supports "plain". 352 4.5. Client sends the code and the secret to the token endpoint 354 Upon receipt of the "code", the client sends the Access Token Request 355 to the token endpoint. In addition to the parameters defined in the 356 OAuth 2.0 Access Token Request (Section 4.1.3 of [RFC6749]), it sends 357 the following parameter: 359 code_verifier REQUIRED. Code verifier 361 4.6. Server verifies code_verifier before returning the tokens 363 Upon receipt of the request at the Access Token endpoint, the server 364 verifies it by calculating the code challenge from received 365 "code_verifier" and comparing it with the previously associated 366 "code_challenge", after first transforming it according to the 367 "code_challenge_method" method specified by the client. 369 If the "code_challenge_method" from Section 4.2 was "S256", the 370 received "code_verifier" is hashed by SHA-256, then base64url 371 encoded, and then compared to the "code_challenge". i.e., 373 BASE64URL-ENCODE(SHA256(ASCII("code_verifier" ))) == "code_challenge" 375 If the "code_challenge_method" from Section 4.2 was "plain", they are 376 compared directly. i.e., 378 "code_verifier" == "code_challenge". 380 If the values are equal, the Access Token endpoint MUST continue 381 processing as normal (as defined by OAuth 2.0 [RFC6749]). If the 382 values are not equal, an error response indicating "invalid_grant" as 383 described in section 5.2 of [RFC6749] MUST be returned. 385 5. Compatibility 387 Server implementations of this specification MAY accept OAuth2.0 388 Clients that do not implement this extension. If the "code_verifier" 389 is not received from the client in the Authorization Request, servers 390 supporting backwards compatibility SHOULD revert to a normal OAuth 391 2.0 [RFC6749] protocol. 393 As the OAuth 2.0 [RFC6749] server responses are unchanged by this 394 specification, client implementations of this specification do not 395 need to know if the server has implemented this specification or not, 396 and SHOULD send the additional parameters as defined in Section 3. to 397 all servers. 399 6. IANA Considerations 401 This specification makes a registration request as follows: 403 6.1. OAuth Parameters Registry 405 This specification registers the following parameters in the IANA 406 OAuth Parameters registry defined in OAuth 2.0 [RFC6749]. 408 o Parameter name: code_verifier 409 o Parameter usage location: Access Token Request 410 o Change controller: IESG 411 o Specification document(s): this document 413 o Parameter name: code_challenge 414 o Parameter usage location: Authorization Request 415 o Change controller: IESG 416 o Specification document(s): this document 417 o Parameter name: code_challenge_method 418 o Parameter usage location: Authorization Request 419 o Change controller: IESG 420 o Specification document(s): this document 422 6.2. PKCE Code Challenge Method Registry 424 This specification establishes the PKCE Code Challenge Method 425 registry. 427 Additional code_challenge_method types for use with the authorization 428 endpoint are registered with a Specification Required ([RFC5226]) 429 after a two-week review period on the oauth-ext-review@ietf.org 430 mailing list, on the advice of one or more Designated Experts. 431 However, to allow for the allocation of values prior to publication, 432 the Designated Expert(s) may approve registration once they are 433 satisfied that such a specification will be published. 435 Registration requests must be sent to the oauth-ext-review@ietf.org 436 mailing list for review and comment, with an appropriate subject 437 (e.g., "Request for PKCE code_challenge_method: example"). 439 Within the review period, the Designated Expert(s) will either 440 approve or deny the registration request, communicating this decision 441 to the review list and IANA. Denials should include an explanation 442 and, if applicable, suggestions as to how to make the request 443 successful. 445 IANA must only accept registry updates from the Designated Expert(s) 446 and should direct all requests for registration to the review mailing 447 list. 449 6.2.1. Registration Template 451 Code Challenge Method Parameter Name: 452 The name requested (e.g., "example"). Because a core goal of this 453 specification is for the resulting representations to be compact, 454 it is RECOMMENDED that the name be short -- not to exceed 8 455 characters without a compelling reason to do so. This name is 456 case-sensitive. Names may not match other registered names in a 457 case-insensitive manner unless the Designated Expert(s) state that 458 there is a compelling reason to allow an exception in this 459 particular case. 460 Change Controller: 461 For Standards Track RFCs, state "IESG". For others, give the name 462 of the responsible party. Other details (e.g., postal address, 463 email address, home page URI) may also be included. 464 Specification Document(s): 466 Reference to the document(s) that specify the parameter, 467 preferably including URI(s) that can be used to retrieve copies of 468 the document(s). An indication of the relevant sections may also 469 be included but is not required. 471 6.2.2. Initial Registry Contents 473 This specification registers the Code Challenge Method Parameter 474 names defined in Section 4.2 in this registry. 476 o Code Challenge Method Parameter Name: "plain" 477 o Change Controller: IESG 478 o Specification Document(s): Section 4.2 of [[ this document ]] 480 o Code Challenge Method Parameter Name: "S256" 481 o Change Controller: IESG 482 o Specification Document(s): Section 4.2 of [[ this document ]] 484 7. Security Considerations 486 7.1. Entropy of the code verifier 488 The security model relies on the fact that the code verifier is not 489 learned or guessed by the attacker. It is vitally important to 490 adhere to this principle. As such, the code verifier has to be 491 created in such a manner that it is cryptographically random and has 492 high entropy that it is not practical for the attacker to guess. It 493 is RECOMMENDED that the output of a suitable random number generator 494 be used to create a 32-octet sequence. 496 7.2. Protection against eavesdroppers 498 Clients MUST NOT try down grading the algorithm after trying "S256" 499 method. If the server is PKCE compliant, then "S256" method works. 500 If the server does not support PKCE, it does not generate error. 501 Only the time that the server returns that it does not support "S256" 502 is there is a MITM trying the algorithm downgrade attack. 504 "S256" method protects against eavesdroppers observing or 505 intercepting the "code_challenge". If the "plain" method is used, 506 there is a chance that it will be observed by the attacker on the 507 device. The use of "S256" protects against it. 509 If "code_challenge" is to be returned inside authorization "code" to 510 achieve a stateless server, it has to be encrypted in such a manner 511 that only the server can decrypt and extract it. 513 7.3. Entropy of the code_verifier 515 The client SHOULD create a code_verifier with a minimum of 256bits of 516 entropy. This can be done by having a suitable random number 517 generator create a 32-octet sequence. The Octet sequence can then be 518 base64url encoded to produce a 43-octet URL safe string to use as a 519 code_challenge that has the required entropy. 521 Salting is not used in the production of the code_verifier, as the 522 code_chalange contains sufficient entropy to prevent brute force 523 attacks. Concatenating a publicly known value to a code_challenge 524 (with 256 bits of entropy) and then hashing it with SHA256 would 525 actually reduce the entropy in the resulting code_verifier making it 526 easier for an attacker to brute force. 528 While the S256 transformation is like hashing a password there are 529 important differences. Passwords tend to be relatively low entropy 530 words that can be hashed offline and the hash looked up in a 531 dictionary. By concatenating a unique though public value to each 532 password prior to hashing, the dictionary space that an attacker 533 needs to search is greatly expanded. 535 Modern graphics processors now allow attackers to calculate hashes in 536 real time faster than they could be looked up from a disk. This 537 eliminates the value of the salt in increasing the complexity of a 538 brute force attack for even low entropy passwords. 540 7.4. OAuth security considerations 542 All the OAuth security analysis presented in [RFC6819] applies so 543 readers SHOULD carefully follow it. 545 7.5. TLS security considerations 547 Curent security considerations can be found in Recommendations for 548 Secure Use of TLS and DTLS [BCP195]. This supersedes the TLS version 549 recommendations in OAuth 2.0 [RFC6749]. 551 8. Acknowledgements 553 The initial draft of this specification was created by the OpenID AB/ 554 Connect Working Group of the OpenID Foundation. 556 This specification is the work of the OAuth Working Group, which 557 includes dozens of active and dedicated participants. In particular, 558 the following individuals contributed ideas, feedback, and wording 559 that shaped and formed the final specification: 561 Anthony Nadalin, Microsoft 562 Axel Nenker, Deutsche Telekom 563 Breno de Medeiros, Google 564 Brian Campbell, Ping Identity 565 Chuck Mortimore, Salesforce 566 Dirk Balfanz, Google 567 Eduardo Gueiros, Jive Communications 568 Hannes Tschonfenig, ARM 569 James Manger, Telstra 570 John Bradley, Ping Identity 571 Justin Richer, MIT Kerberos 572 Josh Mandel, Boston Children's Hospital 573 Lewis Adam, Motorola Solutions 574 Madjid Nakhjiri, Samsung 575 Michael B. Jones, Microsoft 576 Nat Sakimura, Nomura Research Institute 577 Naveen Agarwal, Google 578 Paul Madsen, Ping Identity 579 Phil Hunt, Oracle 580 Prateek Mishra, Oracle 581 Ryo Ito, mixi 582 Scott Tomilson, Ping Identity 583 Sergey Beryozkin 584 Takamichi Saito 585 Torsten Lodderstedt, Deutsche Telekom 586 William Denniss, Google 588 9. Revision History 590 -11 592 o add spanx for plain in sec 4.4 RE Kathleen's comment 593 o Add security consideration on TLS and reference BCP195 595 -10 597 o re #33 specify lower limit to code_verifier in prose 598 o remove base64url decode from draft, all steps now use encode only 599 o Expanded MTI 600 o re #33 change length of 32 octet base64url encoded string back to 601 43 octets 603 -09 605 o clean up some external references so they don't point at internal 606 sections 608 -08 609 o changed BASE64URL to BASE64URL-ENCODE to be more consistent with 610 appendix A Fixed lowercase base64url in appendix B 611 o Added appendix B as an example of S256 processing 612 o Change reference for unreserved characters to RFC3986 from 613 base64URL 615 -07 617 o removed unused discovery reference and UTF8 618 o re #32 added ASCII(STRING) to make clear that it is the byte array 619 that is being hashed 620 o re #2 Remove discovery requirement section. 621 o updated Acknowledgement 622 o re #32 remove unneeded UTF8(STRING) definition, and define STRING 623 for ASCII(STRING) 624 o re #32 remove unneeded utf8 reference from BASE64URL- 625 DECODE(STRING) def 626 o resolves #31 unused definition of concatenation 627 o re #30 Update figure text call out the endpoints 628 o re #30 Update figure to call out the endpoints 629 o small wording change to the introduction 631 -06 633 o fix date 634 o replace spop with pkce for registry and other references 635 o re #29 change name again 636 o re #27 removed US-ASCII reference 637 o re #27 updated ABNF for code_verifier 638 o resolves #24 added security consideration for salting 639 o resolves #29 Changed title 640 o updated reference to RFC4634 to RFC6234 re #27 641 o changed reference for US-ASCII to RFC20 re #27 642 o resolves #28 added Acknowledgements 643 o resolves #27 updated ABNF 644 o resolves #26 updated abstract and added Hannes figure 646 -05 648 o Added IANA registry for code_challenge_method + fixed some broken 649 internal references. 651 -04 653 o Added error response to authorization response. 655 -03 656 o Added an abstract protocol diagram and explanation 658 -02 660 o Copy edits 662 -01 664 o Specified exactly two supported transformations 665 o Moved discovery steps to security considerations. 666 o Incorporated readability comments by Eduardo Gueiros. 667 o Changed MUST in 3.1 to SHOULD. 669 -00 671 o Initial IETF version. 673 10. References 675 10.1. Normative References 677 [BCP195] Sheffer, Y., Holz, R., and P. Saint-Andre, 678 "Recommendations for Secure Use of Transport Layer 679 Security (TLS) and Datagram Transport Layer Security 680 (DTLS)", BCP 195, RFC 7525, May 2015. 682 [RFC0020] Cerf, V., "ASCII format for network interchange", RFC 20, 683 October 1969. 685 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 686 Requirement Levels", BCP 14, RFC 2119, March 1997. 688 [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform 689 Resource Identifier (URI): Generic Syntax", STD 66, RFC 690 3986, January 2005. 692 [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data 693 Encodings", RFC 4648, October 2006. 695 [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax 696 Specifications: ABNF", STD 68, RFC 5234, January 2008. 698 [RFC6234] Eastlake, D. and T. Hansen, "US Secure Hash Algorithms 699 (SHA and SHA-based HMAC and HKDF)", RFC 6234, May 2011. 701 [RFC6749] Hardt, D., "The OAuth 2.0 Authorization Framework", RFC 702 6749, October 2012. 704 10.2. Informative References 706 [RFC6819] Lodderstedt, T., McGloin, M., and P. Hunt, "OAuth 2.0 707 Threat Model and Security Considerations", RFC 6819, 708 January 2013. 710 Appendix A. Notes on implementing base64url encoding without padding 712 This appendix describes how to implement a base64url encoding 713 function without padding based upon standard base64 encoding function 714 that uses padding. 716 To be concrete, example C# code implementing these functions is shown 717 below. Similar code could be used in other languages. 719 static string base64urlencode(byte [] arg) 720 { 721 string s = Convert.ToBase64String(arg); // Regular base64 encoder 722 s = s.Split('=')[0]; // Remove any trailing '='s 723 s = s.Replace('+', '-'); // 62nd char of encoding 724 s = s.Replace('/', '_'); // 63rd char of encoding 725 return s; 726 } 728 An example correspondence between unencoded and encoded values 729 follows. The octet sequence below encodes into the string below, 730 which when decoded, reproduces the octet sequence. 732 3 236 255 224 193 734 A-z_4ME 736 Appendix B. Example for the S256 code_challenge_method 738 The client uses output of a suitable random number generator to 739 create a 32-octet sequence. The octets representing the value in 740 this example (using JSON array notation) are:" 742 [116, 24, 223, 180, 151, 153, 224, 37, 79, 250, 96, 125, 216, 173, 743 187, 186, 22, 212, 37, 77, 105, 214, 191, 240, 91, 88, 5, 88, 83, 744 132, 141, 121] 746 Encoding this octet sequence as a Base64url provides the value of the 747 code_verifier: 749 dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk 751 The code_verifier is then hashed via the SHA256 hash function to 752 produce: 754 [19, 211, 30, 150, 26, 26, 216, 236, 47, 22, 177, 12, 76, 152, 46, 755 8, 118, 168, 120, 173, 109, 241, 68, 86, 110, 225, 137, 74, 203, 756 112, 249, 195] 758 Encoding this octet sequence as a base64url provides the value of the 759 code_challenge: 761 E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM 763 The authorization request includes: 765 code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM 766 &code_challange_method=S256 768 The Authorization server then records the code_challenge and 769 code_challenge_method along with the code that is granted to the 770 client. 772 in the request to the token_endpoint the client includes the code 773 received in the authorization response as well as the additional 774 paramater: 776 code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk 778 The Authorization server retrieves the information for the code 779 grant. Based on the recorded code_challange_method being S256, it 780 then hashes and base64url encodes the value of code_verifier. 781 BASE64URL-ENCODE(SHA256(ASCII("code_verifier" ))) 783 The calculated value is then compared with the value of 784 "code_challenge": 786 BASE64URL-ENCODE(SHA256(ASCII("code_verifier" ))) == code_challenge 788 If the two values are equal then the Authorization server can provide 789 the tokens as long as there are no other errors in the request. If 790 the values are not equal then the request must be rejected, and an 791 error returned. 793 Authors' Addresses 794 Nat Sakimura (editor) 795 Nomura Research Institute 796 1-6-5 Marunouchi, Marunouchi Kitaguchi Bldg. 797 Chiyoda-ku, Tokyo 100-0005 798 Japan 800 Phone: +81-3-5533-2111 801 Email: n-sakimura@nri.co.jp 802 URI: http://nat.sakimura.org/ 804 John Bradley 805 Ping Identity 806 Casilla 177, Sucursal Talagante 807 Talagante, RM 808 Chile 810 Phone: +44 20 8133 3718 811 Email: ve7jtb@ve7jtb.com 812 URI: http://www.thread-safe.com/ 814 Naveen Agarwal 815 Google 816 1600 Amphitheatre Pkwy 817 Mountain View, CA 94043 818 USA 820 Phone: +1 650-253-0000 821 Email: naa@google.com 822 URI: http://google.com/