idnits 2.17.1 draft-ietf-oauth-spop-13.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 (July 5, 2015) is 3210 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 275, but not defined == Missing Reference: '0-9' is mentioned on line 275, but not defined == Missing Reference: 'RFC5226' is mentioned on line 443, 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: January 6, 2016 Ping Identity 6 N. Agarwal 7 Google 8 July 5, 2015 10 Proof Key for Code Exchange by OAuth Public Clients 11 draft-ietf-oauth-spop-13 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 January 6, 2016. 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 . . . . . . . . . . . . . . . . . 8 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 9 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 . . . . . . . . . . . . 12 77 7.3. Salting the code_challenge . . . . . . . . . . . . . . . 12 78 7.4. OAuth security considerations . . . . . . . . . . . . . . 13 79 7.5. TLS security considerations . . . . . . . . . . . . . . . 13 80 8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 13 81 9. Revision History . . . . . . . . . . . . . . . . . . . . . . 14 82 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 16 83 10.1. Normative References . . . . . . . . . . . . . . . . . . 16 84 10.2. Informative References . . . . . . . . . . . . . . . . . 16 85 Appendix A. Notes on implementing base64url encoding without 86 padding . . . . . . . . . . . . . . . . . . . . . . 17 87 Appendix B. Example for the S256 code_challenge_method . . . . . 17 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 4a) The attacker (via the installed app) is able to observe only the 154 responses from the authorization endpoint. The plain 155 code_challenge_method mitigates only this attack. 156 4b) A more sophisticated attack scenario allows the attacker to 157 observe requests (in addition to responses) to the authorization 158 endpoint. The attacker is, however, not able to act as a man-in- 159 the-middle. This has been caused by leaking http log information 160 in the OS. To mitigate this the S256 code_challenge_method or 161 cryptographically secure code_challenge_method extension must be 162 used. 164 While this is a long list of pre-conditions the described attack has 165 been observed in the wild and has to be considered in OAuth 2.0 166 deployments. 167 While the OAuth 2.0 Threat Model Section 4.4.1 [RFC6819] describes 168 mitigation techniques they are, unfortunately, not applicable since 169 they rely on a per-client instance secret or aper client instance 170 redirect URI. 172 To mitigate this attack, this extension utilizes a dynamically 173 created cryptographically random key called 'code verifier'. A 174 unique code verifier is created for every authorization request and 175 its transformed value, called 'code challenge', is sent to the 176 authorization server to obtain the authorization code. The 177 authorization "code" obtained is then sent to the token endpoint with 178 the 'code verifier' and the server compares it with the previously 179 received request code so that it can perform the proof of possession 180 of the 'code verifier' by the client. This works as the mitigation 181 since the attacker would not know this one-time key. 183 1.1. Protocol Flow 184 +-------------------+ 185 | Authz Server | 186 +--------+ | +---------------+ | 187 | |--(A)- Authorization Request ---->| | | 188 | | + t(code_verifier), t | | Authorization | | 189 | | | | Endpoint | | 190 | |<-(B)---- Authorization Code -----| | | 191 | | | +---------------+ | 192 | Client | | | 193 | | | +---------------+ | 194 | |--(C)-- Access Token Request ---->| | | 195 | | + code_verifier | | Token | | 196 | | | | Endpoint | | 197 | |<-(D)------ Access Token ---------| | | 198 +--------+ | +---------------+ | 199 +-------------------+ 201 Figure 2: Abstract Protocol Flow 203 This specification adds additional parameters to the OAuth 2.0 204 Authorization and Access Token Requests, shown in abstract form in 205 Figure 1. 207 A. The client creates and records a secret named the "code_verifier", 208 and derives a transformed version "t(code_verifier)" (referred to 209 as the "code_challenge") which is sent in the OAuth 2.0 210 Authorization Request, along with the transformation method "t". 211 B. The Authorization Endpoint responds as usual, but records 212 "t(code_verifier)" and the transformation method. 213 C. The client then sends the code in the Access Token Request as 214 usual, but includes the "code_verifier" secret generated at (A). 215 D. The authorization server transforms "code_verifier" and compares 216 it to "t(code_verifier)" from (B). Access is denied if they are 217 not equal. 219 An attacker who intercepts the Authorization Grant at (B) is unable 220 to redeem it for an Access Token, as they are not in possession of 221 the "code_verifier" secret. 223 2. Notational Conventions 225 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 226 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 227 "OPTIONAL" in this document are to be interpreted as described in Key 228 words for use in RFCs to Indicate Requirement Levels [RFC2119]. If 229 these words are used without being spelled in uppercase then they are 230 to be interpreted with their normal natural language meanings. 232 This specification uses the Augmented Backus-Naur Form (ABNF) 233 notation of [RFC5234]. 235 STRING denotes a sequence of zero or more ASCII [RFC0020] characters. 237 OCTETS denotes a sequence of zero or more octets. 239 ASCII(STRING) denotes the octets of the ASCII [RFC0020] 240 representation of STRING where STRING is a sequence of zero or more 241 ASCII characters. 243 BASE64URL-ENCODE(OCTETS) denotes the base64url encoding of OCTETS, 244 per Section 3 producing a STRING. 246 BASE64URL-DECODE(STRING) denotes the base64url decoding of STRING, 247 per Section 3, producing a sequence of octets. 249 SHA256(OCTETS) denotes a SHA2 256bit hash [RFC6234] of OCTETS. 251 3. Terminology 253 In addition to the terms defined in OAuth 2.0 [RFC6749], this 254 specification defines the following terms: 256 code verifier A cryptographically random string that is used to 257 correlate the authorization request to the token request. 258 code challenge A challenge derived from the code verifier that is 259 sent in the authorization request, to be verified against later. 260 Base64url Encoding Base64 encoding using the URL- and filename-safe 261 character set defined in Section 5 of [RFC4648], with all trailing 262 '=' characters omitted (as permitted by Section 3.2 of [RFC4648]) 263 and without the inclusion of any line breaks, whitespace, or other 264 additional characters. (See Appendix A for notes on implementing 265 base64url encoding without padding.) 267 4. Protocol 269 4.1. Client creates a code verifier 271 The client first creates a code verifier, "code_verifier", for each 272 OAuth 2.0 [RFC6749] Authorization Request, in the following manner: 274 code_verifier = high entropy cryptographic random STRING using the 275 Unreserved Characters [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~" 276 from Sec 2.3 of [RFC3986], with a minimum length of 43 characters and 277 a maximum length of 128 characters. 279 ABNF for "code_verifier" is as follows. 281 code-verifier = 43*128unreserved 282 unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" 283 ALPHA = %x41-5A / %x61-7A 284 DIGIT = %x30-39 286 NOTE: code verifier SHOULD have enough entropy to make it impractical 287 to guess the value. It is RECOMMENDED that the output of a suitable 288 random number generator be used to create a 32-octet sequence. The 289 Octet sequence is then base64url encoded to produce a 43-octet URL 290 safe string to use as the code verifier. 292 4.2. Client creates the code challenge 294 The client then creates a code challenge, "code_challenge", derived 295 from the "code_verifier" by using one of the following 296 transformations on the "code_verifier": 298 plain "code_challenge" = "code_verifier" 299 S256 "code_challenge" = BASE64URL- 300 ENCODE(SHA256(ASCII("code_verifier"))) 302 Clients SHOULD use the S256 transformation. The plain transformation 303 is for compatibility with existing deployments and for constrained 304 environments that can't use the S256 transformation. 306 ABNF for "code_challenge" is as follows. 308 code-challenge = 43*128unreserved 309 unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" 310 ALPHA = %x41-5A / %x61-7A 311 DIGIT = %x30-39 313 4.3. Client sends the code challenge with the authorization request 315 The client sends the code challenge as part of the OAuth 2.0 316 Authorization Request (Section 4.1.1 of [RFC6749].) using the 317 following additional parameters: 319 code_challenge REQUIRED. Code challenge. 321 code_challenge_method OPTIONAL, defaults to "plain" if not present 322 in the request. Code verifier transformation method, "S256" or 323 "plain". 325 4.4. Server returns the code 327 When the server issues the "code" in the Authorization Response, it 328 MUST associate the "code_challenge" and "code_challenge_method" 329 values with the "code" so it can be verified later. 331 Typically, the "code_challenge" and "code_challenge_method" values 332 are stored in encrypted form in the "code" itself, but could 333 alternatively be stored on the server, associated with the code. The 334 server MUST NOT include the "code_challenge" value in client requests 335 in a form that other entities can extract. 337 The exact method that the server uses to associate the 338 "code_challenge" with the issued "code" is out of scope for this 339 specification. 341 4.4.1. Error Response 343 If the server requires PKCE, and the client does not send the 344 "code_challenge" in the request, the authorization endpoint MUST 345 return the authorization error response with "error" value set to 346 "invalid_request". The "error_description" or the response of 347 "error_uri" SHOULD explain the nature of error, e.g., code challenge 348 required. 350 If the server supporting PKCE does not support the requested 351 transform, the authorization endpoint MUST return the authorization 352 error response with "error" value set to "invalid_request". The 353 "error_description" or the response of "error_uri" SHOULD explain the 354 nature of error, e.g., transform algorithm not supported. 356 If the client is capable of using "S256", it MUST use "S256", as 357 "S256" is Mandatory To Implement (MTI) on the server. Clients MAY 358 use "plain" only if they cannot support "S256" for some technical 359 reason and knows that the server supports "plain". 361 4.5. Client sends the code and the secret to the token endpoint 363 Upon receipt of the "code", the client sends the Access Token Request 364 to the token endpoint. In addition to the parameters defined in the 365 OAuth 2.0 Access Token Request (Section 4.1.3 of [RFC6749]), it sends 366 the following parameter: 368 code_verifier REQUIRED. Code verifier 370 The code_challenge_method is bound to the code when the code is 371 issued. That is the method that the token endpoint MUST use to 372 verify the code_verifier. 374 4.6. Server verifies code_verifier before returning the tokens 376 Upon receipt of the request at the Access Token endpoint, the server 377 verifies it by calculating the code challenge from received 378 "code_verifier" and comparing it with the previously associated 379 "code_challenge", after first transforming it according to the 380 "code_challenge_method" method specified by the client. 382 If the "code_challenge_method" from Section 4.2 was "S256", the 383 received "code_verifier" is hashed by SHA-256, then base64url 384 encoded, and then compared to the "code_challenge". i.e., 386 BASE64URL-ENCODE(SHA256(ASCII("code_verifier" ))) == "code_challenge" 388 If the "code_challenge_method" from Section 4.2 was "plain", they are 389 compared directly. i.e., 391 "code_verifier" == "code_challenge". 393 If the values are equal, the Access Token endpoint MUST continue 394 processing as normal (as defined by OAuth 2.0 [RFC6749]). If the 395 values are not equal, an error response indicating "invalid_grant" as 396 described in section 5.2 of [RFC6749] MUST be returned. 398 5. Compatibility 400 Server implementations of this specification MAY accept OAuth2.0 401 Clients that do not implement this extension. If the "code_verifier" 402 is not received from the client in the Authorization Request, servers 403 supporting backwards compatibility SHOULD revert to a normal OAuth 404 2.0 [RFC6749] protocol. 406 As the OAuth 2.0 [RFC6749] server responses are unchanged by this 407 specification, client implementations of this specification do not 408 need to know if the server has implemented this specification or not, 409 and SHOULD send the additional parameters as defined in Section 3. to 410 all servers. 412 6. IANA Considerations 414 This specification makes a registration request as follows: 416 6.1. OAuth Parameters Registry 418 This specification registers the following parameters in the IANA 419 OAuth Parameters registry defined in OAuth 2.0 [RFC6749]. 421 o Parameter name: code_verifier 422 o Parameter usage location: token request 423 o Change controller: IESG 424 o Specification document(s): this document 426 o Parameter name: code_challenge 427 o Parameter usage location: authorization request 428 o Change controller: IESG 429 o Specification document(s): this document 431 o Parameter name: code_challenge_method 432 o Parameter usage location: authorization request 433 o Change controller: IESG 434 o Specification document(s): this document 436 6.2. PKCE Code Challenge Method Registry 438 This specification establishes the PKCE Code Challenge Method 439 registry. The new registry should be a sub-registry of OAuth 440 Parameters registry. 442 Additional code_challenge_method types for use with the authorization 443 endpoint are registered with a Specification Required ([RFC5226]) 444 after a two-week review period on the oauth-ext-review@ietf.org 445 mailing list, on the advice of one or more Designated Experts. 446 However, to allow for the allocation of values prior to publication, 447 the Designated Expert(s) may approve registration once they are 448 satisfied that such a specification will be published. 450 Registration requests must be sent to the oauth-ext-review@ietf.org 451 mailing list for review and comment, with an appropriate subject 452 (e.g., "Request for PKCE code_challenge_method: example"). 454 Within the review period, the Designated Expert(s) will either 455 approve or deny the registration request, communicating this decision 456 to the review list and IANA. Denials should include an explanation 457 and, if applicable, suggestions as to how to make the request 458 successful. 460 IANA must only accept registry updates from the Designated Expert(s) 461 and should direct all requests for registration to the review mailing 462 list. 464 6.2.1. Registration Template 466 Code Challenge Method Parameter Name: 467 The name requested (e.g., "example"). Because a core goal of this 468 specification is for the resulting representations to be compact, 469 it is RECOMMENDED that the name be short -- not to exceed 8 470 characters without a compelling reason to do so. This name is 471 case-sensitive. Names may not match other registered names in a 472 case-insensitive manner unless the Designated Expert(s) state that 473 there is a compelling reason to allow an exception in this 474 particular case. 475 Change Controller: 476 For Standards Track RFCs, state "IESG". For others, give the name 477 of the responsible party. Other details (e.g., postal address, 478 email address, home page URI) may also be included. 479 Specification Document(s): 480 Reference to the document(s) that specify the parameter, 481 preferably including URI(s) that can be used to retrieve copies of 482 the document(s). An indication of the relevant sections may also 483 be included but is not required. 485 6.2.2. Initial Registry Contents 487 This specification registers the Code Challenge Method Parameter 488 names defined in Section 4.2 in this registry. 490 o Code Challenge Method Parameter Name: "plain" 491 o Change Controller: IESG 492 o Specification Document(s): Section 4.2 of [[ this document ]] 494 o Code Challenge Method Parameter Name: "S256" 495 o Change Controller: IESG 496 o Specification Document(s): Section 4.2 of [[ this document ]] 498 7. Security Considerations 500 7.1. Entropy of the code_verifier 502 The security model relies on the fact that the code verifier is not 503 learned or guessed by the attacker. It is vitally important to 504 adhere to this principle. As such, the code verifier has to be 505 created in such a manner that it is cryptographically random and has 506 high entropy that it is not practical for the attacker to guess. 508 The client SHOULD create a code_verifier with a minimum of 256bits of 509 entropy. This can be done by having a suitable random number 510 generator create a 32-octet sequence. The Octet sequence can then be 511 base64url encoded to produce a 43-octet URL safe string to use as a 512 code_challenge that has the required entropy. 514 7.2. Protection against eavesdroppers 516 Clients MUST NOT try down grading the algorithm after trying "S256" 517 method. If the server is PKCE compliant, then "S256" method will 518 work. If the server does not support PKCE, it will not generate an 519 error. The only time that a server will return that it does not 520 support "S256" is if there is a MITM trying the algorithm downgrade 521 attack. 523 "S256" method protects against eavesdroppers observing or 524 intercepting the "code_challenge". If the "plain" method is used, 525 there is a chance that "code_challenge" will be observed by the 526 attacker on the device, or in the http request. The use of "S256" 527 protects against disclosure of "code_verifier" value to an attacker. 529 The "S256" code_challenge_method or other cryptographically secure 530 code_challenge_method extension SHOULD be used. The plain 531 code_challenge_method relies on the operating system and transport 532 security not to disclose the request to an attacker. 534 If the code_challenge_method is plain, and the "code_challenge" is to 535 be returned inside authorization "code" to achieve a stateless 536 server, it MUST be encrypted in such a manner that only the server 537 can decrypt and extract it. 539 7.3. Salting the code_challenge 541 In order to reduce implementation complexity Salting is not used in 542 the production of the code_challenge, as the code_verifier contains 543 sufficient entropy to prevent brute force attacks. Concatenating a 544 publicly known value to a code_verifier (containing 256 bits of 545 entropy) and then hashing it with SHA256 to produce a code_challenge 546 would not increase the number of attempts necessary to brute force a 547 valid value for code_verifier. 549 While the S256 transformation is like hashing a password there are 550 important differences. Passwords tend to be relatively low entropy 551 words that can be hashed offline and the hash looked up in a 552 dictionary. By concatenating a unique though public value to each 553 password prior to hashing, the dictionary space that an attacker 554 needs to search is greatly expanded. 556 Modern graphics processors now allow attackers to calculate hashes in 557 real time faster than they could be looked up from a disk. This 558 eliminates the value of the salt in increasing the complexity of a 559 brute force attack for even low entropy passwords. 561 7.4. OAuth security considerations 563 All the OAuth security analysis presented in [RFC6819] applies so 564 readers SHOULD carefully follow it. 566 7.5. TLS security considerations 568 Curent security considerations can be found in Recommendations for 569 Secure Use of TLS and DTLS [BCP195]. This supersedes the TLS version 570 recommendations in OAuth 2.0 [RFC6749]. 572 8. Acknowledgements 574 The initial draft of this specification was created by the OpenID AB/ 575 Connect Working Group of the OpenID Foundation. 577 This specification is the work of the OAuth Working Group, which 578 includes dozens of active and dedicated participants. In particular, 579 the following individuals contributed ideas, feedback, and wording 580 that shaped and formed the final specification: 582 Anthony Nadalin, Microsoft 583 Axel Nenker, Deutsche Telekom 584 Breno de Medeiros, Google 585 Brian Campbell, Ping Identity 586 Chuck Mortimore, Salesforce 587 Dirk Balfanz, Google 588 Eduardo Gueiros, Jive Communications 589 Hannes Tschonfenig, ARM 590 James Manger, Telstra 591 John Bradley, Ping Identity 592 Justin Richer, MIT Kerberos 593 Josh Mandel, Boston Children's Hospital 594 Lewis Adam, Motorola Solutions 595 Madjid Nakhjiri, Samsung 596 Michael B. Jones, Microsoft 597 Nat Sakimura, Nomura Research Institute 598 Naveen Agarwal, Google 599 Paul Madsen, Ping Identity 600 Phil Hunt, Oracle 601 Prateek Mishra, Oracle 602 Ryo Ito, mixi 603 Scott Tomilson, Ping Identity 604 Sergey Beryozkin 605 Takamichi Saito 606 Torsten Lodderstedt, Deutsche Telekom 607 William Denniss, Google 609 9. Revision History 611 -13 613 o Fix the parameter usage locations for the OAuth Parameters 614 Registry per Hannes response. 615 o Clarify for IANA that the new registry is a sub-registry of OAuth 616 Parameters registry 617 o aded text on why the code_challenge_method is not sent to the 618 token endpoint. 620 -12 622 o clarify that the client secret we are talking about in the 623 Introduction is a OAuth 2 client_secret. 624 o Update salting security consideration based on Ben's feedback 626 -11 628 o add spanx for plain in sec 4.4 RE Kathleen's comment 629 o Add security consideration on TLS and reference BCP195 630 o Update to make clearer that plain can only be used for backwards 631 compatibility and constrained environments 633 -10 635 o re #33 specify lower limit to code_verifier in prose 636 o remove base64url decode from draft, all steps now use encode only 637 o Expanded MTI 638 o re #33 change length of 32 octet base64url encoded string back to 639 43 octets 641 -09 643 o clean up some external references so they don't point at internal 644 sections 646 -08 648 o changed BASE64URL to BASE64URL-ENCODE to be more consistent with 649 appendix A Fixed lowercase base64url in appendix B 650 o Added appendix B as an example of S256 processing 651 o Change reference for unreserved characters to RFC3986 from 652 base64URL 654 -07 656 o removed unused discovery reference and UTF8 657 o re #32 added ASCII(STRING) to make clear that it is the byte array 658 that is being hashed 659 o re #2 Remove discovery requirement section. 660 o updated Acknowledgement 661 o re #32 remove unneeded UTF8(STRING) definition, and define STRING 662 for ASCII(STRING) 663 o re #32 remove unneeded utf8 reference from BASE64URL- 664 DECODE(STRING) def 665 o resolves #31 unused definition of concatenation 666 o re #30 Update figure text call out the endpoints 667 o re #30 Update figure to call out the endpoints 668 o small wording change to the introduction 670 -06 672 o fix date 673 o replace spop with pkce for registry and other references 674 o re #29 change name again 675 o re #27 removed US-ASCII reference 676 o re #27 updated ABNF for code_verifier 677 o resolves #24 added security consideration for salting 678 o resolves #29 Changed title 679 o updated reference to RFC4634 to RFC6234 re #27 680 o changed reference for US-ASCII to RFC20 re #27 681 o resolves #28 added Acknowledgements 682 o resolves #27 updated ABNF 683 o resolves #26 updated abstract and added Hannes figure 685 -05 687 o Added IANA registry for code_challenge_method + fixed some broken 688 internal references. 690 -04 692 o Added error response to authorization response. 694 -03 696 o Added an abstract protocol diagram and explanation 698 -02 700 o Copy edits 702 -01 704 o Specified exactly two supported transformations 705 o Moved discovery steps to security considerations. 706 o Incorporated readability comments by Eduardo Gueiros. 707 o Changed MUST in 3.1 to SHOULD. 709 -00 711 o Initial IETF version. 713 10. References 715 10.1. Normative References 717 [BCP195] Sheffer, Y., Holz, R., and P. Saint-Andre, 718 "Recommendations for Secure Use of Transport Layer 719 Security (TLS) and Datagram Transport Layer Security 720 (DTLS)", BCP 195, RFC 7525, May 2015. 722 [RFC0020] Cerf, V., "ASCII format for network interchange", RFC 20, 723 October 1969. 725 [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate 726 Requirement Levels", BCP 14, RFC 2119, March 1997. 728 [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform 729 Resource Identifier (URI): Generic Syntax", STD 66, RFC 730 3986, January 2005. 732 [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data 733 Encodings", RFC 4648, October 2006. 735 [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax 736 Specifications: ABNF", STD 68, RFC 5234, January 2008. 738 [RFC6234] Eastlake, D. and T. Hansen, "US Secure Hash Algorithms 739 (SHA and SHA-based HMAC and HKDF)", RFC 6234, May 2011. 741 [RFC6749] Hardt, D., "The OAuth 2.0 Authorization Framework", RFC 742 6749, October 2012. 744 10.2. Informative References 746 [RFC6819] Lodderstedt, T., McGloin, M., and P. Hunt, "OAuth 2.0 747 Threat Model and Security Considerations", RFC 6819, 748 January 2013. 750 Appendix A. Notes on implementing base64url encoding without padding 752 This appendix describes how to implement a base64url encoding 753 function without padding based upon standard base64 encoding function 754 that uses padding. 756 To be concrete, example C# code implementing these functions is shown 757 below. Similar code could be used in other languages. 759 static string base64urlencode(byte [] arg) 760 { 761 string s = Convert.ToBase64String(arg); // Regular base64 encoder 762 s = s.Split('=')[0]; // Remove any trailing '='s 763 s = s.Replace('+', '-'); // 62nd char of encoding 764 s = s.Replace('/', '_'); // 63rd char of encoding 765 return s; 766 } 768 An example correspondence between unencoded and encoded values 769 follows. The octet sequence below encodes into the string below, 770 which when decoded, reproduces the octet sequence. 772 3 236 255 224 193 774 A-z_4ME 776 Appendix B. Example for the S256 code_challenge_method 778 The client uses output of a suitable random number generator to 779 create a 32-octet sequence. The octets representing the value in 780 this example (using JSON array notation) are:" 782 [116, 24, 223, 180, 151, 153, 224, 37, 79, 250, 96, 125, 216, 173, 783 187, 186, 22, 212, 37, 77, 105, 214, 191, 240, 91, 88, 5, 88, 83, 784 132, 141, 121] 786 Encoding this octet sequence as a Base64url provides the value of the 787 code_verifier: 789 dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk 791 The code_verifier is then hashed via the SHA256 hash function to 792 produce: 794 [19, 211, 30, 150, 26, 26, 216, 236, 47, 22, 177, 12, 76, 152, 46, 795 8, 118, 168, 120, 173, 109, 241, 68, 86, 110, 225, 137, 74, 203, 796 112, 249, 195] 798 Encoding this octet sequence as a base64url provides the value of the 799 code_challenge: 801 E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM 803 The authorization request includes: 805 code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM 806 &code_challange_method=S256 808 The Authorization server then records the code_challenge and 809 code_challenge_method along with the code that is granted to the 810 client. 812 in the request to the token_endpoint the client includes the code 813 received in the authorization response as well as the additional 814 paramater: 816 code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk 818 The Authorization server retrieves the information for the code 819 grant. Based on the recorded code_challange_method being S256, it 820 then hashes and base64url encodes the value of code_verifier. 821 BASE64URL-ENCODE(SHA256(ASCII("code_verifier" ))) 823 The calculated value is then compared with the value of 824 "code_challenge": 826 BASE64URL-ENCODE(SHA256(ASCII("code_verifier" ))) == code_challenge 828 If the two values are equal then the Authorization server can provide 829 the tokens as long as there are no other errors in the request. If 830 the values are not equal then the request must be rejected, and an 831 error returned. 833 Authors' Addresses 835 Nat Sakimura (editor) 836 Nomura Research Institute 837 1-6-5 Marunouchi, Marunouchi Kitaguchi Bldg. 838 Chiyoda-ku, Tokyo 100-0005 839 Japan 841 Phone: +81-3-5533-2111 842 Email: n-sakimura@nri.co.jp 843 URI: http://nat.sakimura.org/ 844 John Bradley 845 Ping Identity 846 Casilla 177, Sucursal Talagante 847 Talagante, RM 848 Chile 850 Phone: +44 20 8133 3718 851 Email: ve7jtb@ve7jtb.com 852 URI: http://www.thread-safe.com/ 854 Naveen Agarwal 855 Google 856 1600 Amphitheatre Pkwy 857 Mountain View, CA 94043 858 USA 860 Phone: +1 650-253-0000 861 Email: naa@google.com 862 URI: http://google.com/