RFC3920 XMPP Core--Use of TLS

香水坏坏 发表于 2007-10-4 [specification]

5.1. 概览
XMPP包含的一个保证流安全的方法来防止篡改和偷听.这个传输层安全协议[TLS]的频道加密方法, 模拟了类似的其他"STARTTLS"(见RFC 2595 [USINGTLS])的扩展,如 IMAP [IMAP], POP3 [POP3], and ACAP [ACAP]."STARTTLS"的扩展名字空间是'urn:ietf:params:xml:ns:xmpp-tls'.

一个给定域的管理员可以(MAY)要求客户端和服务器通信以及服务器之间通信时使用TLS,或者两者都要求。客户端应该(SHOULD)在尝试完成 SASL (第六章)握手之前使用 TLS,服务器应该(SHOULD)在两个域之间使用 TLS 以保证服务器间通信的安全。

以下是使用规则:

  1. 一个遵守本协议的初始化实体必须(MUST)在初始化流的头信息中包含一个'version'属性并把值设为“1.0”。
  2. 如果TLS握手发生在两个服务器之间,除非服务器声称的DNS主机名已经被解析(见第十四章第四节 Server-to-Server Communications),通信不能(MUST NOT)继续进行。
  3. 当一个遵守本协议的接收实体接收了一个初始化流(它的头信息中包含一个'version'属性并且值设为“1.0”),在发送应答流的的头信息(其中包含版本标记)之后,它必须发送(MUST)<starttls/>元素(名字空间为 'urn:ietf:params:xml:ns:xmpp-tls')以及其他它支持的流特性 。
  4. 如果初始化实体选择使用TLS,TLS握手必须在SASL握手之前完成;这个顺序用于帮助保护SASL握手时发送的认证信息的安全,同时可以在必要的时候在TLS握手之前为SASL外部机制提供证书。
  5. TLS握手期间,一个实体不能(MUST NOT)在流的根元素中发送任何空格符号作为元素的分隔符(在下面的TLS示例中的任何空格符都仅仅是为了便于阅读);这个禁令用来帮助确保安全层字节精度。
  6. 接收实体必须(MUST)在发送<proceed/> 元素的关闭符号">" 之后立刻开始TLS协商。初始化实体必须(MUST)在从接收实体接收到<proceed/> 元素的关闭符号">" 之后立刻开始TLS协商。
  7. 初始化实体必须(MUST)验证接收实体出示的证书;关于证书验证流程参见Certificate Validation ( 第十四章第二节)。
  8. 证书必须(MUST)检查初始化实体(比如一个用户)提供的主机名;而不是通过DNS系统解析出来的主机名;例如,如果用户指定一个主机名"example.com"而一个DNS SRV [SRV]查询返回"im.example.com",证书必须(MUST)检查"example.com".如果任何种类的XMPP实体(例如客户端或服务器)的JID出现在一个证书里,它必须(MUST)表现为一个别名实体里面的UTF8字符串,存在于subjectAltName之中。如何使用 [ASN.1] 对象标识符 "id-on-xmppAddr" 定义在本文的第五章第一节第一小节。
  9. 如果 TLS 握手成功了,接收实体必须(MUST) 丢弃TLS 生效之前从初始化实体得到的任何不可靠的信息.
  10. 如果 TLS 握手成功了,初始化实体必须(MUST) 丢弃TLS 生效之前从接收实体得到的任何不可靠的信息.
  11. 如果 TLS 握手成功了,接收实体不能(MUST NOT)在流重新开始的时候通过提供其他的流特性来向初始化实体提供 STARTTLS 扩展.
  12. 如果 TLS 握手成功了,初始化实体必须(MUST)继续进行SASL握手。
  13. 如果 TLS 握手失败了,接收实体必须(MUST)终止XML流和相应的TCP连接。
  14.  关于必须(MUST)支持的机制,参照 Mandatory-to-Implement Technologies (第十四章第七节) 。

--------------------------------------------------------------------------------
5.1.1. 用于 XMPP 地址的 ASN.1 对象标识符
上文提到的[ASN.1] 对象标识符 "id-on-xmppAddr"定义如下:

id-pkix OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) dod(6) internet(1) security(5) mechanisms(5) pkix(7) }

id-on OBJECT IDENTIFIER ::= { id-pkix 8 } -- other name forms

id-on-xmppAddr OBJECT IDENTIFIER ::= { id-on 5 }

XmppAddr ::= UTF8String

对象标识符也可以(MAY)使用点分隔的格式,如 "1.3.6.1.5.5.7.8.5".


--------------------------------------------------------------------------------
5.2. 叙述
当一个初始化实体用TLS保护一个和接收实体之间的流,其步骤如下:

  1. 初始化实体打开一个TCP连接,发送一个打开的XML流头信息(其'version'属性设置为"1.0")给接收实体以初始化一个流。
  2.  接收实体打开一个TCP连接,发送一个XML流头信息(其'version'属性设置为"1.0")给初始化实体作为应答。
  3. 接收实体向初始化实体提议STARTTLS范围(包括其他支持的流特性),如果TLS对于和接收实体交互是必需的,它应该(SHOULD)在<starttls/>元素中包含子元素<required/>.
  4. 初始化实体发出STARTTLS命令(例如, 一个符合'urn:ietf:params:xml:ns:xmpp-tls'名字空间的 <starttls/> 元素) 以通知接收实体它希望开始一个TLS握手来保护流。
  5. 接收实体必须(MUST)以'urn:ietf:params:xml:ns:xmpp-tls'名字空间中的<proceed/>元素或<failure/>元素应答。如果失败,接收实体必须(MUST)终止XML流和相应的TCP连接。如果继续进行,接收实体必须(MUST)尝试通过TCP连接完成TLS握手并且在TLS握手完成之前不能(MUST NOT)发送任何其他XML数据。
  6. 初始化实体和接收实体尝试完成TLS握手。(要符合[TLS]规范)
  7. 如果 TLS 握手不成功, 接收实体必须(MUST)终止 TCP 连接. 如果 TLS 握手成功, 初始化实体必须(MUST)发送给接收实体一个打开的XML流头信息来初始化一个新的流(先发送一个关闭标签</stream>是不必要的,因为接收实体和初始化实体必须(MUST)确保原来的流在TLS握手成功之后被关闭) 。
  8. 在从初始化实体收到新的流头信息之后,接收实体必须(MUST)发送一个新的XML流头信息给初始化实体作为应答,其中应包含可用的特性但不包含STATRTTLS特性。

--------------------------------------------------------------------------------
5.3. 客户端-服务器 示例
以下例子展示一个客户端使用STARTTLS保护数据流 (注意: 以下步骤举例说明协议中的失败案例;在这个例子中它们并不详尽并且也不是必须被数据传输触发的).

步骤 1: 客户端初始化流给服务器:

XML/HTML代码
  1. <stream:stream  xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='example.com' version='1.0'>  

步骤 2: 服务器发送一个流标签给客户端作为应答:

 

XML/HTML代码
  1. <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' id='c2s_123' from='example.com' version='1.0'>  

步骤 3: 服务器发送 STARTTLS 范围给客户端(包括验证机制和任何其他流特性):

 

XML/HTML代码
  1. <stream:features>        
  2. <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>       
  3. <required/>        
  4. </starttls>        
  5. <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>          
  6. <mechanism>DIGEST-MD5</mechanism>  
  7. <mechanism>PLAIN</mechanism>        
  8. </mechanisms>      
  9. </stream:features>  

步骤 4: 客户端发送 STARTTLS 命令给服务器:

XML/HTML代码
  1. <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>  


步骤 5: 服务器通知客户端可以继续进行:

XML/HTML代码
  1. <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>  

步骤 5 (或者): 服务器通知客户端 TLS 握手失败并关闭流和TCP连接:

XML/HTML代码
  1. <failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>   </stream:stream>  

步骤 6: 客户端和服务器尝试通过已有的TCP连接完成 TLS 握手.
步骤 7: 如果 TLS 握手成功, 客户端初始化一个新的流给服务器:

XML/HTML代码
  1. <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='example.com' version='1.0'>  

步骤 7 (或者): 如果 TLS 握手不成功, 服务器关闭 TCP 连接.
步骤 8: 服务器发送一个流头信息应答客户端,其中包括任何可用的流特性:

XML/HTML代码
  1. <stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' from='example.com' id='c2s_234' version='1.0'>   
  2. <stream:features>  
  3. <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp sasl'>  
  4. <mechanism>DIGEST-MD5</mechanism>  
  5. <mechanism>PLAIN</mechanism>       
  6. <mechanism>EXTERNAL</mechanism>  
  7. </mechanisms>  
  8. </stream:features>  

步骤 9: 客户端继续 SASL 握手 (第六章).


--------------------------------------------------------------------------------
5.4. 服务器-服务器示例
以下例子展示两个服务器之间使用STARTTLS保护数据流 (注意: 以下步骤举例说明协议中的失败案例;在这个例子中它们并不详尽并且也不是必须被数据传输触发的).

步骤 1: Server1 初始化流给 Server2:

XML/HTML代码
  1. <stream:stream xmlns='jabber:server' xmlns:stream='http://etherx.jabber.org/streams' to='example.com' version='1.0'>  

步骤 2: Server2 发送一个流标签给 Server1 作为应答:

XML/HTML代码
  1. <stream:stream xmlns='jabber:server' xmlns:stream='http://etherx.jabber.org/streams' from='example.com' id='s2s_123' version='1.0'>  

步骤 3: Server2 发送 STARTTLS 范围给 Server1 ,包括验证机制和任何其他流特性:

XML/HTML代码
  1. <stream:features>        
  2. <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'>       
  3. <required/>        
  4. </starttls>        
  5. <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>          
  6. <mechanism>DIGEST-MD5</mechanism>       
  7. <mechanism>KERBEROS_V4</mechanism>        
  8. </mechanisms>      
  9. </stream:features>  

步骤 4: Server1 发送 STARTTLS 命令给 Server2:

 

XML/HTML代码
  1. <starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>  

步骤 5: Server2 通知 Server1 允许继续进行:

 

XML/HTML代码
  1. <proceed xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>  

步骤 5 (或者): Server2 通知 Server1 TLS握手失败并关闭流:

 

XML/HTML代码
  1. <failure xmlns='urn:ietf:params:xml:ns:xmpp-tls'/>   </stream:stream>  

步骤 6: Server1 和 Server2 尝试通过 TCP 完成 TLS 握手.
步骤 7: 如果 TLS 握手成功, Server1 初始化一个新的流给 Server2:

 

XML/HTML代码
  1. <stream:stream xmlns='jabber:server' xmlns:stream='http://etherx.jabber.org/streams' to='example.com' version='1.0'>  

步骤 7 (或者): 如果 TLS 握手不成功, Server2 关闭 TCP 连接.
步骤 8: Server2 发送一个包含任何可用流特性的流头信息给 Server1 :

XML/HTML代码
  1. <stream:stream xmlns='jabber:server' xmlns:stream='http://etherx.jabber.org/streams' from='example.com' id='s2s_234' version='1.0'>   
  2. <stream:features>        
  3. <mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>          
  4. <mechanism>DIGEST-MD5</mechanism>       
  5. <mechanism>KERBEROS_V4</mechanism>       
  6. <mechanism>EXTERNAL</mechanism>        
  7. </mechanisms>      
  8. </stream:features>  

 

RFC3920 XMPP Core--XML Streams

784 0 标签:protocol XML XMPP 协议 
访客评论
  • http://www.aspstat.com/104   RFC3920 XMPP Core--Use of SASL   [2007-10-4]
    Pingback from http://www.aspstat.com/104 RFC3920 XMPP Core--Use of SASL
  • 香水坏坏  RFC3920 XMPP Core--Use of SASL  [2007-10-4]
    Trackback from 香水坏坏
发表评论
  • 你的姓名:
  • 你的网站:
  •   EMAIL:   
  • 评论内容:
  • 私人