idnits 2.17.1 draft-ietf-oauth-spop-09.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 05, 2015) is 3366 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 429, 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 9, 2015 Ping Identity 6 N. Agarwal 7 Google 8 February 05, 2015 10 Proof Key for Code Exchange by OAuth Public Clients 11 draft-ietf-oauth-spop-09 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 9, 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 . . . . . . . . . . . . . . . . . . . . . . . 18 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 length less than 128 270 characters. 272 ABNF for "code_verifier" is as follows. 274 code-verifier = 42*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 42-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 = 42*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 MTI on the server. Clients MAY use plain only if they 348 cannot support "S256" for some technical reason and knows that the 349 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 first hashed with SHA-256 then compared 370 to the base64url decoded "code_challenge". i.e., 372 SHA256(ASCII("code_verifier" )) == BASE64URL- 373 DECODE("code_challenge"). 375 If the "code_challenge_method" from Section 4.2 was "plain", they are 376 compared directly. i.e., 378 "code_challenge" == "code_verifier". 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 418 o Parameter name: code_challenge_method 419 o Parameter usage location: Authorization Request 420 o Change controller: IESG 421 o Specification document(s): this document 423 6.2. PKCE Code Challenge Method Registry 425 This specification establishes the PKCE Code Challenge Method 426 registry. 428 Additional code_challenge_method types for use with the authorization 429 endpoint are registered with a Specification Required ([RFC5226]) 430 after a two-week review period on the oauth-ext-review@ietf.org 431 mailing list, on the advice of one or more Designated Experts. 432 However, to allow for the allocation of values prior to publication, 433 the Designated Expert(s) may approve registration once they are 434 satisfied that such a specification will be published. 436 Registration requests must be sent to the oauth-ext-review@ietf.org 437 mailing list for review and comment, with an appropriate subject 438 (e.g., "Request for PKCE code_challenge_method: example"). 440 Within the review period, the Designated Expert(s) will either 441 approve or deny the registration request, communicating this decision 442 to the review list and IANA. Denials should include an explanation 443 and, if applicable, suggestions as to how to make the request 444 successful. 446 IANA must only accept registry updates from the Designated Expert(s) 447 and should direct all requests for registration to the review mailing 448 list. 450 6.2.1. Registration Template 452 Code Challenge Method Parameter Name: 453 The name requested (e.g., "example"). Because a core goal of this 454 specification is for the resulting representations to be compact, 455 it is RECOMMENDED that the name be short -- not to exceed 8 456 characters without a compelling reason to do so. This name is 457 case-sensitive. Names may not match other registered names in a 458 case-insensitive manner unless the Designated Expert(s) state that 459 there is a compelling reason to allow an exception in this 460 particular case. 461 Change Controller: 463 For Standards Track RFCs, state "IESG". For others, give the name 464 of the responsible party. Other details (e.g., postal address, 465 email address, home page URI) may also be included. 466 Specification Document(s): 467 Reference to the document(s) that specify the parameter, 468 preferably including URI(s) that can be used to retrieve copies of 469 the document(s). An indication of the relevant sections may also 470 be included but is not required. 472 6.2.2. Initial Registry Contents 474 This specification registers the Code Challenge Method Parameter 475 names defined in Section 4.2 in this registry. 477 o Code Challenge Method Parameter Name: "plain" 478 o Change Controller: IESG 479 o Specification Document(s): Section 4.2 of [[ this document ]] 481 o Code Challenge Method Parameter Name: "S256" 482 o Change Controller: IESG 483 o Specification Document(s): Section 4.2 of [[ this document ]] 485 7. Security Considerations 487 7.1. Entropy of the code verifier 489 The security model relies on the fact that the code verifier is not 490 learned or guessed by the attacker. It is vitally important to 491 adhere to this principle. As such, the code verifier has to be 492 created in such a manner that it is cryptographically random and has 493 high entropy that it is not practical for the attacker to guess. It 494 is RECOMMENDED that the output of a suitable random number generator 495 be used to create a 32-octet sequence. 497 7.2. Protection against eavesdroppers 499 Clients MUST NOT try down grading the algorithm after trying "S256" 500 method. If the server is PKCE compliant, then "S256" method works. 501 If the server does not support PKCE, it does not generate error. 502 Only the time that the server returns that it does not support "S256" 503 is there is a MITM trying the algorithm downgrade attack. 505 "S256" method protects against eavesdroppers observing or 506 intercepting the "code_challenge". If the "plain" method is used, 507 there is a chance that it will be observed by the attacker on the 508 device. The use of "S256" protects against it. 510 If "code_challenge" is to be returned inside authorization "code" to 511 achieve a stateless server, it has to be encrypted in such a manner 512 that only the server can decrypt and extract it. 514 7.3. Entropy of the code_verifier 516 The client SHOULD create a code_verifier with a minimum of 256bits of 517 entropy. This can be done by having a suitable random number 518 generator create a 32-octet sequence. The Octet sequence can then be 519 Base64url encoded to produce a 42-octet URL safe string to use as a 520 code_challenge that has the required entropy. 522 Salting is not used in the production of the code_verifier, as the 523 code_chalange contains sufficient entropy to prevent brute force 524 attacks. Concatenating a publicly known value to a code_challenge 525 (with 256 bits of entropy) and then hashing it with SHA256 would 526 actually reduce the entropy in the resulting code_verifier making it 527 easier for an attacker to brute force. 529 While the S256 transformation is like hashing a password there are 530 important differences. Passwords tend to be relatively low entropy 531 words that can be hashed offline and the hash looked up in a 532 dictionary. By concatenating a unique though public value to each 533 password prior to hashing, the dictionary space that an attacker 534 needs to search is greatly expanded. 536 Modern graphics processors now allow attackers to calculate hashes in 537 real time faster than they could be looked up from a disk. This 538 eliminates the value of the salt in increasing the complexity of a 539 brute force attack for even low entropy passwords. 541 7.4. OAuth security considerations 543 All the OAuth security analysis presented in [RFC6819] applies so 544 readers SHOULD carefully follow it. 546 8. Acknowledgements 548 The initial draft of this specification was created by the OpenID AB/ 549 Connect Working Group of the OpenID Foundation. 551 This specification is the work of the OAuth Working Group, which 552 includes dozens of active and dedicated participants. In particular, 553 the following individuals contributed ideas, feedback, and wording 554 that shaped and formed the final specification: 556 Anthony Nadalin, Microsoft 557 Axel Nenker, Deutsche Telekom 558 Breno de Medeiros, Google 559 Brian Campbell, Ping Identity 560 Chuck Mortimore, Salesforce 561 Dirk Balfanz, Google 562 Eduardo Gueiros, Jive Communications 563 Hannes Tschonfenig, ARM 564 James Manger, Telstra 565 John Bradley, Ping Identity 566 Justin Richer, MIT Kerberos 567 Josh Mandel, Boston Children's Hospital 568 Lewis Adam, Motorola Solutions 569 Madjid Nakhjiri, Samsung 570 Michael B. Jones, Microsoft 571 Nat Sakimura, Nomura Research Institute 572 Naveen Agarwal, Google 573 Paul Madsen, Ping Identity 574 Phil Hunt, Oracle 575 Prateek Mishra, Oracle 576 Ryo Ito, mixi 577 Scott Tomilson, Ping Identity 578 Sergey Beryozkin 579 Takamichi Saito 580 Torsten Lodderstedt, Deutsche Telekom 581 William Denniss, Google 583 9. Revision History 585 -08 587 o clean up some external references so they don't point at internal 588 sections 590 -07 592 o changed BASE64URL to BASE64URL-ENCODE to be more consistent with 593 appendix A Fixed lowercase base64url in appendix B 594 o Added appendix B as an example of S256 processing 595 o Change reference for unreserved characters to RFC3986 from 596 base64URL 598 -07 600 o removed unused discovery reference and UTF8 601 o re #32 added ASCII(STRING) to make clear that it is the byte array 602 that is being hashed 603 o re #2 Remove discovery requirement section. 604 o updated Acknowledgement 605 o re #32 remove unneeded UTF8(STRING) definition, and define STRING 606 for ASCII(STRING) 607 o re #32 remove unneeded utf8 reference from BASE64URL- 608 DECODE(STRING) def 609 o resolves #31 unused definition of concatenation 610 o re #30 Update figure text call out the endpoints 611 o re #30 Update figure to call out the endpoints 612 o small wording change to the introduction 614 -06 616 o fix date 617 o replace spop with pkce for registry and other references 618 o re #29 change name again 619 o re #27 removed US-ASCII reference 620 o re #27 updated ABNF for code_verifier 621 o resolves #24 added security consideration for salting 622 o resolves #29 Changed title 623 o updated reference to RFC4634 to RFC6234 re #27 624 o changed reference for US-ASCII to RFC20 re #27 625 o resolves #28 added Acknowledgements 626 o resolves #27 updated ABNF 627 o resolves #26 updated abstract and added Hannes figure 629 -05 631 o Added IANA registry for code_challenge_method + fixed some broken 632 internal references. 634 -04 636 o Added error response to authorization response. 638 -03 640 o Added an abstract protocol diagram and explanation 642 -02 644 o Copy edits 646 -01 648 o Specified exactly two supported transformations 649 o Moved discovery steps to security considerations. 650 o Incorporated readability comments by Eduardo Gueiros. 651 o Changed MUST in 3.1 to SHOULD. 653 -00 655 o Initial IETF version. 657 10. References 659 10.1. Normative References 661 [RFC0020] Cerf, V., "ASCII format for network interchange", RFC 20, 662 October 1969. 664 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 665 Requirement Levels", BCP 14, RFC 2119, March 1997. 667 [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform 668 Resource Identifier (URI): Generic Syntax", STD 66, RFC 669 3986, January 2005. 671 [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data 672 Encodings", RFC 4648, October 2006. 674 [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax 675 Specifications: ABNF", STD 68, RFC 5234, January 2008. 677 [RFC6234] Eastlake, D. and T. Hansen, "US Secure Hash Algorithms 678 (SHA and SHA-based HMAC and HKDF)", RFC 6234, May 2011. 680 [RFC6749] Hardt, D., "The OAuth 2.0 Authorization Framework", RFC 681 6749, October 2012. 683 10.2. Informative References 685 [RFC6819] Lodderstedt, T., McGloin, M., and P. Hunt, "OAuth 2.0 686 Threat Model and Security Considerations", RFC 6819, 687 January 2013. 689 Appendix A. Notes on implementing base64url encoding without padding 691 This appendix describes how to implement base64url encoding and 692 decoding functions without padding based upon standard base64 693 encoding and decoding functions that do use padding. 695 To be concrete, example C# code implementing these functions is shown 696 below. Similar code could be used in other languages. 698 static string base64urlencode(byte [] arg) 699 { 700 string s = Convert.ToBase64String(arg); // Regular base64 encoder 701 s = s.Split('=')[0]; // Remove any trailing '='s 702 s = s.Replace('+', '-'); // 62nd char of encoding 703 s = s.Replace('/', '_'); // 63rd char of encoding 704 return s; 705 } 707 static byte [] base64urldecode(string arg) 708 { 709 string s = arg; 710 s = s.Replace('-', '+'); // 62nd char of encoding 711 s = s.Replace('_', '/'); // 63rd char of encoding 712 switch (s.Length % 4) // Pad with trailing '='s 713 { 714 case 0: break; // No pad chars in this case 715 case 2: s += "=="; break; // Two pad chars 716 case 3: s += "="; break; // One pad char 717 default: throw new System.Exception( 718 "Illegal base64url string!"); 719 } 720 return Convert.FromBase64String(s); // Standard base64 decoder 721 } 723 As per the example code above, the number of '=' padding characters 724 that needs to be added to the end of a base64url encoded string 725 without padding to turn it into one with padding is a deterministic 726 function of the length of the encoded string. Specifically, if the 727 length mod 4 is 0, no padding is added; if the length mod 4 is 2, two 728 '=' padding characters are added; if the length mod 4 is 3, one '=' 729 padding character is added; if the length mod 4 is 1, the input is 730 malformed. 732 An example correspondence between unencoded and encoded values 733 follows. The octet sequence below encodes into the string below, 734 which when decoded, reproduces the octet sequence. 736 3 236 255 224 193 738 A-z_4ME 740 Appendix B. Example for the S256 code_challenge_method 742 The client uses output of a suitable random number generator to 743 create a 32-octet sequence. The octets representing the value in 744 this example (using JSON array notation) are:" 746 [116, 24, 223, 180, 151, 153, 224, 37, 79, 250, 96, 125, 216, 173, 747 187, 186, 22, 212, 37, 77, 105, 214, 191, 240, 91, 88, 5, 88, 83, 748 132, 141, 121] 750 Encoding this octet sequence as a Base64url provides the value of the 751 code_verifier: 753 dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk 755 The code_verifier is then hashed via the SHA256 hash function to 756 produce: 758 [19, 211, 30, 150, 26, 26, 216, 236, 47, 22, 177, 12, 76, 152, 46, 759 8, 118, 168, 120, 173, 109, 241, 68, 86, 110, 225, 137, 74, 203, 760 112, 249, 195] 762 Encoding this octet sequence as a Base64url provides the value of the 763 code_challenge: 765 E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM 767 The authorization request includes: 769 code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM 770 &code_challange_method=S256 772 The Authorization server then records the code_challenge and 773 code_challenge_method along with the code that is granted to the 774 client. 776 in the request to the token_endpoint the client includes the code 777 received in the authorization response as well as the additional 778 paramater: 780 code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk 782 The Authorization server retrieves the information for the code 783 grant. Based on the recorded code_challange_method being S256, it 784 then hashes the value of code_verifier. SHA256(ASCII("code_verifier" 785 )) 787 The Authorization can then either one of: 789 BASE64-DECODE(code_challenge ) == SHA256(ASCII("code_verifier" )) 790 BASE64URL-ENCODE(SHA256(ASCII("code_verifier" ))) == 791 code_challenge 793 If the two values are equal then the Authorization server can provide 794 the tokens as long as there are no other errors in the request. If 795 the values are not equal then the request must be rejected, and an 796 error returned. 798 Authors' Addresses 800 Nat Sakimura (editor) 801 Nomura Research Institute 802 1-6-5 Marunouchi, Marunouchi Kitaguchi Bldg. 803 Chiyoda-ku, Tokyo 100-0005 804 Japan 806 Phone: +81-3-5533-2111 807 Email: n-sakimura@nri.co.jp 808 URI: http://nat.sakimura.org/ 810 John Bradley 811 Ping Identity 812 Casilla 177, Sucursal Talagante 813 Talagante, RM 814 Chile 816 Phone: +44 20 8133 3718 817 Email: ve7jtb@ve7jtb.com 818 URI: http://www.thread-safe.com/ 820 Naveen Agarwal 821 Google 822 1600 Amphitheatre Pkwy 823 Mountain View, CA 94043 824 USA 826 Phone: +1 650-253-0000 827 Email: naa@google.com 828 URI: http://google.com/