idnits 2.17.1 draft-ietf-oauth-spop-06.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 22, 2015) is 3382 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 264, but not defined == Missing Reference: '0-9' is mentioned on line 265, but not defined == Missing Reference: 'RFC5226' is mentioned on line 423, 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: July 26, 2015 Ping Identity 6 N. Agarwal 7 Google 8 January 22, 2015 10 Proof Key for Code Exchange by OAuth Public Clients 11 draft-ietf-oauth-spop-06 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 July 26, 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 . . . . . . . . . . . . . . . . . . . . . . . . 9 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. Checking the Server support . . . . . . . . . . . . . . . 11 78 7.4. Entropy of the code_verifier . . . . . . . . . . . . . . 11 79 7.5. OAuth security considerations . . . . . . . . . . . . . . 12 80 8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 12 81 9. Revision History . . . . . . . . . . . . . . . . . . . . . . 13 82 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 14 83 10.1. Normative References . . . . . . . . . . . . . . . . . . 14 84 10.2. Informative References . . . . . . . . . . . . . . . . . 14 85 Appendix A. Notes on implementing base64url encoding without 86 padding . . . . . . . . . . . . . . . . . . . . . . 15 87 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 16 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. While Section 4.4.1 of [RFC6819] describes mitigation 160 techniques they are, unfortunately, not applicable since they rely on 161 a per-client instance secret or aper client instance redirect URI. 163 To mitigate this attack, this extension utilizes a dynamically 164 created cryptographically random key called 'code verifier'. The 165 code verifier is created for every authorization request and its 166 transformed value, called 'code challenge', is sent to the 167 authorization server to obtain the authorization code. The 168 authorization "code" obtained is then sent to the token endpoint with 169 the 'code verifier' and the server compares it with the previously 170 received request code so that it can perform the proof of possession 171 of the 'code verifier' by the client. This works as the mitigation 172 since the attacker would not know this one-time key. 174 1.1. Protocol Flow 176 +--------+ +---------------+ 177 | |--(A)-- Authorization Request --->| | 178 | | + t(code_verifier), t | Resource | 179 | | | Owner | 180 | |<-(B)--- Authorization Grant -----| | 181 | | +---------------+ 182 | Client | 183 | | +---------------+ 184 | |--(C)--- Access Token Request --->| | 185 | | + code_verifier | Authorization | 186 | | | Server | 187 | |<-(D)------ Access Token ---------| | 188 +--------+ +---------------+ 190 Figure 2: Abstract Protocol Flow 192 This specification adds additional parameters to the OAuth 2.0 193 Authorization and Access Token Requests, shown in abstract form in 194 Figure 1. 196 A. The client creates and records a secret named the "code_verifier", 197 and derives a transformed version "t(code_verifier)" (referred to 198 as the "code_challenge") which is sent in the OAuth 2.0 199 Authorization Request, along with the transformation method "t". 200 B. The resource owner responds as usual, but records 201 "t(code_verifier)" and the transformation method. 202 C. The client then sends the code to the Access Token Request as 203 usual, but includes the "code_verifier" secret generated at (A). 204 D. The authorization server transforms "code_verifier" and compares 205 it to "t(code_verifier)" from (B). Access is denied if they are 206 not equal. 208 An attacker who intercepts the Authorization Grant at (B) is unable 209 to redeem it for an Access Token, as they are not in possession of 210 the "code_verifier" secret. 212 2. Notational Conventions 214 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 215 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 216 "OPTIONAL" in this document are to be interpreted as described in Key 217 words for use in RFCs to Indicate Requirement Levels [RFC2119]. If 218 these words are used without being spelled in uppercase then they are 219 to be interpreted with their normal natural language meanings. 221 This specification uses the Augmented Backus-Naur Form (ABNF) 222 notation of [RFC5234]. 224 BASE64URL(OCTETS) denotes the base64url encoding of OCTETS, per 225 Section 3 producing a ASCII [RFC0020] STRING. 227 BASE64URL-DECODE(STRING) denotes the base64url decoding of STRING, 228 per Section 3, producing a UTF-8 sequence of octets. 230 SHA256(STRING) denotes a SHA2 256bit hash [RFC6234] of STRING. 232 UTF8(STRING) denotes the octets of the UTF-8 [RFC3629] representation 233 of STRING. 235 ASCII(STRING) denotes the octets of the ASCII [RFC0020] 236 representation of STRING. 238 The concatenation of two values A and B is denoted as A || B. 240 3. Terminology 242 In addition to the terms defined in OAuth 2.0 [RFC6749], this 243 specification defines the following terms: 245 code verifier A cryptographically random string that is used to 246 correlate the authorization request to the token request. 247 code challenge A challenge derived from the code verifier that is 248 sent in the authorization request, to be verified against later. 249 Base64url Encoding Base64 encoding using the URL- and filename-safe 250 character set defined in Section 5 of RFC 4648 [RFC4648], with all 251 trailing '=' characters omitted (as permitted by Section 3.2) and 252 without the inclusion of any line breaks, whitespace, or other 253 additional characters. (See Appendix A for notes on implementing 254 base64url encoding without padding.) 256 4. Protocol 258 4.1. Client creates a code verifier 260 The client first creates a code verifier, "code_verifier", for each 261 OAuth 2.0 [RFC6749] Authorization Request, in the following manner: 263 code_verifier = high entropy cryptographic random ASCII [RFC0020] 264 octet sequence using the url and filename safe Alphabet [A-Z] / [a-z] 265 / [0-9] / "-" / "_" from Sec 5 of RFC 4648 [RFC4648], with length 266 less than 128 characters. 268 ABNF for "code_verifier" is as follows. 270 code-verifier = 42*128unreserved 271 unreserved = ALPHA / DIGIT / "-" / "_" 272 ALPHA = %x41-5A / %x61-7A 273 DIGIT = %x30-39 275 NOTE: code verifier SHOULD have enough entropy to make it impractical 276 to guess the value. It is RECOMMENDED that the output of a suitable 277 random number generator be used to create a 32-octet sequence. The 278 Octet sequence is then BASE64URL encoded to produce a 42-octet URL 279 safe string to use as the code verifier. 281 4.2. Client creates the code challenge 283 The client then creates a code challenge, "code_challenge", derived 284 from the "code_verifier" by using one of the following 285 transformations on the "code_verifier": 287 plain "code_challenge" = "code_verifier" 288 S256 "code_challenge" = BASE64URL(SHA256("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("code_verifier" ) == BASE64URL-DECODE("code_challenge"). 369 If the "code_challenge_method" from Section 4.2 was "plain", they are 370 compared directly. i.e., 372 "code_challenge" == "code_verifier". 374 If the values are equal, the Access Token endpoint MUST continue 375 processing as normal (as defined by OAuth 2.0 [RFC6749]). If the 376 values are not equal, an error response indicating "invalid_grant" as 377 described in section 5.2 of OAuth 2.0 [RFC6749] MUST be returned. 379 5. Compatibility 381 Server implementations of this specification MAY accept OAuth2.0 382 Clients that do not implement this extension. If the "code_verifier" 383 is not received from the client in the Authorization Request, servers 384 supporting backwards compatibility SHOULD revert to a normal OAuth 385 2.0 [RFC6749] protocol. 387 As the OAuth 2.0 [RFC6749] server responses are unchanged by this 388 specification, client implementations of this specification do not 389 need to know if the server has implemented this specification or not, 390 and SHOULD send the additional parameters as defined in Section 3. to 391 all servers. 393 6. IANA Considerations 395 This specification makes a registration request as follows: 397 6.1. OAuth Parameters Registry 399 This specification registers the following parameters in the IANA 400 OAuth Parameters registry defined in OAuth 2.0 [RFC6749]. 402 o Parameter name: code_verifier 403 o Parameter usage location: Access Token Request 404 o Change controller: IESG 405 o Specification document(s): this document 407 o Parameter name: code_challenge 408 o Parameter usage location: Authorization Request 409 o Change controller: IESG 410 o Specification document(s): this document 412 o Parameter name: code_challenge_method 413 o Parameter usage location: Authorization Request 414 o Change controller: IESG 415 o Specification document(s): this document 417 6.2. PKCE Code Challenge Method Registry 419 This specification establishes the PKCE Code Challenge Method 420 registry. 422 Additional code_challenge_method types for use with the authorization 423 endpoint are registered with a Specification Required ([RFC5226]) 424 after a two-week review period on the oauth-ext-review@ietf.org 425 mailing list, on the advice of one or more Designated Experts. 426 However, to allow for the allocation of values prior to publication, 427 the Designated Expert(s) may approve registration once they are 428 satisfied that such a specification will be published. 430 Registration requests must be sent to the oauth-ext-review@ietf.org 431 mailing list for review and comment, with an appropriate subject 432 (e.g., "Request for PKCE code_challenge_method: example"). 434 Within the review period, the Designated Expert(s) will either 435 approve or deny the registration request, communicating this decision 436 to the review list and IANA. Denials should include an explanation 437 and, if applicable, suggestions as to how to make the request 438 successful. 440 IANA must only accept registry updates from the Designated Expert(s) 441 and should direct all requests for registration to the review mailing 442 list. 444 6.2.1. Registration Template 446 Code Challenge Method Parameter Name: 447 The name requested (e.g., "example"). Because a core goal of this 448 specification is for the resulting representations to be compact, 449 it is RECOMMENDED that the name be short -- not to exceed 8 450 characters without a compelling reason to do so. This name is 451 case-sensitive. Names may not match other registered names in a 452 case-insensitive manner unless the Designated Expert(s) state that 453 there is a compelling reason to allow an exception in this 454 particular case. 455 Change Controller: 456 For Standards Track RFCs, state "IESG". For others, give the name 457 of the responsible party. Other details (e.g., postal address, 458 email address, home page URI) may also be included. 459 Specification Document(s): 460 Reference to the document(s) that specify the parameter, 461 preferably including URI(s) that can be used to retrieve copies of 462 the document(s). An indication of the relevant sections may also 463 be included but is not required. 465 6.2.2. Initial Registry Contents 467 This specification registers the Code Challenge Method Parameter 468 names defined in Section 4.2 in this registry. 470 o Code Challenge Method Parameter Name: "plain" 471 o Change Controller: IESG 472 o Specification Document(s): Section 4.2 of [[ this document ]] 474 o Code Challenge Method Parameter Name: "S256" 475 o Change Controller: IESG 476 o Specification Document(s): Section 4.2 of [[ this document ]] 478 7. Security Considerations 480 7.1. Entropy of the code verifier 482 The security model relies on the fact that the code verifier is not 483 learned or guessed by the attacker. It is vitally important to 484 adhere to this principle. As such, the code verifier has to be 485 created in such a manner that it is cryptographically random and has 486 high entropy that it is not practical for the attacker to guess. It 487 is RECOMMENDED that the output of a suitable random number generator 488 be used to create a 32-octet sequence. 490 7.2. Protection against eavesdroppers 492 Clients MUST NOT try down grading the algorithm after trying "S256" 493 method. If the server is PKCE compliant, then "S256" method works. 494 If the server does not support PKCE, it does not generate error. 495 Only the time that the server returns that it does not support "S256" 496 is there is a MITM trying the algorithm downgrade attack. 498 "S256" method protects against eavesdroppers observing or 499 intercepting the "code_challenge". If the "plain" method is used, 500 there is a chance that it will be observed by the attacker on the 501 device. The use of "S256" protects against it. 503 If "code_challenge" is to be returned inside authorization "code" to 504 achieve a stateless server, it has to be encrypted in such a manner 505 that only the server can decrypt and extract it. 507 7.3. Checking the Server support 509 Before starting the authorization process, the client SHOULD check if 510 the server supports this specification. Confirmation of the server 511 support may be obtained out-of-band or through some other mechanisms 512 such as the discovery document in OpenID Connect Discovery 513 [OpenID.Discovery]. The exact mechanism on how the client obtains 514 this information, or the action it takes as a result is out of scope 515 of this specification. 517 7.4. Entropy of the code_verifier 519 The client SHOULD create a code_verifier with a minimum of 256bits of 520 entropy. This can be done by having a suitable random number 521 generator create a 32-octet sequence. The Octet sequence can then be 522 Base64url encoded to produce a 42-octet URL safe string to use as a 523 code_challenge that has the required entropy. 525 Salting is not used in the production of the code_verifier, as the 526 code_chalange contains sufficient entropy to prevent brute force 527 attacks. Concatenating a publicly known value to a code_challenge 528 (with 256 bits of entropy) and then hashing it with SHA256 would 529 actually reduce the entropy in the resulting code_verifier making it 530 easier for an attacker to brute force. 532 While the S256 transformation is like hashing a password there are 533 important differences. Passwords tend to be relatively low entropy 534 words that can be hashed offline and the hash looked up in a 535 dictionary. By concatenating a unique though public value to each 536 password prior to hashing, the dictionary space that an attacker 537 needs to search is greatly expanded. 539 Modern graphics processors now allow attackers to calculate hashes in 540 real time faster than they could be looked up from a disk. This 541 eliminates the value of the salt in increasing the complexity of a 542 brute force attack for even low entropy passwords. 544 7.5. OAuth security considerations 546 All the OAuth security analysis presented in [RFC6819] applies so 547 readers SHOULD carefully follow it. 549 8. Acknowledgements 551 The initial draft of this specification was created by the OpenID AB/ 552 Connect Working Group of the OpenID Foundation, most notably by the 553 following people: 555 o Anthony Nadalin, Microsoft 556 o Axel Nenker, Deutsche Telekom 557 o Breno de Medeiros, Google 558 o Brian Campbell, Ping Identity 559 o Chuck Mortimore, Salesforce 560 o Dirk Balfanz, Google 561 o Eduardo Gueiros, Jive Communications 562 o Hannes Tschonfenig, ARM 563 o James Manger, Telstra 564 o John Bradley, Ping Identity 565 o Justin Richer, MIT Kerberos 566 o Josh Mandel, Boston Children's Hospital 567 o Lewis Adam, Motorola Solutions 568 o Madjid Nakhjiri, Samsung 569 o Michael B. Jones, Microsoft 570 o Nat Sakimura, Nomura Research Institute 571 o Naveen Agarwal, Google 572 o Paul Madsen, Ping Identity 573 o Phil Hunt, Oracle 574 o Prateek Mishra, Oracle 575 o Ryo Ito, mixi 576 o Scott Tomlinson 577 o Sergey Beryozkin 578 o Takamichi Saito 579 o Torsten Lodderstedt, Deutsche Telekom 580 o William Denniss, Google 582 9. Revision History 584 -06 586 o fix date 587 o replace spop with pkce for registry and other references 588 o re #29 change name again 589 o re #27 removed US-ASCII reference 590 o re #27 updated ABNF for code_verifier 591 o resolves #24 added security consideration for salting 592 o resolves #29 Changed title 593 o updated reference to RFC4634 to RFC6234 re #27 594 o changed reference for US-ASCII to RFC20 re #27 595 o resolves #28 added Acknowledgements 596 o resolves #27 updated ABNF 597 o resolves #26 updated abstract and added Hannes figure 599 -05 601 o Added IANA registry for code_challenge_method + fixed some broken 602 internal references. 604 -04 606 o Added error response to authorization response. 608 -03 610 o Added an abstract protocol diagram and explanation 612 -02 614 o Copy edits 616 -01 617 o Specified exactly two supported transformations 618 o Moved discovery steps to security considerations. 619 o Incorporated readability comments by Eduardo Gueiros. 620 o Changed MUST in 3.1 to SHOULD. 622 -00 624 o Initial IETF version. 626 10. References 628 10.1. Normative References 630 [RFC0020] Cerf, V., "ASCII format for network interchange", RFC 20, 631 October 1969. 633 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 634 Requirement Levels", BCP 14, RFC 2119, March 1997. 636 [RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 637 10646", STD 63, RFC 3629, November 2003. 639 [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data 640 Encodings", RFC 4648, October 2006. 642 [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax 643 Specifications: ABNF", STD 68, RFC 5234, January 2008. 645 [RFC6234] Eastlake, D. and T. Hansen, "US Secure Hash Algorithms 646 (SHA and SHA-based HMAC and HKDF)", RFC 6234, May 2011. 648 [RFC6749] Hardt, D., "The OAuth 2.0 Authorization Framework", RFC 649 6749, October 2012. 651 10.2. Informative References 653 [OpenID.Discovery] 654 Sakimura, N., Bradley, J., Jones, M., and E. Jay, "OpenID 655 Connect Discovery 1.0", February 2014. 657 [RFC6819] Lodderstedt, T., McGloin, M., and P. Hunt, "OAuth 2.0 658 Threat Model and Security Considerations", RFC 6819, 659 January 2013. 661 Appendix A. Notes on implementing base64url encoding without padding 663 This appendix describes how to implement base64url encoding and 664 decoding functions without padding based upon standard base64 665 encoding and decoding functions that do use padding. 667 To be concrete, example C# code implementing these functions is shown 668 below. Similar code could be used in other languages. 670 static string base64urlencode(byte [] arg) 671 { 672 string s = Convert.ToBase64String(arg); // Regular base64 encoder 673 s = s.Split('=')[0]; // Remove any trailing '='s 674 s = s.Replace('+', '-'); // 62nd char of encoding 675 s = s.Replace('/', '_'); // 63rd char of encoding 676 return s; 677 } 679 static byte [] base64urldecode(string arg) 680 { 681 string s = arg; 682 s = s.Replace('-', '+'); // 62nd char of encoding 683 s = s.Replace('_', '/'); // 63rd char of encoding 684 switch (s.Length % 4) // Pad with trailing '='s 685 { 686 case 0: break; // No pad chars in this case 687 case 2: s += "=="; break; // Two pad chars 688 case 3: s += "="; break; // One pad char 689 default: throw new System.Exception( 690 "Illegal base64url string!"); 691 } 692 return Convert.FromBase64String(s); // Standard base64 decoder 693 } 695 As per the example code above, the number of '=' padding characters 696 that needs to be added to the end of a base64url encoded string 697 without padding to turn it into one with padding is a deterministic 698 function of the length of the encoded string. Specifically, if the 699 length mod 4 is 0, no padding is added; if the length mod 4 is 2, two 700 '=' padding characters are added; if the length mod 4 is 3, one '=' 701 padding character is added; if the length mod 4 is 1, the input is 702 malformed. 704 An example correspondence between unencoded and encoded values 705 follows. The octet sequence below encodes into the string below, 706 which when decoded, reproduces the octet sequence. 708 3 236 255 224 193 709 A-z_4ME 711 Authors' Addresses 713 Nat Sakimura (editor) 714 Nomura Research Institute 715 1-6-5 Marunouchi, Marunouchi Kitaguchi Bldg. 716 Chiyoda-ku, Tokyo 100-0005 717 Japan 719 Phone: +81-3-5533-2111 720 Email: n-sakimura@nri.co.jp 721 URI: http://nat.sakimura.org/ 723 John Bradley 724 Ping Identity 725 Casilla 177, Sucursal Talagante 726 Talagante, RM 727 Chile 729 Phone: +44 20 8133 3718 730 Email: ve7jtb@ve7jtb.com 731 URI: http://www.thread-safe.com/ 733 Naveen Agarwal 734 Google 735 1600 Amphitheatre Pkwy 736 Mountain View, CA 94043 737 USA 739 Phone: +1 650-253-0000 740 Email: naa@google.com 741 URI: http://google.com/