会话初始协议ISP技术要求-中国通信行业标准(5)

时间:2008-10-19 来源: 作者: 点击:
如果类型为message/sip 的MIME 消息实体内包含基本的对话标识头字段( 如To、From, 、Call-ID 和CSeq),则该由CMS 分离数字签名进行标识的MIME 消息体可以提供一些基本的鉴权机制。如果消息接收方无法识别用于标识
  
如果类型为"message/sip" 的MIME 消息实体内包含基本的对话标识头字段( 如To、From, 、Call-ID 和CSeq),则该由CMS 分离数字签名进行标识的MIME 消息体可以提供一些基本的鉴权机制。如果消息接收方无法识别用于标识消息体的证书,或者该证书无法被核实,则用于标识消息体的数字签名可确保对话中其后的请求可被同一个证书拥有者传送。且如果消息接收方必须确保证书的可靠性,则数字签名可用于标识证书主体的身份。
为了避免由于头字段的增减所造成的歧义,消息发送方应将整个头字段值复制于被加密的消息实体内,且任何需要完整性保护的消息体应附加于加密的消息体内。
如果加密的消息体内包含Data 头字段,则消息接收方应将该头字段值与其自身的时钟进行比较。如果时间存在显著偏差,则用户代理(UA) 需要向其用户通报异常状态及安全隐患。
如果消息接收方检查到请求消息的完整性被破坏,则消息接收方应回送403 (Forbidden) 响应消息, 拒绝对该请求消息进行处理,且UA 应向其用户通报状态并请求解决问题处理方法。
以下示例为一个使用类型为"message/sip" 的MIME 进行封装的SIP 隧道消息: INVITE sip:bob@biloxi.com SIP/2.0
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8
To: Bob <sip:bob@biloxi.com>
From: Alice <sip:alice@atlanta.com>;tag=1928301774 Call-ID: a84b4c76e66710 CSeq: 314159 INVITE Max-Forwards: 70 Date: Thu, 21 Feb 2002 13:02:03 GMT Contact: <sip:alice@pc33.atlanta.com> Content-Type: multipart/signed;
protocol="application/pkcs7-signature"; micalg=sha1; boundary=boundary42 Content-Length: 568
--boundary42 Content-Type: message/sip
INVITE sip:bob@biloxi.com SIP/2.0 Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8 To: Bob <bob@biloxi.com> From: Alice <alice@atlanta.com>;tag=1928301774 Call-ID: a84b4c76e66710 CSeq: 314159 INVITE Max-Forwards: 70 Date: Thu, 21 Feb 2002 13:02:03 GMT Contact: <sip:alice@pc33.atlanta.com> Content-Type: application/sdp Content-Length: 147
v=0 o=UserA 2890844526 2890844526 IN IP4 here.com s=Session SDP c=IN IP4 pc33.atlanta.com t=0 0 m=audio 49172 RTP/AVP 0 a=rtpmap:0 PCMU/8000
--boundary42 Content-Type: application/pkcs7-signature; name=smime.p7s Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename=smime.p7s;
handling=required ghyHhHUujhJhjH77n8HHGTrfvbnj756tbB9HG4VQpfyF467GhIGfHfYT6 4VQpfyF467GhIGfHfYT6jH77n8HHGghyHhHUujhJh756tbB9HGTrfvbnj n8HHGTrfvhJhjH776tbB9HG4VQbnj7567GhIGfHfYT6ghyHhHUujpfyF4 7GhIGfHfYT64VQbnj756 --boundary42¬
19.4.5 隧道加密
隧道加密机制用于将CMS EnvelopedData 消息内的类型为"message/sip" 的MIME 消息体进行加密。具体实现时,网络会利用多数消息头字段来获取相关信息,因此,对S/MIME 消息进行加密通常是对消息体部分(如SDP)进行加密,而不是对消息头字段进行加密。诸如Subject 和Organization 等可以保证端到端完整性的头字段。除此之外,另外一个可以被加密传送的头字段的具体应用是采用匿名发送的方式,例如,可以将一个请求消息中的From 头字段值设置为匿名(如: sip:anonymous@anonymizer.invalid)。因此,下一个消息中包含消息发送方真实注册地址的From 头字段应被加密成类型为"message/sip" 的MIME 消息实体内,且仅对话接收方可获取该From 头字段的值。
如果采用这种匿名传送机制,SIP 消息中的From 头字段不能被消息接收方用作索引值来获取密钥环中的证书,从而无法获得消息发送方的S/MIME 密钥。因此,消息接收方首先应对加密后的消息进行解密操作,解密后的From 头字段值才可作为索引值来获取密钥环中的证书。为了保证端到端消息的完整性,被加密的类型为"message/sip" 的MIME 消息体应由消息接收方分配一个数字签名进行标识,标识后生成类型为"multipart/signed" 的MIME 消息实体, 该MIME 消息实体包含一个被加密的实体和一个数字签名,被加密的实体和数字签名的类型都为"application/pkcs7-mime" 。
以下示例为包含一个加密消息体和一个数字签名的SIP 消息,消息中由“*”符号组成的文本框内的内容为加密的消息体。
INVITE sip:bob@biloxi.com SIP/2.0
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8
To: Bob <sip:bob@biloxi.com>
From: Anonymous <sip:anonymous@atlanta.com>;tag=1928301774
Call-ID: a84b4c76e66710
CSeq: 314159 INVITE
Max-Forwards: 70
Date: Thu, 21 Feb 2002 13:02:03 GMT
Contact: <sip:pc33.atlanta.com>
Content-Type: multipart/signed;

protocol="application/pkcs7-signature";
micalg=sha1; boundary=boundary42
Content-Length: 568
--boundary42
Content-Type: application/pkcs7-mime; smime-type=enveloped-data;

name=smime.p7m
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=smime.p7m

handling=required
Content-Length: 231

***********************************************************
* Content-Type: message/sip *
* *
* INVITE sip:bob@biloxi.com SIP/2.0 *
* Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bKnashds8 *
* To: Bob <bob@biloxi.com> *

YD ××××—××××
* From: Alice <alice@atlanta.com>;tag=1928301774 *
* Call-ID: a84b4c76e66710 *
* CSeq: 314159 INVITE *
* Max-Forwards: 70 *
* Date: Thu, 21 Feb 2002 13:02:03 GMT *
* Contact: <sip:alice@pc33.atlanta.com> *
* *
* Content-Type: application/sdp *
* *
* v=0 *
* o=alice 53655765 2353687637 IN IP4 pc33.atlanta.com *
* s=Session SDP *
* t=0 0 *
* c=IN IP4 pc33.atlanta.com *
* m=audio 3456 RTP/AVP 0 1 3 99 *
* a=rtpmap:0 PCMU/8000 *
***********************************************************

--boundary42
Content-Type: application/pkcs7-signature; name=smime.p7s
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=smime.p7s;

handling=required
ghyHhHUujhJhjH77n8HHGTrfvbnj756tbB9HG4VQpfyF467GhIGfHfYT6
4VQpfyF467GhIGfHfYT6jH77n8HHGghyHhHUujhJh756tbB9HGTrfvbnj
n8HHGTrfvhJhjH776tbB9HG4VQbnj7567GhIGfHfYT6ghyHhHUujpfyF4

7GhIGfHfYT64VQbnj756
--boundary42-

20 SIP 协议的扩展BNF
本规范中的所有机制都在以文本形式和RFC 2234 中定义的扩展Backus-Naur 形式(BNF) 语法进行描述的。
20.1 基本规则
下列规则在整个规范中使用以描述基本的语义分解结构。US-ASCII 编码的字符集由ANSI X3.4-1986 定义。
alphanum = ALPHA / DIGIT
在RFC 2396中体现的几个规则已经更新以使这些规则与RFC 2234 相兼容, 这些规则包括:
reserved = ";" / "/" / "?" / ":" / "@" / "&" / "=" / "+" / "$" / "," unreserved = alphanum / mark
mark = "-" / "_" / "." / "!" / "~" / "*" / "'" / "(" / ")"
escaped = "%" HEXDIG HEXDIG

如果连线以空格或者水平tab 符开始,则SIP 的头头字段字段值可以用多个线括起来。所有的LWS, 包括,都具有与SP相同的语义。在解释域值或者向下游转发消息之前,Recipient 可能以单个SP代替任何LWS。如RFC 2616 所描述的, 这样做是按照HTTP/1.1 来正确地运作。当LWS做为任选时,在符号和分隔符之间应使用SWS 构造法。
LWS = [*WSP CRLF] 1*WSP ; linear whitespace
SWS = [LWS] ; sep whitespace
为了将报头名字与其他值分开,可以使用冒号,根据以上规则,冒号前允许有空格但没有行结束符,冒号后允许有空格,可以包括空格。HCOLON 定义了这种构造法。HCOLON = *( SP / HTAB ) ":" SWS
TEXT-UTF8 规则仅仅用于描述性的域内容和值,这些是将不会被解析。TEXT-UTF8 的字符包括来自UTF-8字符集(参见RFC 2279 )的字符。TEXT-UTF8-TRIM 规则用于描述性的域内容, 这些内容不是被引号括起的字符串,且最前面和最后面的LWS 也是没有意义的。在这方面,SIP不同于HTTP,HTTP使用ISO 8859-1字符集。
TEXT-UTF8-TRIM = 1*TEXT-UTF8char *(*LWS TEXT-UTF8char)
TEXT-UTF8char = %x21-7E / UTF8-NONASCII
UTF8-NONASCII = %xC0-DF 1UTF8-CONT
/ %xE0-EF 2UTF8-CONT
/ %xF0-F7 3UTF8-CONT
/ %xF8-Fb 4UTF8-CONT
/ %xFC-FD 5UTF8-CONT
UTF8-CONT = %x80-BF

在TEXT-UTF8-TRIM 定义中允许出现CRLF, 但仅仅做为头字段延续的一部分。在解释在TEXT-UTF8-TRIM 值之前,可以用单个SP替代f括起的 LWS是。在某些协议单元中使用了16进制的数字字符。某些单元如鉴权单元,强制16进制字母是小写的。LHEX = DIGIT / %x61-66 ;小写字母a-f
许多SIP 头字段值由被LWS分隔的词或特殊字符组成。除非其他地方有所陈述,符号是对大小写不敏感的。这些特殊的字符必须位于被引号引用的字符串中以用于参数值中。在Call-ID 中使用的构词法允许采用大多数分隔符。
token = 1*(alphanum / "-" / "." / "!" / "%" / "*" / "_" / "+" / "`" / "'" / "~" ) separators = "(" / ")" / "<" / ">" / "@" / "," / ";" / ":" / "" / DQUOTE / "/" / "[" / "]" / "?" / "=" / "{" / "}" / SP / HTAB
word = 1*(alphanum / "-" / "." / "!" / "%" / "*" /
"_" / "+" / "`" / "'" / "~" / "(" / ")" / "<" / ">" /
":" / "" / DQUOTE / "/" / "[" / "]" / "?" / "{" / "}" )

当使用符号或者在单元之间使用分隔符时,空格经常被允许使用在这些字符之前或者之后:
STAR = SWS "*" SWS ; asterisk
SLASH = SWS "/" SWS ; slash
EQUAL = SWS "=" SWS ; equal
LPAREN = SWS "(" SWS ; left parenthesis
RPAREN = SWS ")" SWS ; right parenthesis
RAQUOT = ">" SWS ; right angle quote
LAQUOT = SWS "<"; left angle quote
COMMA = SWS "," SWS ; comma
SEMI = SWS ";" SWS ; semicolon
COLON = SWS ":" SWS ; colon
LDQUOT = SWS DQUOTE; open double quotation mark
RDQUOT = DQUOTE SWS ; close double quotation mark

在SIP头字段字段中包括注释,用圆括号括起。注释仅仅允许在包含了“comment”的头字段中出现, 做为其头字段值定义的一部分。在所有的其他头字段中,圆括号被认为是字段值的一部分。
comment = LPAREN *(ctext / quoted-pair / comment) RPAREN
ctext = %x21-27 / %x2A-5B / %x5D-7E / UTF8-NONASCII / LWS

ctext包括了所有的字符, 除了左右括号和反斜线符号。如果一串文字被双引号所包围,则该文字串按照单个词来分析。在引号引用的字符串中,需要避免引号(“ )和反斜线符() 。
quoted-string = SWS DQUOTE *(qdtext / quoted-pair ) DQUOTE
qdtext = LWS / %x21 / %x23-5B / %x5D-7E / UTF8-NONASCII

仅仅在引用的字符串和注释的构造中,反斜线符(“” )可以当做单个字符引用机制来使用。不象HTTP/1.1 ,字符CR和LF因此转义来避免与line folding 和头分隔冲突,
quoted-pair = "" (%x00-09 / %x0B-0C / %x0E-7F) SIP-URI = "sip:" [ userinfo ] hostport uri-parameters [ headers ] SIPS-URI = "sips:" [ userinfo ] hostport
uri-parameters [ headers ] userinfo = ( user / telephone-subscriber ) [ ":" password ] "@" user = 1*( unreserved / escaped / user-unreserved ) user-unreserved = "&" / "=" / "+" / "$" / "," / ";" / "?" / "/" password = *( unreserved / escaped / "&" / "=" / "+" / "$" / "," ) hostport = host [ ":" port ] host = hostname / IPv4address / IPv6reference hostname = *( domainlabel "." ) toplabel [ "." ] domainlabel = alphanum / alphanum *( alphanum / "-" ) alphanum
YD ××××—××××
toplabel = ALPHA / ALPHA *( alphanum / "-" ) alphanum
IPv4address = 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT "." 1*3DIGIT
IPv6reference = "[" IPv6address "]"
IPv6address = hexpart [ ":" IPv4address ]
hexpart = hexseq / hexseq "::" [ hexseq ] / "::" [ hexseq ]
hexseq = hex4 *( ":" hex4)
hex4 = 1*4HEXDIG
port = 1*DIGIT

电话用户的BNF参见RFC 2809 。但那里所允许的任何字符在SIP URI的用户部分都是不允许的,都必

须要避免。
uri-parameters uri-parameter
transport-param other-transport user-param other-user method-param ttl-param maddr-param lr-param other-param pname pvalue paramchar param-unreserved
headers =
header =
hname =
hvalue =
hnv-unreserved =
SIP-message =
Request =
Request-Line =
Request-URI =
absoluteURI =
hier-part =
net-path =
abs-path =
opaque-part =
uric =
uric-no-slash =
98

= *( ";" uri-parameter)
= transport-param / user-param / method-param
/ ttl-param / maddr-param / lr-param / other-param
= "transport=" ( "udp" / "tcp" / "sctp" / "tls" / other-transport)
= token
= "user=" ( "phone" / "ip" / other-user)
= token
= "method=" Method
= "ttl=" ttl
= "maddr=" host
= "lr"
= pname [ "=" pvalue ]
= 1*paramchar
= 1*paramchar
= param-unreserved / unreserved / escaped
= "[" / "]" / "/" / ":" / "&" / "+" / "$"

"?" header *( "&" header )
hname "=" hvalue
1*( hnv-unreserved / unreserved / escaped )
*( hnv-unreserved / unreserved / escaped )
"[" / "]" / "/" / "?" / ":" / "+" / "$"

Request / Response Request-Line *( message-header ) CRLF [ message-body ] Method SP Request-URI SP SIP-Version CRLF SIP-URI / SIPS-URI / absoluteURI scheme ":" ( hier-part / opaque-part ) ( net-path / abs-path ) [ "?" query ] "//" authority [ abs-path ] "/" path-segments uric-no-slash *uric reserved / unreserved / escaped unreserved / escaped / ";" / "?" / ":" / "@"
/ "&" / "=" / "+" / "$" / "," path-segments = segment *( "/" segment ) segment = *pchar *( ";" param ) param = *pchar pchar = unreserved / escaped / ":" / "@" / "&" / "=" / "+" / "$" / "," scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) authority = srvr / reg-name srvr = [ [ userinfo "@" ] hostport ] reg-name = 1*( unreserved / escaped / "$" / "," / ";"
/ ":" / "@" / "&" / "=" / "+" ) query = *uric SIP-Version = "SIP" "/" 1*DIGIT "." 1*DIGIT message-header = (Accept
/ Accept-Encoding
/ Accept-Language
/ Alert-Info
/ Allow
/ Authentication-Info
/ Authorization
/ Call-ID
/ Call-Info
/ Contact
/ Content-Disposition
/ Content-Encoding
/ Content-Language
/ Content-Length
/ Content-Type
/ CSeq
/ Date
/ Error-Info
/ Expires
/ From
/ In-Reply-To
/ Max-Forwards
/ MIME-Version
/ Min-Expires
/ Organization
/ Priority
/ Proxy-Authenticate
/ Proxy-Authorization
/ Proxy-Require
/ Record-Route
/ Reply-To
/ Require

/ Retry-After
/ Route
/ Server
/ Subject
/ Supported
/ Timestamp
/ To
/ Unsupported
/ User-Agent
/ Via
/ Warning
/ WWW-Authenticate
/ extension-header) CRLF = %x49.4E.56.49.54.45 ; INVITE in caps = %x41.43.4B ; ACK in caps = %x4F.50.54.49.4F.4E.53 ; OPTIONS in caps = %x42.59.45 ; BYE in caps = %x43.41.4E.43.45.4C ; CANCEL in caps = %x52.45.47.49.53.54.45.52 ; REGISTER in caps INVITEm ACKm OPTIONSm BYEm CANCELm REGISTERm Method
INVITEm / ACKm / OPTIONSm / BYEm / CANCELm / REGISTERm / extension-method extension-method = token
= Status-Line *( message-header ) CRLF [ message-body ] SIP-Version SP Status-Code SP Reason-Phrase CRLF Informational Redirection Success Client-Error Server-Error Global-Failure extension-code
=

Response Status-Line = Status-Code =
/
/
/
/
/
/
extension-code = 3DIGIT
Reason-Phrase = *(reserved / unreserved / escaped
/ UTF8-NONASCII / UTF8-CONT / SP / HTAB)

Informational = "100" ; Trying
/ "180" ; Ringing
/ "181" ; Call Is Being Forwarded
/ "182" ; Queued
/ "183" ; Session Progress
Success = "200" ; OK
Redirection = "300" ; Multiple Choices
/ "301" ; Moved Permanently
/ "302" ; Moved Temporarily
/ "305" ; Use Proxy
/ "380" ; Alternative Service

Client-Error = "400" ; Bad Request
/ "401" ; Unauthorized
/ "402" ; Payment Required
/ "403" ; Forbidden
/ "404" ; Not Found
/ "405" ; Method Not Allowed
/ "406" ; Not Acceptable
/ "407" ; Proxy Authentication Required
/ "408" ; Request Timeout
/ "410" ; Gone
/ "413" ; Request Entity Too Large
/ "414" ; Request-URI Too Large
/ "415" ; Unsupported Media Type
/ "416" ; Unsupported URI Scheme
/ "420" ; Bad Extension
/ "421" ; Extension Required
/ "423" ; Interval Too Brief
/ "480" ; Temporarily not available
/ "481" ; Call Leg/Transaction Does Not Exist
/ "482" ; Loop Detected
/ "483" ; Too Many Hops
/ "484" ; Address Incomplete
/ "485" ; Ambiguous
/ "486" ; Busy Here
/ "487" ; Request Terminated
/ "488" ; Not Acceptable Here
/ "491" ; Request Pending
/ "493" ; Undecipherable
Server-Error = "500" ; Internal Server Error
/ "501" ; Not Implemented
/ "502" ; Bad Gateway
/ "503" ; Service Unavailable
/ "504" ; Server Time-out
/ "505" ; SIP Version not supported
/ "513" ; Message Too Large

Global-Failure = "600" ; Busy Everywhere / "603" ; Decline / "604" ; Does not exist anywhere / "606" ; Not Acceptable
Accept = "Accept" HCOLON
[ accept-range *(COMMA accept-range) ] accept-range = media-range *(SEMI accept-param) media-range = ( "*/*" / ( m-type SLASH "*" ) / ( m-type SLASH m-subtype ) )
*( SEMI m-parameter ) accept-param = qvalue = generic-param = gen-value = ("q" EQUAL qvalue) / generic-param
( "0" [ "." 0*3DIGIT ] ) / ( "1" [ "." 0*3("0") ] )
token [ EQUAL gen-value ]
token / host / quoted-string = "Accept-Encoding" HCOLON
[ encoding *(COMMA encoding) ] = codings *(SEMI accept-param) = content-coding / "*" = token = "Accept-Language" HCOLON
[ language *(COMMA language) ] = language-range *(SEMI accept-param) = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) / "*" ) Accept-Encoding
encoding codings content-codingAccept-Language
language language-range
Alert-Info =
alert-param =
Allow =

Authorization credentials digest-response dig-resp
username username-value digest-uri "Alert-Info" HCOLON alert-param *(COMMA alert-param) LAQUOT absoluteURI RAQUOT *( SEMI generic-param ) "Allow" HCOLON [Method *(COMMA Method)]
= "Authorization" HCOLON credentials
= ("Digest" LWS digest-response) / other-response
= dig-resp *(COMMA dig-resp) = username / realm / nonce / digest-uri / dresponse / algorithm /
cnonce / opaque / message-qop / nonce-count / auth-param
=
=
=

"username" EQUAL username-value quoted-string "uri" EQUAL LDQUOT digest-uri-value RDQUOT rquest-uri ; Equal to request-uri as specified by HTTP/1.1 "qop" EQUAL qop-value "cnonce" EQUAL cnonce-value nonce-value "nc" EQUAL nc-value 8LHEX "response" EQUAL request-digest LDQUOT 32LHEX RDQUOT auth-param-name EQUAL ( token / quoted-string ) token auth-scheme LWS auth-param *(COMMA auth-param) token
= "Authentication-Info" HCOLON ainfo *(COMMA ainfo)
= nextnonce / message-qop / response-auth / cnonce / nonce-count
= "nextnonce" EQUAL nonce-value
= "rspauth" EQUAL response-digest
= LDQUOT *LHEX RDQUOT

digest-uri-value =
message-qop =
cnonce =
cnonce-value =
nonce-count =
nc-value =
dresponse =
request-digest =
auth-param =
auth-param-name =
other-response =
auth-scheme =

Authentication-Info ainfo nextnonce response-auth response-digest
Call-ID = ( "Call-ID" / "i" ) HCOLON callid callid = word [ "@" word ]
Call-Info = "Call-Info" HCOLON info *(COMMA info)
info = LAQUOT absoluteURI RAQUOT *( SEMI info-param)
info-param = ( "purpose" EQUAL ( "icon" / "info" / "card" / token ) ) / generic-param
Contact = ("Contact" / "m" ) HCOLON

( STAR / (contact-param *(COMMA contact-param))) contact-param = (name-addr / addr-spec) *(SEMI contact-params) name-addr = [ display-name ] LAQUOT addr-spec RAQUOT addr-spec = SIP-URI / SIPS-URI / absoluteURI display-name = *(token LWS)/ quoted-string contact-params = c-p-q / c-p-expires / contact-extension c-p-q = "q" EQUAL qvalue c-p-expires = "expires" EQUAL delta-seconds contact-extension = generic-param delta-seconds = 1*DIGIT Content-Disposition = "Content-Disposition" HCOLON
disp-type *( SEMI disp-param ) disp-type = "render" / "session" / "icon" / "alert" / disp-extension-token disp-param = handling-param / generic-param handling-param = "handling" EQUAL ( "optional" / "required" / other-handling ) other-handling = token disp-extension-token = token Content-Encoding = ( "Content-Encoding" / "e" ) HCOLON
content-coding *(COMMA content-coding) Content-Language = "Content-Language" HCOLON
language-tag *(COMMA language-tag) language-tag = primary-tag *( "-" subtag ) primary-tag = 1*8ALPHA subtag = 1*8ALPHA
Content-Length = ( "Content-Length" / "l" ) HCOLON 1*DIGIT Content-Type = ( "Content-Type" / "c" ) HCOLON media-type media-type = m-type SLASH m-subtype *(SEMI m-parameter) m-type = discrete-type / composite-type discrete-type = "text" / "image" / "audio" / "video" / "application" / extension-token composite-type = "message" / "multipart" / extension-token extension-token = ietf-token / x-token ietf-token = token x-token = "x-" token m-subtype = extension-token / iana-token iana-token = token m-parameter = m-attribute EQUAL m-value m-attribute = token m-value = token / quoted-string CSeq = "CSeq" HCOLON 1*DIGIT LWS Method Error-Info = "Error-Info" HCOLON error-uri *(COMMA error-uri) error-uri = LAQUOT absoluteURI RAQUOT *( SEMI generic-param ) Expires = "Expires" HCOLON delta-seconds From = ( "From" / "f" ) HCOLON from-spec from-spec = ( name-addr / addr-spec )*( SEMI from-param ) from-param = tag-param / generic-param tag-param = "tag" EQUAL token In-Reply-To = "In-Reply-To" HCOLON callid *(COMMA callid) Max-Forwards = "Max-Forwards" HCOLON 1*DIGIT MIME-Version = "MIME-Version" HCOLON 1*DIGIT "." 1*DIGIT Min-Expires = "Min-Expires" HCOLON delta-seconds Organization = "Organization" HCOLON [TEXT-UTF8-TRIM] Priority = "Priority" HCOLON priority-value priority-value = "emergency" / "urgent" / "normal" / "non-urgent" / other-priority other-priority = token Proxy-Authenticate = "Proxy-Authenticate" HCOLON challenge challenge = ("Digest" LWS digest-cln *(COMMA digest-cln)) / other-challenge other-challenge = auth-scheme LWS auth-param*(COMMA auth-param) digest-cln = realm / domain / nonce / opaque / stale / algorithm
Date = "Date" HCOLON SIP-date
SIP-date = rfc1123-date
rfc1123-date = wkday "," SP date1 SP time SP "GMT"
date1 = 2DIGIT SP month SP 4DIGIT; day month year (e.g., 02 Jun 1982)
time = 2DIGIT ":" 2DIGIT ":" 2DIGIT; 00:00:00 - 23:59:59
wkday = "Mon" / "Tue" / "Wed" / "Thu" / "Fri" / "Sat" / "Sun"
month = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" / "Jul" / "Aug"
/ "Sep" / "Oct" / "Nov" / "Dec"

/ qop-options / auth-param realm = "realm" EQUAL realm-value realm-value = quoted-string domain = "domain" EQUAL LDQUOT URI
*( 1*SP URI ) RDQUOT URI = absoluteURI / abs-path nonce = "nonce" EQUAL nonce-value nonce-value = quoted-string opaque = "opaque" EQUAL quoted-string stale = "stale" EQUAL ( "true" / "false" ) algorithm = "algorithm" EQUAL ( "MD5" / "MD5-sess" / token ) qop-options = "qop" EQUAL LDQUOT qop-value *("," qop-value) RDQUOT qop-value = "auth" / "auth-int" / token Proxy-Authorization = "Proxy-Authorization" HCOLON credentials Proxy-Require = "Proxy-Require" HCOLON option-tag*(COMMA option-tag) option-tag = token
Record-Route = "Record-Route" HCOLON rec-route *(COMMA rec-route)
rec-route = name-addr *( SEMI rr-param )
rr-param = generic-param
Reply-To = "Reply-To" HCOLON rplyto-spec
rplyto-spec = ( name-addr / addr-spec ) *( SEMI rplyto-param )
rplyto-param = generic-param
Require = "Require" HCOLON option-tag *(COMMA option-tag)

Retry-After = "Retry-After" HCOLON delta-seconds [ comment ] *( SEMI retry-param )
retry-param = ("duration" EQUAL delta-seconds) / generic-param
Route = "Route" HCOLON route-param *(COMMA route-param)
route-param = name-addr *( SEMI rr-param )
Server = "Server" HCOLON server-val *(LWS server-val)
server-val = product / comment
product = token [SLASH product-version]
product-version = token
Subject = ( "Subject" / "s" ) HCOLON [TEXT-UTF8-TRIM]
Supported = ( "Supported" / "k" ) HCOLON[option-tag *(COMMA option-tag)]
Timestamp = "Timestamp" HCOLON 1*(DIGIT)[ "." *(DIGIT) ] [ LWS delay ]
delay = *(DIGIT) [ "." *(DIGIT) ]
To = ( "To" / "t" ) HCOLON ( name-addr / addr-spec ) *( SEMI to-param )
to-param = tag-param / generic-param
Unsupported = "Unsupported" HCOLON option-tag *(COMMA option-tag)
User-Agent = "User-Agent" HCOLON server-val *(LWS server-val)
Via = ( "Via" / "v" ) HCOLON via-parm *(COMMA via-parm)
via-parm = sent-protocol LWS sent-by *( SEMI via-params )
via-params = via-ttl / via-maddr / via-received / via-branch / via-extension
via-ttl = "ttl" EQUAL ttl
via-maddr = "maddr" EQUAL host
via-received = "received" EQUAL (IPv4address / IPv6address)
via-branch = "branch" EQUAL token
via-extension = generic-param
sent-protocol = protocol-name SLASH protocol-version

SLASH transport protocol-name = "SIP" / token protocol-version = token transport = "UDP" / "TCP" / "TLS" / "SCTP"/ other-transport sent-by = host [ COLON port ] ttl = 1*3DIGIT ; 0 to 255 Warning = "Warning" HCOLON warning-value *(COMMA warning-value) warning-value = warn-code SP warn-agent SP warn-text warn-code = 3DIGIT warn-agent = hostport / pseudonym
; the name or pseudonym of the server adding ; the Warning header, for use in debugging
YD ××××—××××
warn-text = quoted-string
pseudonym = token
WWW-Authenticate = "WWW-Authenticate" HCOLON challenge
extension-header = header-name HCOLON header-value
header-name = token
header-value = *(TEXT-UTF8char / UTF8-CONT / LWS)
message-body = *OCTET

106
附录 A (标准性附录)
安全:威胁模式和安全建议
SIP协议不易保证安全。其中介的使用,多方信任关系,和以后的在网络实体之间无信任的应用及用户间的操作使得安全很难保证。现有的解决方案在各种环境和用法中没有得到广泛的配合。因此, 需要一些独特的实现机制。
SIP信令安全本身对RTP 等配合SIP 使用的协议的安全或者是涉及到SIP 可能携带的某些特定部分的安全是没有关系的,虽然MIME 在SIP 安全上有着重要的作用。任何与对话有关的媒体都可以不依赖于任何的相关的SIP信令来进行端到端的加密。本规范不涉及媒体加密的内容。
20.2 A.1 攻击和威胁模型
下面所介绍的威胁对大多数的SIP 配置都很常见。这些威胁用来说明SIP要求的每种安全服务。
以下的示例并不是一个针对SIP的威胁的详细的列表,确切的说,这些“经典”的威胁证明了所需的特殊的安全服务有能力防止所有的威胁。
下列攻击假设攻击者可以读到任何网络上的分组环境,即知道到SIP 将在公网上经常的使用。网络上的攻击者能够在某些中介上修改分组。攻击者也可能窃取服务,窃听或者中断。
A.2 注册攻击
SIP的注册机制允许一个UA标识自己是一个用户所在的设备的注册服务器服务器,该用户有一个指定的记录地址(address-of-record) 。注册服务器可以从REGISTER 消息的From 头字段中的ID来判定是否这个请求可以修改在To 头字段中和记录地址有关的联系地址,虽然这两个字段常常是相同的,仍然有许多有效的配置可以使第三方注册为代表用户的联系地址。
SIP请求消息的From 头字段可以被UA的所有者任意修改,因此就容易受到恶意的注册攻击。攻击者可以成功的假扮授权方来改写纪录地址的联系地址,例如它可以取消所有URI 现存的联系地址并把攻击者的设备注册为正确的联系地址,从而使所有发向被攻击用户的请求指向攻击者的设备。
这是一种针对没有保护的请求发起者的威胁。任何作为一个有值服务的SIP UAS 都希望能够通过对所收到的请求鉴权来控制接入自己的资源。甚至每个终端用户UA也希望确认一个请求发起者的身份。
SIP实体对请求发起者进行鉴权对于安全服务是很必要的。
A.2.1 伪装服务器
请求消息的目的域通常都在request-URI 中指定。UA为了发送请求消息通常联系该域中的服务器。但是这样攻击者就有可以伪装远端服务器来截获UA的请求消息。
例如,一个位于chicago.com 域中的重定向服务器伪装一个位于biloxi.com 中的服务器。用户代理向biloxi.com 发送请求消息,chicago.com 的重定向服务器以伪造的响应回答,但响应带有正确来自于biloxi.com 的相应的SIP头。重定向响应中的伪造的关联地址使发起UA指向非安全的资源或者使得发向biloxi.com 的请求无法继续。
这种威胁又很多种方式,其中的一些是很严重的。例如,一个发往bolixi.com 的注册消息被chicago.com 截获,并回以一个伪造的301响应(Moved Permanently) 。这个响应看来像是从boloxi.com 发送的但是却将chicago.com 指定成为正确的注册服务器。以后所有UA发起者的注册请求都将送到chicago.com 。
为了防止此类威胁,UA必须可以鉴权其请求消息发向的服务器。
A.2.2 篡改消息体
UA请求消息都是通过可信任的代理服务器路由的。无论该信任关系是如何建立的,UA必须信任一个代理服务器来路由请求消息,并且不应检查或是修改该请求所包含的消息体。
如果UA可以用一个SIP 消息体来传送媒体会话密钥。虽然它信任所联系的域代理服务器可以正确的传送信令,但是该域管理员不应解密随后的任何媒体会话。而且,如果该代理服务器是恶意的,它就可以修改会话密钥,也可以作为一个中间方,或者改写发起UA所要求的安全特性。
这类的威胁不仅针对于会话密钥,而且也针对于大多数SIP 消息中端到端所携带的内容格式。这包括发给用户的MIME 消息体,SDP或者封装的电话信令等等。攻击者可以修改SDP 消息体, 例如,为了窃听话音通信而将一个RTP 媒体流指向一个窃听装置。
某些SIP 的头字段为端到端的,如Subject 头字段。UA也可以保护这些头字段和消息体的安全。但是,由于代理服务器在路由一个请求时,该请求的许多头字段可以被服务器合理的检查或更改,所以不是所有的头字段都可以保证端到端的安全。
UA希望能够保证SIP消息体和有限的头字段的端到端的安全。此类安全服务要求包括机密性,完整性和鉴权。这些端到端的安全服务应该独立于用于保护代理服务器之类的媒介的交互的手段的安全服务。
A.2.3 断开会话
一旦对话经过初始化消息而建立,其随后发送的请求消息可以修改对话或者会话的状态。该会话的参与者必须确认这些请求消息是否经攻击者伪造。
例如,某第三方攻击者为了获得对话的参数如to 标签和from 标签等, 而截获某些对话的初始话消息,该消息是通信双方共享的,然后在该对话中插入一个来自对话中任意方的BYE请求消息。目标地址收到BYE 消息,这个对话就会过早的结束。
类似的会话中(mid-session) 威胁还包括发送的伪造的re-INVITE 消息来修改对话, 这样会降低会话的安全性或者通过重定向媒体流来进行窃听攻击。
针对于该威胁的最有效的方法就是对BYE发送者进行鉴权。接收者不需要与对发送者的ID进行绝对的确认, 而只需要知道BYE 来自于该对话中的同一方。(由于消息的机密性, 攻击者在不知道该会话的参数的情况下就不可能伪造BYE 消息。但是,一些媒介( 如代理服务器)在会话建立时需要检查这些参数。
A.2.4 服务拒绝和放大
服务拒绝攻击(Denial-of-service) 通常是通过让过多的网络流量指向某个特定网络实体的接口而使该实体不可用。分布式的服务拒绝攻击是某个网络用户让多个网络主机用极大的流量注入目标主机中。
在许多网络结构中,SIP代理服务器为了接收全球的IP终端发来的请求消息面向公共INTERNET 。而某些分布式服务拒绝攻击者必须被SIP 系统的实施者和运营者所验证和寻址,这样,该SIP 代理服务器受到该类型的攻击。
攻击者能够产生带有伪造的源IP地址和相应的Via头字段的假请求消息来把一个目标主机标识为请求的发起者并然后将这个请求发给很多的SIP网络实体,从而用 UA或者代理来对这个目标发起拒绝服务的流量。
类似的的攻击还有,攻击者也可以在一个请求中使用伪造的Route 头字段值来标识目标主机并发送这种消息给分叉代理服务器(forking proxy )来放大送往目标的消息。
在攻击者确信由请求发起的对话将向后产生许多的事务的时候,用记录路由(record-route )也可以有类似的作用。
如果REGISTER 请求消息没有被注册服务器正确的鉴权,那么很多服务拒绝攻击就会开始。攻击者可以使某个管理域中的一些或者所有的用户被取消注册,从而使这些用户不能被加入一个新的会话中。为了在服务拒绝攻击中将注册服务器和任何有关的代理服务器作为放大器,攻击者可以以一个给定的记录地址注册许多个指向同一个主机的联系地址。攻击者也可通过将大量的绑定放入寄存器来删除注册服务器的可用的内存和磁盘资源。使用多播来传送请求消息能够很大程度上增加服务拒绝攻击的可能性。
20.3 A.3 安全机制
SIP协议所需的基本安全服务包括消息的机密性及完整性保留,重发攻击或消息欺骗的预防,对会话参与者的提供保密及鉴权服务以及预防服务拒绝攻击。SIP消息中的每个部分各自需要其机密性,完整性和鉴权的安全服务。
SIP协议除了使用新的专用的安全机制之外还重用了那些来自于HTTP和SMTP 的已有的可用的安全模式。
消息的全加密是为信令传送提供机密性的最好的方法――它也可以保证消息不被恶意的中介修改。但由于在大多数的网络结构中为了正确路由SIP 请求,消息中如Request-URI,Route 和Via 这样的字段应该对代理应该是可见的,因此SIP请求和响应消息不能被简单的进行全部的端到端的加密。代理服务器也需要修改消息的某些特性如增加via 头字段的值等,来完成某种功能。因此,UA必须信任代理服务器。本规范建议使用低层的安全机制,即在传输线上对整个的SIP请求或响应进行逐跳的加密,这样就可以让端点校验其请求发向的代理服务器的身份了。
SIP实体也需要在一种安全的方式下标识自己。当一个端点对一个对等UA或者一个代理服务器声明它的用户的身份时,该实体应该是可证实的。此时,可以使用密码鉴权机制。SIP消息体的独立的安全机制对端到端的相互鉴权提供了一个可供选择的方案,同时也某种程度上规定了用户代理必须要相信中介。
A.3.1 传输层和网络层安全
传输或网络层的安全服务包括加密信令流并保证消息的机密性和完整性。
通常,证书被用于建立低层的安全。在许多网络结构中,这些证书在也可用来作为一种鉴权的方式。
TLS 和 IPSec 分别用于传输层和网络层提供安全服务。
IPSec 是一套网络层协议工具,它可以全部的替换传统IP的安全策略。它常用在主机或者管理域已经有着相互信任关系的网络结构中。IPSec 通常在主机的操作系统或者在为从一个特定接口收到的所有的流量提供机密性和完整性的安全网关上执行。IPSec 也可以基于逐跳的应用。
在许多的网络结构中,IPSec 不需要集成在SIP应用中;IPSec 适用于难于直接在主机上加入安全配置的网络结构中。与它们的第一跳代理服务器有着共享密钥环的UA很适合用IPSec 保证安全。任何用于SIP的IPSec 配置都需要一个描述SIP安全所需的协议工具的轮廓。
TLS提供了基于有连接的协议的传输层的安全;“tls”(TLS over TCP )可以在一个Via 头字段值或SIP-URI 中被指定为所需的传输协议。TLS适用于在主机间无现存信任关系并需要逐跳安全的网络结构中。例如,Alice信任她的本地代理服务器, 在证书交换之后,该服务器决定信任Bob 所信任的本地代理服务器,这样Bob 和Alice 可以安全的通信。
TLS必须和SIP 应用一起实现。SIP 中的传输机制是逐跳的指定的,这样在TLS 上向代理服务器发送请求的UA就不能保证TLS 是可以用于端到端的安全的。
在具体实现TLS时必须至少支持TLS_RSA_WITH_AES_128_CBC_SHA 密码适配集。为了后向兼容,代理服务器、重定向服务器和注册服务器应该支持TLS_RSA_WITH_3DES_EDE_CBC_SHA 。具体实现时,也可以支持任何其他的密码适配集。
A.3.2 SIPS URI 方案
虽然SIPS URI 方案附于SIP URI 的语法上(19所述) 。其语义和SIP URI有很多不同的。SIPS URI 中,资源可以指定自己是安全的。
SIPS URI 可以作为一个特定用户的记录地址,通过该URI可以得知这个用户。SIPS 方案当于请求消息中作为Request-URI 时,即表示在该请求到达负责Request-URI 中的那部分域的SIP 实体之前的前向上的每一跳,且必须以TLS 保证安全; 如果它到达一个可疑的域时,它将和本地的安全与路由政策相协调,可能任何最后一跳上使用TLS 。SIPS 在用于请求发起者侧时,如发起者用SIPS URI 作为目标记录地址,它将指定到达目标域的整个请求路径的安全。
SIPS 方案可以用于记录地址,联系地址(包括那些REGISTER 方法,Contact 头的内容)和Router 头字段中。在每种情况中,SIPS URI 方案都允许这些现有的字段来指定安全资源。)。上述任何情况下,任何解除SIPS URI 的引用的方式都有着自己的安全特性。
本协议规定,SIPS 的用法应该使用相互的TLS鉴权方式,如密码适配组
TLS_RSA_WITH_AES_128_CBC_SHA 所要求,在鉴权过程中收到的证书应该与客户所持的根证书一起被证实;证书证实失败应该导致请求的失败。
注意到在SIPS URI 方案中,传输是独立于TLS的,虽然UDP不是有效的SIPS 传输方式这样"sips:alice@atlanta.com;transport=tcp" 和 "sips:alice@atlanta.com;transport=sctp" 就都是有效的。本规范不建议使用"transport=tls" ,部分原因是它是特定地针对请求的每一跳的。
把SIPS URI 作为记录地址分发出去的用户可以选择那些会拒绝非安全传输的请求的设备。
A.3.3 HTTP 鉴权
SIP 中可以使用基于HTTP鉴权的质询,该鉴权是依靠401和407 响应代码和携带口令和证书的头字段来进行的。HTTP 分类鉴权方案在SIP中无需作大的改变就可以重用,并可完成重发保护和单向鉴权。
关于分类鉴权参见本规范22章。
A.3.4 S/MIME
如上所述,由于网络中介(如代理服务器) 为了正确路由消息而必须看到消息中某个头字段, 所以不适于对整个SIP 消息进行端到端的加密。如果该中介被安全联盟所排斥,则SIP 消息不可路由。
S/MIME允许SIP UA加密SIP 中的MIME 部分, 在不影响消息头的情况下保证这些部分的端到端安全。S/MIME可以保证消息体端到端的机密性、完整性和相互鉴权。通过SIP消息隧道,可以使用S/MIME 来保证SIP头字段的完整性及机密性。
关于S/MIME 参见本规范23章。
.A.4 安全机制的实现
.A.4.1 SIP 实现要求

代理服务器,重定向服务器和注册服务器必须使用TLS ,并且必须支持交互和单向认证。本规范建议,UA可以初始化TLS; 并可以作为TLS 服务器。代理服务器, 重定向服务器和注册服务器应该拥有一个站点证书,其题目与其规范的主机名一致。UA可以有自己的证书用来与TLS进行相互认证,对于它们的用法不再本规范的范围之内。所有支持TLS的SIP 实体必须有对在TLS 协商中收到证书的证实机制;这样就必须拥有由证书授权者所发的一个或多个根证书。
所有支持TLS 的SIP 实体必须也支持SIPS URI 方案。
代理服务器,重定向服务器,注册服务器和UA也可以实现IPSec 或者其他的低层安全协议。
当UA试图连接一个代理服务器,重定向服务器或者注册服务器时,UAC 应该初始化一个TLS 连接并在其上发送SIP 消息。在一些网络结构中,UAS 也可以接收在TLS 连接上的请求消息。
代理服务器, 重定向服务器和UA必须实现分类鉴权, 具体要求参见本规范22章。代理服务器,重定向服务器和注册服务器配置的Digest 域应该至少有一个,并且至少有一个给定的服务器所支持的“realm” 字符串应该与该服务器的主机名和域名一致。
UA 可以支持MIME 消息体的签名和加密,关于S/MIME 的证书的传输详参见本规范23章。如果UA有着一个或多个授权的根证书来验证TLS或IPSec 的证书,它也应该重用该根证书来校验S/MIME 证书。UA可以有专为验证S/MIME 证书的根证书。
A.4.2 安全解决方案
与这些安全机制相应的操作在某种程度上可以遵循现有的WEB 或email 的安全模式。在更高的水平上,UA 对服务器包括代理服务器,重定向服务器和注册服务器通过一个分类鉴权的用户名和验证TLS 或IPSec 的证书的密码来为自己鉴权;服务器也对UA 或者对另一个服务器在每一跳上通过一个由TLS 发送的站点证书为自己鉴权。
110
在一个对等的水平上,UA 相信网络上一般的相互鉴权; 但是,S/MIME 也可以在网络不信任或者网络不被信任的情况下用来提供直接鉴权。
以下的例子说明这些安全机制被不同的UA 和服务器使用来防止26.1 中所介绍的攻击类型。当实施者和网络管理者可以遵循本章中余下部分的标准化指导,这些就仅作为实现的范例了。
A.4.2.1 注册
当UA 在线并向它的本地管理域注册,它应该建立一个与其注册服务器间的TLS 连接,关于UA 如何连接到它的注册服务器参见本规范10 章。注册服务器应该为UA 提供证书,并且证书的站点标识必须与UA 要注册的域相一致, 例如, 如果UA 要注册记录地址“alice@altanta.com”, 站点证书就必须标识一个在atlanta.com 域中的主机(如sip.atlanta.com)。当UA 收到TLS Certificate 消息, 它就应该校验该证书并检查站点标识。如果证书是无效的或废止的,或者它不能标识正确方,则UA 就不可以发送REGISTER 消息或者继续注册。
当注册服务器已经提供了一个有效的证书,UA 就知道该注册服务器不是可能重定向该UA,窃取密码或者进行其他类似的攻击。
那么UA 创建了一个REGISTER 请求, 该请求应该定位到一个与从注册服务器那里收到的证书相一致的Request-URI 。当该UA 于现有的TLS 连接上发送REGISTER 请求, 注册服务器应该用401 响应来验证这些请求。响应的Proxy-Authenticate 头字段中的“realm ”参数应该与之前在站点证书中给出的域相一致。当UAC 收到口令, 它应该命令用户提供证书或者从口令中“realm” 参数对应的密钥环(keyring)中得到一个正确的证书。证书中的用户名应该与REGISTER 的To 头字段中URI 的“userinfo” 部分一致。一旦Digest 证书被插入到一个正确的Proxy-Authorization 头字段中,REGISTER 就应该被重新提交给注册服务器。
由于注册服务器要求用户代理验证自己,所以攻击者就很难对一个用户记录地址伪造REGISTER 请求。另外,由于REGISTER 在一个保密的TLS 连接上发送, 所以攻击者在任何的重发攻击中也不能截取REGISTER 消息来复制证书。
当注册被注册服务器所接受,UA 就应该让该TLS 连接始终开放,以便注册服务器也可以作为该管理域中的用户请求发向的代理服务器。现存的TLS 连接将被重用把引入的请求传送到刚刚完成注册的UA。
由于UA 已经验证了TLS 另一端的服务器,因此该连接上的所有请求在通过代理服务器的时候都是可见的,因此攻击者不能制造经这台代理服务器发送的欺骗请求。
A.4.2.2 域内请求
假设Alice 的UA 要初始化同一个在远端管理域的用户 (bob@biloxi.com) 之间的会话。也假设本地管理域(atlanta.com)有一个本地的出代理。
一个管理域的处理入请求的代理服务器也可以作为一个本地的出代理;为了简单起见,我们假设这是一个atlantic.com 的例子(否则用户代理要初始化一个新的TLS 连接隔开该地的服务器)。假设客户已经完成了上述的注册过程, 当其发送INVITE 到另一个用户时, 它就应该重用与本地代理服务器之间的TLS 连接。UA 应该重用INVITE 消息中缓存的证书以避免对用户不必要的提示。
当本地的出代理服务器验证用户在INVITE 中的证书时,它应该检查Request-URI 来决定此消息该如何被路由。如果Request-URI 中的“domainname” 部分符合本地域名(atlanta.com)而不是biloxi.com, 则代理服务器就会咨询它的本地服务以决定如何更好的到达请求的用户。
假设如果alice@atlanta.com 试图连接“alex@altanta.com”,本地代理服务器就会将该请求转到由Alex 注册时于注册服务器间已经建立的TLS 连接上。由于Alex 收到从它信任的信道上送来的请求, 它就确信这个Alice 请求已经被本地管理域的代理服务器所授权。
但是, 在这个由Request-URI 指定的远端域的例子中,atlanta.com 的本地出代理服务器应该因此同远端biloxi.com 域中的服务器建立一个TLS 连接。由于本TLS 连接上的双方都是进行站点认证的服务器,所以应该有相互的TLS 鉴权。连接的双方应该校验并检查对方的证书,记录出现在证书中的域名以便于和SIP 消息的头字段相比较。比如,atlanta.com 代理服务器应该在这个阶段校验这个从远端收到的证书是否与biloxi.com 域一致。当它完成这些工作并且TLS 协商完成,就在两个代理间生成一个安全信道,这样,atlanta.com 代理就可以将INVITE 消息转给biloxi.com 。
Biloxi.com 的代理服务器应该依次检查atlanta.com 的代理服务器的证书并将该证书中声明的域与INVITE 的From 头字段中的“domainname ”部分相比较。Biloxi 代理可以有一个严格的安全政策要求拒绝同代理它们的管理域不匹配的请求。
制定这样的安全政策可以防止经常产生垃圾邮件的SIP 等价物SMTP “开放转发”(open relay)。
但是, 这个政策只能保证从其归属域中发来的请求的安全; 它不能让biloxi.com 得知atlanta.com 是如何鉴权Alice 的。只有当biloxi.com 从其他方面得知atlanta.com 的鉴权政策,它才有可能确认Alice 如何证实自己的身份的。Biloxi.com 然后可能制定一个更加严格的政策来禁止来自于不知道是否与biloxi.com 共享同一个鉴权政策的管理域的请求。
一旦INVITE 消息被biloxi 代理所证实, 则该代理服务器就应该标识现存的的与该消息的目标用户(本例中“bob@biloxi.com”)有关的TLS 信道。INVITE 消息应该在这个信道上转给Bob。由于该请求是从之前被证实为biloxi 代理的TLS 连接上收到的,虽然不需要相信Alice 的身份,Bob 也该知道From 头字段没有被篡改并且Alice 已经被atlanta.com 所验证。
每个代理服务器转发请求之前都应该在该请求中加入一个Record-Route 头字段以使以后此对话中的所有请求都会经此代理服务器。从而代理服务器可以继续在对话的整个生存期内提供安全服务。如果代理服务器没有将自己加入到Record-Route 中去, 以后的消息就会在没有任何安全服务的情况下直接在Alice 和Bob 间进行端到端的传送(除非双方都同意某个独立的端到端的安全如S/MIME)。在这点,SIP 梯形模型就可以提供一个更好的网络结构,即站点代理间的协定可以在Alice 和Bob 间提供一个合适的安全信道。
假设攻击者如果想破坏这种结构,由于它无法确定会话的参数并且完整性机制也保护着Alice 和Bob 间的业务,所以它就不能伪造BYE 请求并将其插入到Bob 和Alice 间的信令流中去。
A.4.2.3 对等端请求

另外,UA 所声明的标识carol@chicago.com 没有本地的出代理。当Carol 想发送INVITE 到bob@biloxi.com ,她的UA 应该初始化一个直接到biloxi 的TLS 连接。当它的UA 收到一个从biloxi 代理发来的证书, 在Carol 于该TLS 连接上传送INVITE 消息之前该证书就应正常被验证。然而Carol 没有办法向biloxi 代理证明其身份, 但在INVITE 的“message/sip” 部分上有一个Carol 与CMS 分开的签名。在这种情况下,由于Carol 和biloxi.com 没有正式的关联,所以她就不太可能有任何biloxi.com 域的证书。Biloxi 代理也可能有严格的政策对于在From 头字段的“domainname” 部分中无biloxi.com 的请求甚至不用验证即将其排除,因为它认为这些用户未经授权。
Biloxi 代理对bob 的政策是所有未授权的请求应该被重定向到正确的并不是注册为bob@Biloxi.com 的联系地址上,即<sip:bob@192.0.2.4> 。Carol 收到了它到biloxi 代理间建立的TLS 连接上的重定向响应,则它就会相信这个联系地址是准确的。
然后,Carol 应该建立一个与指定的地址间的TCP 连接并发送一个新的其Request-URI 中包括接收联系地址( 当请求被读时重计算签名) 的INVITE 消息。Bob 在不安全的接口上收到这个INVITE 消息,但其UA 在这种情况下检查并承认该请求From 头字段,并随后用一个本地缓存的证书来匹配INVITE 消息体的签名中的证书。它以同样的方式回答, 对Carol 验证自己并开始一个安全的对话。
有时管理域中的防火墙或者NAT 可以把同UA 直接建立的TCP 连接排除在外。在这种情况下,代理服务器也可能以一种无本地服务器指定的信任关系(例如放弃一个现存的TLS 连接并在明文cleartext 的TCP 上转发请求的方式把请求中继到UA。
A.4.2.4 DoS 保护
为了将使用这些安全方案的网络结构遭受服务拒绝攻击的风险降到最小,实施者应该遵循以下的处理程序。
当一个SIP 代理服务器主机在公共Internet 上是可路由的,它应该放置在一个有防御性政策( 阻塞源端路由的业务, 最好过滤PING 业务) 的管理域中。TLS 和IPSec 也都能利用参与集合了安全隧道和Socket 的安全联盟位于管理域边缘的有防护的主机。这些有防护的主机也可以承受拒绝服务的攻击,保证管理域内的SIP 主机不会被多余的消息传送所消耗资源。
无论使用什么安全方案,指向代理服务器的消息的洪泛都会锁住代理服务器的资源并且阻止有用的业务到达目的地。代理服务器上有处理一个SIP 会话有关的可计算的损失,并且这种损失对于一个有状态(stateful)的代理服务器要比对一个无状态(stateless)的服务器要大。因此有状态的代理要比无状态的代理更易受到洪泛的攻击。
UA 和代理服务器应该只用单个的401 (未鉴权)或407(代理鉴权要求)验证可疑的请求,放弃常规的响应重传算法,从而对于未鉴权的请求就成为无状态请求。
401(未鉴权) 或407(代理鉴权要求) 状态响应的重传使攻击者用伪造的头字段值(如Via )来使业务指向第三方的问题变得更加严重。
总之,代理服务器通过如TLS 这样的机制进行相互鉴权在很大程度上减少了欺诈中介引入伪造的请求或响应拒绝服务的可能性。这使得攻击者更难使无辜的SIP 节点变成放大的代理。
A.5 局限性
虽然用这些安全体制作为判断方法可以制止很多威胁的发生,但实施者和网络运营者必须认识到在这些机制的范围内仍然有着局限性。
A.5.1 HTTP 分类鉴权
SIP 中使用HTTP 分类鉴权是有着一定的局限性的,其中最主要的就是就是分类鉴权的完整性机制在SIP 中用处不大。特别是它们提出了对Request-URI 的保护和消息的方法对于UA 最希望保证安全的头字段却没有任何作用。
现有的重发保护机制(RFC2617) 在SIP 中也有局限性。如“next-nonce” 机制,不支持管道传送的请求。“nonce-count ”机制应该被用于重发保护。
另一个HTTP 分类鉴权的局限性就是域的范围。当用户想对一个与之已有关联的资源( 如某个视此用户为客户的服务提供者) 鉴权自己的时候,就可以使用分类鉴权,并且分类鉴权提供了很有用的功能。TLS 使用范围是域内的或者是多域的,由于证书常是普遍可验证的,所以UA 可以验证之前有关联的服务器。
A.5.2 S/MIME
S/MIME 的最突出的缺点就是它缺少对终端用户很流行的公有密钥结构。如果使用自签名的证书(或者不能被对话中的某个参与方所验证的证书), 那么基于SIP 的密钥交换机制就容易受到中间者攻击,这时, 攻击者可能检查并修改S/MIME 。攻击者需要中断对话双方的第一次密钥交换,从请求及响应中去掉已有的与CMS 分开的签名,并插入一个不同的自己的包含证书的与CMS 分离的签名(但是看来是一个正确的记录地址的证书)。对话双方都认为相互已经交换了密钥,但其实它们只是有了攻击者的公有密钥。
攻击者可以在双方第一次交换密钥时只针对以上该弱点进行攻击-随后,密钥的改变对UA 是显而易见的。以后攻击者也很难留在这个进行以后所有对话的通道里。
SSH 在初次交换密钥时很容易受到同样的中间方的攻击;但是SSH 能很好的改善连接的安全,并可以象SSH 那样使用指纹密码。例如,通信双方用SIP 建立一个语音通信的会话,它们应该读出所收对方的密钥中的指纹并与可以最初的相比较。当然,同信令相比, 中间方更难模仿参与者的话音( 用在基于CLIPPER 芯片的安全的电话)。
------分隔线----------------------------
顶一下
(2)
100%
踩一下
(0)
0%
------分隔线----------------------------
最新评论 查看所有评论
发表评论 查看所有评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 密码: 验证码:
推荐内容
  • VoIP的配置选择

    前面,我们已经围绕Vo I P 讨论了一些问题。现在,让我们讨论几种Vo I P 的配置和拓扑...

  • SIP协议介绍

    介绍 通信提供商及其合作伙伴和用户越来越渴求新一代基于 IP 的服务。现在有了 SIP协...

  • IP电话协议H.323协议 MGCP协议 SIP协议比较

    随着IP电话应用的普及,建立终端设备和网关的可扩展网络已成为业界面临的一大技术挑战...