idnits 2.17.1 draft-ietf-oauth-spop-12.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 (June 6, 2015) is 3247 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 270, but not defined == Missing Reference: '0-9' is mentioned on line 270, but not defined == Missing Reference: 'RFC5226' is mentioned on line 429, but not defined ** Obsolete undefined reference: RFC 5226 (Obsoleted by RFC 8126) ** Obsolete normative reference: RFC 7525 (ref. 'BCP195') (Obsoleted by RFC 9325) ** Downref: Normative reference to an Informational RFC: RFC 6234 Summary: 3 errors (**), 0 flaws (~~), 4 warnings (==), 1 comment (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 OAuth Working Group N. Sakimura, Ed. 3 Internet-Draft Nomura Research Institute 4 Intended status: Standards Track J. Bradley 5 Expires: December 8, 2015 Ping Identity 6 N. Agarwal 7 Google 8 June 6, 2015 10 Proof Key for Code Exchange by OAuth Public Clients 11 draft-ietf-oauth-spop-12 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 December 8, 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. Salting the code_challenge . . . . . . . . . . . . . . . 12 78 7.4. OAuth security considerations . . . . . . . . . . . . . . 12 79 7.5. TLS security considerations . . . . . . . . . . . . . . . 12 80 8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 12 81 9. Revision History . . . . . . . . . . . . . . . . . . . . . . 13 82 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 15 83 10.1. Normative References . . . . . . . . . . . . . . . . . . 15 84 10.2. Informative References . . . . . . . . . . . . . . . . . 16 85 Appendix A. Notes on implementing base64url encoding without 86 padding . . . . . . . . . . . . . . . . . . . . . . 16 87 Appendix B. Example for the S256 code_challenge_method . . . . . 16 88 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 18 90 1. Introduction 92 OAuth 2.0 [RFC6749] public clients are susceptible to the 93 authorization "code" interception attack. 95 The attacker thereby intercepts the authorization code returned from 96 the authorization endpoint within communication path not protected by 97 TLS, such as inter-app communication within the operating system of 98 the client. 100 Once the attacker has gained access to the authorization code it can 101 use it to obtain the access token. 103 Figure 1 shows the attack graphically. In step (1) the native app 104 running on the end device, such as a smart phone, issues an 105 authorization request via the browser/operating system, which then 106 gets forwarded to the OAuth 2.0 authorization server in step (2). 107 The authorization server returns the authorization code in step (3). 108 The malicious app is able to observe the authorization code in step 109 (4) since it is registered to the custom URI scheme used by the 110 legitimate app. This allows the attacker to reguest and obtain an 111 access token in step (5) and step (6), respectively. 113 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ 114 | End Device (e.g., Smart Phone) | 115 | | 116 | +-------------+ +----------+ | (6) Access Token +----------+ 117 | |Legitimate | | Malicious|<--------------------| | 118 | |OAuth 2.0 App| | App |-------------------->| | 119 | +-------------+ +----------+ | (5) Authorization | | 120 | | ^ ^ | Grant | | 121 | | \ | | | | 122 | | \ (4) | | | | 123 | (1) | \ Authz| | | | 124 | Authz| \ Code | | | Authz | 125 | Request| \ | | | Server | 126 | | \ | | | | 127 | | \ | | | | 128 | v \ | | | | 129 | +----------------------------+ | | | 130 | | | | (3) Authz Code | | 131 | | Operating System/ |<--------------------| | 132 | | Browser |-------------------->| | 133 | | | | (2) Authz Request | | 134 | +----------------------------+ | +----------+ 135 +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+ 137 Figure 1: Authorization Code Interception Attack. 139 A number of pre-conditions need to hold in order for this attack to 140 work: 142 1) The attacker manages to register a malicious application on the 143 client device and registers a custom URI scheme that is also used 144 by another application. 146 The operating systems must allow a custom URI schemes to be 147 registered by multiple applications. 148 2) The OAuth 2.0 authorization code grant is used. 149 3) The attacker has access to the OAuth 2.0 [RFC6749] client_id and 150 client_secret(if provisioned). All OAuth 2.0 native app client- 151 instances use the same client_id. Secrets provisioned in client 152 binary applications cannot be considered confidential. 153 4) The attacker (via the installed app) is able to observe responses 154 from the authorization endpoint. As a more sophisticated attack 155 scenario the attacker is also able to observe requests (in 156 addition to responses) to the authorization endpoint. The 157 attacker is, however, not able to act as a man-in-the-middle. 159 While this is a long list of pre-conditions the described attack has 160 been observed in the wild and has to be considered in OAuth 2.0 161 deployments. 162 While the OAuth 2.0 Threat Model Section 4.4.1 [RFC6819] describes 163 mitigation techniques they are, unfortunately, not applicable since 164 they rely on a per-client instance secret or aper client instance 165 redirect URI. 167 To mitigate this attack, this extension utilizes a dynamically 168 created cryptographically random key called 'code verifier'. A 169 unique code verifier is created for every authorization request and 170 its transformed value, called 'code challenge', is sent to the 171 authorization server to obtain the authorization code. The 172 authorization "code" obtained is then sent to the token endpoint with 173 the 'code verifier' and the server compares it with the previously 174 received request code so that it can perform the proof of possession 175 of the 'code verifier' by the client. This works as the mitigation 176 since the attacker would not know this one-time key. 178 1.1. Protocol Flow 179 +-------------------+ 180 | Authz Server | 181 +--------+ | +---------------+ | 182 | |--(A)- Authorization Request ---->| | | 183 | | + t(code_verifier), t | | Authorization | | 184 | | | | Endpoint | | 185 | |<-(B)---- Authorization Code -----| | | 186 | | | +---------------+ | 187 | Client | | | 188 | | | +---------------+ | 189 | |--(C)-- Access Token Request ---->| | | 190 | | + code_verifier | | Token | | 191 | | | | Endpoint | | 192 | |<-(D)------ Access Token ---------| | | 193 +--------+ | +---------------+ | 194 +-------------------+ 196 Figure 2: Abstract Protocol Flow 198 This specification adds additional parameters to the OAuth 2.0 199 Authorization and Access Token Requests, shown in abstract form in 200 Figure 1. 202 A. The client creates and records a secret named the "code_verifier", 203 and derives a transformed version "t(code_verifier)" (referred to 204 as the "code_challenge") which is sent in the OAuth 2.0 205 Authorization Request, along with the transformation method "t". 206 B. The Authorization Endpoint responds as usual, but records 207 "t(code_verifier)" and the transformation method. 208 C. The client then sends the code in the Access Token Request as 209 usual, but includes the "code_verifier" secret generated at (A). 210 D. The authorization server transforms "code_verifier" and compares 211 it to "t(code_verifier)" from (B). Access is denied if they are 212 not equal. 214 An attacker who intercepts the Authorization Grant at (B) is unable 215 to redeem it for an Access Token, as they are not in possession of 216 the "code_verifier" secret. 218 2. Notational Conventions 220 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 221 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 222 "OPTIONAL" in this document are to be interpreted as described in Key 223 words for use in RFCs to Indicate Requirement Levels [RFC2119]. If 224 these words are used without being spelled in uppercase then they are 225 to be interpreted with their normal natural language meanings. 227 This specification uses the Augmented Backus-Naur Form (ABNF) 228 notation of [RFC5234]. 230 STRING denotes a sequence of zero or more ASCII [RFC0020] characters. 232 OCTETS denotes a sequence of zero or more octets. 234 ASCII(STRING) denotes the octets of the ASCII [RFC0020] 235 representation of STRING where STRING is a sequence of zero or more 236 ASCII characters. 238 BASE64URL-ENCODE(OCTETS) denotes the base64url encoding of OCTETS, 239 per Section 3 producing a STRING. 241 BASE64URL-DECODE(STRING) denotes the base64url decoding of STRING, 242 per Section 3, producing a sequence of octets. 244 SHA256(OCTETS) denotes a SHA2 256bit hash [RFC6234] of OCTETS. 246 3. Terminology 248 In addition to the terms defined in OAuth 2.0 [RFC6749], this 249 specification defines the following terms: 251 code verifier A cryptographically random string that is used to 252 correlate the authorization request to the token request. 253 code challenge A challenge derived from the code verifier that is 254 sent in the authorization request, to be verified against later. 255 Base64url Encoding Base64 encoding using the URL- and filename-safe 256 character set defined in Section 5 of [RFC4648], with all trailing 257 '=' characters omitted (as permitted by Section 3.2 of [RFC4648]) 258 and without the inclusion of any line breaks, whitespace, or other 259 additional characters. (See Appendix A for notes on implementing 260 base64url encoding without padding.) 262 4. Protocol 264 4.1. Client creates a code verifier 266 The client first creates a code verifier, "code_verifier", for each 267 OAuth 2.0 [RFC6749] Authorization Request, in the following manner: 269 code_verifier = high entropy cryptographic random STRING using the 270 Unreserved Characters [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~" 271 from Sec 2.3 of [RFC3986], with a minimum length of 43 characters and 272 a maximum length of 128 characters. 274 ABNF for "code_verifier" is as follows. 276 code-verifier = 43*128unreserved 277 unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" 278 ALPHA = %x41-5A / %x61-7A 279 DIGIT = %x30-39 281 NOTE: code verifier SHOULD have enough entropy to make it impractical 282 to guess the value. It is RECOMMENDED that the output of a suitable 283 random number generator be used to create a 32-octet sequence. The 284 Octet sequence is then base64url encoded to produce a 43-octet URL 285 safe string to use as the code verifier. 287 4.2. Client creates the code challenge 289 The client then creates a code challenge, "code_challenge", derived 290 from the "code_verifier" by using one of the following 291 transformations on the "code_verifier": 293 plain "code_challenge" = "code_verifier" 294 S256 "code_challenge" = BASE64URL- 295 ENCODE(SHA256(ASCII("code_verifier"))) 297 It is RECOMMENDED to use the S256 transformation when possible. 299 ABNF for "code_challenge" is as follows. 301 code-challenge = 43*128unreserved 302 unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" 303 ALPHA = %x41-5A / %x61-7A 304 DIGIT = %x30-39 306 4.3. Client sends the code challenge with the authorization request 308 The client sends the code challenge as part of the OAuth 2.0 309 Authorization Request (Section 4.1.1 of [RFC6749].) using the 310 following additional parameters: 312 code_challenge REQUIRED. Code challenge. 314 code_challenge_method OPTIONAL, defaults to "plain". Code verifier 315 transformation method, "S256" or "plain". 317 4.4. Server returns the code 319 When the server issues the "code" in the Authorization Response, it 320 MUST associate the "code_challenge" and "code_challenge_method" 321 values with the "code" so it can be verified later. 323 Typically, the "code_challenge" and "code_challenge_method" values 324 are stored in encrypted form in the "code" itself, but could 325 alternatively be stored on the server, associated with the code. The 326 server MUST NOT include the "code_challenge" value in client requests 327 in a form that other entities can extract. 329 The exact method that the server uses to associate the 330 "code_challenge" with the issued "code" is out of scope for this 331 specification. 333 4.4.1. Error Response 335 If the server requires PKCE, and the client does not send the 336 "code_challenge" in the request, the authorization endpoint MUST 337 return the authorization error response with "error" value set to 338 "invalid_request". The "error_description" or the response of 339 "error_uri" SHOULD explain the nature of error, e.g., code challenge 340 required. 342 If the server supporting PKCE does not support the requested 343 transform, the authorization endpoint MUST return the authorization 344 error response with "error" value set to "invalid_request". The 345 "error_description" or the response of "error_uri" SHOULD explain the 346 nature of error, e.g., transform algorithm not supported. 348 If the client is capable of using "S256", it MUST use "S256", as 349 "S256" is Mandatory To Implement (MTI) on the server. Clients MAY 350 use "plain" only if they cannot support "S256" for some technical 351 reason and knows that the server supports "plain". 353 4.5. Client sends the code and the secret to the token endpoint 355 Upon receipt of the "code", the client sends the Access Token Request 356 to the token endpoint. In addition to the parameters defined in the 357 OAuth 2.0 Access Token Request (Section 4.1.3 of [RFC6749]), it sends 358 the following parameter: 360 code_verifier REQUIRED. Code verifier 362 4.6. Server verifies code_verifier before returning the tokens 364 Upon receipt of the request at the Access Token endpoint, the server 365 verifies it by calculating the code challenge from received 366 "code_verifier" and comparing it with the previously associated 367 "code_challenge", after first transforming it according to the 368 "code_challenge_method" method specified by the client. 370 If the "code_challenge_method" from Section 4.2 was "S256", the 371 received "code_verifier" is hashed by SHA-256, then base64url 372 encoded, and then compared to the "code_challenge". i.e., 374 BASE64URL-ENCODE(SHA256(ASCII("code_verifier" ))) == "code_challenge" 376 If the "code_challenge_method" from Section 4.2 was "plain", they are 377 compared directly. i.e., 379 "code_verifier" == "code_challenge". 381 If the values are equal, the Access Token endpoint MUST continue 382 processing as normal (as defined by OAuth 2.0 [RFC6749]). If the 383 values are not equal, an error response indicating "invalid_grant" as 384 described in section 5.2 of [RFC6749] MUST be returned. 386 5. Compatibility 388 Server implementations of this specification MAY accept OAuth2.0 389 Clients that do not implement this extension. If the "code_verifier" 390 is not received from the client in the Authorization Request, servers 391 supporting backwards compatibility SHOULD revert to a normal OAuth 392 2.0 [RFC6749] protocol. 394 As the OAuth 2.0 [RFC6749] server responses are unchanged by this 395 specification, client implementations of this specification do not 396 need to know if the server has implemented this specification or not, 397 and SHOULD send the additional parameters as defined in Section 3. to 398 all servers. 400 6. IANA Considerations 402 This specification makes a registration request as follows: 404 6.1. OAuth Parameters Registry 406 This specification registers the following parameters in the IANA 407 OAuth Parameters registry defined in OAuth 2.0 [RFC6749]. 409 o Parameter name: code_verifier 410 o Parameter usage location: Access Token Request 411 o Change controller: IESG 412 o Specification document(s): this document 414 o Parameter name: code_challenge 415 o Parameter usage location: Authorization Request 416 o Change controller: IESG 417 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: 462 For Standards Track RFCs, state "IESG". For others, give the name 463 of the responsible party. Other details (e.g., postal address, 464 email address, home page URI) may also be included. 465 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. 495 The client SHOULD create a code_verifier with a minimum of 256bits of 496 entropy. This can be done by having a suitable random number 497 generator create a 32-octet sequence. The Octet sequence can then be 498 base64url encoded to produce a 43-octet URL safe string to use as a 499 code_challenge that has the required entropy. 501 7.2. Protection against eavesdroppers 503 Clients MUST NOT try down grading the algorithm after trying "S256" 504 method. If the server is PKCE compliant, then "S256" method works. 505 If the server does not support PKCE, it does not generate error. 506 Only the time that the server returns that it does not support "S256" 507 is there is a MITM trying the algorithm downgrade attack. 509 "S256" method protects against eavesdroppers observing or 510 intercepting the "code_challenge". If the "plain" method is used, 511 there is a chance that it will be observed by the attacker on the 512 device. The use of "S256" protects against it. 514 If "code_challenge" is to be returned inside authorization "code" to 515 achieve a stateless server, it has to be encrypted in such a manner 516 that only the server can decrypt and extract it. 518 7.3. Salting the code_challenge 520 In order to reduce implementation complexity Salting is not used in 521 the production of the code_challenge, as the code_verifier contains 522 sufficient entropy to prevent brute force attacks. Concatenating a 523 publicly known value to a code_verifier (containing 256 bits of 524 entropy) and then hashing it with SHA256 to produce a code_challenge 525 would not increase the number of attempts necessary to brute force a 526 valid value for code_verifier. 528 While the S256 transformation is like hashing a password there are 529 important differences. Passwords tend to be relatively low entropy 530 words that can be hashed offline and the hash looked up in a 531 dictionary. By concatenating a unique though public value to each 532 password prior to hashing, the dictionary space that an attacker 533 needs to search is greatly expanded. 535 Modern graphics processors now allow attackers to calculate hashes in 536 real time faster than they could be looked up from a disk. This 537 eliminates the value of the salt in increasing the complexity of a 538 brute force attack for even low entropy passwords. 540 7.4. OAuth security considerations 542 All the OAuth security analysis presented in [RFC6819] applies so 543 readers SHOULD carefully follow it. 545 7.5. TLS security considerations 547 Curent security considerations can be found in Recommendations for 548 Secure Use of TLS and DTLS [BCP195]. This supersedes the TLS version 549 recommendations in OAuth 2.0 [RFC6749]. 551 8. Acknowledgements 553 The initial draft of this specification was created by the OpenID AB/ 554 Connect Working Group of the OpenID Foundation. 556 This specification is the work of the OAuth Working Group, which 557 includes dozens of active and dedicated participants. In particular, 558 the following individuals contributed ideas, feedback, and wording 559 that shaped and formed the final specification: 561 Anthony Nadalin, Microsoft 562 Axel Nenker, Deutsche Telekom 563 Breno de Medeiros, Google 564 Brian Campbell, Ping Identity 565 Chuck Mortimore, Salesforce 566 Dirk Balfanz, Google 567 Eduardo Gueiros, Jive Communications 568 Hannes Tschonfenig, ARM 569 James Manger, Telstra 570 John Bradley, Ping Identity 571 Justin Richer, MIT Kerberos 572 Josh Mandel, Boston Children's Hospital 573 Lewis Adam, Motorola Solutions 574 Madjid Nakhjiri, Samsung 575 Michael B. Jones, Microsoft 576 Nat Sakimura, Nomura Research Institute 577 Naveen Agarwal, Google 578 Paul Madsen, Ping Identity 579 Phil Hunt, Oracle 580 Prateek Mishra, Oracle 581 Ryo Ito, mixi 582 Scott Tomilson, Ping Identity 583 Sergey Beryozkin 584 Takamichi Saito 585 Torsten Lodderstedt, Deutsche Telekom 586 William Denniss, Google 588 9. Revision History 590 -12 592 o clarify that the client secret we are talking about in the 593 Introduction is a OAuth 2 client_secret. 594 o Update salting security consideration based on Ben's feedback 596 -11 598 o add spanx for plain in sec 4.4 RE Kathleen's comment 599 o Add security consideration on TLS and reference BCP195 601 -10 603 o re #33 specify lower limit to code_verifier in prose 604 o remove base64url decode from draft, all steps now use encode only 605 o Expanded MTI 606 o re #33 change length of 32 octet base64url encoded string back to 607 43 octets 609 -09 610 o clean up some external references so they don't point at internal 611 sections 613 -08 615 o changed BASE64URL to BASE64URL-ENCODE to be more consistent with 616 appendix A Fixed lowercase base64url in appendix B 617 o Added appendix B as an example of S256 processing 618 o Change reference for unreserved characters to RFC3986 from 619 base64URL 621 -07 623 o removed unused discovery reference and UTF8 624 o re #32 added ASCII(STRING) to make clear that it is the byte array 625 that is being hashed 626 o re #2 Remove discovery requirement section. 627 o updated Acknowledgement 628 o re #32 remove unneeded UTF8(STRING) definition, and define STRING 629 for ASCII(STRING) 630 o re #32 remove unneeded utf8 reference from BASE64URL- 631 DECODE(STRING) def 632 o resolves #31 unused definition of concatenation 633 o re #30 Update figure text call out the endpoints 634 o re #30 Update figure to call out the endpoints 635 o small wording change to the introduction 637 -06 639 o fix date 640 o replace spop with pkce for registry and other references 641 o re #29 change name again 642 o re #27 removed US-ASCII reference 643 o re #27 updated ABNF for code_verifier 644 o resolves #24 added security consideration for salting 645 o resolves #29 Changed title 646 o updated reference to RFC4634 to RFC6234 re #27 647 o changed reference for US-ASCII to RFC20 re #27 648 o resolves #28 added Acknowledgements 649 o resolves #27 updated ABNF 650 o resolves #26 updated abstract and added Hannes figure 652 -05 654 o Added IANA registry for code_challenge_method + fixed some broken 655 internal references. 657 -04 658 o Added error response to authorization response. 660 -03 662 o Added an abstract protocol diagram and explanation 664 -02 666 o Copy edits 668 -01 670 o Specified exactly two supported transformations 671 o Moved discovery steps to security considerations. 672 o Incorporated readability comments by Eduardo Gueiros. 673 o Changed MUST in 3.1 to SHOULD. 675 -00 677 o Initial IETF version. 679 10. References 681 10.1. Normative References 683 [BCP195] Sheffer, Y., Holz, R., and P. Saint-Andre, 684 "Recommendations for Secure Use of Transport Layer 685 Security (TLS) and Datagram Transport Layer Security 686 (DTLS)", BCP 195, RFC 7525, May 2015. 688 [RFC0020] Cerf, V., "ASCII format for network interchange", RFC 20, 689 October 1969. 691 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 692 Requirement Levels", BCP 14, RFC 2119, March 1997. 694 [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform 695 Resource Identifier (URI): Generic Syntax", STD 66, RFC 696 3986, January 2005. 698 [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data 699 Encodings", RFC 4648, October 2006. 701 [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax 702 Specifications: ABNF", STD 68, RFC 5234, January 2008. 704 [RFC6234] Eastlake, D. and T. Hansen, "US Secure Hash Algorithms 705 (SHA and SHA-based HMAC and HKDF)", RFC 6234, May 2011. 707 [RFC6749] Hardt, D., "The OAuth 2.0 Authorization Framework", RFC 708 6749, October 2012. 710 10.2. Informative References 712 [RFC6819] Lodderstedt, T., McGloin, M., and P. Hunt, "OAuth 2.0 713 Threat Model and Security Considerations", RFC 6819, 714 January 2013. 716 Appendix A. Notes on implementing base64url encoding without padding 718 This appendix describes how to implement a base64url encoding 719 function without padding based upon standard base64 encoding function 720 that uses padding. 722 To be concrete, example C# code implementing these functions is shown 723 below. Similar code could be used in other languages. 725 static string base64urlencode(byte [] arg) 726 { 727 string s = Convert.ToBase64String(arg); // Regular base64 encoder 728 s = s.Split('=')[0]; // Remove any trailing '='s 729 s = s.Replace('+', '-'); // 62nd char of encoding 730 s = s.Replace('/', '_'); // 63rd char of encoding 731 return s; 732 } 734 An example correspondence between unencoded and encoded values 735 follows. The octet sequence below encodes into the string below, 736 which when decoded, reproduces the octet sequence. 738 3 236 255 224 193 740 A-z_4ME 742 Appendix B. Example for the S256 code_challenge_method 744 The client uses output of a suitable random number generator to 745 create a 32-octet sequence. The octets representing the value in 746 this example (using JSON array notation) are:" 748 [116, 24, 223, 180, 151, 153, 224, 37, 79, 250, 96, 125, 216, 173, 749 187, 186, 22, 212, 37, 77, 105, 214, 191, 240, 91, 88, 5, 88, 83, 750 132, 141, 121] 752 Encoding this octet sequence as a Base64url provides the value of the 753 code_verifier: 755 dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk 757 The code_verifier is then hashed via the SHA256 hash function to 758 produce: 760 [19, 211, 30, 150, 26, 26, 216, 236, 47, 22, 177, 12, 76, 152, 46, 761 8, 118, 168, 120, 173, 109, 241, 68, 86, 110, 225, 137, 74, 203, 762 112, 249, 195] 764 Encoding this octet sequence as a base64url provides the value of the 765 code_challenge: 767 E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM 769 The authorization request includes: 771 code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM 772 &code_challange_method=S256 774 The Authorization server then records the code_challenge and 775 code_challenge_method along with the code that is granted to the 776 client. 778 in the request to the token_endpoint the client includes the code 779 received in the authorization response as well as the additional 780 paramater: 782 code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk 784 The Authorization server retrieves the information for the code 785 grant. Based on the recorded code_challange_method being S256, it 786 then hashes and base64url encodes the value of code_verifier. 787 BASE64URL-ENCODE(SHA256(ASCII("code_verifier" ))) 789 The calculated value is then compared with the value of 790 "code_challenge": 792 BASE64URL-ENCODE(SHA256(ASCII("code_verifier" ))) == code_challenge 794 If the two values are equal then the Authorization server can provide 795 the tokens as long as there are no other errors in the request. If 796 the values are not equal then the request must be rejected, and an 797 error returned. 799 Authors' Addresses 801 Nat Sakimura (editor) 802 Nomura Research Institute 803 1-6-5 Marunouchi, Marunouchi Kitaguchi Bldg. 804 Chiyoda-ku, Tokyo 100-0005 805 Japan 807 Phone: +81-3-5533-2111 808 Email: n-sakimura@nri.co.jp 809 URI: http://nat.sakimura.org/ 811 John Bradley 812 Ping Identity 813 Casilla 177, Sucursal Talagante 814 Talagante, RM 815 Chile 817 Phone: +44 20 8133 3718 818 Email: ve7jtb@ve7jtb.com 819 URI: http://www.thread-safe.com/ 821 Naveen Agarwal 822 Google 823 1600 Amphitheatre Pkwy 824 Mountain View, CA 94043 825 USA 827 Phone: +1 650-253-0000 828 Email: naa@google.com 829 URI: http://google.com/