idnits 2.17.1 draft-ietf-oauth-spop-10.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 (February 06, 2015) is 3360 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 268, but not defined == Missing Reference: '0-9' is mentioned on line 268, but not defined == Missing Reference: 'RFC5226' is mentioned on line 427, but not defined ** Obsolete undefined reference: RFC 5226 (Obsoleted by RFC 8126) ** Downref: Normative reference to an Informational RFC: RFC 6234 Summary: 2 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: August 10, 2015 Ping Identity 6 N. Agarwal 7 Google 8 February 06, 2015 10 Proof Key for Code Exchange by OAuth Public Clients 11 draft-ietf-oauth-spop-10 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 August 10, 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 8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 12 80 9. Revision History . . . . . . . . . . . . . . . . . . . . . . 13 81 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 15 82 10.1. Normative References . . . . . . . . . . . . . . . . . . 15 83 10.2. Informative References . . . . . . . . . . . . . . . . . 15 84 Appendix A. Notes on implementing base64url encoding without 85 padding . . . . . . . . . . . . . . . . . . . . . . 15 86 Appendix B. Example for the S256 code_challenge_method . . . . . 16 87 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 17 89 1. Introduction 91 OAuth 2.0 [RFC6749] public clients are susceptible to the 92 authorization "code" interception attack. 94 The attacker thereby intercepts the authorization code returned from 95 the authorization endpoint within communication path not protected by 96 TLS, such as inter-app communication within the operating system of 97 the client. 99 Once the attacker has gained access to the authorization code it can 100 use it to obtain the access token. 102 Figure 1 shows the attack graphically. In step (1) the native app 103 running on the end device, such as a smart phone, issues an 104 authorization request via the browser/operating system, which then 105 gets forwarded to the OAuth 2.0 authorization server in step (2). 106 The authorization server returns the authorization code in step (3). 107 The malicious app is able to observe the authorization code in step 108 (4) since it is registered to the custom URI scheme used by the 109 legitimate app. This allows the attacker to reguest and obtain an 110 access token in step (5) and step (6), respectively. 112 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ 113 | End Device (e.g., Smart Phone) | 114 | | 115 | +-------------+ +----------+ | (6) Access Token +----------+ 116 | |Legitimate | | Malicious|<--------------------| | 117 | |OAuth 2.0 App| | App |-------------------->| | 118 | +-------------+ +----------+ | (5) Authorization | | 119 | | ^ ^ | Grant | | 120 | | \ | | | | 121 | | \ (4) | | | | 122 | (1) | \ Authz| | | | 123 | Authz| \ Code | | | Authz | 124 | Request| \ | | | Server | 125 | | \ | | | | 126 | | \ | | | | 127 | v \ | | | | 128 | +----------------------------+ | | | 129 | | | | (3) Authz Code | | 130 | | Operating System/ |<--------------------| | 131 | | Browser |-------------------->| | 132 | | | | (2) Authz Request | | 133 | +----------------------------+ | +----------+ 134 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ 136 Figure 1: Authorization Code Interception Attack. 138 A number of pre-conditions need to hold in order for this attack to 139 work: 141 1) The attacker manages to register a malicious application on the 142 client device and registers a custom URI scheme that is also used 143 by another application. 145 The operating systems must allow a custom URI schemes to be 146 registered by multiple applications. 147 2) The OAuth 2.0 authorization code grant is used. 148 3) The attacker has access to the client id. All native app client- 149 instances use the same client id. No client secret is used (since 150 public clients cannot keep their secrets confidential.) 151 4) The attacker (via the installed app) is able to observe responses 152 from the authorization endpoint. As a more sophisticated attack 153 scenario the attacker is also able to observe requests (in 154 addition to responses) to the authorization endpoint. The 155 attacker is, however, not able to act as a man-in-the-middle. 157 While this is a long list of pre-conditions the described attack has 158 been observed in the wild and has to be considered in OAuth 2.0 159 deployments. 160 While the OAuth 2.0 Threat Model Section 4.4.1 [RFC6819] describes 161 mitigation techniques they are, unfortunately, not applicable since 162 they rely on a per-client instance secret or aper client instance 163 redirect URI. 165 To mitigate this attack, this extension utilizes a dynamically 166 created cryptographically random key called 'code verifier'. A 167 unique code verifier is created for every authorization request and 168 its transformed value, called 'code challenge', is sent to the 169 authorization server to obtain the authorization code. The 170 authorization "code" obtained is then sent to the token endpoint with 171 the 'code verifier' and the server compares it with the previously 172 received request code so that it can perform the proof of possession 173 of the 'code verifier' by the client. This works as the mitigation 174 since the attacker would not know this one-time key. 176 1.1. Protocol Flow 177 +-------------------+ 178 | Authz Server | 179 +--------+ | +---------------+ | 180 | |--(A)- Authorization Request ---->| | | 181 | | + t(code_verifier), t | | Authorization | | 182 | | | | Endpoint | | 183 | |<-(B)---- Authorization Code -----| | | 184 | | | +---------------+ | 185 | Client | | | 186 | | | +---------------+ | 187 | |--(C)-- Access Token Request ---->| | | 188 | | + code_verifier | | Token | | 189 | | | | Endpoint | | 190 | |<-(D)------ Access Token ---------| | | 191 +--------+ | +---------------+ | 192 +-------------------+ 194 Figure 2: Abstract Protocol Flow 196 This specification adds additional parameters to the OAuth 2.0 197 Authorization and Access Token Requests, shown in abstract form in 198 Figure 1. 200 A. The client creates and records a secret named the "code_verifier", 201 and derives a transformed version "t(code_verifier)" (referred to 202 as the "code_challenge") which is sent in the OAuth 2.0 203 Authorization Request, along with the transformation method "t". 204 B. The Authorization Endpoint responds as usual, but records 205 "t(code_verifier)" and the transformation method. 206 C. The client then sends the code in the Access Token Request as 207 usual, but includes the "code_verifier" secret generated at (A). 208 D. The authorization server transforms "code_verifier" and compares 209 it to "t(code_verifier)" from (B). Access is denied if they are 210 not equal. 212 An attacker who intercepts the Authorization Grant at (B) is unable 213 to redeem it for an Access Token, as they are not in possession of 214 the "code_verifier" secret. 216 2. Notational Conventions 218 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 219 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 220 "OPTIONAL" in this document are to be interpreted as described in Key 221 words for use in RFCs to Indicate Requirement Levels [RFC2119]. If 222 these words are used without being spelled in uppercase then they are 223 to be interpreted with their normal natural language meanings. 225 This specification uses the Augmented Backus-Naur Form (ABNF) 226 notation of [RFC5234]. 228 STRING denotes a sequence of zero or more ASCII [RFC0020] characters. 230 OCTETS denotes a sequence of zero or more octets. 232 ASCII(STRING) denotes the octets of the ASCII [RFC0020] 233 representation of STRING where STRING is a sequence of zero or more 234 ASCII characters. 236 BASE64URL-ENCODE(OCTETS) denotes the base64url encoding of OCTETS, 237 per Section 3 producing a STRING. 239 BASE64URL-DECODE(STRING) denotes the base64url decoding of STRING, 240 per Section 3, producing a sequence of octets. 242 SHA256(OCTETS) denotes a SHA2 256bit hash [RFC6234] of OCTETS. 244 3. Terminology 246 In addition to the terms defined in OAuth 2.0 [RFC6749], this 247 specification defines the following terms: 249 code verifier A cryptographically random string that is used to 250 correlate the authorization request to the token request. 251 code challenge A challenge derived from the code verifier that is 252 sent in the authorization request, to be verified against later. 253 Base64url Encoding Base64 encoding using the URL- and filename-safe 254 character set defined in Section 5 of [RFC4648], with all trailing 255 '=' characters omitted (as permitted by Section 3.2 of [RFC4648]) 256 and without the inclusion of any line breaks, whitespace, or other 257 additional characters. (See Appendix A for notes on implementing 258 base64url encoding without padding.) 260 4. Protocol 262 4.1. Client creates a code verifier 264 The client first creates a code verifier, "code_verifier", for each 265 OAuth 2.0 [RFC6749] Authorization Request, in the following manner: 267 code_verifier = high entropy cryptographic random STRING using the 268 Unreserved Characters [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~" 269 from Sec 2.3 of RFC 3986 [RFC3986], with a minimum length of 43 270 characters and a maximum length of 128 characters. 272 ABNF for "code_verifier" is as follows. 274 code-verifier = 43*128unreserved 275 unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" 276 ALPHA = %x41-5A / %x61-7A 277 DIGIT = %x30-39 279 NOTE: code verifier SHOULD have enough entropy to make it impractical 280 to guess the value. It is RECOMMENDED that the output of a suitable 281 random number generator be used to create a 32-octet sequence. The 282 Octet sequence is then base64url encoded to produce a 43-octet URL 283 safe string to use as the code verifier. 285 4.2. Client creates the code challenge 287 The client then creates a code challenge, "code_challenge", derived 288 from the "code_verifier" by using one of the following 289 transformations on the "code_verifier": 291 plain "code_challenge" = "code_verifier" 292 S256 "code_challenge" = BASE64URL- 293 ENCODE(SHA256(ASCII("code_verifier"))) 295 It is RECOMMENDED to use the S256 transformation when possible. 297 ABNF for "code_challenge" is as follows. 299 code-challenge = 43*128unreserved 300 unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" 301 ALPHA = %x41-5A / %x61-7A 302 DIGIT = %x30-39 304 4.3. Client sends the code challenge with the authorization request 306 The client sends the code challenge as part of the OAuth 2.0 307 Authorization Request (Section 4.1.1 of [RFC6749].) using the 308 following additional parameters: 310 code_challenge REQUIRED. Code challenge. 312 code_challenge_method OPTIONAL, defaults to "plain". Code verifier 313 transformation method, "S256" or "plain". 315 4.4. Server returns the code 317 When the server issues the "code" in the Authorization Response, it 318 MUST associate the "code_challenge" and "code_challenge_method" 319 values with the "code" so it can be verified later. 321 Typically, the "code_challenge" and "code_challenge_method" values 322 are stored in encrypted form in the "code" itself, but could 323 alternatively be stored on the server, associated with the code. The 324 server MUST NOT include the "code_challenge" value in client requests 325 in a form that other entities can extract. 327 The exact method that the server uses to associate the 328 "code_challenge" with the issued "code" is out of scope for this 329 specification. 331 4.4.1. Error Response 333 If the server requires PKCE, and the client does not send the 334 "code_challenge" in the request, the authorization endpoint MUST 335 return the authorization error response with "error" value set to 336 "invalid_request". The "error_description" or the response of 337 "error_uri" SHOULD explain the nature of error, e.g., code challenge 338 required. 340 If the server supporting PKCE does not support the requested 341 transform, the authorization endpoint MUST return the authorization 342 error response with "error" value set to "invalid_request". The 343 "error_description" or the response of "error_uri" SHOULD explain the 344 nature of error, e.g., transform algorithm not supported. 346 If the client is capable of using "S256", it MUST use "S256", as 347 "S256" is Mandatory To Implement (MTI) on the server. Clients MAY 348 use plain only if they cannot support "S256" for some technical 349 reason and knows that the server supports "plain". 351 4.5. Client sends the code and the secret to the token endpoint 353 Upon receipt of the "code", the client sends the Access Token Request 354 to the token endpoint. In addition to the parameters defined in the 355 OAuth 2.0 Access Token Request (Section 4.1.3 of [RFC6749]), it sends 356 the following parameter: 358 code_verifier REQUIRED. Code verifier 360 4.6. Server verifies code_verifier before returning the tokens 362 Upon receipt of the request at the Access Token endpoint, the server 363 verifies it by calculating the code challenge from received 364 "code_verifier" and comparing it with the previously associated 365 "code_challenge", after first transforming it according to the 366 "code_challenge_method" method specified by the client. 368 If the "code_challenge_method" from Section 4.2 was "S256", the 369 received "code_verifier" is hashed by SHA-256, then base64url 370 encoded, and then compared to the "code_challenge". i.e., 372 BASE64URL-ENCODE(SHA256(ASCII("code_verifier" ))) == "code_challenge" 374 If the "code_challenge_method" from Section 4.2 was "plain", they are 375 compared directly. i.e., 377 "code_verifier" == "code_challenge". 379 If the values are equal, the Access Token endpoint MUST continue 380 processing as normal (as defined by OAuth 2.0 [RFC6749]). If the 381 values are not equal, an error response indicating "invalid_grant" as 382 described in section 5.2 of [RFC6749] MUST be returned. 384 5. Compatibility 386 Server implementations of this specification MAY accept OAuth2.0 387 Clients that do not implement this extension. If the "code_verifier" 388 is not received from the client in the Authorization Request, servers 389 supporting backwards compatibility SHOULD revert to a normal OAuth 390 2.0 [RFC6749] protocol. 392 As the OAuth 2.0 [RFC6749] server responses are unchanged by this 393 specification, client implementations of this specification do not 394 need to know if the server has implemented this specification or not, 395 and SHOULD send the additional parameters as defined in Section 3. to 396 all servers. 398 6. IANA Considerations 400 This specification makes a registration request as follows: 402 6.1. OAuth Parameters Registry 404 This specification registers the following parameters in the IANA 405 OAuth Parameters registry defined in OAuth 2.0 [RFC6749]. 407 o Parameter name: code_verifier 408 o Parameter usage location: Access Token Request 409 o Change controller: IESG 410 o Specification document(s): this document 412 o Parameter name: code_challenge 413 o Parameter usage location: Authorization Request 414 o Change controller: IESG 415 o Specification document(s): this document 416 o Parameter name: code_challenge_method 417 o Parameter usage location: Authorization Request 418 o Change controller: IESG 419 o Specification document(s): this document 421 6.2. PKCE Code Challenge Method Registry 423 This specification establishes the PKCE Code Challenge Method 424 registry. 426 Additional code_challenge_method types for use with the authorization 427 endpoint are registered with a Specification Required ([RFC5226]) 428 after a two-week review period on the oauth-ext-review@ietf.org 429 mailing list, on the advice of one or more Designated Experts. 430 However, to allow for the allocation of values prior to publication, 431 the Designated Expert(s) may approve registration once they are 432 satisfied that such a specification will be published. 434 Registration requests must be sent to the oauth-ext-review@ietf.org 435 mailing list for review and comment, with an appropriate subject 436 (e.g., "Request for PKCE code_challenge_method: example"). 438 Within the review period, the Designated Expert(s) will either 439 approve or deny the registration request, communicating this decision 440 to the review list and IANA. Denials should include an explanation 441 and, if applicable, suggestions as to how to make the request 442 successful. 444 IANA must only accept registry updates from the Designated Expert(s) 445 and should direct all requests for registration to the review mailing 446 list. 448 6.2.1. Registration Template 450 Code Challenge Method Parameter Name: 451 The name requested (e.g., "example"). Because a core goal of this 452 specification is for the resulting representations to be compact, 453 it is RECOMMENDED that the name be short -- not to exceed 8 454 characters without a compelling reason to do so. This name is 455 case-sensitive. Names may not match other registered names in a 456 case-insensitive manner unless the Designated Expert(s) state that 457 there is a compelling reason to allow an exception in this 458 particular case. 459 Change Controller: 460 For Standards Track RFCs, state "IESG". For others, give the name 461 of the responsible party. Other details (e.g., postal address, 462 email address, home page URI) may also be included. 463 Specification Document(s): 465 Reference to the document(s) that specify the parameter, 466 preferably including URI(s) that can be used to retrieve copies of 467 the document(s). An indication of the relevant sections may also 468 be included but is not required. 470 6.2.2. Initial Registry Contents 472 This specification registers the Code Challenge Method Parameter 473 names defined in Section 4.2 in this registry. 475 o Code Challenge Method Parameter Name: "plain" 476 o Change Controller: IESG 477 o Specification Document(s): Section 4.2 of [[ this document ]] 479 o Code Challenge Method Parameter Name: "S256" 480 o Change Controller: IESG 481 o Specification Document(s): Section 4.2 of [[ this document ]] 483 7. Security Considerations 485 7.1. Entropy of the code verifier 487 The security model relies on the fact that the code verifier is not 488 learned or guessed by the attacker. It is vitally important to 489 adhere to this principle. As such, the code verifier has to be 490 created in such a manner that it is cryptographically random and has 491 high entropy that it is not practical for the attacker to guess. It 492 is RECOMMENDED that the output of a suitable random number generator 493 be used to create a 32-octet sequence. 495 7.2. Protection against eavesdroppers 497 Clients MUST NOT try down grading the algorithm after trying "S256" 498 method. If the server is PKCE compliant, then "S256" method works. 499 If the server does not support PKCE, it does not generate error. 500 Only the time that the server returns that it does not support "S256" 501 is there is a MITM trying the algorithm downgrade attack. 503 "S256" method protects against eavesdroppers observing or 504 intercepting the "code_challenge". If the "plain" method is used, 505 there is a chance that it will be observed by the attacker on the 506 device. The use of "S256" protects against it. 508 If "code_challenge" is to be returned inside authorization "code" to 509 achieve a stateless server, it has to be encrypted in such a manner 510 that only the server can decrypt and extract it. 512 7.3. Entropy of the code_verifier 514 The client SHOULD create a code_verifier with a minimum of 256bits of 515 entropy. This can be done by having a suitable random number 516 generator create a 32-octet sequence. The Octet sequence can then be 517 base64url encoded to produce a 43-octet URL safe string to use as a 518 code_challenge that has the required entropy. 520 Salting is not used in the production of the code_verifier, as the 521 code_chalange contains sufficient entropy to prevent brute force 522 attacks. Concatenating a publicly known value to a code_challenge 523 (with 256 bits of entropy) and then hashing it with SHA256 would 524 actually reduce the entropy in the resulting code_verifier making it 525 easier for an attacker to brute force. 527 While the S256 transformation is like hashing a password there are 528 important differences. Passwords tend to be relatively low entropy 529 words that can be hashed offline and the hash looked up in a 530 dictionary. By concatenating a unique though public value to each 531 password prior to hashing, the dictionary space that an attacker 532 needs to search is greatly expanded. 534 Modern graphics processors now allow attackers to calculate hashes in 535 real time faster than they could be looked up from a disk. This 536 eliminates the value of the salt in increasing the complexity of a 537 brute force attack for even low entropy passwords. 539 7.4. OAuth security considerations 541 All the OAuth security analysis presented in [RFC6819] applies so 542 readers SHOULD carefully follow it. 544 8. Acknowledgements 546 The initial draft of this specification was created by the OpenID AB/ 547 Connect Working Group of the OpenID Foundation. 549 This specification is the work of the OAuth Working Group, which 550 includes dozens of active and dedicated participants. In particular, 551 the following individuals contributed ideas, feedback, and wording 552 that shaped and formed the final specification: 554 Anthony Nadalin, Microsoft 555 Axel Nenker, Deutsche Telekom 556 Breno de Medeiros, Google 557 Brian Campbell, Ping Identity 558 Chuck Mortimore, Salesforce 559 Dirk Balfanz, Google 560 Eduardo Gueiros, Jive Communications 561 Hannes Tschonfenig, ARM 562 James Manger, Telstra 563 John Bradley, Ping Identity 564 Justin Richer, MIT Kerberos 565 Josh Mandel, Boston Children's Hospital 566 Lewis Adam, Motorola Solutions 567 Madjid Nakhjiri, Samsung 568 Michael B. Jones, Microsoft 569 Nat Sakimura, Nomura Research Institute 570 Naveen Agarwal, Google 571 Paul Madsen, Ping Identity 572 Phil Hunt, Oracle 573 Prateek Mishra, Oracle 574 Ryo Ito, mixi 575 Scott Tomilson, Ping Identity 576 Sergey Beryozkin 577 Takamichi Saito 578 Torsten Lodderstedt, Deutsche Telekom 579 William Denniss, Google 581 9. Revision History 583 -10 585 o re #33 specify lower limit to code_verifier in prose 586 o remove base64url decode from draft, all steps now use encode only 587 o Expanded MTI 588 o re #33 change length of 32 octet base64url encoded string back to 589 43 octets 591 -09 593 o clean up some external references so they don't point at internal 594 sections 596 -08 598 o changed BASE64URL to BASE64URL-ENCODE to be more consistent with 599 appendix A Fixed lowercase base64url in appendix B 600 o Added appendix B as an example of S256 processing 601 o Change reference for unreserved characters to RFC3986 from 602 base64URL 604 -07 606 o removed unused discovery reference and UTF8 607 o re #32 added ASCII(STRING) to make clear that it is the byte array 608 that is being hashed 609 o re #2 Remove discovery requirement section. 610 o updated Acknowledgement 611 o re #32 remove unneeded UTF8(STRING) definition, and define STRING 612 for ASCII(STRING) 613 o re #32 remove unneeded utf8 reference from BASE64URL- 614 DECODE(STRING) def 615 o resolves #31 unused definition of concatenation 616 o re #30 Update figure text call out the endpoints 617 o re #30 Update figure to call out the endpoints 618 o small wording change to the introduction 620 -06 622 o fix date 623 o replace spop with pkce for registry and other references 624 o re #29 change name again 625 o re #27 removed US-ASCII reference 626 o re #27 updated ABNF for code_verifier 627 o resolves #24 added security consideration for salting 628 o resolves #29 Changed title 629 o updated reference to RFC4634 to RFC6234 re #27 630 o changed reference for US-ASCII to RFC20 re #27 631 o resolves #28 added Acknowledgements 632 o resolves #27 updated ABNF 633 o resolves #26 updated abstract and added Hannes figure 635 -05 637 o Added IANA registry for code_challenge_method + fixed some broken 638 internal references. 640 -04 642 o Added error response to authorization response. 644 -03 646 o Added an abstract protocol diagram and explanation 648 -02 650 o Copy edits 652 -01 654 o Specified exactly two supported transformations 655 o Moved discovery steps to security considerations. 656 o Incorporated readability comments by Eduardo Gueiros. 657 o Changed MUST in 3.1 to SHOULD. 659 -00 661 o Initial IETF version. 663 10. References 665 10.1. Normative References 667 [RFC0020] Cerf, V., "ASCII format for network interchange", RFC 20, 668 October 1969. 670 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 671 Requirement Levels", BCP 14, RFC 2119, March 1997. 673 [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform 674 Resource Identifier (URI): Generic Syntax", STD 66, RFC 675 3986, January 2005. 677 [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data 678 Encodings", RFC 4648, October 2006. 680 [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax 681 Specifications: ABNF", STD 68, RFC 5234, January 2008. 683 [RFC6234] Eastlake, D. and T. Hansen, "US Secure Hash Algorithms 684 (SHA and SHA-based HMAC and HKDF)", RFC 6234, May 2011. 686 [RFC6749] Hardt, D., "The OAuth 2.0 Authorization Framework", RFC 687 6749, October 2012. 689 10.2. Informative References 691 [RFC6819] Lodderstedt, T., McGloin, M., and P. Hunt, "OAuth 2.0 692 Threat Model and Security Considerations", RFC 6819, 693 January 2013. 695 Appendix A. Notes on implementing base64url encoding without padding 697 This appendix describes how to implement a base64url encoding 698 function without padding based upon standard base64 encoding function 699 that uses padding. 701 To be concrete, example C# code implementing these functions is shown 702 below. Similar code could be used in other languages. 704 static string base64urlencode(byte [] arg) 705 { 706 string s = Convert.ToBase64String(arg); // Regular base64 encoder 707 s = s.Split('=')[0]; // Remove any trailing '='s 708 s = s.Replace('+', '-'); // 62nd char of encoding 709 s = s.Replace('/', '_'); // 63rd char of encoding 710 return s; 711 } 713 An example correspondence between unencoded and encoded values 714 follows. The octet sequence below encodes into the string below, 715 which when decoded, reproduces the octet sequence. 717 3 236 255 224 193 719 A-z_4ME 721 Appendix B. Example for the S256 code_challenge_method 723 The client uses output of a suitable random number generator to 724 create a 32-octet sequence. The octets representing the value in 725 this example (using JSON array notation) are:" 727 [116, 24, 223, 180, 151, 153, 224, 37, 79, 250, 96, 125, 216, 173, 728 187, 186, 22, 212, 37, 77, 105, 214, 191, 240, 91, 88, 5, 88, 83, 729 132, 141, 121] 731 Encoding this octet sequence as a Base64url provides the value of the 732 code_verifier: 734 dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk 736 The code_verifier is then hashed via the SHA256 hash function to 737 produce: 739 [19, 211, 30, 150, 26, 26, 216, 236, 47, 22, 177, 12, 76, 152, 46, 740 8, 118, 168, 120, 173, 109, 241, 68, 86, 110, 225, 137, 74, 203, 741 112, 249, 195] 743 Encoding this octet sequence as a base64url provides the value of the 744 code_challenge: 746 E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM 748 The authorization request includes: 750 code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM 751 &code_challange_method=S256 753 The Authorization server then records the code_challenge and 754 code_challenge_method along with the code that is granted to the 755 client. 757 in the request to the token_endpoint the client includes the code 758 received in the authorization response as well as the additional 759 paramater: 761 code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk 763 The Authorization server retrieves the information for the code 764 grant. Based on the recorded code_challange_method being S256, it 765 then hashes and base64url encodes the value of code_verifier. 766 BASE64URL-ENCODE(SHA256(ASCII("code_verifier" ))) 768 The calculated value is then compared with the value of 769 "code_challenge": 771 BASE64URL-ENCODE(SHA256(ASCII("code_verifier" ))) == code_challenge 773 If the two values are equal then the Authorization server can provide 774 the tokens as long as there are no other errors in the request. If 775 the values are not equal then the request must be rejected, and an 776 error returned. 778 Authors' Addresses 780 Nat Sakimura (editor) 781 Nomura Research Institute 782 1-6-5 Marunouchi, Marunouchi Kitaguchi Bldg. 783 Chiyoda-ku, Tokyo 100-0005 784 Japan 786 Phone: +81-3-5533-2111 787 Email: n-sakimura@nri.co.jp 788 URI: http://nat.sakimura.org/ 789 John Bradley 790 Ping Identity 791 Casilla 177, Sucursal Talagante 792 Talagante, RM 793 Chile 795 Phone: +44 20 8133 3718 796 Email: ve7jtb@ve7jtb.com 797 URI: http://www.thread-safe.com/ 799 Naveen Agarwal 800 Google 801 1600 Amphitheatre Pkwy 802 Mountain View, CA 94043 803 USA 805 Phone: +1 650-253-0000 806 Email: naa@google.com 807 URI: http://google.com/