idnits 2.17.1 draft-ietf-oauth-spop-07.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 (January 31, 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 266, but not defined == Missing Reference: '0-9' is mentioned on line 266, but not defined == Missing Reference: 'RFC5226' is mentioned on line 424, 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 4, 2015 Ping Identity 6 N. Agarwal 7 Google 8 January 31, 2015 10 Proof Key for Code Exchange by OAuth Public Clients 11 draft-ietf-oauth-spop-07 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 4, 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 . . . . . . . . . . . . 6 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 . . . . . . . . . . . . . . . . . . . 7 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 . . . . . . . . . . . . . . . . . . . . . . . . 8 69 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 9 70 6.1. OAuth Parameters Registry . . . . . . . . . . . . . . . . 9 71 6.2. PKCE Code Challenge Method Registry . . . . . . . . . . . 9 72 6.2.1. Registration Template . . . . . . . . . . . . . . . . 10 73 6.2.2. Initial Registry Contents . . . . . . . . . . . . . . 10 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 . . . . . . . . . . . . . . 11 78 7.4. OAuth security considerations . . . . . . . . . . . . . . 12 79 8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 12 80 9. Revision History . . . . . . . . . . . . . . . . . . . . . . 13 81 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 14 82 10.1. Normative References . . . . . . . . . . . . . . . . . . 14 83 10.2. Informative References . . . . . . . . . . . . . . . . . 14 84 Appendix A. Notes on implementing base64url encoding without 85 padding . . . . . . . . . . . . . . . . . . . . . . 14 86 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 16 88 1. Introduction 90 OAuth 2.0 [RFC6749] public clients are susceptible to the 91 authorization "code" interception attack. 93 The attacker thereby intercepts the authorization code returned from 94 the authorization endpoint within communication path not protected by 95 TLS, such as inter-app communication within the operating system of 96 the client. 98 Once the attacker has gained access to the authorization code it can 99 use it to obtain the access token. 101 Figure 1 shows the attack graphically. In step (1) the native app 102 running on the end device, such as a smart phone, issues an 103 authorization request via the browser/operating system, which then 104 gets forwarded to the OAuth 2.0 authorization server in step (2). 105 The authorization server returns the authorization code in step (3). 106 The malicious app is able to observe the authorization code in step 107 (4) since it is registered to the custom URI scheme used by the 108 legitimate app. This allows the attacker to reguest and obtain an 109 access token in step (5) and step (6), respectively. 111 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ 112 | End Device (e.g., Smart Phone) | 113 | | 114 | +-------------+ +----------+ | (6) Access Token +----------+ 115 | |Legitimate | | Malicious|<--------------------| | 116 | |OAuth 2.0 App| | App |-------------------->| | 117 | +-------------+ +----------+ | (5) Authorization | | 118 | | ^ ^ | Grant | | 119 | | \ | | | | 120 | | \ (4) | | | | 121 | (1) | \ Authz| | | | 122 | Authz| \ Code | | | Authz | 123 | Request| \ | | | Server | 124 | | \ | | | | 125 | | \ | | | | 126 | v \ | | | | 127 | +----------------------------+ | | | 128 | | | | (3) Authz Code | | 129 | | Operating System/ |<--------------------| | 130 | | Browser |-------------------->| | 131 | | | | (2) Authz Request | | 132 | +----------------------------+ | +----------+ 133 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ 135 Figure 1: Authorization Code Interception Attack. 137 A number of pre-conditions need to hold in order for this attack to 138 work: 140 1) The attacker manages to register a malicious application on the 141 client device and registers a custom URI scheme that is also used 142 by another application. 143 The operating systems must allow a custom URI schemes to be 144 registered by multiple applications. 145 2) The OAuth 2.0 authorization code grant is used. 147 3) The attacker has access to the client id. All native app client- 148 instances use the same client id. No client secret is used (since 149 public clients cannot keep their secrets confidential.) 150 4) The attacker (via the installed app) is able to observe responses 151 from the authorization endpoint. As a more sophisticated attack 152 scenario the attacker is also able to observe requests (in 153 addition to responses) to the authorization endpoint. The 154 attacker is, however, not able to act as a man-in-the-middle. 156 While this is a long list of pre-conditions the described attack has 157 been observed in the wild and has to be considered in OAuth 2.0 158 deployments. While Section 4.4.1 of [RFC6819] describes mitigation 159 techniques they are, unfortunately, not applicable since they rely on 160 a per-client instance secret or aper client instance redirect URI. 162 To mitigate this attack, this extension utilizes a dynamically 163 created cryptographically random key called 'code verifier'. A 164 unique code verifier is created for every authorization request and 165 its transformed value, called 'code challenge', is sent to the 166 authorization server to obtain the authorization code. The 167 authorization "code" obtained is then sent to the token endpoint with 168 the 'code verifier' and the server compares it with the previously 169 received request code so that it can perform the proof of possession 170 of the 'code verifier' by the client. This works as the mitigation 171 since the attacker would not know this one-time key. 173 1.1. Protocol Flow 175 +-------------------+ 176 | Authz Server | 177 +--------+ | +---------------+ | 178 | |--(A)- Authorization Request ---->| | | 179 | | + t(code_verifier), t | | Authorization | | 180 | | | | Endpoint | | 181 | |<-(B)---- Authorization Code -----| | | 182 | | | +---------------+ | 183 | Client | | | 184 | | | +---------------+ | 185 | |--(C)-- Access Token Request ---->| | | 186 | | + code_verifier | | Token | | 187 | | | | Endpoint | | 188 | |<-(D)------ Access Token ---------| | | 189 +--------+ | +---------------+ | 190 +-------------------+ 192 Figure 2: Abstract Protocol Flow 194 This specification adds additional parameters to the OAuth 2.0 195 Authorization and Access Token Requests, shown in abstract form in 196 Figure 1. 198 A. The client creates and records a secret named the "code_verifier", 199 and derives a transformed version "t(code_verifier)" (referred to 200 as the "code_challenge") which is sent in the OAuth 2.0 201 Authorization Request, along with the transformation method "t". 202 B. The Authorization Endpoint responds as usual, but records 203 "t(code_verifier)" and the transformation method. 204 C. The client then sends the code in the Access Token Request as 205 usual, but includes the "code_verifier" secret generated at (A). 206 D. The authorization server transforms "code_verifier" and compares 207 it to "t(code_verifier)" from (B). Access is denied if they are 208 not equal. 210 An attacker who intercepts the Authorization Grant at (B) is unable 211 to redeem it for an Access Token, as they are not in possession of 212 the "code_verifier" secret. 214 2. Notational Conventions 216 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 217 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 218 "OPTIONAL" in this document are to be interpreted as described in Key 219 words for use in RFCs to Indicate Requirement Levels [RFC2119]. If 220 these words are used without being spelled in uppercase then they are 221 to be interpreted with their normal natural language meanings. 223 This specification uses the Augmented Backus-Naur Form (ABNF) 224 notation of [RFC5234]. 226 STRING denotes a sequence of zero or more ASCII [RFC0020] characters. 228 OCTETS denotes a sequence of zero or more octets. 230 ASCII(STRING) denotes the octets of the ASCII [RFC0020] 231 representation of STRING where STRING is a sequence of zero or more 232 ASCII characters. 234 BASE64URL(OCTETS) denotes the base64url encoding of OCTETS, per 235 Section 3 producing a STRING. 237 BASE64URL-DECODE(STRING) denotes the base64url decoding of STRING, 238 per Section 3, producing a sequence of octets. 240 SHA256(OCTETS) denotes a SHA2 256bit hash [RFC6234] of OCTETS. 242 3. Terminology 244 In addition to the terms defined in OAuth 2.0 [RFC6749], this 245 specification defines the following terms: 247 code verifier A cryptographically random string that is used to 248 correlate the authorization request to the token request. 249 code challenge A challenge derived from the code verifier that is 250 sent in the authorization request, to be verified against later. 251 Base64url Encoding Base64 encoding using the URL- and filename-safe 252 character set defined in Section 5 of RFC 4648 [RFC4648], with all 253 trailing '=' characters omitted (as permitted by Section 3.2) and 254 without the inclusion of any line breaks, whitespace, or other 255 additional characters. (See Appendix A for notes on implementing 256 base64url encoding without padding.) 258 4. Protocol 260 4.1. Client creates a code verifier 262 The client first creates a code verifier, "code_verifier", for each 263 OAuth 2.0 [RFC6749] Authorization Request, in the following manner: 265 code_verifier = high entropy cryptographic random STRING using the 266 url and filename safe Alphabet [A-Z] / [a-z] / [0-9] / "-" / "_" from 267 Sec 5 of RFC 4648 [RFC4648], with length less than 128 characters. 269 ABNF for "code_verifier" is as follows. 271 code-verifier = 42*128unreserved 272 unreserved = ALPHA / DIGIT / "-" / "_" 273 ALPHA = %x41-5A / %x61-7A 274 DIGIT = %x30-39 276 NOTE: code verifier SHOULD have enough entropy to make it impractical 277 to guess the value. It is RECOMMENDED that the output of a suitable 278 random number generator be used to create a 32-octet sequence. The 279 Octet sequence is then BASE64URL encoded to produce a 42-octet URL 280 safe string to use as the code verifier. 282 4.2. Client creates the code challenge 284 The client then creates a code challenge, "code_challenge", derived 285 from the "code_verifier" by using one of the following 286 transformations on the "code_verifier": 288 plain "code_challenge" = "code_verifier" 289 S256 "code_challenge" = BASE64URL(SHA256(ASCII("code_verifier"))) 290 It is RECOMMENDED to use the S256 transformation when possible. 292 ABNF for "code_challenge" is as follows. 294 code-challenge = 42*128unreserved 295 unreserved = ALPHA / DIGIT / "-" / "_" 296 ALPHA = %x41-5A / %x61-7A 297 DIGIT = %x30-39 299 4.3. Client sends the code challenge with the authorization request 301 The client sends the code challenge as part of the OAuth 2.0 302 [RFC6749] Authorization Request (Section 4.1.1.) using the following 303 additional parameters: 305 code_challenge REQUIRED. Code challenge. 307 code_challenge_method OPTIONAL, defaults to "plain". Code verifier 308 transformation method, "S256" or "plain". 310 4.4. Server returns the code 312 When the server issues the "code" in the Authorization Response, it 313 MUST associate the "code_challenge" and "code_challenge_method" 314 values with the "code" so it can be verified later. 316 Typically, the "code_challenge" and "code_challenge_method" values 317 are stored in encrypted form in the "code" itself, but could 318 alternatively be stored on the server, associated with the code. The 319 server MUST NOT include the "code_challenge" value in client requests 320 in a form that other entities can extract. 322 The exact method that the server uses to associate the 323 "code_challenge" with the issued "code" is out of scope for this 324 specification. 326 4.4.1. Error Response 328 If the server requires PKCE, and the client does not send the 329 "code_challenge" in the request, the authorization endpoint MUST 330 return the authorization error response with "error" value set to 331 "invalid_request". The "error_description" or the response of 332 "error_uri" SHOULD explain the nature of error, e.g., code challenge 333 required. 335 If the server supporting PKCE does not support the requested 336 transform, the authorization endpoint MUST return the authorization 337 error response with "error" value set to "invalid_request". The 338 "error_description" or the response of "error_uri" SHOULD explain the 339 nature of error, e.g., transform algorithm not supported. 341 If the client is capable of using "S256", it MUST use "S256", as 342 "S256" is MTI on the server. Clients MAY use plain only if they 343 cannot support "S256" for some technical reason and knows that the 344 server supports "plain". 346 4.5. Client sends the code and the secret to the token endpoint 348 Upon receipt of the "code", the client sends the Access Token Request 349 to the token endpoint. In addition to the parameters defined in 350 OAuth 2.0 [RFC6749] Access Token Request (Section 4.1.3.), it sends 351 the following parameter: 353 code_verifier REQUIRED. Code verifier 355 4.6. Server verifies code_verifier before returning the tokens 357 Upon receipt of the request at the Access Token endpoint, the server 358 verifies it by calculating the code challenge from received 359 "code_verifier" and comparing it with the previously associated 360 "code_challenge", after first transforming it according to the 361 "code_challenge_method" method specified by the client. 363 If the "code_challenge_method" from Section 4.2 was "S256", the 364 received "code_verifier" is first hashed with SHA-256 then compared 365 to the base64url decoded "code_challenge". i.e., 367 SHA256(ASCII("code_verifier" )) == BASE64URL- 368 DECODE("code_challenge"). 370 If the "code_challenge_method" from Section 4.2 was "plain", they are 371 compared directly. i.e., 373 "code_challenge" == "code_verifier". 375 If the values are equal, the Access Token endpoint MUST continue 376 processing as normal (as defined by OAuth 2.0 [RFC6749]). If the 377 values are not equal, an error response indicating "invalid_grant" as 378 described in section 5.2 of OAuth 2.0 [RFC6749] MUST be returned. 380 5. Compatibility 382 Server implementations of this specification MAY accept OAuth2.0 383 Clients that do not implement this extension. If the "code_verifier" 384 is not received from the client in the Authorization Request, servers 385 supporting backwards compatibility SHOULD revert to a normal OAuth 386 2.0 [RFC6749] protocol. 388 As the OAuth 2.0 [RFC6749] server responses are unchanged by this 389 specification, client implementations of this specification do not 390 need to know if the server has implemented this specification or not, 391 and SHOULD send the additional parameters as defined in Section 3. to 392 all servers. 394 6. IANA Considerations 396 This specification makes a registration request as follows: 398 6.1. OAuth Parameters Registry 400 This specification registers the following parameters in the IANA 401 OAuth Parameters registry defined in OAuth 2.0 [RFC6749]. 403 o Parameter name: code_verifier 404 o Parameter usage location: Access Token Request 405 o Change controller: IESG 406 o Specification document(s): this document 408 o Parameter name: code_challenge 409 o Parameter usage location: Authorization Request 410 o Change controller: IESG 411 o Specification document(s): this document 413 o Parameter name: code_challenge_method 414 o Parameter usage location: Authorization Request 415 o Change controller: IESG 416 o Specification document(s): this document 418 6.2. PKCE Code Challenge Method Registry 420 This specification establishes the PKCE Code Challenge Method 421 registry. 423 Additional code_challenge_method types for use with the authorization 424 endpoint are registered with a Specification Required ([RFC5226]) 425 after a two-week review period on the oauth-ext-review@ietf.org 426 mailing list, on the advice of one or more Designated Experts. 427 However, to allow for the allocation of values prior to publication, 428 the Designated Expert(s) may approve registration once they are 429 satisfied that such a specification will be published. 431 Registration requests must be sent to the oauth-ext-review@ietf.org 432 mailing list for review and comment, with an appropriate subject 433 (e.g., "Request for PKCE code_challenge_method: example"). 435 Within the review period, the Designated Expert(s) will either 436 approve or deny the registration request, communicating this decision 437 to the review list and IANA. Denials should include an explanation 438 and, if applicable, suggestions as to how to make the request 439 successful. 441 IANA must only accept registry updates from the Designated Expert(s) 442 and should direct all requests for registration to the review mailing 443 list. 445 6.2.1. Registration Template 447 Code Challenge Method Parameter Name: 448 The name requested (e.g., "example"). Because a core goal of this 449 specification is for the resulting representations to be compact, 450 it is RECOMMENDED that the name be short -- not to exceed 8 451 characters without a compelling reason to do so. This name is 452 case-sensitive. Names may not match other registered names in a 453 case-insensitive manner unless the Designated Expert(s) state that 454 there is a compelling reason to allow an exception in this 455 particular case. 456 Change Controller: 457 For Standards Track RFCs, state "IESG". For others, give the name 458 of the responsible party. Other details (e.g., postal address, 459 email address, home page URI) may also be included. 460 Specification Document(s): 461 Reference to the document(s) that specify the parameter, 462 preferably including URI(s) that can be used to retrieve copies of 463 the document(s). An indication of the relevant sections may also 464 be included but is not required. 466 6.2.2. Initial Registry Contents 468 This specification registers the Code Challenge Method Parameter 469 names defined in Section 4.2 in this registry. 471 o Code Challenge Method Parameter Name: "plain" 472 o Change Controller: IESG 473 o Specification Document(s): Section 4.2 of [[ this document ]] 475 o Code Challenge Method Parameter Name: "S256" 476 o Change Controller: IESG 477 o Specification Document(s): Section 4.2 of [[ this document ]] 479 7. Security Considerations 481 7.1. Entropy of the code verifier 483 The security model relies on the fact that the code verifier is not 484 learned or guessed by the attacker. It is vitally important to 485 adhere to this principle. As such, the code verifier has to be 486 created in such a manner that it is cryptographically random and has 487 high entropy that it is not practical for the attacker to guess. It 488 is RECOMMENDED that the output of a suitable random number generator 489 be used to create a 32-octet sequence. 491 7.2. Protection against eavesdroppers 493 Clients MUST NOT try down grading the algorithm after trying "S256" 494 method. If the server is PKCE compliant, then "S256" method works. 495 If the server does not support PKCE, it does not generate error. 496 Only the time that the server returns that it does not support "S256" 497 is there is a MITM trying the algorithm downgrade attack. 499 "S256" method protects against eavesdroppers observing or 500 intercepting the "code_challenge". If the "plain" method is used, 501 there is a chance that it will be observed by the attacker on the 502 device. The use of "S256" protects against it. 504 If "code_challenge" is to be returned inside authorization "code" to 505 achieve a stateless server, it has to be encrypted in such a manner 506 that only the server can decrypt and extract it. 508 7.3. Entropy of the code_verifier 510 The client SHOULD create a code_verifier with a minimum of 256bits of 511 entropy. This can be done by having a suitable random number 512 generator create a 32-octet sequence. The Octet sequence can then be 513 Base64url encoded to produce a 42-octet URL safe string to use as a 514 code_challenge that has the required entropy. 516 Salting is not used in the production of the code_verifier, as the 517 code_chalange contains sufficient entropy to prevent brute force 518 attacks. Concatenating a publicly known value to a code_challenge 519 (with 256 bits of entropy) and then hashing it with SHA256 would 520 actually reduce the entropy in the resulting code_verifier making it 521 easier for an attacker to brute force. 523 While the S256 transformation is like hashing a password there are 524 important differences. Passwords tend to be relatively low entropy 525 words that can be hashed offline and the hash looked up in a 526 dictionary. By concatenating a unique though public value to each 527 password prior to hashing, the dictionary space that an attacker 528 needs to search is greatly expanded. 530 Modern graphics processors now allow attackers to calculate hashes in 531 real time faster than they could be looked up from a disk. This 532 eliminates the value of the salt in increasing the complexity of a 533 brute force attack for even low entropy passwords. 535 7.4. OAuth security considerations 537 All the OAuth security analysis presented in [RFC6819] applies so 538 readers SHOULD carefully follow it. 540 8. Acknowledgements 542 The initial draft of this specification was created by the OpenID AB/ 543 Connect Working Group of the OpenID Foundation. 545 This specification is the work of the OAuth Working Group, which 546 includes dozens of active and dedicated participants. In particular, 547 the following individuals contributed ideas, feedback, and wording 548 that shaped and formed the final specification: 550 Anthony Nadalin, Microsoft 551 Axel Nenker, Deutsche Telekom 552 Breno de Medeiros, Google 553 Brian Campbell, Ping Identity 554 Chuck Mortimore, Salesforce 555 Dirk Balfanz, Google 556 Eduardo Gueiros, Jive Communications 557 Hannes Tschonfenig, ARM 558 James Manger, Telstra 559 John Bradley, Ping Identity 560 Justin Richer, MIT Kerberos 561 Josh Mandel, Boston Children's Hospital 562 Lewis Adam, Motorola Solutions 563 Madjid Nakhjiri, Samsung 564 Michael B. Jones, Microsoft 565 Nat Sakimura, Nomura Research Institute 566 Naveen Agarwal, Google 567 Paul Madsen, Ping Identity 568 Phil Hunt, Oracle 569 Prateek Mishra, Oracle 570 Ryo Ito, mixi 571 Scott Tomilson, Ping Identity 572 Sergey Beryozkin 573 Takamichi Saito 574 Torsten Lodderstedt, Deutsche Telekom 575 William Denniss, Google 577 9. Revision History 579 -07 581 o removed unused discovery reference and UTF8 582 o re #32 added ASCII(STRING) to make clear that it is the byte array 583 that is being hashed 584 o re #2 Remove discovery requirement section. 585 o updated Acknowledgement 586 o re #32 remove unneeded UTF8(STRING) definition, and define STRING 587 for ASCII(STRING) 588 o re #32 remove unneeded utf8 reference from BASE64URL- 589 DECODE(STRING) def 590 o resolves #31 unused definition of concatenation 591 o re #30 Update figure text call out the endpoints 592 o re #30 Update figure to call out the endpoints 593 o small wording change to the introduction 595 -06 597 o fix date 598 o replace spop with pkce for registry and other references 599 o re #29 change name again 600 o re #27 removed US-ASCII reference 601 o re #27 updated ABNF for code_verifier 602 o resolves #24 added security consideration for salting 603 o resolves #29 Changed title 604 o updated reference to RFC4634 to RFC6234 re #27 605 o changed reference for US-ASCII to RFC20 re #27 606 o resolves #28 added Acknowledgements 607 o resolves #27 updated ABNF 608 o resolves #26 updated abstract and added Hannes figure 610 -05 612 o Added IANA registry for code_challenge_method + fixed some broken 613 internal references. 615 -04 617 o Added error response to authorization response. 619 -03 621 o Added an abstract protocol diagram and explanation 622 -02 624 o Copy edits 626 -01 628 o Specified exactly two supported transformations 629 o Moved discovery steps to security considerations. 630 o Incorporated readability comments by Eduardo Gueiros. 631 o Changed MUST in 3.1 to SHOULD. 633 -00 635 o Initial IETF version. 637 10. References 639 10.1. Normative References 641 [RFC0020] Cerf, V., "ASCII format for network interchange", RFC 20, 642 October 1969. 644 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 645 Requirement Levels", BCP 14, RFC 2119, March 1997. 647 [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data 648 Encodings", RFC 4648, October 2006. 650 [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax 651 Specifications: ABNF", STD 68, RFC 5234, January 2008. 653 [RFC6234] Eastlake, D. and T. Hansen, "US Secure Hash Algorithms 654 (SHA and SHA-based HMAC and HKDF)", RFC 6234, May 2011. 656 [RFC6749] Hardt, D., "The OAuth 2.0 Authorization Framework", RFC 657 6749, October 2012. 659 10.2. Informative References 661 [RFC6819] Lodderstedt, T., McGloin, M., and P. Hunt, "OAuth 2.0 662 Threat Model and Security Considerations", RFC 6819, 663 January 2013. 665 Appendix A. Notes on implementing base64url encoding without padding 667 This appendix describes how to implement base64url encoding and 668 decoding functions without padding based upon standard base64 669 encoding and decoding functions that do use padding. 671 To be concrete, example C# code implementing these functions is shown 672 below. Similar code could be used in other languages. 674 static string base64urlencode(byte [] arg) 675 { 676 string s = Convert.ToBase64String(arg); // Regular base64 encoder 677 s = s.Split('=')[0]; // Remove any trailing '='s 678 s = s.Replace('+', '-'); // 62nd char of encoding 679 s = s.Replace('/', '_'); // 63rd char of encoding 680 return s; 681 } 683 static byte [] base64urldecode(string arg) 684 { 685 string s = arg; 686 s = s.Replace('-', '+'); // 62nd char of encoding 687 s = s.Replace('_', '/'); // 63rd char of encoding 688 switch (s.Length % 4) // Pad with trailing '='s 689 { 690 case 0: break; // No pad chars in this case 691 case 2: s += "=="; break; // Two pad chars 692 case 3: s += "="; break; // One pad char 693 default: throw new System.Exception( 694 "Illegal base64url string!"); 695 } 696 return Convert.FromBase64String(s); // Standard base64 decoder 697 } 699 As per the example code above, the number of '=' padding characters 700 that needs to be added to the end of a base64url encoded string 701 without padding to turn it into one with padding is a deterministic 702 function of the length of the encoded string. Specifically, if the 703 length mod 4 is 0, no padding is added; if the length mod 4 is 2, two 704 '=' padding characters are added; if the length mod 4 is 3, one '=' 705 padding character is added; if the length mod 4 is 1, the input is 706 malformed. 708 An example correspondence between unencoded and encoded values 709 follows. The octet sequence below encodes into the string below, 710 which when decoded, reproduces the octet sequence. 712 3 236 255 224 193 714 A-z_4ME 716 Authors' Addresses 718 Nat Sakimura (editor) 719 Nomura Research Institute 720 1-6-5 Marunouchi, Marunouchi Kitaguchi Bldg. 721 Chiyoda-ku, Tokyo 100-0005 722 Japan 724 Phone: +81-3-5533-2111 725 Email: n-sakimura@nri.co.jp 726 URI: http://nat.sakimura.org/ 728 John Bradley 729 Ping Identity 730 Casilla 177, Sucursal Talagante 731 Talagante, RM 732 Chile 734 Phone: +44 20 8133 3718 735 Email: ve7jtb@ve7jtb.com 736 URI: http://www.thread-safe.com/ 738 Naveen Agarwal 739 Google 740 1600 Amphitheatre Pkwy 741 Mountain View, CA 94043 742 USA 744 Phone: +1 650-253-0000 745 Email: naa@google.com 746 URI: http://google.com/