|
1 // Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // Name : sipsecrequestdata.cpp |
|
15 // Part of : SIPSec/DigestPlugin |
|
16 // Version : SIP/6.0 |
|
17 // |
|
18 |
|
19 |
|
20 |
|
21 #include "CSIPSecDigest.h" |
|
22 #include "sipsecrequestdata.h" |
|
23 #include "sipsecdigestcontext.h" |
|
24 |
|
25 _LIT8( KSIPSecReqDataSeparator, ":" ); |
|
26 const TInt KSSIPSecReqDataMethod( 1 ); |
|
27 const TInt KSSIPSecReqDataURI( 2 ); |
|
28 const TInt KSSIPSecReqDataMessage( 3 ); |
|
29 const TInt KSSIPSecReqDataServer( 4 ); |
|
30 |
|
31 |
|
32 // ============================ MEMBER FUNCTIONS =============================== |
|
33 |
|
34 // ---------------------------------------------------------------------------- |
|
35 // RSIPSecRequestDataField::RSIPSecRequestDataField |
|
36 // ---------------------------------------------------------------------------- |
|
37 // |
|
38 |
|
39 RSIPSecRequestDataField::RSIPSecRequestDataField() : |
|
40 iValue ( TPtrC8() ), |
|
41 iNeedsHashing( EFalse ), |
|
42 iBuffer( NULL ) |
|
43 { |
|
44 } |
|
45 |
|
46 // ---------------------------------------------------------------------------- |
|
47 // RSIPSecRequestDataField::RSIPSecRequestDataField |
|
48 // ---------------------------------------------------------------------------- |
|
49 // |
|
50 RSIPSecRequestDataField::RSIPSecRequestDataField( const TDesC8& aValue, |
|
51 TBool aNeedsHashing ) : |
|
52 iValue( TPtrC8( aValue ) ), |
|
53 iNeedsHashing( aNeedsHashing ), |
|
54 iBuffer( NULL ) |
|
55 { |
|
56 } |
|
57 |
|
58 // ---------------------------------------------------------------------------- |
|
59 // RSIPSecRequestDataField::RSIPSecRequestDataField |
|
60 // ---------------------------------------------------------------------------- |
|
61 // |
|
62 RSIPSecRequestDataField::RSIPSecRequestDataField( TPtrC8 aValue, |
|
63 TBool aNeedsHashing ) : |
|
64 iValue( TPtrC8( aValue ) ), |
|
65 iNeedsHashing( aNeedsHashing ), |
|
66 iBuffer( NULL ) |
|
67 { |
|
68 } |
|
69 |
|
70 // ---------------------------------------------------------------------------- |
|
71 // RSIPSecRequestDataField::RSIPSecRequestDataField |
|
72 // ---------------------------------------------------------------------------- |
|
73 // |
|
74 RSIPSecRequestDataField::RSIPSecRequestDataField( HBufC8* aValue, |
|
75 TBool aNeedsHashing ) : |
|
76 iValue( TPtrC8( aValue->Des() ) ), |
|
77 iNeedsHashing( aNeedsHashing ), |
|
78 iBuffer( aValue ) |
|
79 { |
|
80 } |
|
81 |
|
82 // ---------------------------------------------------------------------------- |
|
83 // RSIPSecRequestDataField::NeedsHashing |
|
84 // ---------------------------------------------------------------------------- |
|
85 // |
|
86 TBool RSIPSecRequestDataField::NeedsHashing() const |
|
87 { |
|
88 return iNeedsHashing; |
|
89 } |
|
90 |
|
91 // ---------------------------------------------------------------------------- |
|
92 // RSIPSecRequestDataField::Value |
|
93 // ---------------------------------------------------------------------------- |
|
94 // |
|
95 TPtrC8 RSIPSecRequestDataField::Value() |
|
96 { |
|
97 return iValue; |
|
98 } |
|
99 |
|
100 // ---------------------------------------------------------------------------- |
|
101 // RSIPSecRequestDataField::Close |
|
102 // ---------------------------------------------------------------------------- |
|
103 // |
|
104 void RSIPSecRequestDataField::Close() |
|
105 { |
|
106 delete iBuffer; |
|
107 iBuffer = NULL; |
|
108 } |
|
109 |
|
110 |
|
111 |
|
112 // ============================ MEMBER FUNCTIONS =============================== |
|
113 |
|
114 // ---------------------------------------------------------------------------- |
|
115 // CSIPSecRequestData::NewL |
|
116 // ---------------------------------------------------------------------------- |
|
117 // |
|
118 CSIPSecRequestData* CSIPSecRequestData::NewL( TSIPSecDigestCtxProcess& aContext, |
|
119 CSIPSecRequestData::TQop aQop ) |
|
120 { |
|
121 CSIPSecRequestData* self = new ( ELeave ) CSIPSecRequestData( aContext, |
|
122 aQop ); |
|
123 CleanupStack::PushL( self ); |
|
124 self->ConstructL(); |
|
125 CleanupStack::Pop( self ); |
|
126 return self; |
|
127 } |
|
128 |
|
129 // ---------------------------------------------------------------------------- |
|
130 // CSIPSecRequestData::CSIPSecRequestData |
|
131 // ---------------------------------------------------------------------------- |
|
132 // |
|
133 CSIPSecRequestData::CSIPSecRequestData( TSIPSecDigestCtxProcess& aContext, |
|
134 CSIPSecRequestData::TQop aQop ) : |
|
135 iDigestContext( aContext ), |
|
136 iIterator( 0 ), |
|
137 iQop( aQop ) |
|
138 { |
|
139 if ( iQop == CSIPSecRequestData::EDoesNotExist ) |
|
140 { |
|
141 //Previously iQop was set to auth-int if qop didn't exist. |
|
142 //But shouldn't it be set to auth, since A2 is calculated differently |
|
143 //for case when qop=auth or unspecified and when qop=auth-int. |
|
144 //(see RFC 2617 3.2.2.3) |
|
145 iQop = CSIPSecRequestData::EAuth; |
|
146 } |
|
147 } |
|
148 |
|
149 // ---------------------------------------------------------------------------- |
|
150 // CSIPSecRequestData::Size |
|
151 // ---------------------------------------------------------------------------- |
|
152 // |
|
153 TInt CSIPSecRequestData::Size() const |
|
154 { |
|
155 return iSize; |
|
156 } |
|
157 |
|
158 // ---------------------------------------------------------------------------- |
|
159 // CSIPSecRequestData::ConstructL |
|
160 // |
|
161 // Calculating A2: |
|
162 // If the "qop" directive's value is "auth" or is unspecified, then A2 is: |
|
163 // A2 = Method ":" digest-uri-value |
|
164 // If the "qop" value is "auth-int", then A2 is: |
|
165 // A2 = Method ":" digest-uri-value ":" H(entity-body) |
|
166 // |
|
167 // Note: if qop was unspecified, "auth" was selected in the constructor. |
|
168 // ---------------------------------------------------------------------------- |
|
169 // |
|
170 void CSIPSecRequestData::ConstructL() |
|
171 { |
|
172 __ASSERT_ALWAYS( iQop != EUnknown ,User::Leave( KErrArgument ) ); |
|
173 |
|
174 const TDesC8& method = iDigestContext.Method(); |
|
175 const TDesC8& requestURI = iDigestContext.DigestURI(); |
|
176 |
|
177 iSize = method.Length() + |
|
178 KSIPSecReqDataSeparator().Length() + |
|
179 requestURI.Length(); |
|
180 if ( iQop != EAuth ) |
|
181 { |
|
182 iSize = iSize + |
|
183 KSIPSecReqDataSeparator().Length() + |
|
184 KSIPSecDigestHashHexSize; |
|
185 } |
|
186 } |
|
187 |
|
188 // ---------------------------------------------------------------------------- |
|
189 // CSIPSecRequestData::Next |
|
190 // ---------------------------------------------------------------------------- |
|
191 // |
|
192 RSIPSecRequestDataField CSIPSecRequestData::NextL() |
|
193 { |
|
194 __ASSERT_ALWAYS( !EndOfData() , User::Leave( KErrGeneral ) ); |
|
195 |
|
196 iIterator++; |
|
197 |
|
198 switch( iIterator ) |
|
199 { |
|
200 case KSSIPSecReqDataMethod: |
|
201 { |
|
202 return RSIPSecRequestDataField ( |
|
203 iDigestContext.Method(), EFalse ); |
|
204 } |
|
205 case KSSIPSecReqDataURI: |
|
206 { |
|
207 return RSIPSecRequestDataField( |
|
208 iDigestContext.DigestURI(), EFalse ); |
|
209 } |
|
210 case KSSIPSecReqDataMessage: |
|
211 { |
|
212 return RSIPSecRequestDataField( |
|
213 iDigestContext.Message(), ETrue ); |
|
214 } |
|
215 default: |
|
216 { |
|
217 User::Leave( KErrGeneral ); |
|
218 } |
|
219 } |
|
220 |
|
221 return RSIPSecRequestDataField(); |
|
222 } |
|
223 |
|
224 // ---------------------------------------------------------------------------- |
|
225 // CSIPSecRequestData::EndOfData |
|
226 // ---------------------------------------------------------------------------- |
|
227 // |
|
228 TBool CSIPSecRequestData::EndOfData() const |
|
229 { |
|
230 if ( iQop == EAuthInt ) |
|
231 { |
|
232 return iIterator >= KSSIPSecReqDataMessage; |
|
233 } |
|
234 |
|
235 return iIterator >= KSSIPSecReqDataURI; |
|
236 } |
|
237 |
|
238 // ---------------------------------------------------------------------------- |
|
239 // CSIPSecRequestData::Separator |
|
240 // ---------------------------------------------------------------------------- |
|
241 // |
|
242 const TDesC8& CSIPSecRequestData::Separator() const |
|
243 { |
|
244 if ( EndOfData() ) |
|
245 { |
|
246 return KNullDesC8; |
|
247 } |
|
248 |
|
249 return KSIPSecReqDataSeparator; |
|
250 } |
|
251 |
|
252 |
|
253 |
|
254 // ============================ MEMBER FUNCTIONS =============================== |
|
255 |
|
256 // ---------------------------------------------------------------------------- |
|
257 // CSIPSecDigestVerifyData::NewL |
|
258 // ---------------------------------------------------------------------------- |
|
259 // |
|
260 CSIPSecDigestVerifyData* |
|
261 CSIPSecDigestVerifyData::NewL( TSIPSecDigestVerifyContext& aContext, |
|
262 CSIPSecRequestData::TQop aQop ) |
|
263 { |
|
264 CSIPSecDigestVerifyData* self = |
|
265 new ( ELeave ) CSIPSecDigestVerifyData( aContext, aQop ); |
|
266 CleanupStack::PushL( self ); |
|
267 self->ConstructL(); |
|
268 CleanupStack::Pop( self ); |
|
269 return self; |
|
270 } |
|
271 |
|
272 // ---------------------------------------------------------------------------- |
|
273 // CSIPSecDigestVerifyData::CSIPSecDigestVerifyData |
|
274 // ---------------------------------------------------------------------------- |
|
275 // |
|
276 CSIPSecDigestVerifyData::CSIPSecDigestVerifyData( |
|
277 TSIPSecDigestVerifyContext& aContext, |
|
278 CSIPSecRequestData::TQop aQop ) : |
|
279 CSIPSecRequestData( aContext, aQop ) |
|
280 { |
|
281 } |
|
282 |
|
283 // ---------------------------------------------------------------------------- |
|
284 // CSIPSecDigestVerifyData::ConstructL |
|
285 // ---------------------------------------------------------------------------- |
|
286 // |
|
287 void CSIPSecDigestVerifyData::ConstructL() |
|
288 { |
|
289 TSIPSecDigestVerifyContext& digestCtx = |
|
290 static_cast<TSIPSecDigestVerifyContext&>( iDigestContext ); |
|
291 |
|
292 const TDesC8& method = iDigestContext.Method(); |
|
293 const TDesC8& requestURI = iDigestContext.DigestURI(); |
|
294 |
|
295 HBufC8* secServerBuf = digestCtx.SecurityServerHeaderL(); |
|
296 __ASSERT_ALWAYS( secServerBuf, User::Leave( KErrArgument ) ); |
|
297 |
|
298 CleanupStack::PushL( secServerBuf ); |
|
299 const TDesC8& secServer = secServerBuf->Des(); |
|
300 |
|
301 if ( iQop == EAuth ) |
|
302 { |
|
303 iSize = KSIPSecReqDataSeparator().Length() * 2; |
|
304 iSize += method.Length() + requestURI.Length() + secServer.Length(); |
|
305 } |
|
306 else |
|
307 { |
|
308 iSize = KSIPSecReqDataSeparator().Length() * 3; |
|
309 iSize += method.Length() + requestURI.Length() + |
|
310 KSIPSecDigestHashHexSize + secServer.Length(); |
|
311 } |
|
312 |
|
313 CleanupStack::PopAndDestroy( secServerBuf ); |
|
314 } |
|
315 |
|
316 // ---------------------------------------------------------------------------- |
|
317 // CSIPSecDigestVerifyData::NextL |
|
318 // |
|
319 // RFC3329 2.2: |
|
320 // If the qop is "auth" or unspecified, then A2 is: |
|
321 // A2 = Method ":" digest-uri-value ":" security-server |
|
322 // |
|
323 // If the "qop" value is "auth-int", then A2 is: |
|
324 // A2 = Method ":" digest-uri-value ":" H(entity-body) ":" security-server |
|
325 // ---------------------------------------------------------------------------- |
|
326 // |
|
327 RSIPSecRequestDataField CSIPSecDigestVerifyData::NextL() |
|
328 { |
|
329 __ASSERT_ALWAYS( !EndOfData() , User::Leave( KErrGeneral ) ); |
|
330 |
|
331 TSIPSecDigestVerifyContext& digestCtx = |
|
332 static_cast<TSIPSecDigestVerifyContext&>( iDigestContext ); |
|
333 |
|
334 switch( ++iIterator ) |
|
335 { |
|
336 case KSSIPSecReqDataMethod: |
|
337 { |
|
338 return RSIPSecRequestDataField( |
|
339 iDigestContext.Method(), EFalse ); |
|
340 } |
|
341 case KSSIPSecReqDataURI: |
|
342 { |
|
343 return RSIPSecRequestDataField( |
|
344 iDigestContext.DigestURI(), EFalse ); |
|
345 } |
|
346 case KSSIPSecReqDataMessage: |
|
347 { |
|
348 if ( iQop == EAuthInt ) |
|
349 { |
|
350 return RSIPSecRequestDataField( |
|
351 iDigestContext.Message(), ETrue ); |
|
352 } |
|
353 |
|
354 return RSIPSecRequestDataField( |
|
355 digestCtx.SecurityServerHeaderL(), EFalse ); |
|
356 } |
|
357 case KSSIPSecReqDataServer: |
|
358 { |
|
359 return RSIPSecRequestDataField( |
|
360 digestCtx.SecurityServerHeaderL(), EFalse ); |
|
361 } |
|
362 default: |
|
363 { |
|
364 User::Leave( KErrGeneral ); |
|
365 } |
|
366 } |
|
367 |
|
368 return RSIPSecRequestDataField(); |
|
369 } |
|
370 |
|
371 // ---------------------------------------------------------------------------- |
|
372 // CSIPSecDigestVerifyData::EndOfData |
|
373 // This function differs from CSIPSecRequestData::EndOfData. |
|
374 // ---------------------------------------------------------------------------- |
|
375 // |
|
376 TBool CSIPSecDigestVerifyData::EndOfData() const |
|
377 { |
|
378 if ( iQop == EAuthInt ) |
|
379 { |
|
380 return iIterator >= KSSIPSecReqDataServer; |
|
381 } |
|
382 |
|
383 return iIterator >= KSSIPSecReqDataMessage; |
|
384 } |