draft-ietf-oauth-spop-14.txt   draft-ietf-oauth-spop-15.txt 
OAuth Working Group N. Sakimura, Ed. OAuth Working Group N. Sakimura, Ed.
Internet-Draft Nomura Research Institute Internet-Draft Nomura Research Institute
Intended status: Standards Track J. Bradley Intended status: Standards Track J. Bradley
Expires: January 7, 2016 Ping Identity Expires: January 9, 2016 Ping Identity
N. Agarwal N. Agarwal
Google Google
July 6, 2015 July 8, 2015
Proof Key for Code Exchange by OAuth Public Clients Proof Key for Code Exchange by OAuth Public Clients
draft-ietf-oauth-spop-14 draft-ietf-oauth-spop-15
Abstract Abstract
OAuth 2.0 public clients utilizing the Authorization Code Grant are OAuth 2.0 public clients utilizing the Authorization Code Grant are
susceptible to the authorization code interception attack. This susceptible to the authorization code interception attack. This
specification describes the attack as well as a technique to mitigate specification describes the attack as well as a technique to mitigate
against the threat through the use of Proof Key for Code Exchange against the threat through the use of Proof Key for Code Exchange
(PKCE, pronounced "pixy"). (PKCE, pronounced "pixy").
Status of This Memo Status of This Memo
skipping to change at page 1, line 37 skipping to change at page 1, line 37
Internet-Drafts are working documents of the Internet Engineering Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet- working documents as Internet-Drafts. The list of current Internet-
Drafts is at http://datatracker.ietf.org/drafts/current/. Drafts is at http://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress." material or to cite them other than as "work in progress."
This Internet-Draft will expire on January 7, 2016. This Internet-Draft will expire on January 9, 2016.
Copyright Notice Copyright Notice
Copyright (c) 2015 IETF Trust and the persons identified as the Copyright (c) 2015 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents Provisions Relating to IETF Documents
(http://trustee.ietf.org/license-info) in effect on the date of (http://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents publication of this document. Please review these documents
skipping to change at page 2, line 20 skipping to change at page 2, line 20
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1. Protocol Flow . . . . . . . . . . . . . . . . . . . . . . 5 1.1. Protocol Flow . . . . . . . . . . . . . . . . . . . . . . 5
2. Notational Conventions . . . . . . . . . . . . . . . . . . . 6 2. Notational Conventions . . . . . . . . . . . . . . . . . . . 6
3. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 7 3. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 7
3.1. Abbreviations . . . . . . . . . . . . . . . . . . . . . . 7 3.1. Abbreviations . . . . . . . . . . . . . . . . . . . . . . 7
4. Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . 7 4. Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . 7
4.1. Client creates a code verifier . . . . . . . . . . . . . 7 4.1. Client creates a code verifier . . . . . . . . . . . . . 7
4.2. Client creates the code challenge . . . . . . . . . . . . 8 4.2. Client creates the code challenge . . . . . . . . . . . . 8
4.3. Client sends the code challenge with the authorization 4.3. Client sends the code challenge with the authorization
request . . . . . . . . . . . . . . . . . . . . . . . . . 8 request . . . . . . . . . . . . . . . . . . . . . . . . . 8
4.4. Server returns the code . . . . . . . . . . . . . . . . . 8 4.4. Server returns the code . . . . . . . . . . . . . . . . . 9
4.4.1. Error Response . . . . . . . . . . . . . . . . . . . 9 4.4.1. Error Response . . . . . . . . . . . . . . . . . . . 9
4.5. Client sends the Authorization Code and the Code Verifier 4.5. Client sends the Authorization Code and the Code Verifier
to the token endpoint . . . . . . . . . . . . . . . . . . 9 to the token endpoint . . . . . . . . . . . . . . . . . . 9
4.6. Server verifies code_verifier before returning the tokens 9 4.6. Server verifies code_verifier before returning the tokens 10
5. Compatibility . . . . . . . . . . . . . . . . . . . . . . . . 10 5. Compatibility . . . . . . . . . . . . . . . . . . . . . . . . 10
6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 10 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 10
6.1. OAuth Parameters Registry . . . . . . . . . . . . . . . . 10 6.1. OAuth Parameters Registry . . . . . . . . . . . . . . . . 10
6.2. PKCE Code Challenge Method Registry . . . . . . . . . . . 11 6.2. PKCE Code Challenge Method Registry . . . . . . . . . . . 11
6.2.1. Registration Template . . . . . . . . . . . . . . . . 11 6.2.1. Registration Template . . . . . . . . . . . . . . . . 11
6.2.2. Initial Registry Contents . . . . . . . . . . . . . . 12 6.2.2. Initial Registry Contents . . . . . . . . . . . . . . 12
7. Security Considerations . . . . . . . . . . . . . . . . . . . 12 7. Security Considerations . . . . . . . . . . . . . . . . . . . 12
7.1. Entropy of the code_verifier . . . . . . . . . . . . . . 12 7.1. Entropy of the code_verifier . . . . . . . . . . . . . . 12
7.2. Protection against eavesdroppers . . . . . . . . . . . . 12 7.2. Protection against eavesdroppers . . . . . . . . . . . . 13
7.3. Salting the code_challenge . . . . . . . . . . . . . . . 13 7.3. Salting the code_challenge . . . . . . . . . . . . . . . 13
7.4. OAuth security considerations . . . . . . . . . . . . . . 14 7.4. OAuth security considerations . . . . . . . . . . . . . . 14
7.5. TLS security considerations . . . . . . . . . . . . . . . 14 7.5. TLS security considerations . . . . . . . . . . . . . . . 14
8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 14 8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 14
9. Revision History . . . . . . . . . . . . . . . . . . . . . . 15 9. Revision History . . . . . . . . . . . . . . . . . . . . . . 15
10. References . . . . . . . . . . . . . . . . . . . . . . . . . 17 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 17
10.1. Normative References . . . . . . . . . . . . . . . . . . 17 10.1. Normative References . . . . . . . . . . . . . . . . . . 18
10.2. Informative References . . . . . . . . . . . . . . . . . 18 10.2. Informative References . . . . . . . . . . . . . . . . . 18
Appendix A. Notes on implementing base64url encoding without Appendix A. Notes on implementing base64url encoding without
padding . . . . . . . . . . . . . . . . . . . . . . 18 padding . . . . . . . . . . . . . . . . . . . . . . 18
Appendix B. Example for the S256 code_challenge_method . . . . . 18 Appendix B. Example for the S256 code_challenge_method . . . . . 19
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 20 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 20
1. Introduction 1. Introduction
OAuth 2.0 [RFC6749] public clients are susceptible to the OAuth 2.0 [RFC6749] public clients are susceptible to the
authorization code interception attack. authorization code interception attack.
The attacker thereby intercepts the authorization code returned from The attacker thereby intercepts the authorization code returned from
the authorization endpoint within communication path not protected by the authorization endpoint within communication path not protected by
TLS, such as inter-app communication within the operating system of TLS, such as inter-app communication within the operating system of
skipping to change at page 5, line 33 skipping to change at page 5, line 33
of the "code verifier" by the client. This works as the mitigation of the "code verifier" by the client. This works as the mitigation
since the attacker would not know this one-time key, since it is sent since the attacker would not know this one-time key, since it is sent
over TLS and cannot be intercepted. over TLS and cannot be intercepted.
1.1. Protocol Flow 1.1. Protocol Flow
+-------------------+ +-------------------+
| Authz Server | | Authz Server |
+--------+ | +---------------+ | +--------+ | +---------------+ |
| |--(A)- Authorization Request ---->| | | | |--(A)- Authorization Request ---->| | |
| | + t(code_verifier), t | | Authorization | | | | + t(code_verifier), t_m | | Authorization | |
| | | | Endpoint | | | | | | Endpoint | |
| |<-(B)---- Authorization Code -----| | | | |<-(B)---- Authorization Code -----| | |
| | | +---------------+ | | | | +---------------+ |
| Client | | | | Client | | |
| | | +---------------+ | | | | +---------------+ |
| |--(C)-- Access Token Request ---->| | | | |--(C)-- Access Token Request ---->| | |
| | + code_verifier | | Token | | | | + code_verifier | | Token | |
| | | | Endpoint | | | | | | Endpoint | |
| |<-(D)------ Access Token ---------| | | | |<-(D)------ Access Token ---------| | |
+--------+ | +---------------+ | +--------+ | +---------------+ |
skipping to change at page 6, line 8 skipping to change at page 6, line 8
Figure 2: Abstract Protocol Flow Figure 2: Abstract Protocol Flow
This specification adds additional parameters to the OAuth 2.0 This specification adds additional parameters to the OAuth 2.0
Authorization and Access Token Requests, shown in abstract form in Authorization and Access Token Requests, shown in abstract form in
Figure 1. Figure 1.
A. The client creates and records a secret named the "code_verifier", A. The client creates and records a secret named the "code_verifier",
and derives a transformed version "t(code_verifier)" (referred to and derives a transformed version "t(code_verifier)" (referred to
as the "code_challenge") which is sent in the OAuth 2.0 as the "code_challenge") which is sent in the OAuth 2.0
Authorization Request, along with the transformation method "t". Authorization Request, along with the transformation method "t_m".
B. The Authorization Endpoint responds as usual, but records B. The Authorization Endpoint responds as usual, but records
"t(code_verifier)" and the transformation method. "t(code_verifier)" and the transformation method.
C. The client then sends the authorization code in the Access Token C. The client then sends the authorization code in the Access Token
Request as usual, but includes the "code_verifier" secret Request as usual, but includes the "code_verifier" secret
generated at (A). generated at (A).
D. The authorization server transforms "code_verifier" and compares D. The authorization server transforms "code_verifier" and compares
it to "t(code_verifier)" from (B). Access is denied if they are it to "t(code_verifier)" from (B). Access is denied if they are
not equal. not equal.
An attacker who intercepts the Authorization Grant at (B) is unable An attacker who intercepts the Authorization Grant at (B) is unable
skipping to change at page 8, line 19 skipping to change at page 8, line 19
The client then creates a code challenge derived from the code The client then creates a code challenge derived from the code
verifier by using one of the following transformations on the code verifier by using one of the following transformations on the code
verifier: verifier:
plain plain
code_challenge = code_verifier code_challenge = code_verifier
S256 S256
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier))) code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
Clients SHOULD use the S256 transformation. The plain transformation If the client is capable of using "S256", it MUST use "S256", as
is for compatibility with existing deployments and for constrained "S256" is Mandatory To Implement (MTI) on the server. Clients are
environments that can't use the S256 transformation. permitted to use "plain" only if they cannot support "S256" for some
technical reason and know via out of band configuration that the
server supports "plain".
The plain transformation is for compatibility with existing
deployments and for constrained environments that can't use the S256
transformation.
ABNF for "code_challenge" is as follows. ABNF for "code_challenge" is as follows.
code-challenge = 43*128unreserved code-challenge = 43*128unreserved
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
ALPHA = %x41-5A / %x61-7A ALPHA = %x41-5A / %x61-7A
DIGIT = %x30-39 DIGIT = %x30-39
4.3. Client sends the code challenge with the authorization request 4.3. Client sends the code challenge with the authorization request
skipping to change at page 9, line 26 skipping to change at page 9, line 37
error response with "error" value set to "invalid_request". The error response with "error" value set to "invalid_request". The
"error_description" or the response of "error_uri" SHOULD explain the "error_description" or the response of "error_uri" SHOULD explain the
nature of error, e.g., code challenge required. nature of error, e.g., code challenge required.
If the server supporting PKCE does not support the requested If the server supporting PKCE does not support the requested
transform, the authorization endpoint MUST return the authorization transform, the authorization endpoint MUST return the authorization
error response with "error" value set to "invalid_request". The error response with "error" value set to "invalid_request". The
"error_description" or the response of "error_uri" SHOULD explain the "error_description" or the response of "error_uri" SHOULD explain the
nature of error, e.g., transform algorithm not supported. nature of error, e.g., transform algorithm not supported.
If the client is capable of using "S256", it MUST use "S256", as
"S256" is Mandatory To Implement (MTI) on the server. Clients are
permitted to use "plain" only if they cannot support "S256" for some
technical reason and knows that the server supports "plain".
4.5. Client sends the Authorization Code and the Code Verifier to the 4.5. Client sends the Authorization Code and the Code Verifier to the
token endpoint token endpoint
Upon receipt of the Authorization Code, the client sends the Access Upon receipt of the Authorization Code, the client sends the Access
Token Request to the token endpoint. In addition to the parameters Token Request to the token endpoint. In addition to the parameters
defined in the OAuth 2.0 Access Token Request (Section 4.1.3 of defined in the OAuth 2.0 Access Token Request (Section 4.1.3 of
[RFC6749]), it sends the following parameter: [RFC6749]), it sends the following parameter:
code_verifier REQUIRED. Code verifier code_verifier REQUIRED. Code verifier
skipping to change at page 11, line 16 skipping to change at page 11, line 25
o Change controller: IESG o Change controller: IESG
o Specification document(s): this document o Specification document(s): this document
6.2. PKCE Code Challenge Method Registry 6.2. PKCE Code Challenge Method Registry
This specification establishes the PKCE Code Challenge Method This specification establishes the PKCE Code Challenge Method
registry. The new registry should be a sub-registry of OAuth registry. The new registry should be a sub-registry of OAuth
Parameters registry. Parameters registry.
Additional code_challenge_method types for use with the authorization Additional code_challenge_method types for use with the authorization
endpoint are registered with a Specification Required ([RFC5226]) endpoint are registered using the Specification Required policy
after a two-week review period on the oauth-ext-review@ietf.org [RFC5226], which includes review of the request by one or more
mailing list, on the advice of one or more Designated Experts. Designated Experts. The DEs will ensure there is at least a two-week
However, to allow for the allocation of values prior to publication, review of the request on the oauth-ext-review@ietf.org mailing list,
the Designated Expert(s) may approve registration once they are and that any discussion on that list converges before they respond to
satisfied that such a specification will be published. the request. To allow for the allocation of values prior to
publication, the Designated Expert(s) may approve registration once
they are satisfied that an acceptable specification will be
published.
Registration requests must be sent to the oauth-ext-review@ietf.org Registration requests and discussion on the oauth-ext-review@ietf.org
mailing list for review and comment, with an appropriate subject mailing list should use an appropriate subject, such as "Request for
(e.g., "Request for PKCE code_challenge_method: example"). PKCE code_challenge_method: example").
Within the review period, the Designated Expert(s) will either The Designated Expert(s) should consider the discussion on the
approve or deny the registration request, communicating this decision mailing list, as well as the overall security properties of the
to the review list and IANA. Denials should include an explanation challenge Method when evaluating registration requests. New methods
should not disclose the value of the code_verifier in the request to
the Authorization endpoint. Denials should include an explanation
and, if applicable, suggestions as to how to make the request and, if applicable, suggestions as to how to make the request
successful. successful.
IANA must only accept registry updates from the Designated Expert(s)
and should direct all requests for registration to the review mailing
list.
6.2.1. Registration Template 6.2.1. Registration Template
Code Challenge Method Parameter Name: Code Challenge Method Parameter Name:
The name requested (e.g., "example"). Because a core goal of this The name requested (e.g., "example"). Because a core goal of this
specification is for the resulting representations to be compact, specification is for the resulting representations to be compact,
it is RECOMMENDED that the name be short -- not to exceed 8 it is RECOMMENDED that the name be short -- not to exceed 8
characters without a compelling reason to do so. This name is characters without a compelling reason to do so. This name is
case-sensitive. Names may not match other registered names in a case-sensitive. Names may not match other registered names in a
case-insensitive manner unless the Designated Expert(s) state that case-insensitive manner unless the Designated Expert(s) state that
there is a compelling reason to allow an exception in this there is a compelling reason to allow an exception in this
skipping to change at page 12, line 42 skipping to change at page 13, line 7
high entropy that it is not practical for the attacker to guess. high entropy that it is not practical for the attacker to guess.
The client SHOULD create a code_verifier with a minimum of 256bits of The client SHOULD create a code_verifier with a minimum of 256bits of
entropy. This can be done by having a suitable random number entropy. This can be done by having a suitable random number
generator create a 32-octet sequence. The Octet sequence can then be generator create a 32-octet sequence. The Octet sequence can then be
base64url encoded to produce a 43-octet URL safe string to use as a base64url encoded to produce a 43-octet URL safe string to use as a
code_challenge that has the required entropy. code_challenge that has the required entropy.
7.2. Protection against eavesdroppers 7.2. Protection against eavesdroppers
Clients MUST NOT try down grading the algorithm after trying "S256" Clients MUST NOT downgrade to "plain" after trying "S256" method.
method. If the server is PKCE compliant, then "S256" method will Servers that support PKCE are required to support "S256", and servers
work. If the server does not support PKCE, it will not generate an that do not support PKCE will simply ignore the unknown
error. The only time that a server will return that it does not "code_verifier" OAuth 2.0 (see Section 3.2 of [RFC6749]. Because of
support "S256" is if there is a MITM trying the algorithm downgrade that, an error when "S256" is presented can only mean that the server
attack. is faulty or that a MITM attacker is trying a downgrade attack.
"S256" method protects against eavesdroppers observing or "S256" method protects against eavesdroppers observing or
intercepting the "code_challenge", because the challenge cannot be intercepting the "code_challenge", because the challenge cannot be
used without the verifier. With the "plain" method, there is a used without the verifier. With the "plain" method, there is a
chance that "code_challenge" will be observed by the attacker on the chance that "code_challenge" will be observed by the attacker on the
device, or in the http request. Since the code challenge is the same device, or in the http request. Since the code challenge is the same
as the code verifier in this case, "plain" method deso not protect as the code verifier in this case, "plain" method does not protect
against the eavesdropping of the initial request. against the eavesdropping of the initial request.
The use of "S256" protects against disclosure of "code_verifier" The use of "S256" protects against disclosure of "code_verifier"
value to an attacker. value to an attacker.
Because of this, "plain" SHOULD NOT be used, and exists only for Because of this, "plain" SHOULD NOT be used, and exists only for
compatibility with deployed implementations where the request path is compatibility with deployed implementations where the request path is
already protected. The "plain" method MUST NOT be used in new already protected. The "plain" method SHOULD NOT be used in new
implementations. implementations, unless they cannot support "S256" for some technical
reason.
The "S256" code_challenge_method or other cryptographically secure The "S256" code_challenge_method or other cryptographically secure
code_challenge_method extension SHOULD be used. The plain code_challenge_method extension SHOULD be used. The plain
code_challenge_method relies on the operating system and transport code_challenge_method relies on the operating system and transport
security not to disclose the request to an attacker. security not to disclose the request to an attacker.
If the code_challenge_method is plain, and the "code_challenge" is to If the code_challenge_method is plain, and the "code_challenge" is to
be returned inside authorization "code" to achieve a stateless be returned inside authorization "code" to achieve a stateless
server, it MUST be encrypted in such a manner that only the server server, it MUST be encrypted in such a manner that only the server
can decrypt and extract it. can decrypt and extract it.
skipping to change at page 15, line 7 skipping to change at page 15, line 16
Prateek Mishra, Oracle Prateek Mishra, Oracle
Ryo Ito, mixi Ryo Ito, mixi
Scott Tomilson, Ping Identity Scott Tomilson, Ping Identity
Sergey Beryozkin Sergey Beryozkin
Takamichi Saito Takamichi Saito
Torsten Lodderstedt, Deutsche Telekom Torsten Lodderstedt, Deutsche Telekom
William Denniss, Google William Denniss, Google
9. Revision History 9. Revision History
-15
o Addressed Barry's IESG comments around IANA Registration
o Addressed Barry's IESG comments around Sec 7.2 downgrade attack
o fix a typo for William and make a small change to Fig 1.1
clarifying t_m
o more wording changes to sec 7.2 re Barry
o made the two SHOULD NOT use plain recommendations consistent.
o slightly cleaned up grammer in Sec 7.2
-14 -14
o #38. Expanded Section 7.2 to explain why plain should not be o #38. Expanded Section 7.2 to explain why plain should not be
used. used.
o #39. Modified Section 4.4.1 to discourage the use of plain. o #39. Modified Section 4.4.1 to discourage the use of plain.
o #40. Modified Intro text to explain the attack better. o #40. Modified Intro text to explain the attack better.
o #41. Added explanation that the token request is protected in the o #41. Added explanation that the token request is protected in the
Last paragraph of the Introduction. Last paragraph of the Introduction.
o #42. Sec 4.2: Removed redundant double quotes caused by spanx. o #42. Sec 4.2: Removed redundant double quotes caused by spanx.
o #43. Sec 4.4: Replaced code with authorization code. o #43. Sec 4.4: Replaced code with authorization code.
skipping to change at page 17, line 47 skipping to change at page 18, line 24
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, March 1997. Requirement Levels", BCP 14, RFC 2119, March 1997.
[RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
Resource Identifier (URI): Generic Syntax", STD 66, RFC Resource Identifier (URI): Generic Syntax", STD 66, RFC
3986, January 2005. 3986, January 2005.
[RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data
Encodings", RFC 4648, October 2006. Encodings", RFC 4648, October 2006.
[RFC5226] Narten, T. and H. Alvestrand, "Guidelines for Writing an
IANA Considerations Section in RFCs", BCP 26, RFC 5226,
May 2008.
[RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax [RFC5234] Crocker, D. and P. Overell, "Augmented BNF for Syntax
Specifications: ABNF", STD 68, RFC 5234, January 2008. Specifications: ABNF", STD 68, RFC 5234, January 2008.
[RFC6234] Eastlake, D. and T. Hansen, "US Secure Hash Algorithms [RFC6234] Eastlake, D. and T. Hansen, "US Secure Hash Algorithms
(SHA and SHA-based HMAC and HKDF)", RFC 6234, May 2011. (SHA and SHA-based HMAC and HKDF)", RFC 6234, May 2011.
[RFC6749] Hardt, D., "The OAuth 2.0 Authorization Framework", RFC [RFC6749] Hardt, D., "The OAuth 2.0 Authorization Framework", RFC
6749, October 2012. 6749, October 2012.
10.2. Informative References 10.2. Informative References
 End of changes. 22 change blocks. 
44 lines changed or deleted 61 lines changed or added

This html diff was produced by rfcdiff 1.42. The latest version is available from http://tools.ietf.org/tools/rfcdiff/