|
1 /* |
|
2 * Copyright (c) 2003-2008 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: This class handles all client requests. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // INCLUDE FILES |
|
20 #include <s32file.h> |
|
21 #include <f32file.h> |
|
22 #include <symmetric.h> |
|
23 #include <rijndael.h> |
|
24 #include <caf/caf.h> |
|
25 #include <x509keys.h> |
|
26 #include <asn1dec.h> |
|
27 #include <dcfrep.h> |
|
28 |
|
29 #include <e32math.h> |
|
30 #include <utf.h> |
|
31 |
|
32 #include <SysUtil.h> // Disk space checking |
|
33 |
|
34 #ifdef RD_MULTIPLE_DRIVE |
|
35 #include <DriveInfo.h> |
|
36 #endif |
|
37 |
|
38 #include "Oma2Agent.h" |
|
39 #include "DRMPermission.h" |
|
40 #include "DRMDbSession.h" |
|
41 #include "drmengineclientserver.h" |
|
42 #include "DRMRightsServer.h" |
|
43 #include "RoapStorageClient.h" |
|
44 #include "OmaCrypto.h" |
|
45 #include "CmlaCrypto.h" |
|
46 #include "DrmKeyStorage.h" |
|
47 #include "drmrightsdb.h" |
|
48 #include "drmparentstorage.h" |
|
49 #include "DrmDomainContext.h" |
|
50 #include "DrmRiContext.h" |
|
51 #include "drmenginetypedefs.h" |
|
52 #include "DRMXOma.h" |
|
53 |
|
54 #include "DRMNotifier.h" |
|
55 #include "DRMEventAddRemove.h" |
|
56 #include "DRMEventModify.h" |
|
57 #include "DRMRightsCleaner.h" |
|
58 #include "DRMActiveOperation.h" |
|
59 #include "drmconsume.h" |
|
60 #include "drmlog.h" |
|
61 #include "drmpointerarray.h" |
|
62 #include "base64.h" |
|
63 |
|
64 #ifdef RD_DRM_METERING |
|
65 #include "drmmeteringdbdata.h" |
|
66 #endif |
|
67 |
|
68 // NAMESPACES |
|
69 using namespace DRMEngine; |
|
70 |
|
71 // EXTERNAL DATA STRUCTURES |
|
72 // EXTERNAL FUNCTION PROTOTYPES |
|
73 // CONSTANTS |
|
74 |
|
75 // MACROS |
|
76 #define REPLAYCACHE reinterpret_cast< CDRMRightsServer* >\ |
|
77 (const_cast<CServer2*>(Server()))->ReplayCache() |
|
78 #define DRMDB ( ( CDRMRightsServer* )( Server() ) )->Database() |
|
79 #ifdef RD_DRM_METERING |
|
80 #define METERINGDB reinterpret_cast< CDRMRightsServer* >\ |
|
81 (const_cast<CServer2*>(Server()))->MeteringDatabase() |
|
82 #endif |
|
83 #define RFSSESSION ( ( CDRMRightsServer* )( Server() ) )->FileServerSession() |
|
84 #define DRMNOTIFIER ( ( CDRMRightsServer* )( Server() ) )->Notifier() |
|
85 #define XOMAHEADER ( ( CDRMRightsServer* )( Server() ) )->XOmaHeaders() |
|
86 #define IMEI ( ( CDRMRightsServer* )( Server() ) )->GetIMEIL() |
|
87 #define IMSI ( ( CDRMRightsServer* )( Server() ) )->GetIMSIL() |
|
88 #define SERVER reinterpret_cast< CDRMRightsServer* >\ |
|
89 (const_cast<CServer2*>(Server())) |
|
90 |
|
91 #define IPCREAD0L( a ) aMessage.ReadL( 0, a ) |
|
92 #define IPCREAD1L( a ) aMessage.ReadL( 1, a ) |
|
93 #define IPCREAD2L( a ) aMessage.ReadL( 2, a ) |
|
94 #define IPCREAD3L( a ) aMessage.ReadL( 3, a ) |
|
95 #define IPCWRITE0L( a ) aMessage.WriteL( 0, a ) |
|
96 #define IPCWRITE1L( a ) aMessage.WriteL( 1, a ) |
|
97 #define IPCWRITE2L( a ) aMessage.WriteL( 2, a ) |
|
98 #define IPCWRITE3L( a ) aMessage.WriteL( 3, a ) |
|
99 #define IPCGETDESLEN0 aMessage.GetDesLength( 0 ) |
|
100 #define IPCGETDESLEN1 aMessage.GetDesLength( 1 ) |
|
101 #define IPCGETDESLEN2 aMessage.GetDesLength( 2 ) |
|
102 #define IPCGETDESLEN3 aMessage.GetDesLength( 3 ) |
|
103 #define IPCGETDESMAXLEN0 aMessage.GetDesMaxLength( 0 ) |
|
104 #define IPCGETDESMAXLEN1 aMessage.GetDesMaxLength( 1 ) |
|
105 #define IPCGETDESMAXLEN2 aMessage.GetDesMaxLength( 2 ) |
|
106 #define IPCGETDESMAXLEN3 aMessage.GetDesMaxLength( 3 ) |
|
107 |
|
108 // LOCAL CONSTANTS AND MACROS |
|
109 |
|
110 #ifdef RD_MULTIPLE_DRIVE |
|
111 |
|
112 _LIT( KDbTempPath, "%c:\\system\\temp\\" ); |
|
113 _LIT( KTimedReplayCacheFile, "%c:\\private\\101F51F2\\timererc.dat" ); |
|
114 _LIT( KPlainReplayCacheFile, "%c:\\private\\101F51F2\\plainrc.dat" ); |
|
115 #ifdef RD_DRM_METERING |
|
116 _LIT( KMeteringDataBaseFile, "%c:\\private\\101F51F2\\meterdb.dat" ); |
|
117 #endif |
|
118 |
|
119 #else |
|
120 |
|
121 _LIT( KTimedReplayCacheFile, "c:\\private\\101F51F2\\timererc.dat" ); |
|
122 _LIT( KPlainReplayCacheFile, "c:\\private\\101F51F2\\plainrc.dat" ); |
|
123 #ifdef RD_DRM_METERING |
|
124 _LIT( KMeteringDataBaseFile, "c:\\private\\101F51F2\\meterdb.dat" ); |
|
125 #endif |
|
126 |
|
127 #endif |
|
128 |
|
129 |
|
130 const TInt KMicrosecondsToSecond = 1000000; |
|
131 _LIT8( KFLPrefix, "flk" ); |
|
132 _LIT8( KFLLongPrefix, "flk:flk" ); |
|
133 |
|
134 _LIT8( KFLSuffix, "@localhost" ); |
|
135 |
|
136 // These need to be updated if the DRM Filter / Oma1DcfCreator URI's change |
|
137 // IMPORTANT IMPORTANT IMPORTANT |
|
138 _LIT8( KDCMUri, "ldf:31415926535@localhost"); |
|
139 _LIT8( KLDFUri, "flk:flkS60_3_0_Hutchinson_2005"); |
|
140 |
|
141 _LIT8(KTimeStamp, "timeStamp"); |
|
142 #ifdef RD_DRM_METERING |
|
143 _LIT8(KMeteringDelimiter, ":"); |
|
144 _LIT8(KCRLF, "\r\n" ); |
|
145 #endif |
|
146 |
|
147 LOCAL_C const TUint8 KFLPrefixLength = 3; |
|
148 const TUint32 KTrustedShutdownClient = 0x10205CB5; |
|
149 const TUint32 KAppInstSrv = 0x101F875A; |
|
150 |
|
151 |
|
152 const TInt KSanityDataLengthLow = 0; |
|
153 const TInt KSanityDataLengthHigh = 32768; |
|
154 |
|
155 // MODULE DATA STRUCTURES |
|
156 NONSHARABLE_STRUCT( TDeleteFile ) |
|
157 { |
|
158 RFs* iFs; |
|
159 TFileName* iFileName; |
|
160 }; |
|
161 |
|
162 // ============================ auto_handde helper class ======================= |
|
163 //Auto handle for easening handle release on exceptional exit situations |
|
164 template<class T> class auto_handle |
|
165 { |
|
166 public: |
|
167 |
|
168 auto_handle() {} |
|
169 auto_handle(T aHandle) : iHandle( aHandle ) {} |
|
170 auto_handle( auto_handle<T>& aHandle) : iHandle( aHandle.release() ) {} |
|
171 ~auto_handle() { iHandle.Close(); } |
|
172 const T& operator()() const { return iHandle; } |
|
173 T& operator()() { return iHandle; } |
|
174 T get() const { return iHandle; } |
|
175 T release() { T temp = iHandle; iHandle = 0; return temp; } |
|
176 |
|
177 private: |
|
178 T iHandle; |
|
179 }; |
|
180 |
|
181 // DATA TYPES |
|
182 // LOCAL FUNCTION PROTOTYPES |
|
183 LOCAL_C void DeleteFile( TAny* aHandle ); |
|
184 LOCAL_C void DeleteObject( TAny* aObject ); |
|
185 LOCAL_C TTime EndTime( const TTime& aTime1, const TTime& aTime2 ); |
|
186 |
|
187 // FORWARD DECLARATIONS |
|
188 LOCAL_C void ModifyRightsObjectByTimeL( CDRMPermission* aRights, |
|
189 TTimeIntervalMicroSeconds& aChange, |
|
190 TBool aModifyInsertionTime ); |
|
191 LOCAL_C void ModifyTimesInListL( CDRMPermissionList* aList, |
|
192 TTimeIntervalMicroSeconds& aChange, |
|
193 TBool aModifyInsertionTime ); |
|
194 |
|
195 LOCAL_C void ModifyConstraintByTime( CDRMConstraint* aConstraint, |
|
196 TTimeIntervalMicroSeconds& aChange ); |
|
197 |
|
198 LOCAL_C TPtrC8 ExtractElement( const TDesC8& aRights, const TDesC8& aElement, |
|
199 TInt& aOffset ); |
|
200 |
|
201 LOCAL_C TTime Iso8601ToTime( TDesC8& aTimeString ); |
|
202 |
|
203 // ============================= LOCAL FUNCTIONS ============================== |
|
204 |
|
205 // ----------------------------------------------------------------------------- |
|
206 // SanitizeL |
|
207 // Performs a sanity check on length parameters |
|
208 // ----------------------------------------------------------------------------- |
|
209 // |
|
210 LOCAL_C void SanitizeL( TInt aParam ) |
|
211 { |
|
212 if( aParam <= KSanityDataLengthLow || aParam > KSanityDataLengthHigh ) |
|
213 { |
|
214 User::Leave(KErrArgument); |
|
215 } |
|
216 } |
|
217 |
|
218 |
|
219 LOCAL_C void ModifyTimesInListL( CDRMPermissionList* aList, |
|
220 TTimeIntervalMicroSeconds& aChange, |
|
221 TBool aModifyInsertionTime ) |
|
222 { |
|
223 TInt i = 0; |
|
224 |
|
225 // Go through the whole list and run the modification for all objects |
|
226 for( i = 0; i < aList->Count(); i++ ) |
|
227 { |
|
228 // Call modification for each rights object in the list |
|
229 ModifyRightsObjectByTimeL( (*aList)[i], aChange, aModifyInsertionTime ); |
|
230 } |
|
231 }; |
|
232 |
|
233 LOCAL_C void ModifyRightsObjectByTimeL( CDRMPermission* aRights, |
|
234 TTimeIntervalMicroSeconds& aChange, |
|
235 TBool aModifyInsertionTime ) |
|
236 { |
|
237 |
|
238 // If original insertion time exists and we want to change it, change it |
|
239 if ( aModifyInsertionTime && aRights->iOriginalInsertTime != Time::NullTTime() ) |
|
240 { |
|
241 aRights->iOriginalInsertTime += aChange; |
|
242 } |
|
243 |
|
244 if ( aRights->iAvailableRights & ERightsTopLevel ) |
|
245 { |
|
246 ModifyConstraintByTime( aRights->iTopLevel, aChange ); |
|
247 } |
|
248 |
|
249 // If play rights are available, check if they need to be changed |
|
250 if ( aRights->iAvailableRights & ERightsPlay ) |
|
251 { |
|
252 ModifyConstraintByTime( aRights->iPlay, aChange ); |
|
253 } |
|
254 |
|
255 // If display rights are available, check if they need to be changed |
|
256 if ( aRights->iAvailableRights & ERightsDisplay ) |
|
257 { |
|
258 ModifyConstraintByTime( aRights->iDisplay, aChange ); |
|
259 } |
|
260 |
|
261 // If execute rights are available, check if they need to be changed |
|
262 if ( aRights->iAvailableRights & ERightsExecute ) |
|
263 { |
|
264 ModifyConstraintByTime( aRights->iExecute, aChange ); |
|
265 } |
|
266 |
|
267 // If print rights are available, check if they need to be changed |
|
268 if ( aRights->iAvailableRights & ERightsPrint ) |
|
269 { |
|
270 ModifyConstraintByTime( aRights->iPrint, aChange ); |
|
271 } |
|
272 |
|
273 }; |
|
274 |
|
275 LOCAL_C void ModifyConstraintByTime( |
|
276 CDRMConstraint* aConstraint, |
|
277 TTimeIntervalMicroSeconds& aChange ) |
|
278 { |
|
279 // if start time exists, modify it |
|
280 if ( aConstraint->iActiveConstraints & EConstraintStartTime ) |
|
281 { |
|
282 aConstraint->iStartTime += aChange; |
|
283 } |
|
284 |
|
285 // if end time exists, modify it |
|
286 if ( aConstraint->iActiveConstraints & EConstraintEndTime ) |
|
287 { |
|
288 aConstraint->iEndTime += aChange; |
|
289 } |
|
290 |
|
291 // if activated interval exists, modify it |
|
292 if ( aConstraint->iActiveConstraints & EConstraintInterval && |
|
293 aConstraint->iIntervalStart != Time::NullTTime() ) |
|
294 { |
|
295 aConstraint->iIntervalStart += aChange; |
|
296 } |
|
297 }; |
|
298 |
|
299 LOCAL_C TPtrC8 ExtractElement( const TDesC8& aRights, |
|
300 const TDesC8& aElement, |
|
301 TInt& aOffset ) |
|
302 { |
|
303 DRMLOG( _L("CDRMDbSession::ExtractElement") ); |
|
304 |
|
305 TPtrC8 temp( KNullDesC8 ); |
|
306 TInt startPos = ( 0 ); |
|
307 TInt endPos = ( 0 ); |
|
308 TInt ret( 0 ); |
|
309 TInt startLength ( 0 ); |
|
310 |
|
311 auto_handle< RBuf8 > tagToBeFound; |
|
312 // Must be nonleaving since this function is nonleaving |
|
313 ret = tagToBeFound().Create( aElement.Length() + 3 ); // max "</" aElement ">" |
|
314 if ( ret != KErrNone ) |
|
315 { |
|
316 aOffset = -1; |
|
317 return KNullDesC8(); |
|
318 } |
|
319 |
|
320 // First we try to find the start tag (as localname) |
|
321 tagToBeFound().SetLength( 0 ); |
|
322 tagToBeFound().AppendFormat( _L8( "<%S" ), &aElement ); |
|
323 |
|
324 temp.Set( aRights.Mid( aOffset ) ); |
|
325 |
|
326 startPos = temp.Find( tagToBeFound() ); |
|
327 |
|
328 startLength = tagToBeFound().Length(); |
|
329 startPos += aOffset; |
|
330 temp.Set( aRights.Mid( startPos + startLength ) ); |
|
331 |
|
332 // Now find the end of the start tag |
|
333 tagToBeFound().SetLength( 0 ); |
|
334 tagToBeFound().Append( _L8( ">" ) ); // '>' as last |
|
335 |
|
336 // Define the starting point of the data after the start tag |
|
337 // and skip the '>' mark. |
|
338 startPos = startPos + startLength + temp.Find( tagToBeFound() ) + 1; |
|
339 |
|
340 temp.Set( aRights.Mid( startPos ) ); |
|
341 |
|
342 // Finally find the start of the end tag |
|
343 tagToBeFound().SetLength( 0 ); |
|
344 tagToBeFound().AppendFormat( _L8( "</%S" ), &aElement ); |
|
345 |
|
346 endPos = startPos + temp.Find(tagToBeFound() ); |
|
347 |
|
348 if ( endPos < startPos ) |
|
349 { |
|
350 aOffset = -1; |
|
351 return KNullDesC8(); |
|
352 } |
|
353 |
|
354 temp.Set( aRights.Mid(startPos, endPos - startPos) ); |
|
355 |
|
356 aOffset = endPos; |
|
357 DRMLOG2( _L( "Calculated length %d" ), endPos - startPos); |
|
358 DRMLOG( _L( "Extracted element" ) ); |
|
359 |
|
360 //auto_handle closes and frees allocated resources |
|
361 return temp; |
|
362 }; |
|
363 |
|
364 LOCAL_C TTime Iso8601ToTime( TDesC8& aTimeString ) |
|
365 { |
|
366 |
|
367 DRMLOG( _L("CDRMDbSession::Iso8601ToTime") ); |
|
368 |
|
369 TLex8 lex; |
|
370 TInt year = 0; |
|
371 TInt month = 0; |
|
372 TInt day = 0; |
|
373 TInt hour = 0; |
|
374 TInt minute = 0; |
|
375 TInt second = 0; |
|
376 TTime r = Time::NullTTime(); |
|
377 TLocale l; |
|
378 TTimeIntervalSeconds offset(l.UniversalTimeOffset()); |
|
379 |
|
380 if (aTimeString.Length() > 0) |
|
381 { |
|
382 lex = aTimeString; |
|
383 lex.Val(year); |
|
384 lex.Inc(); |
|
385 lex.Val(month); |
|
386 lex.Inc(); |
|
387 lex.Val(day); |
|
388 lex.Inc(); |
|
389 lex.Val(hour); |
|
390 lex.Inc(); |
|
391 lex.Val(minute); |
|
392 lex.Inc(); |
|
393 lex.Val(second); |
|
394 r = TTime(TDateTime(year, static_cast<TMonth>(month - 1), day - 1, |
|
395 hour, minute, second, 0)); |
|
396 if (lex.Get() != 'Z') |
|
397 { |
|
398 r += offset; |
|
399 } |
|
400 } |
|
401 return r; |
|
402 } |
|
403 |
|
404 #ifdef RD_DRM_METERING |
|
405 LOCAL_C HBufC8* CreateMeteringDataL( CDRMPointerArray<CDrmMeteringDbData>* meteringArray ) |
|
406 { |
|
407 // Calculate buffer size of cipher data |
|
408 TInt size( sizeof( KCRLF ) ); |
|
409 HBufC8* cipherData = NULL; |
|
410 TPtr8 ptr( NULL, 0 ); |
|
411 |
|
412 _LIT8( KElementStart, "<rawMeteringReportData>"); |
|
413 _LIT8( KElementEnd, "</rawMeteringReportData>"); |
|
414 |
|
415 size = KElementStart().Size() + KElementEnd().Size(); |
|
416 |
|
417 for( TUint i(0); i < meteringArray->Count(); i++ ) |
|
418 { |
|
419 size += sizeof( ( *meteringArray)[i]->iContentId ); |
|
420 if ( (*meteringArray)[i]->iParentUid && |
|
421 (*meteringArray)[i]->iParentUid->Size() ) |
|
422 { |
|
423 size += (*meteringArray)[i]->iParentUid->Size() + 1; |
|
424 } |
|
425 switch( (*meteringArray)[i]->iPermission ) |
|
426 { |
|
427 case EPlay: |
|
428 size += 4; |
|
429 break; |
|
430 case EView: |
|
431 case EExecute: |
|
432 size += 7; |
|
433 break; |
|
434 case EPrint: |
|
435 size+= 5; |
|
436 break; |
|
437 default: |
|
438 break; // Not a valid permission |
|
439 } |
|
440 size += (*meteringArray)[i]->iContentId->Size(); |
|
441 size += sizeof( (*meteringArray)[i]->iAccumulatedTime.Int() / 60 ); |
|
442 size += sizeof( (*meteringArray)[i]->iAccumulatedTime.Int() % 60 ); |
|
443 if( ( ( *meteringArray)[i]->iAccumulatedTime.Int() % 60 ) < 10 ) |
|
444 { |
|
445 size++; //for precending zero for seconds.. |
|
446 } |
|
447 size += sizeof( ( *meteringArray)[i]->iCount ); |
|
448 size += 4 * sizeof( KMeteringDelimiter ); // ":" -delimiter |
|
449 size += sizeof( KCRLF ); |
|
450 } |
|
451 |
|
452 cipherData = HBufC8::NewLC( size ); |
|
453 ptr.Set( cipherData->Des() ); |
|
454 ptr.Append( KElementStart ); |
|
455 |
|
456 for( TUint i(0); i < meteringArray->Count(); i++ ) |
|
457 { |
|
458 ptr.Append( KCRLF ); |
|
459 if ( (*meteringArray)[i]->iParentUid && |
|
460 (*meteringArray)[i]->iParentUid->Size() ) |
|
461 { |
|
462 ptr.Append( *(*meteringArray)[i]->iParentUid ); |
|
463 ptr.Append( _L(";") ); |
|
464 } |
|
465 ptr.Append( *(*meteringArray)[i]->iContentId ); |
|
466 ptr.Append( KMeteringDelimiter ); |
|
467 switch( (*meteringArray)[i]->iPermission ) |
|
468 { |
|
469 case EPlay: |
|
470 ptr.Append( _L("play") ); |
|
471 break; |
|
472 case EView: |
|
473 ptr.Append( _L("display") ); |
|
474 break; |
|
475 case EExecute: |
|
476 ptr.Append( _L("execute") ); |
|
477 break; |
|
478 case EPrint: |
|
479 ptr.Append( _L("print") ); |
|
480 break; |
|
481 default: |
|
482 break; // Not a valid permission |
|
483 } // export not supported |
|
484 ptr.Append( KMeteringDelimiter ); |
|
485 ptr.AppendNum( (*meteringArray)[i]->iCount ); |
|
486 ptr.Append( KMeteringDelimiter ); |
|
487 ptr.AppendNum( (*meteringArray)[i]->iAccumulatedTime.Int() / 60 ); |
|
488 ptr.Append( KMeteringDelimiter ); |
|
489 if( ( ( *meteringArray)[i]->iAccumulatedTime.Int() % 60 ) < 10 ) |
|
490 { |
|
491 ptr.AppendNum( 0 ); //precending zero for seconds.. |
|
492 } |
|
493 ptr.AppendNum( (*meteringArray)[i]->iAccumulatedTime.Int() % 60 ); |
|
494 } |
|
495 ptr.Append( KCRLF ); |
|
496 ptr.Append( KElementEnd ); |
|
497 CleanupStack::Pop( cipherData ); |
|
498 return cipherData; |
|
499 } |
|
500 #endif |
|
501 |
|
502 // ---------------------------------------------------------------------------- |
|
503 // DeleteFile |
|
504 // Deletes the file by TFileName presented by aHandle |
|
505 // ---------------------------------------------------------------------------- |
|
506 // |
|
507 void DeleteFile( TAny* aHandle ) |
|
508 { |
|
509 __ASSERT_DEBUG( aHandle, User::Panic( _L( "DeleteFile" ), KErrArgument ) ); |
|
510 TDeleteFile* handle = reinterpret_cast< TDeleteFile* >( aHandle ); |
|
511 |
|
512 handle->iFs->Delete( *( handle->iFileName ) ); |
|
513 } |
|
514 |
|
515 // ---------------------------------------------------------------------------- |
|
516 // DeleteObject |
|
517 // Deletes the file by TFileName presented by aHandle |
|
518 // ---------------------------------------------------------------------------- |
|
519 // |
|
520 void DeleteObject( TAny* aObject ) |
|
521 { |
|
522 __ASSERT_DEBUG( aObject, User::Panic( _L( "DeleteObject" ), KErrArgument ) ); |
|
523 MDrmKeyStorage* object = reinterpret_cast< MDrmKeyStorage* >( aObject ); |
|
524 delete object; |
|
525 object = NULL; |
|
526 } |
|
527 |
|
528 |
|
529 // ---------------------------------------------------------------------------- |
|
530 // EndTime |
|
531 // Calculate the true end time: pick the smaller one of aTime1 & aTime2, |
|
532 // but ignore Time::NullTTime anyhow. |
|
533 // ---------------------------------------------------------------------------- |
|
534 // |
|
535 TTime EndTime( const TTime& aTime1, const TTime& aTime2 ) |
|
536 { |
|
537 TTime nullTime = Time::NullTTime(); |
|
538 |
|
539 if ( aTime1 == nullTime ) |
|
540 { |
|
541 return aTime2; |
|
542 } |
|
543 |
|
544 if ( aTime2 == nullTime ) |
|
545 { |
|
546 return aTime1; |
|
547 } |
|
548 |
|
549 return Min( aTime1, aTime2 ); |
|
550 } |
|
551 |
|
552 // ============================ MEMBER FUNCTIONS ============================== |
|
553 // ---------------------------------------------------------------------------- |
|
554 // CDRMRightsServer::NewLC |
|
555 // Two-phased constructor. |
|
556 // ---------------------------------------------------------------------------- |
|
557 // |
|
558 CDRMDbSession* CDRMDbSession::NewL() |
|
559 { |
|
560 CDRMDbSession* self = new( ELeave ) CDRMDbSession(); |
|
561 |
|
562 CleanupStack::PushL( self ); |
|
563 self->ConstructL(); |
|
564 CleanupStack::Pop( self ); |
|
565 return self; |
|
566 } |
|
567 |
|
568 // ---------------------------------------------------------------------------- |
|
569 // CDRMRightsServer::~CDRMDbSession |
|
570 // Destructor. |
|
571 // ---------------------------------------------------------------------------- |
|
572 // |
|
573 CDRMDbSession::~CDRMDbSession() |
|
574 { |
|
575 DRMLOG( _L( "CDRMDbSession::~" ) ); |
|
576 delete iPreparedData; |
|
577 iPreparedData = NULL; |
|
578 |
|
579 delete iWidePreparedData; |
|
580 iWidePreparedData = NULL; |
|
581 |
|
582 delete iFileName; |
|
583 iFileName = NULL; |
|
584 |
|
585 if ( iPendingRequest ) |
|
586 { |
|
587 delete iPendingRequest; |
|
588 } |
|
589 |
|
590 delete iContentId; |
|
591 iContentId = NULL; |
|
592 |
|
593 iClient.Close(); |
|
594 |
|
595 iCek = KNullDesC8; |
|
596 iCek.FillZ(); |
|
597 |
|
598 delete iConsume; |
|
599 iRoapClient.Close(); |
|
600 } |
|
601 |
|
602 // ---------------------------------------------------------------------------- |
|
603 // CDRMRightsServer::CDRMDbSession |
|
604 // Default constructor. |
|
605 // ---------------------------------------------------------------------------- |
|
606 // |
|
607 CDRMDbSession::CDRMDbSession(): |
|
608 iCredentialsChecked(ENotChecked), |
|
609 iContentId(NULL) |
|
610 { |
|
611 iRek.SetLength( 0 ); |
|
612 } |
|
613 |
|
614 |
|
615 // ---------------------------------------------------------------------------- |
|
616 // CDRMDbSession::RoapClient |
|
617 // Returns a handle to the Roap client |
|
618 // ---------------------------------------------------------------------------- |
|
619 Roap::RRoapStorageClient& CDRMDbSession::RoapClient() |
|
620 { |
|
621 return iRoapClient; |
|
622 } |
|
623 |
|
624 // ---------------------------------------------------------------------------- |
|
625 // CDRMRightsServer::ServiceL |
|
626 // Forwards requests from clients to helper methods. |
|
627 // ---------------------------------------------------------------------------- |
|
628 // |
|
629 void CDRMDbSession::ServiceL( const RMessage2& aMessage ) |
|
630 { |
|
631 DRMLOG( _L( "CDRMDbSession::ServiceL" ) ); |
|
632 DRMLOG2( _L( "Message Handle: %08x"), aMessage.Handle() ); |
|
633 |
|
634 // Close the client before opening a new connection over it to avoid |
|
635 // leaking memory in the kernel side |
|
636 iClient.Close(); |
|
637 |
|
638 aMessage.ClientL( iClient ); |
|
639 |
|
640 // This function call is TRAPped by framework, and message is completed |
|
641 // with the error in case of leaving operation. |
|
642 switch ( aMessage.Function() ) |
|
643 { |
|
644 case EAddRecord: |
|
645 AddRecordL( aMessage, ENoProtection ); |
|
646 break; |
|
647 |
|
648 case EAddProtectedRecord: |
|
649 AddRecordL( aMessage, EPublicKey ); |
|
650 break; |
|
651 |
|
652 case EAddDomainRecord: |
|
653 AddRecordL( aMessage, EDomainKey ); |
|
654 break; |
|
655 |
|
656 case EGetDbEntry: |
|
657 GetRecordL( aMessage ); |
|
658 break; |
|
659 |
|
660 case EGetEntryList: |
|
661 GetEntryListL( aMessage ); |
|
662 break; |
|
663 |
|
664 case EDeleteWithCID: |
|
665 DeleteL( aMessage ); |
|
666 break; |
|
667 |
|
668 case EDeleteRO: |
|
669 DeleteRecordL( aMessage ); |
|
670 break; |
|
671 |
|
672 case EExportCIDs: |
|
673 ExportCIDsL( aMessage ); |
|
674 break; |
|
675 |
|
676 case EGetKey: |
|
677 GetKeyL( aMessage ); |
|
678 break; |
|
679 |
|
680 case ECheckRights: |
|
681 CheckRightsL( aMessage ); |
|
682 break; |
|
683 |
|
684 case ECount: |
|
685 CountL( aMessage ); |
|
686 break; |
|
687 |
|
688 case EDeleteAll: |
|
689 DeleteAllL( aMessage ); |
|
690 break; |
|
691 |
|
692 case EConsume: |
|
693 ConsumeL( aMessage ); |
|
694 break; |
|
695 |
|
696 case ECheckConsume: |
|
697 CheckConsumeL( aMessage ); |
|
698 break; |
|
699 |
|
700 case ECalculatePadding: |
|
701 CalculatePaddingL( aMessage); |
|
702 break; |
|
703 |
|
704 case ESecureTime: |
|
705 SecureTimeL( aMessage ); |
|
706 break; |
|
707 |
|
708 case EGetPreparedData: |
|
709 GetPreparedDataL( aMessage ); |
|
710 break; |
|
711 |
|
712 case EAddDomainRO: |
|
713 AddDomainROL( aMessage ); |
|
714 break; |
|
715 |
|
716 case EGetDomainRO: |
|
717 GetDomainROL( aMessage ); |
|
718 break; |
|
719 |
|
720 case EDeleteDomainRO: |
|
721 DeleteDomainROL( aMessage ); |
|
722 break; |
|
723 |
|
724 case EIsInCache: |
|
725 IsInCacheL( aMessage ); |
|
726 break; |
|
727 |
|
728 case EAddToCache: |
|
729 AddToCacheL( aMessage ); |
|
730 break; |
|
731 |
|
732 case EDecrypt: |
|
733 DecryptL( aMessage ); |
|
734 break; |
|
735 |
|
736 case EEncrypt: |
|
737 EncryptL( aMessage ); |
|
738 break; |
|
739 |
|
740 case EInitializeKey: |
|
741 InitializeKeyL( aMessage ); |
|
742 break; |
|
743 |
|
744 case EInitializeGroupKey: |
|
745 InitializeGroupKeyL( aMessage ); |
|
746 break; |
|
747 |
|
748 case EGetDomainRoForCid: |
|
749 GetDomainRosForCidL( aMessage ); |
|
750 break; |
|
751 |
|
752 case EDeleteExpired: |
|
753 DeleteExpiredPermissionsL( aMessage ); |
|
754 break; |
|
755 |
|
756 case ESetEstimatedArrival: |
|
757 SetEstimatedArrivalL( aMessage ); |
|
758 break; |
|
759 |
|
760 case EGetEstimatedArrival: |
|
761 GetEstimatedArrivalL( aMessage ); |
|
762 break; |
|
763 |
|
764 case ESetName: |
|
765 SetNameL( aMessage ); |
|
766 break; |
|
767 |
|
768 case EGetName: |
|
769 GetNameL( aMessage ); |
|
770 break; |
|
771 |
|
772 case EGetWideData: |
|
773 GetWideDataL( aMessage ); |
|
774 break; |
|
775 |
|
776 case ECancel: |
|
777 Cancel( aMessage ); |
|
778 break; |
|
779 |
|
780 case EGetUdtData: |
|
781 GetUdtDataL( aMessage ); |
|
782 break; |
|
783 |
|
784 case EInitiateUdt: |
|
785 InitiateUdtL( aMessage ); |
|
786 break; |
|
787 |
|
788 case EInitOrphanedList: |
|
789 InitExportOrphanedCIDsL( aMessage ); |
|
790 break; |
|
791 |
|
792 case EGetOrphanedList: |
|
793 ExportOrphanedCIDsL( aMessage ); |
|
794 break; |
|
795 |
|
796 case EGetFLUri: |
|
797 GetFLUriL( aMessage ); |
|
798 break; |
|
799 |
|
800 case EEncodeRightsIssuerField: |
|
801 EncodeRightsIssuerL( aMessage ); |
|
802 break; |
|
803 |
|
804 case EDecodeRightsIssuerField: |
|
805 DecodeRightsIssuerL( aMessage ); |
|
806 break; |
|
807 |
|
808 case ESetAuthenticationSeed: |
|
809 SetAuthenticationSeedL( aMessage ); |
|
810 break; |
|
811 |
|
812 case EGetAuthenticationSeed: |
|
813 GetAuthenticationSeedL( aMessage ); |
|
814 break; |
|
815 |
|
816 case EVerifyMac: |
|
817 VerifyMacL( aMessage ); |
|
818 break; |
|
819 |
|
820 case EGetSupportedIndividuals: |
|
821 GetSupportedIndividualsL( aMessage ); |
|
822 break; |
|
823 |
|
824 case EStopWatching: |
|
825 StopWatchingL( aMessage ); |
|
826 break; |
|
827 |
|
828 case EUnwrapDeviceMacAndRek: |
|
829 UnwrapMacAndRekL( aMessage, EFalse ); |
|
830 break; |
|
831 |
|
832 case EUnwrapDomainMacAndRek: |
|
833 UnwrapMacAndRekL( aMessage, ETrue ); |
|
834 break; |
|
835 |
|
836 case EGetRandomData: |
|
837 GetRandomDataL( aMessage ); |
|
838 break; |
|
839 |
|
840 case EGetMeteringData: |
|
841 GetMeteringDataL( aMessage ); |
|
842 break; |
|
843 |
|
844 case EDeleteMeteringData: |
|
845 DeleteMeteringDataL( aMessage ); |
|
846 break; |
|
847 |
|
848 default: |
|
849 DRMLOG( _L( "CDRMDbSession::DispatchL: Invalid command" ) ); |
|
850 User::Leave( KErrNotSupported ); |
|
851 } |
|
852 |
|
853 // The message has already completed successfully. |
|
854 DRMLOG2( _L( "CDRMDbSession::ServiceL ok (%08x)"), aMessage.Handle() ); |
|
855 } |
|
856 |
|
857 // ---------------------------------------------------------------------------- |
|
858 // CDRMRightsServer::ServiceError |
|
859 // Completes the request with given error code if the request is still pending. |
|
860 // ---------------------------------------------------------------------------- |
|
861 // |
|
862 void CDRMDbSession::ServiceError( const RMessage2& aMessage, TInt aError ) |
|
863 { |
|
864 DRMLOG2( _L( "CDRMDbSession::ServiceError: error %d" ), aError ); |
|
865 |
|
866 if ( !aMessage.IsNull() ) |
|
867 { |
|
868 aMessage.Complete( aError ); |
|
869 } |
|
870 } |
|
871 |
|
872 // ----------------------------------------------------------------------------- |
|
873 // CDRMRightsServer::ConstructL |
|
874 // Second phase constructor. |
|
875 // ----------------------------------------------------------------------------- |
|
876 // |
|
877 void CDRMDbSession::ConstructL() |
|
878 { |
|
879 iRoapClientConnected = EFalse; |
|
880 } |
|
881 |
|
882 // ----------------------------------------------------------------------------- |
|
883 // CDRMRightsServer::AddRecord |
|
884 // Get the information from the client, construct a rights object, and add |
|
885 // it to the database. |
|
886 // ----------------------------------------------------------------------------- |
|
887 // |
|
888 void CDRMDbSession::AddRecordL( |
|
889 const RMessage2& aMessage, |
|
890 TProtectionType aProtection ) |
|
891 { |
|
892 DRMLOG( _L( "CDRMDbSession::AddRecordL" ) ); |
|
893 //__UHEAP_MARK; |
|
894 |
|
895 CDRMPermission* permission = NULL; |
|
896 HBufC8* wrappedcek = NULL; |
|
897 HBufC8* cek = NULL; |
|
898 HBufC8* CID = NULL; |
|
899 HBufC8* rightsData = NULL; |
|
900 TInt size = 0; |
|
901 TPtr8 data( NULL, 0 ); |
|
902 TDRMUniqueID UID; |
|
903 |
|
904 |
|
905 CDRMEventAddRemove* event = CDRMEventAddRemove::NewLC( ERightsObjectRecieved ); |
|
906 TRequestStatus status; |
|
907 |
|
908 SanitizeL( aMessage.GetDesLength(0) ); |
|
909 SanitizeL( aMessage.GetDesLength(1) ); |
|
910 |
|
911 size = User::LeaveIfError( IPCGETDESLEN1 ); |
|
912 rightsData = HBufC8::NewMaxLC( size ); |
|
913 data.Set( const_cast< TUint8* >( rightsData->Ptr() ), 0, size ); |
|
914 IPCREAD1L( data ); |
|
915 permission = CDRMPermission::NewLC(); |
|
916 permission->ImportL( data ); |
|
917 |
|
918 UpdateSecureTime(); |
|
919 |
|
920 // Determine whether the RO is legal. |
|
921 if ( ( ( permission->iAvailableRights & ERightsPlay ) && |
|
922 ( Invalid( *permission->iPlay ) ) ) || |
|
923 ( ( permission->iAvailableRights & ERightsDisplay ) && |
|
924 ( Invalid( *permission->iDisplay ) ) ) || |
|
925 ( ( permission->iAvailableRights & ERightsExecute ) && |
|
926 ( Invalid( *permission->iExecute ) ) ) || |
|
927 ( ( permission->iAvailableRights & ERightsPrint ) && |
|
928 ( Invalid( *permission->iPrint ) ) ) || |
|
929 ( ( permission->iAvailableRights & ERightsTopLevel ) && |
|
930 ( Invalid( *permission->iTopLevel ) ) ) ) |
|
931 { |
|
932 User::Leave( ENoRights ); |
|
933 } |
|
934 |
|
935 size = User::LeaveIfError( IPCGETDESLEN0 ); |
|
936 CID = HBufC8::NewLC( size ); |
|
937 |
|
938 size = User::LeaveIfError( IPCGETDESLEN2 ); |
|
939 |
|
940 // Always reserve enough space for a key, if it's 0 then it is, length will be as well. |
|
941 size = size > KDCFKeySize ? size : KDCFKeySize; |
|
942 if( size > KSanityDataLengthHigh ) |
|
943 { |
|
944 User::Leave(KErrArgument); |
|
945 } |
|
946 wrappedcek = HBufC8::NewLC( size ); |
|
947 |
|
948 data.Set( CID->Des() ); |
|
949 IPCREAD0L( data ); |
|
950 |
|
951 data.Set( wrappedcek->Des() ); |
|
952 IPCREAD2L( data ); |
|
953 |
|
954 |
|
955 if ( aProtection != ENoProtection ) |
|
956 { |
|
957 if(!iRek.Length()) |
|
958 { |
|
959 User::Leave(KErrNotReady); |
|
960 } |
|
961 |
|
962 cek = OmaCrypto::AesUnwrapL(iRek, *wrappedcek); |
|
963 CleanupStack::PopAndDestroy( wrappedcek ); |
|
964 CleanupStack::PushL( cek ); |
|
965 } |
|
966 else |
|
967 { |
|
968 cek = wrappedcek; |
|
969 } |
|
970 |
|
971 DRMLOG(_L("CEK:")); |
|
972 DRMLOGHEX(( *cek )); |
|
973 |
|
974 if ( permission->iOriginalInsertTime == Time::NullTTime() ) |
|
975 { |
|
976 permission->iOriginalInsertTime = iTrustedTime; |
|
977 } |
|
978 |
|
979 DRMDB.AddDBEntryL( *CID, *permission, *cek, UID ); |
|
980 |
|
981 // Remove a rights object from the xoma list if it is there |
|
982 RPointerArray<CDRMXOma>& array = XOMAHEADER; |
|
983 TInt i = 0; |
|
984 |
|
985 for( ; i < array.Count(); i++ ) |
|
986 { |
|
987 // if the content id is found, remove it from the list |
|
988 if( !CID->Compare( array[i]->ContentID() ) ) |
|
989 { |
|
990 delete array[i]; |
|
991 array.Remove( i ); |
|
992 break; |
|
993 } |
|
994 } |
|
995 |
|
996 // Write the UID back to the client. |
|
997 data.Set( reinterpret_cast< TUint8* >( &UID ), sizeof( UID ), |
|
998 sizeof( UID ) ); |
|
999 IPCWRITE3L( data ); |
|
1000 |
|
1001 // Notify clients |
|
1002 event->SetContentIDL(CID->Des()); |
|
1003 |
|
1004 DRMNOTIFIER.SendEventL(*event,status); |
|
1005 User::WaitForRequest(status); |
|
1006 |
|
1007 CleanupStack::PopAndDestroy( 5 ); // cek, CID, permission, data, event |
|
1008 |
|
1009 aMessage.Complete( KErrNone ); |
|
1010 |
|
1011 //__UHEAP_MARKEND; |
|
1012 DRMLOG( _L( "CDRMDbSession::AddRecordL done" ) ); |
|
1013 } |
|
1014 |
|
1015 // ----------------------------------------------------------------------------- |
|
1016 // CDRMRightsServer::GetRecordL |
|
1017 // Get record. |
|
1018 // ----------------------------------------------------------------------------- |
|
1019 // |
|
1020 void CDRMDbSession::GetRecordL( const RMessage2& aMessage ) |
|
1021 { |
|
1022 DRMLOG( _L( "CDRMDbSession::GetRecordL" ) ); |
|
1023 |
|
1024 CDRMPermission* object = NULL; |
|
1025 TInt size = 0; |
|
1026 TPckg< TInt > package( size ); |
|
1027 TDRMUniqueID id; |
|
1028 HBufC8* CID = NULL; |
|
1029 TPtr8 data( reinterpret_cast< TUint8* >( &id ), 0, sizeof( id ) ); |
|
1030 |
|
1031 // Cleanup. |
|
1032 if ( iPreparedData ) |
|
1033 { |
|
1034 delete iPreparedData; |
|
1035 iPreparedData = NULL; |
|
1036 } |
|
1037 |
|
1038 IPCREAD2L( data ); |
|
1039 |
|
1040 SanitizeL( aMessage.GetDesLength(3) ); |
|
1041 CID = HBufC8::NewLC( IPCGETDESLEN3 ); |
|
1042 |
|
1043 data.Set( CID->Des() ); |
|
1044 IPCREAD3L( data ); |
|
1045 |
|
1046 object = DRMDB.GetDBEntryByContentIDL( *CID, id ); |
|
1047 CleanupStack::PushL( object ); |
|
1048 |
|
1049 // modify the times in the rights object to UI time |
|
1050 UpdateSecureTime(); |
|
1051 TTime currentTime; |
|
1052 currentTime.HomeTime(); |
|
1053 TTimeIntervalMicroSeconds change = currentTime.Int64() - iTrustedTime.Int64(); |
|
1054 ModifyRightsObjectByTimeL( object, change, ETrue ); |
|
1055 |
|
1056 iPreparedData = object->ExportL(); |
|
1057 size = iPreparedData->Length(); |
|
1058 |
|
1059 IPCWRITE0L( package ); |
|
1060 |
|
1061 CleanupStack::PopAndDestroy( object ); |
|
1062 CleanupStack::PopAndDestroy( CID ); |
|
1063 |
|
1064 aMessage.Complete( KErrNone ); |
|
1065 |
|
1066 DRMLOG( _L( "CDRMDbSession::GetRecordL ok" ) ); |
|
1067 } |
|
1068 |
|
1069 // ----------------------------------------------------------------------------- |
|
1070 // CDRMRightsServer::GetEntryListL |
|
1071 // Create a temporary file from RPointerArray list the database created. |
|
1072 // Return the file name to the client. In case of an error, the temporary file |
|
1073 // is deleted. |
|
1074 // ----------------------------------------------------------------------------- |
|
1075 // |
|
1076 void CDRMDbSession::GetEntryListL( const RMessage2& aMessage ) |
|
1077 { |
|
1078 DRMLOG( _L( "CDRMDbSession::GetEntryListL" ) ); |
|
1079 __UHEAP_MARK; |
|
1080 |
|
1081 TFileName tmpFile( KNullDesC ); |
|
1082 HBufC8* CID = NULL; |
|
1083 TPtr8 data( NULL, 0 ); |
|
1084 |
|
1085 SanitizeL( aMessage.GetDesLength(1)); |
|
1086 |
|
1087 CID = HBufC8::NewLC( IPCGETDESLEN1 ); |
|
1088 |
|
1089 |
|
1090 TDeleteFile dodeletefile = |
|
1091 { |
|
1092 &RFSSESSION, |
|
1093 &tmpFile |
|
1094 }; |
|
1095 |
|
1096 CDRMPermissionList* list = CDRMPermissionList::NewLC(); |
|
1097 list->SetAutoCleanup( ETrue ); |
|
1098 |
|
1099 data.Set( CID->Des() ); |
|
1100 IPCREAD1L( data ); |
|
1101 |
|
1102 DRMDB.GetDBEntryByContentIDL( *CID, *list ); |
|
1103 |
|
1104 // Exclude domain rights where we are not part of the domain |
|
1105 RemoveInvalidPermissionsL( list ); |
|
1106 if ( list->Count() == 0 ) |
|
1107 { |
|
1108 User::Leave( KErrCANoRights ); |
|
1109 } |
|
1110 |
|
1111 // modify the times in the rights object to UI time |
|
1112 UpdateSecureTime(); |
|
1113 TTime currentTime; |
|
1114 currentTime.HomeTime(); |
|
1115 TTimeIntervalMicroSeconds change = currentTime.Int64() - iTrustedTime.Int64(); |
|
1116 ModifyTimesInListL( list, change, ETrue ); |
|
1117 |
|
1118 // Delete the file if something goes wrong. |
|
1119 TCleanupItem fileCleanup( DeleteFile, &dodeletefile ); |
|
1120 CleanupStack::PushL( fileCleanup ); |
|
1121 |
|
1122 // Convert the list to a permanent file store. |
|
1123 ListToFileL( *list, tmpFile ); |
|
1124 |
|
1125 // It is virtually impossible to make WriteL to leave in this case, |
|
1126 // but anything is still possible... |
|
1127 IPCWRITE0L( tmpFile ); |
|
1128 |
|
1129 CleanupStack::Pop( &dodeletefile ); |
|
1130 CleanupStack::PopAndDestroy( 2 ); // list, CID |
|
1131 |
|
1132 __UHEAP_MARKEND; |
|
1133 |
|
1134 // All done |
|
1135 aMessage.Complete( KErrNone ); |
|
1136 |
|
1137 DRMLOG( _L( "CDRMDbSession::GetEntryListL: ok" ) ); |
|
1138 } |
|
1139 |
|
1140 // ----------------------------------------------------------------------------- |
|
1141 // CDRMRightsServer::DeleteL |
|
1142 // Delete all rights objects with a certain CID. |
|
1143 // ----------------------------------------------------------------------------- |
|
1144 // |
|
1145 void CDRMDbSession::DeleteL( const RMessage2& aMessage ) |
|
1146 { |
|
1147 DRMLOG( _L( "CDRMDbSession::DeleteL" ) ); |
|
1148 __UHEAP_MARK; |
|
1149 TPtr8 data( NULL, 0 ); |
|
1150 |
|
1151 // Check for VendorId |
|
1152 |
|
1153 _LIT_SECURITY_POLICY_V0(vidCheck, VID_DEFAULT); // Check Default VID |
|
1154 if ( !vidCheck().CheckPolicy(iClient) ) |
|
1155 { |
|
1156 User::Leave( KErrAccessDenied ); |
|
1157 } |
|
1158 |
|
1159 CDRMEventAddRemove* event = CDRMEventAddRemove::NewLC( ERightsObjectDeletedAll ); |
|
1160 TRequestStatus status; |
|
1161 |
|
1162 HBufC8* CID = HBufC8::NewLC( |
|
1163 User::LeaveIfError( IPCGETDESLEN2 ) ); |
|
1164 |
|
1165 data.Set( CID->Des() ); |
|
1166 |
|
1167 IPCREAD2L( data ); |
|
1168 |
|
1169 |
|
1170 // Check if deletion is allowed: |
|
1171 if( DeleteAllowedL( *CID ) ) |
|
1172 { |
|
1173 DRMDB.DeleteDBEntryL( *CID ); |
|
1174 |
|
1175 // Notify |
|
1176 event->SetContentIDL(CID->Des()); |
|
1177 |
|
1178 DRMNOTIFIER.SendEventL(*event,status); |
|
1179 User::WaitForRequest(status); |
|
1180 } |
|
1181 CleanupStack::PopAndDestroy( 2 ); // CID, event |
|
1182 aMessage.Complete( KErrNone ); |
|
1183 __UHEAP_MARKEND; |
|
1184 DRMLOG( _L( "CDRMDbSession::DeleteL ok" ) ); |
|
1185 } |
|
1186 |
|
1187 // ----------------------------------------------------------------------------- |
|
1188 // CDRMRightsServer::DeleteRecordL |
|
1189 // Delete a single RO. |
|
1190 // ----------------------------------------------------------------------------- |
|
1191 // |
|
1192 void CDRMDbSession::DeleteRecordL( const RMessage2& aMessage ) |
|
1193 { |
|
1194 DRMLOG( _L( "CDRMDbSession::DeleteRecordL" ) ); |
|
1195 __UHEAP_MARK; |
|
1196 TDRMUniqueID id; |
|
1197 |
|
1198 _LIT_SECURITY_POLICY_V0(vidCheck, VID_DEFAULT); // Check Default VID |
|
1199 if ( !vidCheck().CheckPolicy(iClient) ) |
|
1200 { |
|
1201 User::Leave( KErrAccessDenied ); |
|
1202 } |
|
1203 |
|
1204 CDRMEventAddRemove* event = CDRMEventAddRemove::NewLC( ERightsObjectDeleted ); |
|
1205 TRequestStatus status; |
|
1206 |
|
1207 TPtr8 data( |
|
1208 reinterpret_cast< TUint8* >( &id ), 0, sizeof( TDRMUniqueID ) ); |
|
1209 |
|
1210 HBufC8* CID = HBufC8::NewLC( |
|
1211 User::LeaveIfError( IPCGETDESLEN3 ) ); |
|
1212 |
|
1213 IPCREAD0L( data ); |
|
1214 |
|
1215 data.Set( CID->Des() ); |
|
1216 IPCREAD3L( data ); |
|
1217 |
|
1218 // Check if deletion is allowed: |
|
1219 if( DeleteAllowedL( *CID ) ) |
|
1220 { |
|
1221 DRMDB.DeleteDBEntryL( *CID, id ); |
|
1222 |
|
1223 event->SetContentIDL( CID->Des() ); |
|
1224 |
|
1225 DRMNOTIFIER.SendEventL( *event, status ); |
|
1226 User::WaitForRequest( status ); |
|
1227 } |
|
1228 |
|
1229 CleanupStack::PopAndDestroy( 2 ); // CID, event |
|
1230 |
|
1231 aMessage.Complete( KErrNone ); |
|
1232 __UHEAP_MARKEND; |
|
1233 DRMLOG( _L( "CDRMDbSession::DeleteRecordL ok" ) ); |
|
1234 } |
|
1235 |
|
1236 // ----------------------------------------------------------------------------- |
|
1237 // CDRMRightsServer::ExportCIDsL |
|
1238 // Create a temporary file for rights database to export the CIDs, |
|
1239 // and write the file name to the client. |
|
1240 // ----------------------------------------------------------------------------- |
|
1241 // |
|
1242 void CDRMDbSession::ExportCIDsL( const RMessage2& aMessage ) |
|
1243 { |
|
1244 DRMLOG( _L( "CDRMDbSession::ExportCIDsL" ) ); |
|
1245 __UHEAP_MARK; |
|
1246 |
|
1247 TFileName fileName( KNullDesC ); |
|
1248 TDeleteFile deletefile = |
|
1249 { |
|
1250 &RFSSESSION, |
|
1251 &fileName |
|
1252 }; |
|
1253 |
|
1254 TCleanupItem item( DeleteFile, &deletefile ); |
|
1255 CleanupStack::PushL( item ); |
|
1256 |
|
1257 DRMDB.ExportContentIDListL( fileName ); |
|
1258 |
|
1259 IPCWRITE0L( fileName ); |
|
1260 |
|
1261 CleanupStack::Pop( &deletefile ); |
|
1262 |
|
1263 aMessage.Complete( KErrNone ); |
|
1264 __UHEAP_MARKEND; |
|
1265 DRMLOG( _L( "CDRMDbSession::ExportCIDsL: ok" ) ); |
|
1266 } |
|
1267 |
|
1268 // ----------------------------------------------------------------------------- |
|
1269 // CDRMRightsServer::GetKeyL |
|
1270 // Ask for a list of rights object based on the given CID. |
|
1271 // If there is even one rights object which allows the required consuming |
|
1272 // operation, get the key from database updating the RO if necessary. |
|
1273 // ----------------------------------------------------------------------------- |
|
1274 // |
|
1275 void CDRMDbSession::GetKeyL( const RMessage2& aMessage ) |
|
1276 { |
|
1277 DRMLOG( _L( "CDRMDbSession::GetKeyL" ) ); |
|
1278 __UHEAP_MARK; |
|
1279 // If credentials haven't been checked, don't return the key |
|
1280 if (iCredentialsChecked == ECheckedAndAllowed) |
|
1281 { |
|
1282 if (iCek.Length() > 0) |
|
1283 { |
|
1284 aMessage.Write(2, iCek); |
|
1285 aMessage.Complete(KErrNone); |
|
1286 } |
|
1287 else |
|
1288 { |
|
1289 aMessage.Complete(KErrCANoRights); |
|
1290 } |
|
1291 } |
|
1292 else |
|
1293 { |
|
1294 aMessage.Complete(KErrAccessDenied); |
|
1295 } |
|
1296 __UHEAP_MARKEND; |
|
1297 DRMLOG( _L( "CDRMDbSession::GetKeyL: Ok" ) ); |
|
1298 } |
|
1299 |
|
1300 // ----------------------------------------------------------------------------- |
|
1301 // CDRMRightsServer::CheckRightsL |
|
1302 // Check if there are sufficient rights at the moment. Nothing is changed from |
|
1303 // the database. |
|
1304 // ----------------------------------------------------------------------------- |
|
1305 // |
|
1306 void CDRMDbSession::CheckRightsL( const RMessage2& aMessage ) |
|
1307 { |
|
1308 DRMLOG( _L( "CDRMDbSession::CheckRightsL" ) ); |
|
1309 TIntent intent; |
|
1310 TInt length = 0; |
|
1311 CDRMPermission* child = NULL; |
|
1312 HBufC8* cid = NULL; |
|
1313 HBufC8* buffer = NULL; |
|
1314 TPtr8 tmp( NULL, 0, 0 ); |
|
1315 TInt r = KErrNone; |
|
1316 TInt size = 0; |
|
1317 TPckg<TInt> package( size ); |
|
1318 TTime currentTime; |
|
1319 TTimeIntervalMicroSeconds change; |
|
1320 TUint32 reason = 0; |
|
1321 TPckg<TUint32> package2( reason ); |
|
1322 TInt error = KErrNone; |
|
1323 HBufC8* uri = NULL; |
|
1324 |
|
1325 delete iPreparedData; |
|
1326 iPreparedData = NULL; |
|
1327 intent = static_cast<TIntent>( aMessage.Int0() ); |
|
1328 DRMLOG2(_L("Intent: %d"), intent); |
|
1329 |
|
1330 if ( intent == EPlay || intent == EView || |
|
1331 intent == EExecute || intent == EPrint || intent == EUnknown ) |
|
1332 { |
|
1333 length = User::LeaveIfError( aMessage.GetDesLength( 1 ) ); |
|
1334 cid = HBufC8::NewLC( length ); |
|
1335 tmp.Set( cid->Des() ); |
|
1336 aMessage.ReadL( 1, tmp ); |
|
1337 DRMLOG(_L("CID:")); |
|
1338 DRMLOGHEX(tmp); |
|
1339 error = FindRightsObject( intent, *cid, child, uri, reason ); |
|
1340 delete uri; |
|
1341 uri = NULL; // URI not used anywhere |
|
1342 |
|
1343 // if an error occurs we still need to write the information to the client, |
|
1344 // but then we can leave |
|
1345 if( error ) |
|
1346 { |
|
1347 aMessage.WriteL( 3, package2 ); |
|
1348 User::Leave( error ); |
|
1349 } |
|
1350 |
|
1351 CleanupStack::PopAndDestroy( cid ); |
|
1352 CleanupStack::PushL( child ); |
|
1353 } |
|
1354 else if ( intent == EInstall || intent == EPeek ) |
|
1355 { |
|
1356 length = User::LeaveIfError( aMessage.GetDesLength( 1 ) ); |
|
1357 cid = HBufC8::NewLC( length ); |
|
1358 tmp.Set( cid->Des() ); |
|
1359 aMessage.ReadL( 1, tmp ); |
|
1360 DRMLOG(_L("CID:")); |
|
1361 DRMLOGHEX(tmp); |
|
1362 |
|
1363 // If we have the key, install and peek always have full rights |
|
1364 buffer = DRMDB.GetDecryptionKeyL( *cid ); |
|
1365 CleanupStack::PopAndDestroy( cid ); |
|
1366 |
|
1367 if ( buffer ) |
|
1368 { |
|
1369 delete buffer; |
|
1370 child = CDRMPermission::NewL(); |
|
1371 CleanupStack::PushL( child ); |
|
1372 child->iAvailableRights = ERightsAll; |
|
1373 } |
|
1374 else |
|
1375 { |
|
1376 r = KErrCANoRights; |
|
1377 } |
|
1378 } |
|
1379 else if ( ( intent == EPause || intent == EContinue || intent == EStop ) && |
|
1380 iConsume ) |
|
1381 { |
|
1382 // These intents only make sense if we have an ongoing session |
|
1383 child = CDRMPermission::NewL(); |
|
1384 CleanupStack::PushL( child ); |
|
1385 child->DuplicateL( iConsume->GetChild() ); |
|
1386 } |
|
1387 else |
|
1388 { |
|
1389 r = KErrArgument; |
|
1390 } |
|
1391 |
|
1392 if ( child ) |
|
1393 { |
|
1394 UpdateSecureTime(); |
|
1395 currentTime.HomeTime(); |
|
1396 change = currentTime.Int64() - iTrustedTime.Int64(); |
|
1397 ModifyRightsObjectByTimeL( child, change, ETrue ); |
|
1398 iPreparedData = child->ExportL(); |
|
1399 size = iPreparedData->Length(); |
|
1400 aMessage.WriteL( 2, package ); |
|
1401 CleanupStack::PopAndDestroy( child ); |
|
1402 } |
|
1403 |
|
1404 aMessage.Complete( r ); |
|
1405 |
|
1406 DRMLOG2( _L( "CDRMDbSession::CheckRightsL: ok (%d)" ), r ); |
|
1407 } |
|
1408 |
|
1409 // ----------------------------------------------------------------------------- |
|
1410 // CDRMRightsServer::CountL |
|
1411 // Tell the client how many ROs there are. |
|
1412 // ----------------------------------------------------------------------------- |
|
1413 // |
|
1414 void CDRMDbSession::CountL( const RMessage2& aMessage ) |
|
1415 { |
|
1416 DRMLOG( _L( "CDRMDbSession::CountL" ) ); |
|
1417 __UHEAP_MARK; |
|
1418 TInt count = DRMDB.GetAmountOfRightsObjectsL(); |
|
1419 |
|
1420 TPtr8 data( reinterpret_cast< TUint8* >( &count ), |
|
1421 sizeof( TInt ), |
|
1422 sizeof( TInt ) ); |
|
1423 |
|
1424 IPCWRITE0L( data ); |
|
1425 |
|
1426 aMessage.Complete( KErrNone ); |
|
1427 __UHEAP_MARKEND; |
|
1428 DRMLOG( _L( "CDRMDbSession::CountL: ok" ) ); |
|
1429 } |
|
1430 |
|
1431 // ----------------------------------------------------------------------------- |
|
1432 // CDRMRightsServer::DeleteAll |
|
1433 // Delete all ROs. |
|
1434 // ----------------------------------------------------------------------------- |
|
1435 // |
|
1436 void CDRMDbSession::DeleteAllL( const RMessage2& aMessage ) |
|
1437 { |
|
1438 DRMLOG( _L( "CDRMDbSession::DeleteAllL" ) ); |
|
1439 |
|
1440 User::LeaveIfError( VerifyCredentials(NULL, NULL, EUnknown) ); |
|
1441 if( iCredentialsChecked == ECheckedAndDenied ) |
|
1442 { |
|
1443 User::Leave( KErrPermissionDenied ); |
|
1444 } |
|
1445 |
|
1446 //__UHEAP_MARK; |
|
1447 |
|
1448 DRMDB.DeleteDBL(); |
|
1449 |
|
1450 REPLAYCACHE.Close(); |
|
1451 |
|
1452 #ifndef RD_MULTIPLE_DRIVE |
|
1453 |
|
1454 #ifdef RD_DRM_METERING |
|
1455 METERINGDB.Close(); |
|
1456 RFSSESSION.Delete( KMeteringDataBaseFile ); |
|
1457 METERINGDB.InitL( KMeteringDataBaseFile ); |
|
1458 #endif |
|
1459 |
|
1460 RFSSESSION.Delete( KTimedReplayCacheFile ); |
|
1461 RFSSESSION.Delete( KPlainReplayCacheFile ); |
|
1462 |
|
1463 REPLAYCACHE.InitL( KTimedReplayCacheFile, KPlainReplayCacheFile ); |
|
1464 |
|
1465 #else //RD_MULTIPLE_DRIVE |
|
1466 |
|
1467 TFileName tempPath; |
|
1468 TFileName tempPath2; |
|
1469 TInt driveNumber( -1 ); |
|
1470 TChar driveLetter; |
|
1471 DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber ); |
|
1472 |
|
1473 RFSSESSION.DriveToChar( driveNumber, driveLetter ); |
|
1474 |
|
1475 #ifdef RD_DRM_METERING |
|
1476 tempPath.Format( KMeteringDataBaseFile, (TUint)driveLetter ); |
|
1477 |
|
1478 METERINGDB.Close(); |
|
1479 RFSSESSION.Delete( tempPath ); |
|
1480 METERINGDB.InitL( tempPath ); |
|
1481 #endif |
|
1482 |
|
1483 tempPath.Format( KTimedReplayCacheFile, (TUint)driveLetter ); |
|
1484 tempPath2.Format( KPlainReplayCacheFile, (TUint)driveLetter ); |
|
1485 |
|
1486 RFSSESSION.Delete( tempPath ); |
|
1487 RFSSESSION.Delete( tempPath2 ); |
|
1488 |
|
1489 REPLAYCACHE.InitL( tempPath, tempPath2 ); |
|
1490 |
|
1491 #endif |
|
1492 |
|
1493 if ( !iRoapClientConnected ) |
|
1494 { |
|
1495 User::LeaveIfError( iRoapClient.Connect() ); |
|
1496 iRoapClientConnected = ETrue; |
|
1497 } |
|
1498 |
|
1499 iRoapClient.DeleteAllL(); |
|
1500 |
|
1501 aMessage.Complete( KErrNone ); |
|
1502 //__UHEAP_MARKEND; |
|
1503 DRMLOG( _L( "CDRMDbSession::DeleteAllL ok" ) ); |
|
1504 } |
|
1505 |
|
1506 // ----------------------------------------------------------------------------- |
|
1507 // CDRMRightsServer::ListToFileL |
|
1508 // Convert the list to a file representation. |
|
1509 // ----------------------------------------------------------------------------- |
|
1510 // |
|
1511 void CDRMDbSession::ListToFileL( RPointerArray< CDRMPermission >& aList, |
|
1512 TFileName& aFile ) |
|
1513 { |
|
1514 __UHEAP_MARK; |
|
1515 DRMLOG( _L( "CDRMDbSession::ListToFileL" ) ); |
|
1516 |
|
1517 TInt count( 0 ); |
|
1518 |
|
1519 |
|
1520 RFileWriteStream fileStream; |
|
1521 |
|
1522 #ifndef RD_MULTIPLE_DRIVE |
|
1523 |
|
1524 User::LeaveIfError( |
|
1525 fileStream.Temp( RFSSESSION, |
|
1526 KDRMDbTempPath, |
|
1527 aFile, |
|
1528 EFileWrite | EFileStream ) ); |
|
1529 |
|
1530 #else //RD_MULTIPLE_DRIVE |
|
1531 |
|
1532 TInt driveNumber( -1 ); |
|
1533 TChar driveLetter; |
|
1534 DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber ); |
|
1535 |
|
1536 RFSSESSION.DriveToChar( driveNumber, driveLetter ); |
|
1537 |
|
1538 TFileName dbTempPath; |
|
1539 dbTempPath.Format( KDbTempPath, (TUint)driveLetter ); |
|
1540 |
|
1541 User::LeaveIfError( |
|
1542 fileStream.Temp( RFSSESSION, |
|
1543 dbTempPath, |
|
1544 aFile, |
|
1545 EFileWrite | EFileStream ) ); |
|
1546 |
|
1547 #endif |
|
1548 |
|
1549 CleanupClosePushL( fileStream ); |
|
1550 |
|
1551 TInt size( sizeof( TUint32 ) ); // streams store also other info there. |
|
1552 |
|
1553 for( count = 0; count < aList.Count(); count++ ) |
|
1554 { |
|
1555 size += aList[ count ]->Size(); |
|
1556 } |
|
1557 |
|
1558 // Reset count variable: |
|
1559 count = 0; |
|
1560 |
|
1561 #ifndef RD_MULTIPLE_DRIVE |
|
1562 |
|
1563 if ( SysUtil::DiskSpaceBelowCriticalLevelL( &RFSSESSION, |
|
1564 size, |
|
1565 EDriveC ) ) |
|
1566 |
|
1567 #else //RD_MULTIPLE_DRIVE |
|
1568 |
|
1569 if ( SysUtil::DiskSpaceBelowCriticalLevelL( &RFSSESSION, |
|
1570 size, |
|
1571 driveNumber ) ) |
|
1572 |
|
1573 #endif |
|
1574 { |
|
1575 DRMLOG( _L( "CDRMDbSession::ListToFileL: KErrDiskFull" ) ); |
|
1576 User::Leave( KErrDiskFull ); |
|
1577 } |
|
1578 |
|
1579 fileStream.WriteInt32L( aList.Count() ); |
|
1580 |
|
1581 // Write the whole stuff into the file. |
|
1582 // URIs are ignored. No use to put them to file (always the same |
|
1583 // and the client knows it already). |
|
1584 while( count < aList.Count() ) |
|
1585 { |
|
1586 aList[ count ]->ExternalizeL( fileStream ); |
|
1587 ++count; |
|
1588 } |
|
1589 |
|
1590 fileStream.CommitL(); |
|
1591 |
|
1592 CleanupStack::PopAndDestroy( &fileStream ); |
|
1593 |
|
1594 DRMLOG( _L( "CDRMDbSession::ListToFileL: ok" ) ); |
|
1595 __UHEAP_MARKEND; |
|
1596 } |
|
1597 |
|
1598 |
|
1599 // ----------------------------------------------------------------------------- |
|
1600 // CDRMRightsServer::FindRightsObjectL |
|
1601 // Try to locate the best RO from the given list which allows consuming of |
|
1602 // content. |
|
1603 // If end time is defined or an interval activated, the smallest endtime |
|
1604 // is always chosen first. |
|
1605 // ----------------------------------------------------------------------------- |
|
1606 // |
|
1607 void CDRMDbSession::FindRightsObjectL( TIntent aIntent, |
|
1608 const TDesC8& aURI, |
|
1609 CDRMPermission*& aChild, |
|
1610 HBufC8*& aUsedURI, |
|
1611 TUint32& aReason ) |
|
1612 { |
|
1613 DRMLOG( _L( "CDRMDbSession::FindRightsObjectL" ) ); |
|
1614 TInt res = KErrNotFound; |
|
1615 |
|
1616 if ( aUsedURI || aChild ) |
|
1617 { |
|
1618 // Check that return parameters are null initially. |
|
1619 User::Leave( KErrArgument ); |
|
1620 } |
|
1621 |
|
1622 CDRMPermissionList *perms = CDRMPermissionList::NewLC(); |
|
1623 TTime time; |
|
1624 |
|
1625 perms->SetAutoCleanup( ETrue ); |
|
1626 DRMDB.GetDBEntryByContentIDL( aURI , *perms ); |
|
1627 |
|
1628 UpdateSecureTime(); |
|
1629 |
|
1630 if ( iSecureTime ) |
|
1631 { |
|
1632 time = iTrustedTime; |
|
1633 } |
|
1634 else |
|
1635 { |
|
1636 time = Time::NullTTime(); |
|
1637 } |
|
1638 |
|
1639 if ( aIntent == EPeek || aIntent == EInstall ) |
|
1640 { |
|
1641 // There is at least one RO available. |
|
1642 // Use any RO, whether they are valid or not. |
|
1643 // Pick the first RO in the list. |
|
1644 |
|
1645 aChild = (*perms)[0]; |
|
1646 (*perms).Remove( 0 ); |
|
1647 |
|
1648 CleanupStack::PopAndDestroy( perms ); |
|
1649 return; |
|
1650 } |
|
1651 else if ( aIntent == EUnknown ) |
|
1652 { |
|
1653 // Pick one that works, no matter what the intent is |
|
1654 for ( TInt i = 0; res == KErrNotFound && i < perms->Count(); i++ ) |
|
1655 { |
|
1656 if ( (*perms)[i]->Valid( time, IMSI, aReason ) ) |
|
1657 { |
|
1658 res = i; |
|
1659 } |
|
1660 } |
|
1661 if ( res != KErrNotFound ) |
|
1662 { |
|
1663 aChild = (*perms)[res]; |
|
1664 perms->Remove( res ); |
|
1665 } |
|
1666 else |
|
1667 { |
|
1668 User::Leave( KErrCANoPermission ); |
|
1669 } |
|
1670 } |
|
1671 else |
|
1672 { |
|
1673 res = FindBestROsL( *perms, aURI, aIntent, aUsedURI, aReason ); |
|
1674 if ( res >= 0 ) |
|
1675 { |
|
1676 aChild = (*perms)[res]; |
|
1677 perms->Remove( res ); |
|
1678 } |
|
1679 else |
|
1680 { |
|
1681 User::Leave( KErrCANoPermission ); |
|
1682 } |
|
1683 } |
|
1684 CleanupStack::PopAndDestroy( perms ); |
|
1685 } |
|
1686 |
|
1687 |
|
1688 // ----------------------------------------------------------------------------- |
|
1689 // CDRMRightsServer::FindRightsObject |
|
1690 // Try to locate the best RO from the given list which allows consuming of |
|
1691 // content. |
|
1692 // If end time is defined or an interval activated, the smallest endtime |
|
1693 // is always chosen first. |
|
1694 // ----------------------------------------------------------------------------- |
|
1695 // |
|
1696 TInt CDRMDbSession::FindRightsObject( TIntent aIntent, |
|
1697 const TDesC8& aURI, |
|
1698 CDRMPermission*& aChild, |
|
1699 HBufC8*& aUsedURI, |
|
1700 TUint32& aReason ) |
|
1701 { |
|
1702 DRMLOG( _L( "CDRMDbSession::FindRightsObject" ) ); |
|
1703 TInt error = KErrNone; |
|
1704 |
|
1705 TRAP( error, FindRightsObjectL( aIntent, aURI, aChild, aUsedURI, aReason ) ); |
|
1706 if ( ( error == KErrCANoRights || error == KErrCANoPermission ) && |
|
1707 PendingRights(aURI) ) |
|
1708 { |
|
1709 error = KErrCAPendingRights; |
|
1710 } |
|
1711 return error; |
|
1712 } |
|
1713 |
|
1714 // ----------------------------------------------------------------------------- |
|
1715 // CDRMDbSession::CheckConsumeL |
|
1716 // Check if Consume is possible |
|
1717 // ----------------------------------------------------------------------------- |
|
1718 // |
|
1719 void CDRMDbSession::CheckConsumeL( const RMessage2& aMessage ) |
|
1720 { |
|
1721 DRMLOG( _L( "CDRMDbSession::CheckConsumeL" ) ); |
|
1722 |
|
1723 __UHEAP_MARK; |
|
1724 |
|
1725 HBufC8* CID = NULL; |
|
1726 TPtr8 cid( NULL, 0, 0 ); |
|
1727 TInt length = 0; |
|
1728 TIntent intent; |
|
1729 TUint32 reason = 0; |
|
1730 |
|
1731 length = User::LeaveIfError( IPCGETDESLEN1 ); |
|
1732 CID = HBufC8::NewLC( length ); |
|
1733 cid.Set( CID->Des() ); |
|
1734 IPCREAD1L( cid ); |
|
1735 intent = static_cast<TIntent>(aMessage.Int0()); |
|
1736 |
|
1737 // Check only intents which are actually consuming something. All others |
|
1738 // always succeed, because CheckConsume is called by default when a file |
|
1739 // is opened. |
|
1740 if ( intent == EPlay || intent == EView || |
|
1741 intent == EExecute || intent == EPrint || intent == EUnknown ) |
|
1742 { |
|
1743 // Count constraints are valid for the duration of the |
|
1744 // session after they have been consumed earlier |
|
1745 if ( !( iConsume && iConsume->CountConstraintActive() || |
|
1746 SERVER->HasActiveCountConstraint( *CID ) ) ) |
|
1747 { |
|
1748 CDRMPermission* child( NULL ); |
|
1749 HBufC8* uri( NULL ); |
|
1750 TInt error( FindRightsObject( intent, *CID, child, uri, reason ) ); |
|
1751 delete child; |
|
1752 delete uri; |
|
1753 User::LeaveIfError( error ); |
|
1754 } |
|
1755 } |
|
1756 /* Enable this code as soon as clients use EUnknown, and it is safe to fail |
|
1757 when no key is available |
|
1758 else if ( intent == EPeek || EInstall ) |
|
1759 { |
|
1760 // We need at least the key for peek and install. This will leave if no |
|
1761 // key is there. |
|
1762 HBufC8* key = DRMDB.GetDecryptionKeyL( *CID ); |
|
1763 delete key; |
|
1764 } |
|
1765 */ |
|
1766 |
|
1767 CleanupStack::PopAndDestroy( CID ); |
|
1768 aMessage.Complete( KErrNone ); |
|
1769 __UHEAP_MARKEND; |
|
1770 DRMLOG( _L( "CDRMDbSession::CheckConsumeL: ok" ) ); |
|
1771 } |
|
1772 |
|
1773 // ----------------------------------------------------------------------------- |
|
1774 // CDRMDbSession::ConsumeL |
|
1775 // Consume the right and register the consumption. |
|
1776 // ----------------------------------------------------------------------------- |
|
1777 // |
|
1778 void CDRMDbSession::ConsumeL( const RMessage2& aMessage ) |
|
1779 { |
|
1780 DRMLOG( _L( "CDRMDbSession::ConsumeL" ) ); |
|
1781 |
|
1782 const TIntent intent = static_cast<TIntent>(aMessage.Int0()); |
|
1783 HBufC8* CID = NULL; |
|
1784 TInt length = 0; |
|
1785 TPtr8 cid( NULL, 0, 0 ); |
|
1786 |
|
1787 length = User::LeaveIfError( IPCGETDESLEN1 ); |
|
1788 |
|
1789 CID = HBufC8::NewLC( length ); |
|
1790 |
|
1791 cid.Set( CID->Des() ); |
|
1792 IPCREAD1L( cid ); |
|
1793 |
|
1794 if ( intent != EUnknown ) |
|
1795 { |
|
1796 if ( intent == EPeek || intent == EInstall ) |
|
1797 { |
|
1798 User::LeaveIfError( VerifyCredentials( CID, NULL, intent ) ); |
|
1799 } |
|
1800 else |
|
1801 { |
|
1802 if ( intent == EPlay || |
|
1803 intent == EView || |
|
1804 intent == EExecute || |
|
1805 intent == EPrint || |
|
1806 intent == EStop ) |
|
1807 { |
|
1808 |
|
1809 if ( iConsume ) |
|
1810 { |
|
1811 delete iConsume; |
|
1812 iConsume = NULL; |
|
1813 } |
|
1814 if ( intent != EStop ) |
|
1815 { |
|
1816 CDRMConsume* consume( NULL ); |
|
1817 consume = CDRMConsume::NewLC( *this, *CID, NULL ); |
|
1818 consume->HandleL( intent ); |
|
1819 CleanupStack::Pop( consume ); |
|
1820 iConsume = consume; |
|
1821 } |
|
1822 } |
|
1823 else |
|
1824 { |
|
1825 if ( !iConsume ) |
|
1826 { |
|
1827 User::Leave( KErrNotReady ); |
|
1828 } |
|
1829 |
|
1830 if ( intent == EPause ) |
|
1831 { |
|
1832 iConsume->Pause(); |
|
1833 } |
|
1834 else if ( intent == EContinue ) |
|
1835 { |
|
1836 iConsume->ContinueL(); |
|
1837 } |
|
1838 else |
|
1839 { |
|
1840 iConsume->Stop(); |
|
1841 } |
|
1842 } |
|
1843 } |
|
1844 } |
|
1845 else |
|
1846 { |
|
1847 // None of the other intents are allowed here, fail |
|
1848 User::Leave( KErrArgument ); |
|
1849 } |
|
1850 |
|
1851 |
|
1852 CleanupStack::PopAndDestroy( CID ); |
|
1853 aMessage.Complete( KErrNone ); |
|
1854 DRMLOG( _L( "CDRMDbSession::ConsumeL: ok" ) ); |
|
1855 } |
|
1856 |
|
1857 // ----------------------------------------------------------------------------- |
|
1858 // CDRMDbSession::CalculatePaddingL |
|
1859 // |
|
1860 // ----------------------------------------------------------------------------- |
|
1861 // |
|
1862 void CDRMDbSession::CalculatePaddingL( const RMessage2& aMessage ) |
|
1863 { |
|
1864 __UHEAP_MARK; |
|
1865 DRMLOG( _L( "CDRMDbSession::CalculatePaddingL" ) ); |
|
1866 |
|
1867 CAESDecryptor* decryptor( NULL ); |
|
1868 TInt i( 0 ); |
|
1869 |
|
1870 TBuf8<KDCFKeySize * 2> data; |
|
1871 TBuf8<KDCFKeySize> iv; |
|
1872 TBuf8<KDCFKeySize> block; |
|
1873 TPtr8 tmp( NULL, 0, 0 ); |
|
1874 |
|
1875 aMessage.ReadL( 0, data ); |
|
1876 |
|
1877 // Check that the data we read is actually of the proper length |
|
1878 if( data.Length() != KDCFKeySize*2 ) |
|
1879 { |
|
1880 User::Leave(KErrArgument); |
|
1881 } |
|
1882 |
|
1883 iv.Copy(data.Left(KDCFKeySize)); |
|
1884 block.Copy(data.Right(KDCFKeySize)); |
|
1885 |
|
1886 if( iCek.Length() != KDRMKeyLength ) |
|
1887 { |
|
1888 User::Leave(KErrNotReady); |
|
1889 } |
|
1890 |
|
1891 decryptor = CAESDecryptor::NewLC(iCek); |
|
1892 decryptor->Transform(block); |
|
1893 CleanupStack::PopAndDestroy( decryptor ); |
|
1894 |
|
1895 for (i = 0; i < KDCFKeySize; i++) |
|
1896 { |
|
1897 block[i] ^= iv[i]; |
|
1898 } |
|
1899 |
|
1900 if ( block[ KDCFKeySize - 1 ] > 0 && block[ KDCFKeySize - 1 ] <= 16 ) |
|
1901 { |
|
1902 for ( i = KDCFKeySize - block[ KDCFKeySize - 1 ]; |
|
1903 i < KDCFKeySize - 1; |
|
1904 ++i ) |
|
1905 { |
|
1906 if ( block[ i ] != block[ KDCFKeySize - 1 ] ) |
|
1907 { |
|
1908 User::Leave( KErrCorrupt ); |
|
1909 } |
|
1910 } |
|
1911 |
|
1912 aMessage.Complete( block[ KDCFKeySize - 1 ] ); |
|
1913 DRMLOG2( _L( "CDRMDbSession::CalculatePaddingL: Padding = %d" ), |
|
1914 block[ KDCFKeySize - 1 ] ); |
|
1915 |
|
1916 return; |
|
1917 } |
|
1918 |
|
1919 User::Leave( KErrCorrupt ); |
|
1920 |
|
1921 __UHEAP_MARKEND; |
|
1922 } |
|
1923 |
|
1924 // ----------------------------------------------------------------------------- |
|
1925 // CDRMDbSession::SecureTimeL |
|
1926 // returns the secure time |
|
1927 // ----------------------------------------------------------------------------- |
|
1928 // |
|
1929 void CDRMDbSession::SecureTimeL( const RMessage2& aMessage ) |
|
1930 { |
|
1931 DRMLOG( _L( "CDRMDbSession::SecureTimeL" ) ); |
|
1932 __UHEAP_MARK; |
|
1933 TPckgBuf< TInt64 > time; |
|
1934 TPckg< TBool > levelPckg( iSecureTime ); |
|
1935 |
|
1936 UpdateSecureTime(); |
|
1937 |
|
1938 time() = iTrustedTime.Int64(); |
|
1939 |
|
1940 IPCWRITE0L( time ); |
|
1941 IPCWRITE1L( levelPckg ); |
|
1942 |
|
1943 aMessage.Complete( KErrNone ); |
|
1944 __UHEAP_MARKEND; |
|
1945 DRMLOG( _L( "CDRMDbSession::SecureTime: ok" ) ); |
|
1946 } |
|
1947 |
|
1948 // ----------------------------------------------------------------------------- |
|
1949 // CDRMDbSession::EncryptL |
|
1950 // |
|
1951 // ----------------------------------------------------------------------------- |
|
1952 // |
|
1953 void CDRMDbSession::EncryptL(const RMessage2& aMessage) |
|
1954 { |
|
1955 TBuf8<KDCFKeySize> iv; |
|
1956 HBufC8* data = NULL; |
|
1957 TPtr8 ptr(NULL, 0, 0); |
|
1958 TBool addPadding; |
|
1959 __UHEAP_MARK; |
|
1960 |
|
1961 DRMLOG(_L("CDRMDbSession::EncryptL")); |
|
1962 |
|
1963 if( iCek.Length() != KDRMKeyLength ) |
|
1964 { |
|
1965 User::Leave( KErrNotReady ); |
|
1966 } |
|
1967 |
|
1968 SanitizeL( aMessage.GetDesLength(0) ); |
|
1969 |
|
1970 addPadding = aMessage.Int2() != 0 ? ETrue : EFalse; |
|
1971 aMessage.Read(0, iv); |
|
1972 data = HBufC8::NewLC(aMessage.GetDesMaxLength(1)); |
|
1973 ptr.Set(data->Des()); |
|
1974 aMessage.Read(1, ptr); |
|
1975 |
|
1976 AesEncryptL( iCek, iv, addPadding, ptr ); |
|
1977 |
|
1978 aMessage.Write(1, ptr); |
|
1979 aMessage.Complete(KErrNone); |
|
1980 CleanupStack::PopAndDestroy( data ); |
|
1981 __UHEAP_MARKEND; |
|
1982 DRMLOG(_L("CDRMDbSession::EncryptL: Ok")); |
|
1983 } |
|
1984 |
|
1985 // ----------------------------------------------------------------------------- |
|
1986 // CDRMDbSession::DecryptL |
|
1987 // Decrypt data and return it to the caller, using the CEK for this session |
|
1988 // ----------------------------------------------------------------------------- |
|
1989 // |
|
1990 void CDRMDbSession::DecryptL(const RMessage2& aMessage) |
|
1991 { |
|
1992 DRMLOG(_L("CDRMDbSession::DecryptL")); |
|
1993 |
|
1994 // If credentials haven't been checked, do it now, check for expired rights |
|
1995 if (iCredentialsChecked == ECheckedAndDenied || |
|
1996 iCredentialsChecked == ENotChecked && |
|
1997 VerifyCredentials(iContentId, NULL, EUnknown) != KErrNone) |
|
1998 { |
|
1999 DRMLOG(_L("Decrypt failed: untrusted client")); |
|
2000 aMessage.Complete(KErrAccessDenied); |
|
2001 } |
|
2002 else if ( iConsume && iConsume->IsExpired() ) |
|
2003 { |
|
2004 DRMLOG(_L("Decrypt failed: rights expired")); |
|
2005 aMessage.Complete(KErrCANoPermission); |
|
2006 } |
|
2007 else |
|
2008 { |
|
2009 if (iCek.Length() > 0) |
|
2010 { |
|
2011 TBuf8<KDCFKeySize> iv; |
|
2012 HBufC8* data = NULL; |
|
2013 TPtr8 ptr(NULL, 0, 0); |
|
2014 TBool removePadding; |
|
2015 |
|
2016 removePadding = aMessage.Int2() != 0 ? ETrue : EFalse; |
|
2017 aMessage.Read(0, iv); |
|
2018 |
|
2019 data = HBufC8::NewMaxLC(aMessage.GetDesMaxLength(1)); |
|
2020 |
|
2021 ptr.Set(data->Des()); |
|
2022 aMessage.Read(1, ptr); |
|
2023 |
|
2024 AesDecryptL( iCek, |
|
2025 iv, |
|
2026 removePadding, |
|
2027 ptr ); |
|
2028 |
|
2029 aMessage.Write(1, ptr); |
|
2030 aMessage.Complete(KErrNone); |
|
2031 CleanupStack::PopAndDestroy( data ); |
|
2032 } |
|
2033 else |
|
2034 { |
|
2035 aMessage.Complete(KErrCANoRights); |
|
2036 } |
|
2037 } |
|
2038 DRMLOG(_L("CDRMDbSession::DecryptL: Ok")); |
|
2039 } |
|
2040 |
|
2041 // ----------------------------------------------------------------------------- |
|
2042 // CDRMDbSession::InitializeKeyL |
|
2043 // Initialize the CEK for this session based on the content ID. Also sets the |
|
2044 // content ID for later usage. |
|
2045 // ----------------------------------------------------------------------------- |
|
2046 // |
|
2047 void CDRMDbSession::InitializeKeyL( const RMessage2& aMessage ) |
|
2048 { |
|
2049 TPtr8 tmp(NULL, 0, 0); |
|
2050 HBufC8* key = NULL; |
|
2051 TInt error = KErrNone; |
|
2052 |
|
2053 DRMLOG( _L( "CDRMDbSession::InitializeKeyL")); |
|
2054 if ( iContentId ) |
|
2055 { |
|
2056 delete iContentId; |
|
2057 iContentId = NULL; |
|
2058 } |
|
2059 iContentId = HBufC8::NewL( User::LeaveIfError( IPCGETDESLEN0 ) ); |
|
2060 tmp.Set( iContentId->Des() ); |
|
2061 IPCREAD0L( tmp ); |
|
2062 |
|
2063 __UHEAP_MARK; |
|
2064 TRAP( error, key = DRMDB.GetDecryptionKeyL( *iContentId ) ); |
|
2065 if ( ( error == KErrCANoRights || error == KErrCANoPermission ) && |
|
2066 PendingRights( *iContentId , EFalse ) ) |
|
2067 { |
|
2068 error = KErrCAPendingRights; |
|
2069 } |
|
2070 |
|
2071 if ( error == KErrNone ) |
|
2072 { |
|
2073 iCek.Copy( *key ); |
|
2074 delete key; |
|
2075 aMessage.Complete( KErrNone ); |
|
2076 } |
|
2077 else |
|
2078 { |
|
2079 aMessage.Complete( error ); |
|
2080 } |
|
2081 __UHEAP_MARKEND; |
|
2082 DRMLOG2( _L( "CDRMDbSession::InitializeKeyL: %d" ), error ); |
|
2083 } |
|
2084 |
|
2085 // ----------------------------------------------------------------------------- |
|
2086 // CDRMDbSession::InitializeGroupKeyL |
|
2087 // Initialize the CEK for this session from a given group key |
|
2088 // ----------------------------------------------------------------------------- |
|
2089 // |
|
2090 void CDRMDbSession::InitializeGroupKeyL(const RMessage2& aMessage ) |
|
2091 { |
|
2092 HBufC8* groupId = NULL; |
|
2093 HBufC8* groupKey = NULL; |
|
2094 TPtr8 tmp(NULL, 0, 0 ); |
|
2095 HBufC8* key = NULL; |
|
2096 TRequestStatus status; |
|
2097 CAESDecryptor* aes = NULL; |
|
2098 CModeCBCDecryptor* cbc = NULL; |
|
2099 |
|
2100 __UHEAP_MARK; |
|
2101 |
|
2102 SanitizeL( aMessage.GetDesLength(0) ); |
|
2103 SanitizeL( aMessage.GetDesLength(1) ); |
|
2104 |
|
2105 DRMLOG(_L("CDRMDbSession::InitializeGroupKeyL")); |
|
2106 if (aMessage.Int2() == EMethodAES_128_CBC) |
|
2107 { |
|
2108 groupId = HBufC8::NewLC(aMessage.GetDesLength(0)); |
|
2109 tmp.Set(groupId->Des()); |
|
2110 aMessage.Read(0, tmp); |
|
2111 |
|
2112 groupKey = HBufC8::NewLC(aMessage.GetDesLength(1)); |
|
2113 tmp.Set(groupKey->Des()); |
|
2114 aMessage.Read(1, tmp); |
|
2115 |
|
2116 key = DRMDB.GetDecryptionKeyL(*groupId); |
|
2117 CleanupStack::PushL(key); |
|
2118 |
|
2119 if ( key ) |
|
2120 { |
|
2121 aes = CAESDecryptor::NewLC(*key); |
|
2122 cbc = CModeCBCDecryptor::NewL(aes, groupKey->Left(KDCFKeySize)); |
|
2123 CleanupStack::Pop( aes ); |
|
2124 iCek.Copy(groupKey->Mid(KDCFKeySize, KDCFKeySize)); |
|
2125 cbc->Transform(iCek); |
|
2126 delete cbc; |
|
2127 aMessage.Complete(KErrNone); |
|
2128 } |
|
2129 else |
|
2130 { |
|
2131 aMessage.Complete(KErrCANoRights); |
|
2132 } |
|
2133 CleanupStack::PopAndDestroy(3); // key, groupKey, groupId |
|
2134 } |
|
2135 else |
|
2136 { |
|
2137 aMessage.Complete(KErrNotSupported); |
|
2138 } |
|
2139 |
|
2140 __UHEAP_MARKEND; |
|
2141 DRMLOG(_L("CDRMDbSession::InitializeGroupKeyL: Ok")); |
|
2142 } |
|
2143 |
|
2144 // ----------------------------------------------------------------------------- |
|
2145 // CDRMDbSession::GetPreparedDataL |
|
2146 // Returns data which has been allocated before |
|
2147 // ----------------------------------------------------------------------------- |
|
2148 // |
|
2149 void CDRMDbSession::GetPreparedDataL( const RMessage2& aMessage ) |
|
2150 { |
|
2151 DRMLOG( _L( "CDRMDbSession::GetPreparedDataL" ) ); |
|
2152 |
|
2153 if( !iPreparedData ) |
|
2154 { |
|
2155 User::Leave( KErrNotReady ); |
|
2156 } |
|
2157 |
|
2158 if( iPreparedData->Length() > aMessage.GetDesMaxLength(0) ) |
|
2159 { |
|
2160 User::Leave(KErrArgument); |
|
2161 } |
|
2162 |
|
2163 IPCWRITE0L( iPreparedData->Des() ); |
|
2164 |
|
2165 aMessage.Complete( KErrNone ); |
|
2166 DRMLOG( _L( "CDRMDbSession::GetPreparedDataL: ok" ) ); |
|
2167 |
|
2168 // Delete the data |
|
2169 delete iPreparedData; |
|
2170 iPreparedData = NULL; |
|
2171 } |
|
2172 |
|
2173 // ----------------------------------------------------------------------------- |
|
2174 // CDRMDbSession::IsInCacheL |
|
2175 // Checks whether the given entry is in replay cache or not. |
|
2176 // ----------------------------------------------------------------------------- |
|
2177 void CDRMDbSession::IsInCacheL( const RMessage2& aMessage ) |
|
2178 { |
|
2179 DRMLOG( _L( "CDRMDbSession::IsInCacheL" ) ); |
|
2180 |
|
2181 HBufC8* buf = HBufC8::NewLC( |
|
2182 User::LeaveIfError( IPCGETDESLEN0 ) ); |
|
2183 |
|
2184 TPckgBuf< TBool > res; |
|
2185 TPtr8 data( buf->Des() ); |
|
2186 |
|
2187 IPCREAD0L( data ); |
|
2188 |
|
2189 if ( aMessage.Ptr1() ) |
|
2190 { |
|
2191 TPckgBuf< TTime > time; |
|
2192 |
|
2193 IPCREAD1L( time ); |
|
2194 |
|
2195 res = REPLAYCACHE.InCacheL( *buf, time() ); |
|
2196 } |
|
2197 else |
|
2198 { |
|
2199 res = REPLAYCACHE.InCacheL( *buf ); |
|
2200 } |
|
2201 |
|
2202 CleanupStack::PopAndDestroy( buf ); |
|
2203 |
|
2204 IPCWRITE2L( res ); |
|
2205 |
|
2206 aMessage.Complete( KErrNone ); |
|
2207 |
|
2208 DRMLOG( _L( "CDRMDbSession::IsInCache ok" ) ); |
|
2209 } |
|
2210 |
|
2211 // ----------------------------------------------------------------------------- |
|
2212 // CDRMDbSession::AddToCacheL |
|
2213 // Adds an entry to replay cache. |
|
2214 // ----------------------------------------------------------------------------- |
|
2215 void CDRMDbSession::AddToCacheL( const RMessage2& aMessage ) |
|
2216 { |
|
2217 DRMLOG( _L( "CDRMDbSession::AddToCacheL" ) ); |
|
2218 |
|
2219 HBufC8* buf = NULL; |
|
2220 |
|
2221 UpdateSecureTime(); |
|
2222 |
|
2223 if ( !iSecureTime ) |
|
2224 { |
|
2225 // DoSomething! |
|
2226 } |
|
2227 |
|
2228 buf = HBufC8::NewLC( |
|
2229 User::LeaveIfError( IPCGETDESLEN0 ) ); |
|
2230 |
|
2231 TPtr8 data( buf->Des() ); |
|
2232 |
|
2233 IPCREAD0L( data ); |
|
2234 |
|
2235 if ( aMessage.Ptr1() ) |
|
2236 { |
|
2237 TPckgBuf< TTime > time; |
|
2238 |
|
2239 IPCREAD1L( time ); |
|
2240 |
|
2241 REPLAYCACHE.AddL( *buf, time(), iTrustedTime ); |
|
2242 } |
|
2243 |
|
2244 else |
|
2245 { |
|
2246 REPLAYCACHE.AddL( *buf, iTrustedTime ); |
|
2247 } |
|
2248 |
|
2249 CleanupStack::PopAndDestroy( buf ); |
|
2250 |
|
2251 aMessage.Complete( KErrNone ); |
|
2252 |
|
2253 DRMLOG( _L( "CDRMDbSession::AddToCacheL ok" ) ); |
|
2254 } |
|
2255 |
|
2256 // ----------------------------------------------------------------------------- |
|
2257 // CDRMDbSession::AddDomainROL |
|
2258 // Add domain ro xml data |
|
2259 // ----------------------------------------------------------------------------- |
|
2260 // |
|
2261 void CDRMDbSession::AddDomainROL( const RMessage2& aMessage ) |
|
2262 { |
|
2263 DRMLOG( _L( "CDRMDbSession::AddDomainROL" ) ); |
|
2264 __UHEAP_MARK; |
|
2265 HBufC8* RoId = NULL; |
|
2266 HBufC8* XMLData = NULL; |
|
2267 TInt size = 0; |
|
2268 TPtr8 data( NULL, 0 ); |
|
2269 |
|
2270 size = User::LeaveIfError( IPCGETDESLEN0 ); |
|
2271 RoId = HBufC8::NewLC( size ); |
|
2272 |
|
2273 size = User::LeaveIfError( IPCGETDESLEN1 ); |
|
2274 XMLData = HBufC8::NewLC( size ); |
|
2275 |
|
2276 data.Set( RoId->Des() ); |
|
2277 IPCREAD0L( data ); |
|
2278 |
|
2279 data.Set( XMLData->Des() ); |
|
2280 IPCREAD1L( data ); |
|
2281 |
|
2282 DRMDB.AddDomainROL( *RoId, *XMLData ); |
|
2283 |
|
2284 CleanupStack::PopAndDestroy( 2 ); // RoId, XMLData |
|
2285 |
|
2286 aMessage.Complete( KErrNone ); |
|
2287 __UHEAP_MARKEND; |
|
2288 DRMLOG( _L( "CDRMDbSession::AddDomainROL done" ) ); |
|
2289 }; |
|
2290 |
|
2291 // ----------------------------------------------------------------------------- |
|
2292 // CDRMDbSession::GetDomainROL |
|
2293 // Get domain ro xml data |
|
2294 // ----------------------------------------------------------------------------- |
|
2295 // |
|
2296 void CDRMDbSession::GetDomainROL( const RMessage2& aMessage ) |
|
2297 { |
|
2298 DRMLOG( _L( "CDRMDbSession::GetDomainROL" ) ); |
|
2299 |
|
2300 TInt size = 0; |
|
2301 TPckg< TInt > package( size ); |
|
2302 HBufC8* RoId = NULL; |
|
2303 TPtr8 data(NULL, 0); |
|
2304 |
|
2305 // Cleanup. |
|
2306 if ( iPreparedData ) |
|
2307 { |
|
2308 delete iPreparedData; |
|
2309 iPreparedData = NULL; |
|
2310 } |
|
2311 |
|
2312 size = User::LeaveIfError( IPCGETDESLEN1 ); |
|
2313 |
|
2314 RoId = HBufC8::NewLC( size ); |
|
2315 |
|
2316 data.Set( RoId->Des() ); |
|
2317 IPCREAD1L( data ); |
|
2318 |
|
2319 iPreparedData = DRMDB.GetDomainROL( *RoId ); |
|
2320 |
|
2321 size = iPreparedData->Length(); |
|
2322 |
|
2323 IPCWRITE0L( package ); |
|
2324 |
|
2325 CleanupStack::PopAndDestroy( RoId ); |
|
2326 |
|
2327 aMessage.Complete( KErrNone ); |
|
2328 |
|
2329 DRMLOG( _L( "CDRMDbSession::GetDomainROL ok" ) ); |
|
2330 }; |
|
2331 |
|
2332 // ----------------------------------------------------------------------------- |
|
2333 // CDRMDbSession::DeleteDomainROL |
|
2334 // Delete domain ro xml data |
|
2335 // ----------------------------------------------------------------------------- |
|
2336 // |
|
2337 void CDRMDbSession::DeleteDomainROL( const RMessage2& aMessage ) |
|
2338 { |
|
2339 DRMLOG( _L( "CDRMDbSession::DeleteDomainROL" ) ); |
|
2340 __UHEAP_MARK; |
|
2341 TPtr8 data( NULL, 0 ); |
|
2342 TInt size = 0; |
|
2343 |
|
2344 size = User::LeaveIfError( IPCGETDESLEN0 ); |
|
2345 |
|
2346 |
|
2347 HBufC8* RoId = HBufC8::NewLC( size ); |
|
2348 |
|
2349 data.Set( RoId->Des() ); |
|
2350 |
|
2351 IPCREAD0L( data ); |
|
2352 |
|
2353 DRMDB.DeleteDomainROL( *RoId ); |
|
2354 |
|
2355 CleanupStack::PopAndDestroy( RoId ); |
|
2356 |
|
2357 aMessage.Complete( KErrNone ); |
|
2358 __UHEAP_MARKEND; |
|
2359 DRMLOG( _L( "CDRMDbSession::DeleteDomainROL ok" ) ); |
|
2360 }; |
|
2361 |
|
2362 |
|
2363 // ----------------------------------------------------------------------------- |
|
2364 // CDRMDbSession::GetDomainRosForCidL |
|
2365 // Return the domain ROs for a content ID in a buffer. Each RO is preceded |
|
2366 // by a length field |
|
2367 // ----------------------------------------------------------------------------- |
|
2368 // |
|
2369 void CDRMDbSession::GetDomainRosForCidL( |
|
2370 const RMessage2& aMessage) |
|
2371 { |
|
2372 DRMLOG(_L("CDRMDbSession::GetDomainRosForCidL")); |
|
2373 TInt size(0); |
|
2374 TInt roSize(0); |
|
2375 TInt pos = 0; |
|
2376 TInt indexLatest = -1; |
|
2377 TTime timeStamp = 0; |
|
2378 TTime timeLatest = 0; |
|
2379 TPckg<TInt> pkg(size); |
|
2380 TPtr8 ptr(NULL, 0); |
|
2381 TPtrC8 elementPtr(KNullDesC8); |
|
2382 TPckg<TInt> roSizePkg(roSize); |
|
2383 HBufC8* element = NULL; |
|
2384 HBufC8* id(NULL); |
|
2385 HBufC8* ro(NULL); |
|
2386 CDRMPointerArray<CDRMPermission>* |
|
2387 rights( CDRMPointerArray<CDRMPermission>::NewLC() ); |
|
2388 rights->SetAutoCleanup(ETrue); |
|
2389 |
|
2390 delete iPreparedData; |
|
2391 iPreparedData = NULL; |
|
2392 |
|
2393 SanitizeL( aMessage.GetDesLength(0) ); |
|
2394 |
|
2395 id = HBufC8::NewLC(aMessage.GetDesLength(0)); |
|
2396 ptr.Set(id->Des()); |
|
2397 aMessage.Read(0, ptr); |
|
2398 |
|
2399 TRAPD(r, DRMDB.GetDBEntryByContentIDL(*id, *rights)); |
|
2400 |
|
2401 if (r == KErrCANoRights || r == KErrCANoPermission ) |
|
2402 { |
|
2403 r = KErrNone; |
|
2404 } |
|
2405 User::LeaveIfError(r); |
|
2406 |
|
2407 for (TInt i(0); i < rights->Count(); i++) |
|
2408 { |
|
2409 if ( (*rights)[i]->iDomainID ) |
|
2410 { |
|
2411 ro = DRMDB.GetDomainROL(*(*rights)[i]->iRoID); |
|
2412 CleanupStack::PushL(ro); |
|
2413 |
|
2414 elementPtr.Set(ExtractElement(*ro, KTimeStamp, pos)); |
|
2415 |
|
2416 /* Check whether the timestamp was found or not and whether it is |
|
2417 the newest one so far or not */ |
|
2418 if (pos >= 0) |
|
2419 { |
|
2420 element = elementPtr.AllocLC(); |
|
2421 timeStamp = Iso8601ToTime(*element); |
|
2422 CleanupStack::PopAndDestroy(element); |
|
2423 |
|
2424 if (timeStamp > timeLatest) |
|
2425 { |
|
2426 indexLatest = i; |
|
2427 } |
|
2428 } |
|
2429 CleanupStack::PopAndDestroy(ro); |
|
2430 ro = NULL; |
|
2431 } |
|
2432 pos = 0; |
|
2433 } |
|
2434 |
|
2435 /* At least one timestamp was found */ |
|
2436 if (indexLatest >= 0 && indexLatest < rights->Count()) |
|
2437 { |
|
2438 ro = DRMDB.GetDomainROL(*(*rights)[indexLatest]->iRoID); |
|
2439 CleanupStack::PushL(ro); |
|
2440 |
|
2441 roSize = ro->Size(); |
|
2442 if ( !iPreparedData ) |
|
2443 { |
|
2444 iPreparedData = HBufC8::NewL(sizeof (TInt) + roSize); |
|
2445 } |
|
2446 else |
|
2447 { |
|
2448 iPreparedData = iPreparedData->ReAllocL( |
|
2449 size + sizeof (TInt) + roSize ); |
|
2450 } |
|
2451 ptr.Set(iPreparedData->Des()); |
|
2452 ptr.Append(roSizePkg); |
|
2453 ptr.Append(*ro); |
|
2454 size += sizeof (TInt) + roSize; |
|
2455 CleanupStack::PopAndDestroy(ro); |
|
2456 } |
|
2457 |
|
2458 aMessage.Write(1, pkg); |
|
2459 CleanupStack::PopAndDestroy( id ); |
|
2460 CleanupStack::PopAndDestroy( rights ); |
|
2461 |
|
2462 aMessage.Complete(KErrNone); |
|
2463 DRMLOG(_L("CDRMDbSession::GetDomainRosForCidL ok")); |
|
2464 } |
|
2465 |
|
2466 |
|
2467 //------------------------------------------------------------------------------ |
|
2468 // CDRMDbSession::DeleteExpiredPermissionsL |
|
2469 // Delete expired permissions if we have secure time. |
|
2470 //------------------------------------------------------------------------------ |
|
2471 void CDRMDbSession::DeleteExpiredPermissionsL( const RMessage2& aMessage ) |
|
2472 { |
|
2473 DRMLOG( _L( "CDRMDbSession::DeleteExpiredPermissionsL" ) ); |
|
2474 CDRMActiveOperation* active( NULL ); |
|
2475 TTime time; |
|
2476 |
|
2477 User::LeaveIfError( VerifyCredentials(NULL, NULL, EUnknown) ); |
|
2478 if( iCredentialsChecked == ECheckedAndDenied ) |
|
2479 { |
|
2480 User::Leave( KErrPermissionDenied ); |
|
2481 } |
|
2482 |
|
2483 UpdateSecureTime(); |
|
2484 |
|
2485 if ( iSecureTime ) |
|
2486 { |
|
2487 time = iTrustedTime; |
|
2488 } |
|
2489 else |
|
2490 { |
|
2491 time = Time::NullTTime(); |
|
2492 } |
|
2493 |
|
2494 if ( iPendingRequest ) |
|
2495 { |
|
2496 User::Leave( KErrAlreadyExists ); |
|
2497 } |
|
2498 |
|
2499 active = CDRMActiveOperation::NewLC( aMessage, *this, |
|
2500 CDRMActiveOperation::EOperationDeleteExpired ); |
|
2501 active->ActivateL( DRMDB, iTrustedTime ); |
|
2502 |
|
2503 iPendingRequest = active; |
|
2504 |
|
2505 CleanupStack::Pop( active ); |
|
2506 |
|
2507 DRMLOG( _L( "CDRMDbSession::DeleteExpiredPermissionsL ok" ) ); |
|
2508 } |
|
2509 |
|
2510 // ----------------------------------------------------------------------------- |
|
2511 // CDRMDbSession::SetEstimatedArrivalL |
|
2512 // set the estimated arrival time for the content uri |
|
2513 // ----------------------------------------------------------------------------- |
|
2514 // |
|
2515 void CDRMDbSession::SetEstimatedArrivalL( const RMessage2& aMessage ) |
|
2516 { |
|
2517 HBufC8* CID = NULL; |
|
2518 TFileName fileName; |
|
2519 TInt length = 0; |
|
2520 TPtr8 inRead( NULL, 0 ); |
|
2521 TTimeIntervalSeconds interval = 0; |
|
2522 TPckg<TTimeIntervalSeconds> package( interval ); |
|
2523 RPointerArray<CDRMXOma>& array = XOMAHEADER; |
|
2524 CDRMXOma* omaData = NULL; |
|
2525 |
|
2526 // Read the content id |
|
2527 length = User::LeaveIfError( IPCGETDESLEN0 ); |
|
2528 CID = HBufC8::NewLC( length ); |
|
2529 inRead.Set( CID->Des() ); |
|
2530 IPCREAD0L( inRead ); |
|
2531 |
|
2532 // Read the interval |
|
2533 IPCREAD1L( package ); |
|
2534 |
|
2535 |
|
2536 for( TInt i = 0; i < array.Count(); i++ ) |
|
2537 { |
|
2538 if( !CID->Compare( (array)[i]->ContentID() ) ) |
|
2539 { |
|
2540 omaData = (array)[i]; |
|
2541 break; |
|
2542 } |
|
2543 } |
|
2544 |
|
2545 // Update the secure time |
|
2546 UpdateSecureTime(); |
|
2547 |
|
2548 if( omaData ) // Exists, update |
|
2549 { |
|
2550 omaData->SetWaitTimeL( interval ); |
|
2551 omaData->SetTimeStampL( iTrustedTime ); |
|
2552 } |
|
2553 else // Doesn't exist, create a new one |
|
2554 { |
|
2555 omaData = CDRMXOma::NewLC( *CID, iTrustedTime, interval ); |
|
2556 array.AppendL( omaData ); |
|
2557 CleanupStack::Pop( omaData ); |
|
2558 } |
|
2559 |
|
2560 CleanupStack::PopAndDestroy( CID ); |
|
2561 |
|
2562 // Complete the command |
|
2563 aMessage.Complete( KErrNone ); |
|
2564 }; |
|
2565 |
|
2566 // ----------------------------------------------------------------------------- |
|
2567 // CDRMDbSession::GetEstimatedArrivalL |
|
2568 // get the estimated arrival time for the content uri |
|
2569 // ----------------------------------------------------------------------------- |
|
2570 // |
|
2571 void CDRMDbSession::GetEstimatedArrivalL( const RMessage2& aMessage ) |
|
2572 { |
|
2573 HBufC8* CID = NULL; |
|
2574 TInt length = 0; |
|
2575 TPtr8 inRead( NULL, 0 ); |
|
2576 RPointerArray<CDRMXOma>& array = XOMAHEADER; |
|
2577 CDRMXOma* omaData = NULL; |
|
2578 TInt64 interval = 0; |
|
2579 TInt i = 0; |
|
2580 TTimeIntervalSeconds result = 0; |
|
2581 |
|
2582 // Read the content id |
|
2583 length = User::LeaveIfError( IPCGETDESLEN0 ); |
|
2584 CID = HBufC8::NewLC( length ); |
|
2585 inRead.Set( CID->Des() ); |
|
2586 IPCREAD0L( inRead ); |
|
2587 |
|
2588 for( ; i < array.Count(); i++ ) |
|
2589 { |
|
2590 if( !CID->Compare( (array)[i]->ContentID() ) ) |
|
2591 { |
|
2592 omaData = (array)[i]; |
|
2593 break; |
|
2594 } |
|
2595 } |
|
2596 |
|
2597 // Update the secure time |
|
2598 UpdateSecureTime(); |
|
2599 |
|
2600 if( omaData ) // Exists, update |
|
2601 { |
|
2602 |
|
2603 // Special case, the rights have expired before, but have not been removed |
|
2604 // so that we do not lose the notification |
|
2605 if( omaData->WaitTime().Int() == KErrCAPendingRights ) |
|
2606 { |
|
2607 interval = -1; // Fixed value for this case: |
|
2608 // -1 means the rights should have arrived already |
|
2609 |
|
2610 delete omaData; |
|
2611 omaData = 0; |
|
2612 |
|
2613 array.Remove( i ); |
|
2614 } |
|
2615 else |
|
2616 { |
|
2617 // Update the secure time |
|
2618 UpdateSecureTime(); |
|
2619 |
|
2620 interval = omaData->WaitTime().Int(); |
|
2621 interval -= ( iTrustedTime.Int64() - omaData->TimeStamp().Int64() ) / |
|
2622 KMicrosecondsToSecond; |
|
2623 |
|
2624 if( interval <= 0 ) |
|
2625 { |
|
2626 interval = -1; // Fixed value for this case: |
|
2627 // -1 means the rights should have arrived already |
|
2628 |
|
2629 // Clean up the data: if the function fails before this |
|
2630 // the instance remains like it should |
|
2631 delete omaData; |
|
2632 omaData = 0; |
|
2633 |
|
2634 array.Remove( i ); // Remove from the array |
|
2635 } |
|
2636 } |
|
2637 result = I64INT(interval); |
|
2638 TPckg<TTimeIntervalSeconds> package( result ); |
|
2639 IPCWRITE1L( package ); |
|
2640 } |
|
2641 else // Doesn't exist, create a new one |
|
2642 { |
|
2643 User::Leave( KErrNotFound ); |
|
2644 } |
|
2645 |
|
2646 CleanupStack::PopAndDestroy( CID ); |
|
2647 |
|
2648 // Complete the command |
|
2649 aMessage.Complete( KErrNone ); |
|
2650 }; |
|
2651 |
|
2652 |
|
2653 |
|
2654 //------------------------------------------------------------------------------ |
|
2655 // CDRMDbSession::PendingRights |
|
2656 // Check if rights are pending |
|
2657 //------------------------------------------------------------------------------ |
|
2658 TBool CDRMDbSession::PendingRights(const TDesC8& aCid, TBool aRemoval) |
|
2659 { |
|
2660 TBool f = EFalse; |
|
2661 RPointerArray<CDRMXOma>& array = XOMAHEADER; |
|
2662 CDRMXOma* omaData = NULL; |
|
2663 TInt64 interval = 0; |
|
2664 TInt i = 0; |
|
2665 TTimeIntervalSeconds result = 0; |
|
2666 |
|
2667 for( ; i < array.Count() && !f; i++ ) |
|
2668 { |
|
2669 if( !aCid.Compare( (array)[i]->ContentID() ) ) |
|
2670 { |
|
2671 omaData = (array)[i]; |
|
2672 // Exists and is different from KErrCAPendingRights -> update |
|
2673 if( omaData && omaData->WaitTime().Int() != KErrCAPendingRights ) |
|
2674 { |
|
2675 // Update the secure time |
|
2676 UpdateSecureTime(); |
|
2677 interval = omaData->WaitTime().Int(); |
|
2678 interval -= ( iTrustedTime.Int64() - omaData->TimeStamp().Int64() ) / |
|
2679 KMicrosecondsToSecond; |
|
2680 |
|
2681 // check if removal from the list is needed |
|
2682 if( aRemoval && interval <= 0 ) |
|
2683 { |
|
2684 TRAPD( error, omaData->SetWaitTimeL( KErrCAPendingRights ) ); |
|
2685 error = error; // remove error |
|
2686 } |
|
2687 f = ETrue; |
|
2688 } |
|
2689 } |
|
2690 } |
|
2691 return f; |
|
2692 } |
|
2693 |
|
2694 |
|
2695 |
|
2696 //------------------------------------------------------------------------------ |
|
2697 // CDRMDbSession::GetUdtDataL |
|
2698 // Gets the user data transfer header data |
|
2699 //------------------------------------------------------------------------------ |
|
2700 void CDRMDbSession::GetUdtDataL( const RMessage2& aMessage ) |
|
2701 { |
|
2702 DRMLOG( _L( "CDRMDbSession::GetUdtDataL" ) ); |
|
2703 __UHEAP_MARK; |
|
2704 // Usage intent. |
|
2705 HBufC8* udtData = NULL; |
|
2706 |
|
2707 // Get the key |
|
2708 udtData = DRMDB.GetUdtDataLC(); |
|
2709 |
|
2710 // Write the udt data to the client. |
|
2711 // This shouldn't fail anyway. |
|
2712 IPCWRITE0L( *udtData ); |
|
2713 |
|
2714 CleanupStack::PopAndDestroy( udtData ); |
|
2715 |
|
2716 aMessage.Complete( KErrNone ); |
|
2717 __UHEAP_MARKEND; |
|
2718 DRMLOG( _L( "CDRMDbSession::GetUdtDataL: Ok" ) ); |
|
2719 }; |
|
2720 |
|
2721 //------------------------------------------------------------------------------ |
|
2722 // CDRMDbSession::InitiateUdtL |
|
2723 // Initiate user data transfer |
|
2724 //------------------------------------------------------------------------------ |
|
2725 void CDRMDbSession::InitiateUdtL( const RMessage2& aMessage ) |
|
2726 { |
|
2727 DRMLOG( _L( "CDRMDbSession::InitiateUdtL" ) ); |
|
2728 __UHEAP_MARK; |
|
2729 |
|
2730 HBufC8* encryptionKey = NULL; |
|
2731 TInt size = 0; |
|
2732 TPtr8 data( NULL, 0 ); |
|
2733 |
|
2734 SanitizeL( aMessage.GetDesLength(0)); |
|
2735 |
|
2736 size = User::LeaveIfError( IPCGETDESLEN0 ); |
|
2737 encryptionKey = HBufC8::NewLC( size ); |
|
2738 |
|
2739 data.Set( encryptionKey->Des() ); |
|
2740 IPCREAD0L( data ); |
|
2741 |
|
2742 // The encrypted data is encrypted with 2048 byte key, it always needs to be atleast this long |
|
2743 if( encryptionKey->Length() < 254) |
|
2744 { |
|
2745 User::Leave(KErrArgument); |
|
2746 } |
|
2747 |
|
2748 DRMDB.InitiateUdtL( *encryptionKey ); |
|
2749 |
|
2750 CleanupStack::PopAndDestroy( encryptionKey ); |
|
2751 |
|
2752 aMessage.Complete( KErrNone ); |
|
2753 __UHEAP_MARKEND; |
|
2754 |
|
2755 DRMLOG( _L( "CDRMDbSession::InitiateUdtL done" ) ); |
|
2756 }; |
|
2757 |
|
2758 //------------------------------------------------------------------------------ |
|
2759 // CDRMDbSession::InitExportOrhanedCIDsL |
|
2760 // Create and export the list of orphaned content id's |
|
2761 //------------------------------------------------------------------------------ |
|
2762 void CDRMDbSession::InitExportOrphanedCIDsL( const RMessage2& aMessage ) |
|
2763 { |
|
2764 DRMLOG( _L( "CDRMDbSession::InitExportOrphanedCIDsL" ) ); |
|
2765 CDRMActiveOperation* active( NULL ); |
|
2766 TBool performScan = EFalse; |
|
2767 |
|
2768 User::LeaveIfError( VerifyCredentials(NULL,NULL,ContentAccess::EUnknown) ); |
|
2769 |
|
2770 if ( iPendingRequest ) |
|
2771 { |
|
2772 User::Leave( KErrAlreadyExists ); |
|
2773 } |
|
2774 |
|
2775 // if the old filename exists, delete it, a new operation starts |
|
2776 if( iFileName ) |
|
2777 { |
|
2778 delete iFileName; |
|
2779 iFileName = NULL; |
|
2780 } |
|
2781 |
|
2782 // Read the scan data: |
|
2783 performScan = aMessage.Int0() != 0 ? ETrue : EFalse; |
|
2784 |
|
2785 |
|
2786 active = CDRMActiveOperation::NewLC( aMessage, *this, |
|
2787 CDRMActiveOperation::EOperationExportObsolete ); |
|
2788 |
|
2789 #ifndef RD_MULTIPLE_DRIVE |
|
2790 |
|
2791 active->ActivateL( DRMDB, RFSSESSION, KDRMDbTempPath, performScan ); |
|
2792 |
|
2793 #else //RD_MULTIPLE_DRIVE |
|
2794 |
|
2795 TInt driveNumber( -1 ); |
|
2796 TChar driveLetter; |
|
2797 DriveInfo::GetDefaultDrive( DriveInfo::EDefaultSystem, driveNumber ); |
|
2798 |
|
2799 RFSSESSION.DriveToChar( driveNumber, driveLetter ); |
|
2800 |
|
2801 TFileName dbTempPath; |
|
2802 dbTempPath.Format( KDbTempPath, (TUint)driveLetter ); |
|
2803 |
|
2804 active->ActivateL( DRMDB, RFSSESSION, dbTempPath, performScan ); |
|
2805 |
|
2806 #endif |
|
2807 |
|
2808 iPendingRequest = active; |
|
2809 |
|
2810 CleanupStack::Pop( active ); |
|
2811 |
|
2812 DRMLOG( _L( "CDRMDbSession::InitExportOrphanedCIDsL: ok" ) ); |
|
2813 }; |
|
2814 |
|
2815 |
|
2816 //------------------------------------------------------------------------------ |
|
2817 // CDRMDbSession::ExportOrhanedCIDsL |
|
2818 // Create and export the list of orphaned content id's |
|
2819 //------------------------------------------------------------------------------ |
|
2820 void CDRMDbSession::ExportOrphanedCIDsL( const RMessage2& aMessage ) |
|
2821 { |
|
2822 DRMLOG( _L( "CDRMDbSession::ExportOrphanedCIDsL" ) ); |
|
2823 if( !iFileName ) |
|
2824 { |
|
2825 aMessage.Complete( KErrNotReady ); |
|
2826 return; |
|
2827 } |
|
2828 |
|
2829 if( iFileName->Length() > aMessage.GetDesMaxLength(0) ) |
|
2830 { |
|
2831 User::Leave(KErrArgument); |
|
2832 } |
|
2833 |
|
2834 // It is virtually impossible to make WriteL to leave in this case, |
|
2835 // but anything is still possible... |
|
2836 IPCWRITE0L( *iFileName ); |
|
2837 |
|
2838 // if everything went well, delete the filename if not leave it |
|
2839 delete iFileName; |
|
2840 iFileName = NULL; |
|
2841 |
|
2842 // All done |
|
2843 aMessage.Complete( KErrNone ); |
|
2844 |
|
2845 DRMLOG( _L( "CDRMDbSession::ExportOrphanedCIDsL: ok" ) ); |
|
2846 }; |
|
2847 |
|
2848 // ---------------------------------------------------------------------------- |
|
2849 // CDRMDbSession::UnwrapMacAndRekL |
|
2850 // Unwraps public key encrypted MAC and REK keys |
|
2851 // ---------------------------------------------------------------------------- |
|
2852 // |
|
2853 void CDRMDbSession::UnwrapMacAndRekL( const RMessage2& aMessage, TBool aDomainRo ) |
|
2854 { |
|
2855 DRMLOG( _L( "CDRMDbSession::UnwrapMacAndRekL" ) ); |
|
2856 |
|
2857 __UHEAP_MARK; |
|
2858 |
|
2859 MDrmKeyStorage* storage; |
|
2860 TBuf8<OmaCrypto::KMacSize> mac; |
|
2861 TBuf8<OmaCrypto::KKeySize> rek; |
|
2862 HBufC8* data = NULL; |
|
2863 TPtr8 dataPtr(0, 0); |
|
2864 TPtrC8 macAndRekPtr(0, 0); |
|
2865 HBufC8* riId = NULL; |
|
2866 TPtr8 riIdPtr(0, 0); |
|
2867 HBufC8* domainId = NULL; |
|
2868 TPtr8 domainIdPtr(0, 0); |
|
2869 CDRMRIContext* riContext = NULL; |
|
2870 TInt size = 0; |
|
2871 TKeyTransportScheme transport; |
|
2872 HBufC8* unwrappedMacAndRek = NULL; |
|
2873 CDRMDomainContext* domainContext; |
|
2874 HBufC8* domainKey = NULL; |
|
2875 |
|
2876 DRMLOG(_L("CDRMDbSession::UnwrapMacAndRekL")); |
|
2877 |
|
2878 |
|
2879 |
|
2880 SanitizeL( aMessage.GetDesLength(0) ); |
|
2881 SanitizeL( aMessage.GetDesLength(1) ); |
|
2882 |
|
2883 size = User::LeaveIfError( IPCGETDESLEN0 ); |
|
2884 data = HBufC8::NewLC( size ); |
|
2885 |
|
2886 size = User::LeaveIfError( IPCGETDESLEN1 ); |
|
2887 riId = HBufC8::NewLC( size ); |
|
2888 |
|
2889 if(aDomainRo) |
|
2890 { |
|
2891 SanitizeL( aMessage.GetDesLength(2) ); |
|
2892 size = User::LeaveIfError( IPCGETDESLEN2 ); |
|
2893 domainId = HBufC8::NewLC( size ); |
|
2894 } |
|
2895 |
|
2896 dataPtr.Set( data->Des() ); |
|
2897 IPCREAD0L( dataPtr ); |
|
2898 |
|
2899 riIdPtr.Set( riId->Des() ); |
|
2900 IPCREAD1L( riIdPtr ); |
|
2901 |
|
2902 if(aDomainRo) |
|
2903 { |
|
2904 domainIdPtr.Set( domainId->Des() ); |
|
2905 IPCREAD2L( domainIdPtr ); |
|
2906 } |
|
2907 |
|
2908 // The first byte defines the transport scheme |
|
2909 transport = static_cast<TKeyTransportScheme>(dataPtr[0]); |
|
2910 macAndRekPtr.Set(dataPtr.Mid(1)); |
|
2911 |
|
2912 DRMLOG2(_L("Transport scheme: %d"), transport); |
|
2913 DRMLOG(_L("MAC + REK:")); |
|
2914 DRMLOGHEX(macAndRekPtr); |
|
2915 |
|
2916 if ( !iRoapClientConnected ) |
|
2917 { |
|
2918 User::LeaveIfError( iRoapClient.Connect() ); |
|
2919 iRoapClientConnected = ETrue; |
|
2920 } |
|
2921 |
|
2922 if (!aDomainRo) |
|
2923 { |
|
2924 // get the trusted root from the rights issuer context |
|
2925 riContext = iRoapClient.GetRIContextL(riIdPtr); |
|
2926 if ( !riContext ) |
|
2927 { |
|
2928 DRMLOG(_L("RI not registered")); |
|
2929 User::Leave(KErrRightsServerRiNotRegistered); |
|
2930 } |
|
2931 CleanupStack::PushL(riContext); |
|
2932 // connect to the storage of our PKI keys |
|
2933 storage = DrmKeyStorageNewL(); |
|
2934 TCleanupItem storageCleanup( DeleteObject, storage ); |
|
2935 CleanupStack::PushL(storageCleanup); |
|
2936 storage->SelectTrustedRootL(riContext->SelectedDeviceRoot()); |
|
2937 |
|
2938 if (transport == EOma) |
|
2939 { |
|
2940 OmaCrypto::RsaKemKwsDecryptL(storage, macAndRekPtr, rek, mac); |
|
2941 } |
|
2942 else |
|
2943 { |
|
2944 CmlaCrypto::CmlaIpDecryptL(transport, storage, macAndRekPtr, rek, mac); |
|
2945 } |
|
2946 CleanupStack::PopAndDestroy(4, data); |
|
2947 } |
|
2948 else |
|
2949 { |
|
2950 domainContext = iRoapClient.GetDomainContextL(domainIdPtr); |
|
2951 if ( !domainContext ) |
|
2952 { |
|
2953 DRMLOG(_L("Domain not registered")); |
|
2954 User::Leave(KErrRightsServerDomainNotRegistered); |
|
2955 } |
|
2956 CleanupStack::PushL(domainContext); |
|
2957 |
|
2958 // last three digits presents the domain generation |
|
2959 TInt generation = 0; |
|
2960 TLex8 lex( domainIdPtr.Right(3)); |
|
2961 lex.Val(generation); |
|
2962 |
|
2963 domainKey = domainContext->DomainKeyL(generation); |
|
2964 CleanupStack::PushL( domainKey ); |
|
2965 |
|
2966 // unwrap MAC and REK first with the domain key, the CEK with REK |
|
2967 unwrappedMacAndRek = OmaCrypto::AesUnwrapL(*domainKey, macAndRekPtr); |
|
2968 CleanupStack::PushL(unwrappedMacAndRek); |
|
2969 |
|
2970 mac.Copy( unwrappedMacAndRek->Left( OmaCrypto::KKeySize) ); |
|
2971 rek.Copy( unwrappedMacAndRek->Right( OmaCrypto::KKeySize) ); |
|
2972 CleanupStack::PopAndDestroy(6, data); |
|
2973 } |
|
2974 |
|
2975 DRMLOG(_L("REK:")); |
|
2976 DRMLOGHEX(rek); |
|
2977 DRMLOG(_L("MAC:")); |
|
2978 DRMLOGHEX(mac); |
|
2979 |
|
2980 iMac.Copy(mac); |
|
2981 iRek.Copy(rek); |
|
2982 |
|
2983 aMessage.Complete( KErrNone ); |
|
2984 |
|
2985 __UHEAP_MARKEND; |
|
2986 |
|
2987 DRMLOG( _L( "CDRMDbSession::UnwrapMacAndRekL: ok" ) ); |
|
2988 } |
|
2989 |
|
2990 //------------------------------------------------------------------------------ |
|
2991 // CDRMDbSession::FindParentsAndRemoveUnusableL() |
|
2992 // Find the best ROs from aList and store references to aBest. |
|
2993 //------------------------------------------------------------------------------ |
|
2994 void CDRMDbSession::FindParentsAndRemoveUnusableL( RDRMPermissionList& aList, |
|
2995 const TDesC8& aURI, |
|
2996 CDRMPointerArray<HBufC8>& aCids, |
|
2997 const TIntent aIntent, |
|
2998 const TTime& aDrmTime, |
|
2999 TUint32& aReason ) |
|
3000 { |
|
3001 |
|
3002 CDRMPermissionList *permList = NULL; |
|
3003 TInt error = KErrNone; |
|
3004 HBufC8* uri = NULL; |
|
3005 |
|
3006 aCids.ResetAndDestroy(); |
|
3007 |
|
3008 |
|
3009 // to separate parents and children we store the content id, since the content id is needed |
|
3010 // by drm consume: |
|
3011 for( TInt count = 0; count < aList.Count(); count++ ) |
|
3012 { |
|
3013 uri = aURI.AllocLC(); |
|
3014 aCids.AppendL( uri ); |
|
3015 CleanupStack::Pop( uri ); // uri |
|
3016 } |
|
3017 |
|
3018 |
|
3019 // Go though the list and remove the unusable RO's |
|
3020 for( TInt i = aList.Count() - 1 ; i >= 0; i-- ) |
|
3021 { |
|
3022 // If the RO has valid parent rights add them to the list |
|
3023 if( aList[i]->iParentUID ) |
|
3024 { |
|
3025 permList = CDRMPermissionList::NewLC(); |
|
3026 permList->SetAutoCleanup( ETrue ); |
|
3027 |
|
3028 TRAP( error, DRMDB.GetDBEntryByContentIDL( *aList[i]->iParentUID, *permList )); |
|
3029 if( !error ) |
|
3030 { |
|
3031 for( TInt j = 0; j < permList->Count(); j++ ) |
|
3032 { |
|
3033 // check if the permission is valid and if the RI ID for child and parent |
|
3034 // match |
|
3035 if ( aList[i]->iRiId.Compare( (*permList)[j]->iRiId ) == 0 && |
|
3036 IsValidPermissionL( *(*permList)[j], aIntent, aDrmTime, aReason ) ) |
|
3037 { |
|
3038 aList.AppendL( (*permList)[j] ); |
|
3039 (*permList)[j] = 0; |
|
3040 uri = aList[i]->iParentUID->AllocLC(); |
|
3041 aCids.AppendL( uri ); |
|
3042 CleanupStack::Pop( uri ); |
|
3043 } |
|
3044 } |
|
3045 } |
|
3046 CleanupStack::PopAndDestroy( permList ); |
|
3047 } |
|
3048 |
|
3049 // If the child is not valid remove it from the list |
|
3050 if ( !IsValidPermissionL( *aList[i], aIntent, aDrmTime, aReason ) ) |
|
3051 { |
|
3052 CDRMPermission* perm = aList[i]; |
|
3053 delete perm; |
|
3054 aList.Remove( i ); |
|
3055 |
|
3056 uri = aCids[i]; |
|
3057 delete uri; |
|
3058 aCids.Remove( i ); |
|
3059 perm = NULL; |
|
3060 uri = NULL; |
|
3061 } |
|
3062 } |
|
3063 // Now the list should contain only valid RO's or parents of the RO's |
|
3064 // which are valid |
|
3065 } |
|
3066 |
|
3067 |
|
3068 //------------------------------------------------------------------------------ |
|
3069 // CDRMDbSession::FindBestROsL |
|
3070 // Find the best ROs from aList and store references to aBest. |
|
3071 //------------------------------------------------------------------------------ |
|
3072 TInt CDRMDbSession::FindBestROsL( |
|
3073 RDRMPermissionList& aList, |
|
3074 const TDesC8& aURI, |
|
3075 const TIntent aIntent, |
|
3076 HBufC8*& aUsedURI, |
|
3077 TUint32& aReason ) |
|
3078 { |
|
3079 TTime time = Time::NullTTime(); |
|
3080 CDRMPointerArray<HBufC8>* uriList = CDRMPointerArray<HBufC8>::NewLC(); |
|
3081 uriList->SetAutoCleanup(ETrue); |
|
3082 |
|
3083 TInt bestRo = -1; |
|
3084 |
|
3085 if ( iSecureTime ) |
|
3086 { |
|
3087 time = iTrustedTime; |
|
3088 } |
|
3089 else |
|
3090 { |
|
3091 time = Time::NullTTime(); |
|
3092 } |
|
3093 |
|
3094 FindParentsAndRemoveUnusableL( aList, aURI, *uriList, aIntent, time, aReason ); |
|
3095 |
|
3096 if( aList.Count() == 0 ) |
|
3097 { |
|
3098 User::Leave(KErrCANoPermission); |
|
3099 } |
|
3100 |
|
3101 bestRo = GetBestROL( aList, aIntent, aReason ); |
|
3102 |
|
3103 // Delete if it already exists |
|
3104 if( aUsedURI ) |
|
3105 { |
|
3106 delete aUsedURI; |
|
3107 } |
|
3108 aUsedURI = NULL; |
|
3109 |
|
3110 // if it's not the same as the normal URI return a value otherwise NULL |
|
3111 if( (*uriList)[ bestRo ]->Compare( aURI ) ) |
|
3112 { |
|
3113 aUsedURI = (*uriList)[ bestRo ]->AllocL(); |
|
3114 } |
|
3115 |
|
3116 CleanupStack::PopAndDestroy( uriList ); |
|
3117 return bestRo; |
|
3118 } |
|
3119 |
|
3120 // ----------------------------------------------------------------------------- |
|
3121 // CDRMDbSession::IsValidPermissionL |
|
3122 // ETrue if not expired. If the candidate has expired permission (intent, |
|
3123 // not top level), ETrue is returned if the child knows it is a child. |
|
3124 // ----------------------------------------------------------------------------- |
|
3125 TBool CDRMDbSession::IsValidPermissionL( |
|
3126 CDRMPermission& aPermission, |
|
3127 const ContentAccess::TIntent aIntent, |
|
3128 const TTime& aTime, |
|
3129 TUint32& aReason ) |
|
3130 { |
|
3131 CDRMConstraint* toplevel = NULL; |
|
3132 CDRMConstraint* constraint = NULL; |
|
3133 CDRMDomainContext* domainContext = NULL; |
|
3134 TBool r = ETrue; |
|
3135 #ifdef RD_DRM_METERING |
|
3136 CDRMRIContext* riContext = NULL; |
|
3137 #endif |
|
3138 |
|
3139 toplevel = aPermission.TopLevelConstraint(); |
|
3140 if ( toplevel && ( !( toplevel->Valid( aTime, IMSI, aReason ) ) ) ) |
|
3141 { |
|
3142 r = EFalse; |
|
3143 } |
|
3144 else |
|
3145 { |
|
3146 constraint = aPermission.ConstraintForIntent( aIntent ); |
|
3147 if ( !constraint || constraint && |
|
3148 ( !( constraint->Valid( aTime, IMSI, aReason ) ) ) ) |
|
3149 { |
|
3150 r = EFalse; |
|
3151 } |
|
3152 else if ( aPermission.iDomainID ) |
|
3153 { |
|
3154 if ( !iRoapClientConnected ) |
|
3155 { |
|
3156 User::LeaveIfError( iRoapClient.Connect() ); |
|
3157 iRoapClientConnected = ETrue; |
|
3158 } |
|
3159 domainContext = iRoapClient.GetDomainContextL( *aPermission.iDomainID ); |
|
3160 if ( domainContext ) |
|
3161 { |
|
3162 delete domainContext; |
|
3163 } |
|
3164 else |
|
3165 { |
|
3166 r = EFalse; |
|
3167 } |
|
3168 |
|
3169 } |
|
3170 |
|
3171 // If the constraint is software constrained and the sw secureid does not match |
|
3172 // remove it from the list handling |
|
3173 if( r && aPermission.SoftwareConstrained() ) |
|
3174 { |
|
3175 _LIT_SECURITY_POLICY_S0(swSidCheck, constraint->iSecureId.iUid); |
|
3176 if (constraint->iActiveConstraints & EConstraintSoftware) |
|
3177 { |
|
3178 if (!swSidCheck().CheckPolicy(iClient)) |
|
3179 { |
|
3180 r = EFalse; |
|
3181 } |
|
3182 } |
|
3183 } |
|
3184 } |
|
3185 |
|
3186 #ifdef RD_DRM_METERING |
|
3187 |
|
3188 // Check if metering restricts the content usage |
|
3189 if ( r != EFalse && constraint->iDrmMeteringInfo && |
|
3190 !constraint->iDrmMeteringInfo->iAllowUseWithoutMetering ) |
|
3191 { |
|
3192 if ( !iRoapClientConnected ) |
|
3193 { |
|
3194 User::LeaveIfError( iRoapClient.Connect() ); |
|
3195 iRoapClientConnected = ETrue; |
|
3196 } |
|
3197 riContext = iRoapClient.GetRIContextL( aPermission.iRiId ); |
|
3198 if ( !riContext || !riContext->IsMeteringAllowed() ) |
|
3199 { |
|
3200 aReason |= EConstraintMetering; |
|
3201 return EFalse; |
|
3202 } |
|
3203 } |
|
3204 |
|
3205 delete riContext; |
|
3206 |
|
3207 #endif |
|
3208 |
|
3209 return r; |
|
3210 } |
|
3211 |
|
3212 //------------------------------------------------------------------------------ |
|
3213 // CDRMDbSession::GetBestROL |
|
3214 // Find the best ROs from aList and store references to aBest. |
|
3215 //------------------------------------------------------------------------------ |
|
3216 TInt CDRMDbSession::GetBestROL( |
|
3217 RDRMPermissionList& aList, |
|
3218 const TIntent aIntent, |
|
3219 TUint32& aReason ) |
|
3220 { |
|
3221 TInt count( 0 ); |
|
3222 TTime time; |
|
3223 |
|
3224 CDRMConstraint* normalized = CDRMConstraint::NewLC(); |
|
3225 CDRMConstraint* bestOne = CDRMConstraint::NewLC(); |
|
3226 |
|
3227 TInt bestRo( -1 ); |
|
3228 |
|
3229 if ( iSecureTime ) |
|
3230 { |
|
3231 time = iTrustedTime; |
|
3232 } |
|
3233 else |
|
3234 { |
|
3235 time = Time::NullTTime(); |
|
3236 } |
|
3237 |
|
3238 // 'count' is updated if something useful is found, and aList is |
|
3239 // updated if the permission cannot be used. |
|
3240 while ( count < aList.Count() ) |
|
3241 { |
|
3242 CDRMPermission* perm = aList[ count ]; |
|
3243 TBool found( EFalse ); |
|
3244 |
|
3245 // If there is no constraint for the intent, there is no need to normalize |
|
3246 // There can be no rights to use in that permission |
|
3247 if( perm->ConstraintForIntent( aIntent ) ) |
|
3248 { |
|
3249 Normalize( *perm, *normalized, aIntent ); |
|
3250 if ( normalized->Valid( time, IMSI, aReason ) ) |
|
3251 { |
|
3252 found = ETrue; |
|
3253 } |
|
3254 } |
|
3255 |
|
3256 if ( found ) |
|
3257 { |
|
3258 // Compare whether "normalized" is more suitable than "bestOne". |
|
3259 // If this is the first usable child & parent combination, |
|
3260 // take it. |
|
3261 if ( ( bestRo < 0 ) || BetterPermission( *normalized, *bestOne ) ) |
|
3262 { |
|
3263 // "normalized" is the new "bestOne" |
|
3264 CDRMConstraint* temp = bestOne; |
|
3265 bestOne = normalized; |
|
3266 normalized = temp; |
|
3267 |
|
3268 bestRo = count; |
|
3269 |
|
3270 ++count; |
|
3271 } |
|
3272 else |
|
3273 { |
|
3274 // This isn't any better than the previous ones. Throw it away. |
|
3275 found = EFalse; |
|
3276 } |
|
3277 } |
|
3278 |
|
3279 if ( !found ) |
|
3280 { |
|
3281 // Unusable child. |
|
3282 delete perm; perm = NULL; |
|
3283 aList.Remove( count ); |
|
3284 } |
|
3285 } |
|
3286 |
|
3287 CleanupStack::PopAndDestroy( 2 ); // bestOne, normalized |
|
3288 |
|
3289 return bestRo; |
|
3290 } |
|
3291 |
|
3292 // ----------------------------------------------------------------------------- |
|
3293 // CDRMDbSession::Normalize |
|
3294 // Normalizes a permission. |
|
3295 // ----------------------------------------------------------------------------- |
|
3296 void CDRMDbSession::Normalize( CDRMPermission& aPermission, |
|
3297 CDRMConstraint& aNormalized, |
|
3298 const ContentAccess::TIntent aIntent ) |
|
3299 { |
|
3300 __ASSERT_DEBUG( aPermission.ConstraintForIntent( aIntent ), User::Invariant() ); |
|
3301 |
|
3302 TRAPD( error, aNormalized.DuplicateL( *( aPermission.ConstraintForIntent( aIntent ) ) ) ); |
|
3303 if( !error ) |
|
3304 { |
|
3305 if ( aPermission.TopLevelConstraint() ) |
|
3306 { |
|
3307 aNormalized.Merge( *( aPermission.TopLevelConstraint() ) ); |
|
3308 } |
|
3309 } |
|
3310 } |
|
3311 // ----------------------------------------------------------------------------- |
|
3312 // CDRMDbSession::BetterPermission |
|
3313 // Compares two permissions, and returns ETrue if aNewOne is more suitable |
|
3314 // for the usage. Assumes both are valid, i.e. not expired. |
|
3315 // ----------------------------------------------------------------------------- |
|
3316 TBool CDRMDbSession::BetterPermission( const CDRMConstraint& aNewOne, |
|
3317 const CDRMConstraint& aOldOne ) |
|
3318 { |
|
3319 // Check Order: |
|
3320 // 1. Full |
|
3321 // 2. Start End, closest end time first |
|
3322 // 3. Interval, shortest first |
|
3323 // 4. Accumulated, shortest first |
|
3324 // 5. Timed Counter, least counters first, longest time first |
|
3325 // 6. Counter, least counters first or the first one found |
|
3326 |
|
3327 const TTime nullTime = Time::NullTTime(); |
|
3328 TTime oldTime = nullTime; |
|
3329 TTime newTime = nullTime; |
|
3330 TTime oldTimePos = nullTime; |
|
3331 TTime newTimePos = nullTime; |
|
3332 |
|
3333 // 1. Full |
|
3334 // If the old or new one is the ultimate one, don't bother to |
|
3335 // check anything else. |
|
3336 if ( aOldOne.iActiveConstraints == EConstraintNone ) |
|
3337 { |
|
3338 return EFalse; |
|
3339 } |
|
3340 |
|
3341 if ( aNewOne.iActiveConstraints == EConstraintNone ) |
|
3342 { |
|
3343 return ETrue; |
|
3344 } |
|
3345 |
|
3346 // 2. Start & End Time |
|
3347 // Choose the one with the closest end time first |
|
3348 // All RO's to this check are already checked to be valid |
|
3349 // ActiveIntervals Also hit this spot |
|
3350 |
|
3351 // First get the start and end times from the intervals if they are active or inactive: |
|
3352 if ( aOldOne.iActiveConstraints & EConstraintInterval ) |
|
3353 { |
|
3354 if( aOldOne.iIntervalStart == nullTime ) |
|
3355 { |
|
3356 oldTimePos = iTrustedTime; |
|
3357 oldTimePos += TTimeIntervalSeconds( aOldOne.iInterval ); |
|
3358 } |
|
3359 else |
|
3360 { |
|
3361 oldTime = aOldOne.iIntervalStart; |
|
3362 oldTime += TTimeIntervalSeconds( aOldOne.iInterval ); |
|
3363 } |
|
3364 } |
|
3365 |
|
3366 if( aNewOne.iActiveConstraints & EConstraintInterval ) |
|
3367 { |
|
3368 if( aNewOne.iIntervalStart == nullTime ) |
|
3369 { |
|
3370 newTimePos = iTrustedTime; |
|
3371 newTimePos += TTimeIntervalSeconds( aNewOne.iInterval ); |
|
3372 } |
|
3373 else |
|
3374 { |
|
3375 newTime = aNewOne.iIntervalStart; |
|
3376 newTime += TTimeIntervalSeconds( aNewOne.iInterval ); |
|
3377 } |
|
3378 } |
|
3379 |
|
3380 if ( aOldOne.iActiveConstraints & EConstraintEndTime || oldTime != nullTime ) |
|
3381 { |
|
3382 oldTime = EndTime( oldTime, aOldOne.iEndTime ); |
|
3383 |
|
3384 if ( aNewOne.iActiveConstraints & EConstraintEndTime || newTime != nullTime ) |
|
3385 { |
|
3386 newTime = EndTime( newTime, aNewOne.iEndTime ); |
|
3387 |
|
3388 if( newTime != oldTime ) |
|
3389 { |
|
3390 return ( newTime < oldTime ); |
|
3391 } |
|
3392 } |
|
3393 else |
|
3394 { |
|
3395 return EFalse; |
|
3396 } |
|
3397 } |
|
3398 else if ( aNewOne.iActiveConstraints & EConstraintEndTime || newTime != nullTime ) |
|
3399 { |
|
3400 return ETrue; |
|
3401 } |
|
3402 |
|
3403 |
|
3404 // 3. Inactive Intervals: |
|
3405 // Choose the one with the interval ending first: |
|
3406 // Continue here if the no SE's exist or SE's are the same |
|
3407 if( aOldOne.iActiveConstraints & EConstraintInterval ) |
|
3408 { |
|
3409 if( aNewOne.iActiveConstraints & EConstraintInterval ) |
|
3410 { |
|
3411 oldTimePos = EndTime( oldTime, oldTimePos ); |
|
3412 newTimePos = EndTime( newTime, newTimePos ); |
|
3413 |
|
3414 if( oldTimePos != newTimePos ) |
|
3415 { |
|
3416 return ( newTimePos < oldTimePos ); |
|
3417 } |
|
3418 } |
|
3419 else |
|
3420 { |
|
3421 if( aNewOne.iActiveConstraints & EConstraintAccumulated || |
|
3422 aNewOne.iActiveConstraints & EConstraintTimedCounter || |
|
3423 aNewOne.iActiveConstraints & EConstraintCounter ) |
|
3424 { |
|
3425 return EFalse; |
|
3426 } |
|
3427 else |
|
3428 { |
|
3429 return ETrue; |
|
3430 } |
|
3431 } |
|
3432 } |
|
3433 else if( aNewOne.iActiveConstraints & EConstraintInterval ) |
|
3434 { |
|
3435 if( aOldOne.iActiveConstraints & EConstraintAccumulated || |
|
3436 aOldOne.iActiveConstraints & EConstraintTimedCounter || |
|
3437 aOldOne.iActiveConstraints & EConstraintCounter ) |
|
3438 { |
|
3439 return ETrue; |
|
3440 } |
|
3441 else |
|
3442 { |
|
3443 return EFalse; |
|
3444 } |
|
3445 } |
|
3446 |
|
3447 // 4. Accumulated: |
|
3448 // Choose the shortest accumulated first |
|
3449 // Continue here if SE's or intervals do not exist or they are the same |
|
3450 if( aOldOne.iActiveConstraints & EConstraintAccumulated ) |
|
3451 { |
|
3452 if( aNewOne.iActiveConstraints & EConstraintAccumulated ) |
|
3453 { |
|
3454 if( aNewOne.iAccumulatedTime != aOldOne.iAccumulatedTime ) |
|
3455 { |
|
3456 return ( aNewOne.iAccumulatedTime < aOldOne.iAccumulatedTime ); |
|
3457 } |
|
3458 } |
|
3459 else |
|
3460 { |
|
3461 if( aNewOne.iActiveConstraints & EConstraintTimedCounter || |
|
3462 aNewOne.iActiveConstraints & EConstraintCounter ) |
|
3463 { |
|
3464 return EFalse; |
|
3465 } |
|
3466 else |
|
3467 { |
|
3468 return ETrue; |
|
3469 } |
|
3470 } |
|
3471 } |
|
3472 else if( aNewOne.iActiveConstraints & EConstraintAccumulated ) |
|
3473 { |
|
3474 if( aOldOne.iActiveConstraints & EConstraintTimedCounter || |
|
3475 aOldOne.iActiveConstraints & EConstraintCounter ) |
|
3476 { |
|
3477 return ETrue; |
|
3478 } |
|
3479 else |
|
3480 { |
|
3481 return EFalse; |
|
3482 } |
|
3483 } |
|
3484 |
|
3485 |
|
3486 // 5. Timed Counter |
|
3487 // Choose the one with least counters first. If there is an equal number of counters |
|
3488 // left, use the one with the longest time |
|
3489 // Continue here if SE's or intervals or accumulateds do not exist or they are the same |
|
3490 if( aOldOne.iActiveConstraints & EConstraintTimedCounter ) |
|
3491 { |
|
3492 if( aNewOne.iActiveConstraints & EConstraintTimedCounter ) |
|
3493 { |
|
3494 if( aNewOne.iTimedCounter == aOldOne.iTimedCounter ) |
|
3495 { |
|
3496 if( aNewOne.iTimedInterval != aOldOne.iTimedInterval ) |
|
3497 { |
|
3498 return ( aNewOne.iTimedInterval < aOldOne.iTimedInterval ); |
|
3499 } |
|
3500 else |
|
3501 { |
|
3502 if( aNewOne.iActiveConstraints & EConstraintCounter ) |
|
3503 { |
|
3504 |
|
3505 } |
|
3506 } |
|
3507 } |
|
3508 else |
|
3509 { |
|
3510 return ( aNewOne.iTimedCounter < aOldOne.iTimedCounter ); |
|
3511 } |
|
3512 |
|
3513 } |
|
3514 else |
|
3515 { |
|
3516 if( aNewOne.iActiveConstraints & EConstraintCounter ) |
|
3517 { |
|
3518 return EFalse; |
|
3519 } |
|
3520 else |
|
3521 { |
|
3522 return ETrue; |
|
3523 } |
|
3524 } |
|
3525 } |
|
3526 else if( aNewOne.iActiveConstraints & EConstraintTimedCounter ) |
|
3527 { |
|
3528 if( aOldOne.iActiveConstraints & EConstraintCounter ) |
|
3529 { |
|
3530 return ETrue; |
|
3531 } |
|
3532 else |
|
3533 { |
|
3534 return EFalse; |
|
3535 } |
|
3536 } |
|
3537 |
|
3538 // 6. Counter |
|
3539 // Choose the one with least counters: |
|
3540 // if they are the same choose the first one. |
|
3541 // Continue here if SE's or intervals or accumulateds or timed counters |
|
3542 // do not exist or they are the same |
|
3543 if( aOldOne.iActiveConstraints & EConstraintCounter ) |
|
3544 { |
|
3545 if( aNewOne.iActiveConstraints & EConstraintCounter ) |
|
3546 { |
|
3547 return ( aNewOne.iCounter < aOldOne.iCounter ); |
|
3548 } |
|
3549 else |
|
3550 { |
|
3551 return ETrue; |
|
3552 } |
|
3553 } |
|
3554 |
|
3555 // If all else fails use the old one: |
|
3556 return EFalse; |
|
3557 } |
|
3558 |
|
3559 |
|
3560 // ----------------------------------------------------------------------------- |
|
3561 // CDRMDbSession::BetterPermission |
|
3562 // Compares two permissions, and returns ETrue if aNewOne is more suitable |
|
3563 // for the usage. Assumes both are valid, i.e. not expired. |
|
3564 // ----------------------------------------------------------------------------- |
|
3565 TBool BetterPermissionOld( const CDRMConstraint& aNewOne, |
|
3566 const CDRMConstraint& aOldOne ) //const |
|
3567 { |
|
3568 |
|
3569 const TTime nullTime = Time::NullTTime(); |
|
3570 TTime oldTime = nullTime; |
|
3571 TTime newTime = nullTime; |
|
3572 TBool inactiveIntervals = EFalse; |
|
3573 |
|
3574 // If the old or new one is the ultimate one, don't bother to |
|
3575 // check anything else. |
|
3576 if ( aOldOne.iActiveConstraints == EConstraintNone ) |
|
3577 { |
|
3578 return EFalse; |
|
3579 } |
|
3580 |
|
3581 if ( aNewOne.iActiveConstraints == EConstraintNone ) |
|
3582 { |
|
3583 return ETrue; |
|
3584 } |
|
3585 |
|
3586 // If old one has count constraints but the new doesn't, the new |
|
3587 // is better. If the old one doesn't have counters but the |
|
3588 // new has, the old one is better. |
|
3589 if ( aOldOne.iActiveConstraints & EConstraintCounter ) |
|
3590 { |
|
3591 if ( !( aNewOne.iActiveConstraints & EConstraintCounter ) || |
|
3592 ( aNewOne.iCounter < aOldOne.iCounter ) ) |
|
3593 { |
|
3594 return ETrue; |
|
3595 } |
|
3596 } |
|
3597 else |
|
3598 { |
|
3599 if ( aNewOne.iActiveConstraints & EConstraintCounter ) |
|
3600 { |
|
3601 return EFalse; |
|
3602 } |
|
3603 } |
|
3604 |
|
3605 if ( aOldOne.iActiveConstraints & EConstraintTimedCounter ) |
|
3606 { |
|
3607 if ( !( aNewOne.iActiveConstraints & EConstraintTimedCounter ) || |
|
3608 ( aNewOne.iTimedCounter < aOldOne.iTimedCounter ) ) |
|
3609 { |
|
3610 return ETrue; |
|
3611 } |
|
3612 } |
|
3613 else |
|
3614 { |
|
3615 if ( aNewOne.iActiveConstraints & EConstraintTimedCounter ) |
|
3616 { |
|
3617 return EFalse; |
|
3618 } |
|
3619 } |
|
3620 |
|
3621 if ( aOldOne.iActiveConstraints & EConstraintAccumulated ) |
|
3622 { |
|
3623 if ( !( aNewOne.iActiveConstraints & EConstraintAccumulated ) || |
|
3624 ( aNewOne.iAccumulatedTime < aOldOne.iAccumulatedTime ) ) |
|
3625 { |
|
3626 return ETrue; |
|
3627 } |
|
3628 } |
|
3629 else |
|
3630 { |
|
3631 if ( aNewOne.iActiveConstraints & EConstraintAccumulated ) |
|
3632 { |
|
3633 return EFalse; |
|
3634 } |
|
3635 } |
|
3636 |
|
3637 // - No intervals is better than inactive intervals. |
|
3638 // - No intervals compared to activated interval goes to |
|
3639 // end time constraint comparison. |
|
3640 // - Activated interval is better than inactive interval. |
|
3641 // - Two inactive intervals go to end time constraint comparison. |
|
3642 if ( aOldOne.iActiveConstraints & EConstraintInterval ) |
|
3643 { |
|
3644 if ( aNewOne.iActiveConstraints & EConstraintInterval ) |
|
3645 { |
|
3646 if ( aOldOne.iIntervalStart == nullTime ) |
|
3647 { |
|
3648 if ( aNewOne.iIntervalStart != nullTime ) |
|
3649 { |
|
3650 return ETrue; |
|
3651 } |
|
3652 |
|
3653 // Both have inactive intervals. |
|
3654 inactiveIntervals = ETrue; |
|
3655 |
|
3656 // oldTime = iTrustedTime; |
|
3657 oldTime += TTimeIntervalSeconds( aOldOne.iInterval ); |
|
3658 |
|
3659 // newTime = iTrustedTime; |
|
3660 newTime += TTimeIntervalSeconds( aNewOne.iInterval ); |
|
3661 } |
|
3662 else |
|
3663 { |
|
3664 // Old one has activated interval. |
|
3665 if ( aNewOne.iIntervalStart == nullTime ) |
|
3666 { |
|
3667 return EFalse; |
|
3668 } |
|
3669 |
|
3670 // Both have activated intervals. |
|
3671 oldTime = aOldOne.iIntervalStart; |
|
3672 oldTime += TTimeIntervalSeconds( aOldOne.iInterval ); |
|
3673 |
|
3674 newTime = aNewOne.iIntervalStart; |
|
3675 newTime += TTimeIntervalSeconds( aNewOne.iInterval ); |
|
3676 } |
|
3677 } |
|
3678 else |
|
3679 { |
|
3680 // No intervals in the new one. |
|
3681 if ( aOldOne.iIntervalStart == nullTime ) |
|
3682 { |
|
3683 return ETrue; |
|
3684 } |
|
3685 |
|
3686 oldTime = aOldOne.iIntervalStart; |
|
3687 oldTime += TTimeIntervalSeconds( aOldOne.iInterval ); |
|
3688 } |
|
3689 } |
|
3690 else |
|
3691 { |
|
3692 // The old one doesn't have intervals. |
|
3693 if ( aNewOne.iActiveConstraints & EConstraintInterval ) |
|
3694 { |
|
3695 if ( aNewOne.iIntervalStart == nullTime ) |
|
3696 { |
|
3697 return EFalse; |
|
3698 } |
|
3699 |
|
3700 newTime = aNewOne.iIntervalStart + TTimeIntervalSeconds( aNewOne.iInterval ); |
|
3701 } |
|
3702 } |
|
3703 |
|
3704 if ( inactiveIntervals ) |
|
3705 { |
|
3706 // The one with end time goes first. |
|
3707 if ( aOldOne.iActiveConstraints & EConstraintEndTime ) |
|
3708 { |
|
3709 if ( aNewOne.iActiveConstraints & EConstraintEndTime ) |
|
3710 { |
|
3711 oldTime = EndTime( oldTime, aOldOne.iEndTime ); |
|
3712 newTime = EndTime( newTime, aNewOne.iEndTime ); |
|
3713 |
|
3714 return ( newTime < oldTime ); |
|
3715 } |
|
3716 |
|
3717 return EFalse; |
|
3718 } |
|
3719 |
|
3720 if( aNewOne.iActiveConstraints & EConstraintEndTime ) |
|
3721 { |
|
3722 return ETrue; |
|
3723 } |
|
3724 |
|
3725 // Both have just inactive intervals. |
|
3726 return ( newTime < oldTime ); |
|
3727 } |
|
3728 |
|
3729 // Check end times and/or activated intervals. |
|
3730 if ( aOldOne.iActiveConstraints & EConstraintEndTime || oldTime != nullTime ) |
|
3731 { |
|
3732 oldTime = EndTime( oldTime, aOldOne.iEndTime ); |
|
3733 |
|
3734 if ( aNewOne.iActiveConstraints & EConstraintEndTime || newTime != nullTime ) |
|
3735 { |
|
3736 newTime = EndTime( newTime, aNewOne.iEndTime ); |
|
3737 |
|
3738 return ( newTime < oldTime ); |
|
3739 } |
|
3740 |
|
3741 // The new one doesn't have end time constraint and/or activated intervals. |
|
3742 return EFalse; |
|
3743 } |
|
3744 |
|
3745 if ( aNewOne.iActiveConstraints & EConstraintEndTime || newTime != nullTime ) |
|
3746 { |
|
3747 return ETrue; |
|
3748 } |
|
3749 |
|
3750 // Start time does not expire, so let's keep the old one. |
|
3751 |
|
3752 return EFalse; |
|
3753 } |
|
3754 |
|
3755 |
|
3756 // ---------------------------------------------------------------------------- |
|
3757 // UnwrapProtectedCekL |
|
3758 // Unwraps the protected CEK aProtectedCek. Caller owns the returned buffer. |
|
3759 // ---------------------------------------------------------------------------- |
|
3760 // |
|
3761 HBufC8* CDRMDbSession::UnwrapProtectedCekL( |
|
3762 const TDesC8& aProtectedCek ) |
|
3763 { |
|
3764 MDrmKeyStorage* storage; |
|
3765 TBuf8<OmaCrypto::KMacSize> mac; |
|
3766 TBuf8<OmaCrypto::KKeySize> rek; |
|
3767 HBufC8* cek = NULL; |
|
3768 TPtrC8 macAndRek(0, 0); |
|
3769 TPtrC8 wrappedCek(0, 0); |
|
3770 TKeyTransportScheme transport; |
|
3771 TBuf8<KRiIdSize> rightsIssuer; |
|
3772 CDRMRIContext* riContext = NULL; |
|
3773 TInt i; |
|
3774 TInt len; |
|
3775 |
|
3776 DRMLOG(_L("CDRMDbSession::UnwrapProtectedCekL")); |
|
3777 |
|
3778 // first element: one byte for the transport scheme |
|
3779 i = 0; |
|
3780 transport = static_cast<TKeyTransportScheme>(aProtectedCek[i]); |
|
3781 i++; |
|
3782 |
|
3783 DRMLOG2(_L("Transport scheme: %d"), transport); |
|
3784 |
|
3785 // second element: the concatenated MAC and REK wrapped with the KEK |
|
3786 len = aProtectedCek[i]; |
|
3787 macAndRek.Set(aProtectedCek.Mid(i + 1, len)); |
|
3788 i = i + 1 + len; |
|
3789 DRMLOG(_L("MAC + REK:")); |
|
3790 DRMLOGHEX(macAndRek); |
|
3791 |
|
3792 // third element: 20 bytes with the rights issuer ID |
|
3793 len = aProtectedCek[i]; |
|
3794 rightsIssuer.Copy(aProtectedCek.Mid(i + 1, len)); |
|
3795 i = i + 1 + len; |
|
3796 DRMLOG(_L("RI ID:")); |
|
3797 DRMLOGHEX(rightsIssuer); |
|
3798 |
|
3799 // get the trusted root from the rights issuer context |
|
3800 if ( !iRoapClientConnected ) |
|
3801 { |
|
3802 User::LeaveIfError( iRoapClient.Connect() ); |
|
3803 iRoapClientConnected = ETrue; |
|
3804 } |
|
3805 riContext = iRoapClient.GetRIContextL(rightsIssuer); |
|
3806 if ( !riContext ) |
|
3807 { |
|
3808 DRMLOG(_L("RI not registered")); |
|
3809 User::Leave(KErrRightsServerRiNotRegistered); |
|
3810 } |
|
3811 CleanupStack::PushL(riContext); |
|
3812 |
|
3813 // connect to the storage of our PKI keys |
|
3814 storage = DrmKeyStorageNewL(); |
|
3815 TCleanupItem storageCleanup( DeleteObject, storage ); |
|
3816 CleanupStack::PushL(storageCleanup); |
|
3817 storage->SelectTrustedRootL(riContext->SelectedDeviceRoot()); |
|
3818 |
|
3819 if (transport == EOma) |
|
3820 { |
|
3821 OmaCrypto::RsaKemKwsDecryptL(storage, macAndRek, rek, mac); |
|
3822 } |
|
3823 else |
|
3824 { |
|
3825 CmlaCrypto::CmlaIpDecryptL(transport, storage, macAndRek, rek, mac); |
|
3826 } |
|
3827 |
|
3828 DRMLOG(_L("REK:")); |
|
3829 DRMLOGHEX(rek); |
|
3830 DRMLOG(_L("MAC:")); |
|
3831 DRMLOGHEX(mac); |
|
3832 |
|
3833 iMac.Copy(mac); |
|
3834 iRek.Copy(rek); |
|
3835 |
|
3836 // fourth element: 24 bytes for the CEK (wrapped with the REK), |
|
3837 // this can be empty, e.g. for a parent RO (indicated by a zero length) |
|
3838 len = aProtectedCek[i]; |
|
3839 if (len > 0) |
|
3840 { |
|
3841 wrappedCek.Set(aProtectedCek.Mid(i + 1, len)); |
|
3842 DRMLOG(_L("Wrapped CEK:")); |
|
3843 DRMLOGHEX(wrappedCek); |
|
3844 cek = OmaCrypto::AesUnwrapL(rek, wrappedCek); |
|
3845 DRMLOG(_L("CEK:")); |
|
3846 DRMLOGHEX(( *cek )); |
|
3847 } |
|
3848 else |
|
3849 { |
|
3850 DRMLOG(_L("No CEK")); |
|
3851 cek = KNullDesC8().AllocL(); |
|
3852 } |
|
3853 |
|
3854 CleanupStack::PopAndDestroy(2); // riContext, storageCleanup |
|
3855 return cek; |
|
3856 } |
|
3857 |
|
3858 // ---------------------------------------------------------------------------- |
|
3859 // UnwrapDomainCekL |
|
3860 // Unwraps CEK with is wrapped with a domain key. Caller owns the returned |
|
3861 // buffer. |
|
3862 // ---------------------------------------------------------------------------- |
|
3863 // |
|
3864 HBufC8* CDRMDbSession::UnwrapDomainCekL( |
|
3865 const TDesC8& aProtectedCek, |
|
3866 const TDesC8& aDomainId ) |
|
3867 { |
|
3868 HBufC8* unwrappedMacAndRek = NULL; |
|
3869 HBufC8* cek = NULL; |
|
3870 TPtrC8 macAndRek(0, 0); |
|
3871 TPtrC8 wrappedCek(0, 0); |
|
3872 CDRMDomainContext* domainContext; |
|
3873 HBufC8* domainKey = NULL; |
|
3874 TInt i; |
|
3875 TInt len; |
|
3876 |
|
3877 DRMLOG(_L("CDRMDbSession::UnwrapDomainCekL")); |
|
3878 |
|
3879 // first element (one byte for the transport scheme) is ignored |
|
3880 i = 1; |
|
3881 |
|
3882 // second element: MAC and REK wrapped with the domain key (40 bytes) |
|
3883 len = aProtectedCek[i]; |
|
3884 macAndRek.Set(aProtectedCek.Mid(i + 1, len)); |
|
3885 i = i + 1 + len; |
|
3886 DRMLOG(_L("MAC + REK:")); |
|
3887 DRMLOGHEX(macAndRek); |
|
3888 |
|
3889 // third element: 20 bytes with the rights issuer ID, is ignored |
|
3890 len = aProtectedCek[i]; |
|
3891 i = i + 1 + len; |
|
3892 |
|
3893 // fourth element: 24 bytes for the CEK (wrapped with the REK) |
|
3894 len = aProtectedCek[i]; |
|
3895 wrappedCek.Set(aProtectedCek.Mid(i + 1, len)); |
|
3896 DRMLOG(_L("Wrapped CEK:")); |
|
3897 DRMLOGHEX(wrappedCek); |
|
3898 |
|
3899 // get the domain key from the domain context |
|
3900 if ( !iRoapClientConnected ) |
|
3901 { |
|
3902 User::LeaveIfError( iRoapClient.Connect() ); |
|
3903 iRoapClientConnected = ETrue; |
|
3904 } |
|
3905 domainContext = iRoapClient.GetDomainContextL(aDomainId); |
|
3906 if ( !domainContext ) |
|
3907 { |
|
3908 DRMLOG(_L("Domain not registered")); |
|
3909 User::Leave(KErrRightsServerDomainNotRegistered); |
|
3910 } |
|
3911 CleanupStack::PushL(domainContext); |
|
3912 |
|
3913 // last three digits presents the domain generation |
|
3914 TInt generation = 0; |
|
3915 TLex8 lex( aDomainId.Right(3)); |
|
3916 lex.Val(generation); |
|
3917 |
|
3918 domainKey = domainContext->DomainKeyL(generation); |
|
3919 CleanupStack::PushL( domainKey ); |
|
3920 |
|
3921 // unwrap MAC and REK first with the domain key, the CEK with REK |
|
3922 unwrappedMacAndRek = OmaCrypto::AesUnwrapL(*domainKey, macAndRek); |
|
3923 CleanupStack::PushL(unwrappedMacAndRek); |
|
3924 cek = OmaCrypto::AesUnwrapL(unwrappedMacAndRek->Right( |
|
3925 OmaCrypto::KKeySize), wrappedCek); |
|
3926 iMac.Copy( unwrappedMacAndRek->Left( OmaCrypto::KKeySize) ); |
|
3927 CleanupStack::PopAndDestroy(3); // unwrappedMacAndRek, domainKey, domainContext |
|
3928 |
|
3929 return cek; |
|
3930 } |
|
3931 |
|
3932 // ---------------------------------------------------------------------------- |
|
3933 // CDRMDbSession::VerifyCredentials |
|
3934 // Check if the client has enough credentials to grant access to later |
|
3935 // decryption. |
|
3936 // ---------------------------------------------------------------------------- |
|
3937 // |
|
3938 TInt CDRMDbSession::VerifyCredentials( |
|
3939 HBufC8* aContentId, |
|
3940 CDRMPermission* aPermission, |
|
3941 TIntent aIntent) |
|
3942 { |
|
3943 CDRMConstraint* constraint = NULL; |
|
3944 _LIT_SECURITY_POLICY_C1(drmCheck, ECapabilityDRM); |
|
3945 _LIT_SECURITY_POLICY_V0(vidCheck, VID_DEFAULT); // Check Default VID |
|
3946 RPointerArray<CDRMPermission> permissions; |
|
3947 TInt r = KErrAccessDenied; |
|
3948 TBool hasOma2Permissions = EFalse; |
|
3949 TBool hasSoftwareConstraints = EFalse; |
|
3950 TInt i; |
|
3951 |
|
3952 __UHEAP_MARK; |
|
3953 // Get the applicable permission, and check if there are OMA 2 permissions or |
|
3954 // software constraints |
|
3955 if (aPermission) |
|
3956 { |
|
3957 constraint = aPermission->ConstraintForIntent(aIntent); |
|
3958 } |
|
3959 if ( aContentId ) |
|
3960 { |
|
3961 TRAP_IGNORE( DRMDB.GetDBEntryByContentIDL(*aContentId, permissions) ); |
|
3962 for (i = 0; i < permissions.Count(); i++) |
|
3963 { |
|
3964 if (permissions[i]->iRightsObjectVersion.iVersionMain == EOma2Rights || |
|
3965 permissions[i]->iRightsObjectVersion.iVersionMain == ECmlaRights) |
|
3966 { |
|
3967 hasOma2Permissions = ETrue; |
|
3968 } |
|
3969 if (permissions[i]->SoftwareConstrained()) |
|
3970 { |
|
3971 hasSoftwareConstraints = ETrue; |
|
3972 } |
|
3973 } |
|
3974 permissions.ResetAndDestroy(); |
|
3975 permissions.Close(); |
|
3976 } |
|
3977 |
|
3978 // First, check for DRM capability, access granted only if there are no software |
|
3979 // constraints. |
|
3980 if (drmCheck().CheckPolicy(iClient) && !hasSoftwareConstraints) |
|
3981 { |
|
3982 r = KErrNone; |
|
3983 } |
|
3984 |
|
3985 // If a permission is given, check for license manager cases as well as |
|
3986 // OMA DRM 1.0 case |
|
3987 if ( r != KErrNone && aPermission ) |
|
3988 { |
|
3989 // Fallback: Check if the vendor ID is the default vendor ID, |
|
3990 // allow access for OMA DRM 1.0 rights |
|
3991 if ((aPermission->iRightsObjectVersion.iVersionMain == EOma1Rights && |
|
3992 vidCheck().CheckPolicy(iClient))) |
|
3993 { |
|
3994 r = KErrNone; |
|
3995 } |
|
3996 |
|
3997 // Check the software constraint, this can override the fallback above! |
|
3998 if ( constraint ) |
|
3999 { |
|
4000 _LIT_SECURITY_POLICY_S0(swSidCheck, constraint->iSecureId.iUid); |
|
4001 _LIT_SECURITY_POLICY_V0(swVidCheck, constraint->iVendorId.iUid); |
|
4002 if (constraint->iActiveConstraints & EConstraintVendor) |
|
4003 { |
|
4004 if (swVidCheck().CheckPolicy(iClient)) |
|
4005 { |
|
4006 r = KErrNone; |
|
4007 } |
|
4008 else |
|
4009 { |
|
4010 r = KErrAccessDenied; |
|
4011 } |
|
4012 } |
|
4013 if (constraint->iActiveConstraints & EConstraintSoftware) |
|
4014 { |
|
4015 if (swSidCheck().CheckPolicy(iClient)) |
|
4016 { |
|
4017 r = KErrNone; |
|
4018 } |
|
4019 else |
|
4020 { |
|
4021 r = KErrAccessDenied; |
|
4022 } |
|
4023 } |
|
4024 } |
|
4025 |
|
4026 } |
|
4027 |
|
4028 // Application installer needs to be able to use the content even if it has SW constraints |
|
4029 _LIT_SECURITY_POLICY_S0(swSidCheck2, KAppInstSrv); |
|
4030 |
|
4031 if( swSidCheck2().CheckPolicy(iClient) && hasSoftwareConstraints ) |
|
4032 { |
|
4033 r = KErrNone; |
|
4034 } |
|
4035 |
|
4036 |
|
4037 // Check if access can be granted when only |
|
4038 // OMA DRM 1.0 permissions are currently available, and the client |
|
4039 // has the default vendor ID |
|
4040 if ( r != KErrNone && !hasOma2Permissions && |
|
4041 !hasSoftwareConstraints && vidCheck().CheckPolicy( iClient ) ) |
|
4042 { |
|
4043 r = KErrNone; |
|
4044 } |
|
4045 __UHEAP_MARKEND; |
|
4046 |
|
4047 if ( r == KErrNone ) |
|
4048 { |
|
4049 iCredentialsChecked = ECheckedAndAllowed; |
|
4050 } |
|
4051 else |
|
4052 { |
|
4053 iCredentialsChecked = ECheckedAndDenied; |
|
4054 } |
|
4055 return r; |
|
4056 } |
|
4057 |
|
4058 // ---------------------------------------------------------------------------- |
|
4059 // CDRMDbSession::RemoveInvalidPermissionsL |
|
4060 // Remove all permissions where the domain context is not available |
|
4061 // ---------------------------------------------------------------------------- |
|
4062 // |
|
4063 void CDRMDbSession::RemoveInvalidPermissionsL( |
|
4064 CDRMPermissionList* aList ) |
|
4065 { |
|
4066 CDRMDomainContext* domainContext = NULL; |
|
4067 TInt i; |
|
4068 if ( !iRoapClientConnected ) |
|
4069 { |
|
4070 User::LeaveIfError( iRoapClient.Connect() ); |
|
4071 iRoapClientConnected = ETrue; |
|
4072 } |
|
4073 for ( i = aList->Count() - 1; i >= 0; i-- ) |
|
4074 { |
|
4075 if ( (*aList)[i]->iDomainID ) |
|
4076 { |
|
4077 domainContext = iRoapClient.GetDomainContextL( |
|
4078 *(*aList)[i]->iDomainID ); |
|
4079 if ( domainContext ) |
|
4080 { |
|
4081 delete domainContext; |
|
4082 } |
|
4083 else |
|
4084 { |
|
4085 aList->Remove( i ); |
|
4086 } |
|
4087 } |
|
4088 } |
|
4089 } |
|
4090 |
|
4091 // ---------------------------------------------------------------------------- |
|
4092 // CDRMDbSession:: |
|
4093 // |
|
4094 // ---------------------------------------------------------------------------- |
|
4095 // |
|
4096 void CDRMDbSession::SetNameL( const RMessage2& aMessage ) |
|
4097 { |
|
4098 DRMLOG( _L( "CDRMDbSession::SetNameL" ) ); |
|
4099 __UHEAP_MARK; |
|
4100 |
|
4101 SanitizeL( aMessage.GetDesLength( 0 ) ); |
|
4102 SanitizeL( aMessage.GetDesLength( 1 ) ); |
|
4103 |
|
4104 TInt namelength = User::LeaveIfError( IPCGETDESLEN1 ); |
|
4105 HBufC8* cid = HBufC8::NewLC( IPCGETDESLEN0 ); |
|
4106 HBufC* name = HBufC::NewLC( namelength > 0 ? namelength : 1 ); |
|
4107 TPtr8 tmp( cid->Des() ); |
|
4108 |
|
4109 IPCREAD0L( tmp ); |
|
4110 if ( namelength ) |
|
4111 { |
|
4112 TPtr tmp2( name->Des() ); |
|
4113 IPCREAD1L( tmp2 ); |
|
4114 } |
|
4115 |
|
4116 DRMDB.NameContentL( *cid, *name ); |
|
4117 |
|
4118 CleanupStack::PopAndDestroy( 2 ); |
|
4119 __UHEAP_MARKEND; |
|
4120 aMessage.Complete( KErrNone ); |
|
4121 } |
|
4122 |
|
4123 // ---------------------------------------------------------------------------- |
|
4124 // CDRMDbSession:: |
|
4125 // |
|
4126 // ---------------------------------------------------------------------------- |
|
4127 // |
|
4128 void CDRMDbSession::GetNameL( const RMessage2& aMessage ) |
|
4129 { |
|
4130 DRMLOG( _L( "CDRMDbSession::GetNameL" ) ); |
|
4131 HBufC8* cid = NULL; |
|
4132 TPckgBuf< TInt > size( 0 ); |
|
4133 |
|
4134 // Cleanup. |
|
4135 if ( iWidePreparedData ) |
|
4136 { |
|
4137 delete iWidePreparedData; |
|
4138 iWidePreparedData = NULL; |
|
4139 } |
|
4140 |
|
4141 SanitizeL( aMessage.GetDesLength( 0 ) ); |
|
4142 cid = HBufC8::NewLC( IPCGETDESLEN0 ); |
|
4143 TPtr8 tmp( cid->Des() ); |
|
4144 IPCREAD0L( tmp ); |
|
4145 |
|
4146 iWidePreparedData = DRMDB.ContentNameLC( *cid ); |
|
4147 |
|
4148 CleanupStack::Pop( iWidePreparedData ); |
|
4149 CleanupStack::PopAndDestroy( cid ); |
|
4150 |
|
4151 size() = iWidePreparedData->Length(); |
|
4152 if ( iWidePreparedData->Length() == 0 ) |
|
4153 { |
|
4154 // Empty name --> not asked. |
|
4155 delete iWidePreparedData; |
|
4156 iWidePreparedData = NULL; |
|
4157 } |
|
4158 |
|
4159 IPCWRITE1L( size ); |
|
4160 |
|
4161 aMessage.Complete( KErrNone ); |
|
4162 } |
|
4163 |
|
4164 // ---------------------------------------------------------------------------- |
|
4165 // CDRMDbSession:: |
|
4166 // |
|
4167 // ---------------------------------------------------------------------------- |
|
4168 // |
|
4169 void CDRMDbSession::GetWideDataL( const RMessage2& aMessage ) |
|
4170 { |
|
4171 DRMLOG( _L( "CDRMDbSesion::GetWideDataL" ) ); |
|
4172 if ( iWidePreparedData ) |
|
4173 { |
|
4174 if( iWidePreparedData->Length() > aMessage.GetDesMaxLength(0) ) |
|
4175 { |
|
4176 User::Leave(KErrArgument); |
|
4177 } |
|
4178 |
|
4179 IPCWRITE0L( *iWidePreparedData ); |
|
4180 |
|
4181 delete iWidePreparedData; |
|
4182 iWidePreparedData = NULL; |
|
4183 |
|
4184 aMessage.Complete( KErrNone ); |
|
4185 return; |
|
4186 } |
|
4187 |
|
4188 aMessage.Complete( KErrNotReady ); |
|
4189 } |
|
4190 |
|
4191 // ---------------------------------------------------------------------------- |
|
4192 // CDRMDbSession:: |
|
4193 // |
|
4194 // ---------------------------------------------------------------------------- |
|
4195 // |
|
4196 void CDRMDbSession::Cancel( const RMessage2& aMessage ) |
|
4197 { |
|
4198 DRMLOG( _L( "CDRMDbSession::Cancel" ) ); |
|
4199 if ( iPendingRequest ) |
|
4200 { |
|
4201 static_cast<CDRMActiveOperation*>(iPendingRequest)->Remove(); |
|
4202 } |
|
4203 |
|
4204 aMessage.Complete( KErrNone ); |
|
4205 } |
|
4206 |
|
4207 // ---------------------------------------------------------------------------- |
|
4208 // CDRMDbSession:: |
|
4209 // |
|
4210 // ---------------------------------------------------------------------------- |
|
4211 // |
|
4212 void CDRMDbSession::GetFLUriL( const RMessage2& aMessage ) |
|
4213 { |
|
4214 DRMLOG( _L( "CDRMDbSession::GetFLUriL" ) ); |
|
4215 |
|
4216 TBuf8< KMaxOmaV1CIDLength > URI; |
|
4217 |
|
4218 GetFlURI( URI ); |
|
4219 |
|
4220 if( URI.Length() > aMessage.GetDesMaxLength(0) ) |
|
4221 { |
|
4222 User::Leave(KErrArgument); |
|
4223 } |
|
4224 |
|
4225 IPCWRITE0L( URI ); |
|
4226 aMessage.Complete( KErrNone ); |
|
4227 } |
|
4228 |
|
4229 // ---------------------------------------------------------------------------- |
|
4230 // CDRMDbSession:: |
|
4231 // |
|
4232 // ---------------------------------------------------------------------------- |
|
4233 // |
|
4234 void CDRMDbSession::EncodeRightsIssuerL( const RMessage2& aMessage ) |
|
4235 { |
|
4236 __UHEAP_MARK; |
|
4237 |
|
4238 DRMLOG( _L( "CRMDbSession::EncodeRightsIssuerL" ) ); |
|
4239 TBuf8< KDCFKeySize > iv; |
|
4240 HBufC8* data( NULL ); |
|
4241 HBufC8* tmp( NULL ); |
|
4242 iv.SetLength( KDCFKeySize ); |
|
4243 |
|
4244 TInt size( User::LeaveIfError( IPCGETDESLEN0 ) ); |
|
4245 TPtr8 des( NULL, 0, 0 ); |
|
4246 |
|
4247 if ( size < 1 ) |
|
4248 { |
|
4249 User::Leave( KErrArgument ); |
|
4250 } |
|
4251 |
|
4252 // Calculate the size. It could be retrieved also from GetDesMaxLength, |
|
4253 // but at least now we can be sure we won't panic in case of |
|
4254 // descriptor overflow. |
|
4255 size += KDCFKeySize - ( size % KDCFKeySize ); //padding |
|
4256 size += KDCFKeySize; //iv |
|
4257 size = ( size + 2 ) / 3 * 4; //base64 |
|
4258 size += IMEI.Length(); |
|
4259 size += KFLPrefixLength; |
|
4260 |
|
4261 data = HBufC8::NewLC( size < KMaxOmaV1CIDLength ? KMaxOmaV1CIDLength : size ); |
|
4262 des.Set( data->Des() ); |
|
4263 |
|
4264 GetFlURI( des ); |
|
4265 |
|
4266 tmp = DRMDB.GetDecryptionKeyL( *data ); |
|
4267 CleanupStack::PushL( tmp ); |
|
4268 |
|
4269 // Get the data from client. |
|
4270 IPCREAD0L( des ); |
|
4271 GenerateIVL( iv ); |
|
4272 |
|
4273 // Fits ok. |
|
4274 AesEncryptL( *tmp, iv, ETrue, des ); |
|
4275 |
|
4276 CleanupStack::PopAndDestroy( tmp ); |
|
4277 |
|
4278 // Fits ok. |
|
4279 des.Insert( 0, iv ); |
|
4280 |
|
4281 tmp = Base64EncodeL( *data ); |
|
4282 |
|
4283 __ASSERT_DEBUG( tmp->Length() + KFLPrefixLength + IMEI.Length() <= size, |
|
4284 User::Invariant() ); |
|
4285 |
|
4286 // Overwrite the original data. |
|
4287 des = KFLPrefix; |
|
4288 des.Append( IMEI ); |
|
4289 des.Append( *tmp ); |
|
4290 |
|
4291 delete tmp; |
|
4292 tmp = NULL; |
|
4293 |
|
4294 IPCWRITE0L( *data ); |
|
4295 |
|
4296 CleanupStack::PopAndDestroy( data ); |
|
4297 |
|
4298 aMessage.Complete( KErrNone ); |
|
4299 |
|
4300 __UHEAP_MARKEND; |
|
4301 } |
|
4302 |
|
4303 |
|
4304 // ---------------------------------------------------------------------------- |
|
4305 // CDRMDbSession:: |
|
4306 // |
|
4307 // ---------------------------------------------------------------------------- |
|
4308 // |
|
4309 void CDRMDbSession::DecodeRightsIssuerL( const RMessage2& aMessage ) |
|
4310 { |
|
4311 DRMLOG( _L( "CDRMDbSession::DecodeRightsIssuerL" ) ); |
|
4312 __UHEAP_MARK; |
|
4313 |
|
4314 HBufC8* data( NULL ); |
|
4315 TInt size( IPCGETDESLEN0 ); |
|
4316 TPtr8 des( NULL, 0, 0 ); |
|
4317 |
|
4318 if ( !size ) |
|
4319 { |
|
4320 User::Leave( KErrArgument ); |
|
4321 } |
|
4322 |
|
4323 SanitizeL( size ); |
|
4324 |
|
4325 data = HBufC8::NewLC( size ); |
|
4326 des.Set( data->Des() ); |
|
4327 |
|
4328 IPCREAD0L( des ); |
|
4329 |
|
4330 if ( des.Left( KFLPrefixLength ).Compare( KFLPrefix ) == 0 ) |
|
4331 { |
|
4332 HBufC8* tmp( NULL ); |
|
4333 HBufC8* tmp2( NULL ); |
|
4334 TPtr8 des2( NULL, 0, 0 ); |
|
4335 |
|
4336 tmp = CnvUtfConverter::ConvertFromUnicodeToUtf8L( IMEI ); |
|
4337 CleanupStack::PushL( tmp ); |
|
4338 |
|
4339 if ( des.Mid( KFLPrefixLength, IMEI.Length() ).Compare( *tmp ) ) |
|
4340 { |
|
4341 User::Leave( KErrCANoPermission ); |
|
4342 } |
|
4343 |
|
4344 tmp2 = Base64DecodeL( des.Mid( KFLPrefixLength + tmp->Length() ) ); |
|
4345 |
|
4346 *data = *tmp2; |
|
4347 |
|
4348 delete tmp2; |
|
4349 tmp2 = NULL; |
|
4350 |
|
4351 CleanupStack::PopAndDestroy( tmp ); |
|
4352 |
|
4353 if ( ( data->Length() % KDCFKeySize ) || |
|
4354 data->Length() < ( KDCFKeySize << 1 ) ) |
|
4355 { |
|
4356 User::Leave( KErrArgument ); |
|
4357 } |
|
4358 |
|
4359 tmp = HBufC8::NewLC( KMaxOmaV1CIDLength ); |
|
4360 |
|
4361 des.Set( tmp->Des() ); |
|
4362 |
|
4363 GetFlURI( des ); |
|
4364 |
|
4365 tmp2 = DRMDB.GetDecryptionKeyL( *tmp ); |
|
4366 |
|
4367 CleanupStack::PopAndDestroy( tmp ); |
|
4368 CleanupStack::PushL( tmp2 ); |
|
4369 |
|
4370 des2.Set( const_cast< TText8* >( data->Ptr() ), |
|
4371 KDCFKeySize, |
|
4372 KDCFKeySize ); |
|
4373 |
|
4374 // AesDecrypt overwrites the data. |
|
4375 des.Set( const_cast< TText8* >( data->Ptr() ) + KDCFKeySize, |
|
4376 data->Length() - KDCFKeySize, |
|
4377 data->Length() - KDCFKeySize ); |
|
4378 |
|
4379 AesDecryptL( *tmp2, des2, ETrue, des ); |
|
4380 |
|
4381 // Erase the key. |
|
4382 des2.Set( tmp2->Des() ); |
|
4383 des2.FillZ(); |
|
4384 |
|
4385 CleanupStack::PopAndDestroy( tmp2 ); |
|
4386 |
|
4387 if( des.Length() > aMessage.GetDesMaxLength(1) ) |
|
4388 { |
|
4389 User::Leave(KErrArgument); |
|
4390 } |
|
4391 IPCWRITE1L( des ); |
|
4392 } |
|
4393 |
|
4394 // Something else, can't handle it. Leave it as it is. |
|
4395 CleanupStack::PopAndDestroy( data ); |
|
4396 |
|
4397 aMessage.Complete( KErrNone ); |
|
4398 |
|
4399 __UHEAP_MARKEND; |
|
4400 |
|
4401 DRMLOG( _L( "CDRMDbSession::DecodeRightsIssuerL ok" ) ); |
|
4402 } |
|
4403 |
|
4404 // ---------------------------------------------------------------------------- |
|
4405 // CDRMDbSession:: |
|
4406 // |
|
4407 // ---------------------------------------------------------------------------- |
|
4408 // |
|
4409 void CDRMDbSession::GetFlURI( TDes8& aURI ) |
|
4410 { |
|
4411 aURI = KFLLongPrefix; |
|
4412 aURI.Append( IMEI ); |
|
4413 aURI.Append( KFLSuffix ); |
|
4414 } |
|
4415 |
|
4416 // ---------------------------------------------------------------------------- |
|
4417 // CDRMDbSession::AesEncryptL |
|
4418 // Encrypt data using a given key |
|
4419 // ---------------------------------------------------------------------------- |
|
4420 // |
|
4421 void CDRMDbSession::AesEncryptL( const TDesC8& aKey, |
|
4422 const TDesC8& aIV, |
|
4423 const TBool aAddPadding, |
|
4424 TDes8& aData ) |
|
4425 { |
|
4426 DRMLOG( _L( "CDRMDbSession::AesEncryptL" ) ); |
|
4427 |
|
4428 __UHEAP_MARK; |
|
4429 |
|
4430 CModeCBCEncryptor* cbc( NULL ); |
|
4431 TInt lastBlockStart( 0 ); |
|
4432 TPtr8 data( NULL, 0, 0 ); |
|
4433 |
|
4434 if( aIV.Length() % KDCFKeySize || |
|
4435 aKey.Length() % KDCFKeySize ) |
|
4436 { |
|
4437 User::Leave( KErrArgument ); |
|
4438 } |
|
4439 |
|
4440 cbc = CModeCBCEncryptor::NewL( CAESEncryptor::NewLC( aKey ), aIV ); |
|
4441 CleanupStack::Pop(); // CAESEncryptor, owned by cbc. |
|
4442 CleanupStack::PushL( cbc ); |
|
4443 |
|
4444 lastBlockStart = aData.Length() - ( aData.Length() % KDCFKeySize ); |
|
4445 for ( TInt i = 0; i < lastBlockStart; i+= KDCFKeySize ) |
|
4446 { |
|
4447 data.Set( aData.MidTPtr( i, KDCFKeySize ) ); |
|
4448 |
|
4449 cbc->Transform( data ); |
|
4450 } |
|
4451 |
|
4452 if ( aAddPadding ) |
|
4453 { |
|
4454 TInt dataLength = aData.Length(); |
|
4455 TUint8 padding( static_cast< TUint8 > |
|
4456 ( lastBlockStart + KDCFKeySize - dataLength ) ); |
|
4457 |
|
4458 __ASSERT_DEBUG( lastBlockStart + KDCFKeySize - dataLength <= KDCFKeySize, |
|
4459 User::Invariant() ); |
|
4460 |
|
4461 aData.SetLength( lastBlockStart + KDCFKeySize ); |
|
4462 |
|
4463 for ( TInt i = dataLength; i < aData.Length(); ++i ) |
|
4464 { |
|
4465 aData[ i ] = padding; |
|
4466 } |
|
4467 |
|
4468 data.Set( aData.MidTPtr( lastBlockStart, KDCFKeySize ) ); |
|
4469 cbc->Transform( data ); |
|
4470 } |
|
4471 |
|
4472 CleanupStack::PopAndDestroy( cbc ); |
|
4473 |
|
4474 __UHEAP_MARKEND; |
|
4475 |
|
4476 DRMLOG( _L( "CDRMDbSession::AesEncryptL ok" ) ); |
|
4477 } |
|
4478 |
|
4479 // ---------------------------------------------------------------------------- |
|
4480 // CDRMDbSession::AesDecryptL |
|
4481 // Decrypt data using a given key |
|
4482 // ---------------------------------------------------------------------------- |
|
4483 // |
|
4484 void CDRMDbSession::AesDecryptL( const TDesC8& aKey, |
|
4485 const TDesC8& aIV, |
|
4486 const TBool aRemovePadding, |
|
4487 TDes8& aData ) |
|
4488 { |
|
4489 DRMLOG( _L( "CDRMDbSession::AesDecryptL" ) ); |
|
4490 |
|
4491 __UHEAP_MARK; |
|
4492 |
|
4493 CModeCBCDecryptor* cbc( NULL ); |
|
4494 |
|
4495 cbc = CModeCBCDecryptor::NewL( |
|
4496 CAESDecryptor::NewLC( aKey ), aIV ); |
|
4497 |
|
4498 CleanupStack::Pop(); // CAESDecryptor |
|
4499 |
|
4500 __ASSERT_DEBUG( ( aData.Length() >= 0 ) && |
|
4501 ( aData.Length() % KDCFKeySize == 0 ), |
|
4502 User::Invariant() ); |
|
4503 |
|
4504 for ( TInt count = 0; count < aData.Length(); count += KDCFKeySize ) |
|
4505 { |
|
4506 TPtr8 d( aData.MidTPtr( count, KDCFKeySize ) ); |
|
4507 |
|
4508 cbc->Transform( d ); |
|
4509 } |
|
4510 |
|
4511 delete cbc; cbc = NULL; |
|
4512 |
|
4513 if ( aRemovePadding ) |
|
4514 { |
|
4515 TInt count( aData.Length() ); |
|
4516 TUint8 c( aData[ count - 1 ] ); |
|
4517 |
|
4518 if ( c > KDCFKeySize ) |
|
4519 { |
|
4520 User::Leave( KErrCorrupt ); |
|
4521 } |
|
4522 |
|
4523 aData.SetLength( count - c ); |
|
4524 } |
|
4525 |
|
4526 __UHEAP_MARKEND; |
|
4527 |
|
4528 DRMLOG( _L( "CDRMDbSession::AesDecryptL ok" ) ); |
|
4529 } |
|
4530 |
|
4531 // ---------------------------------------------------------------------------- |
|
4532 // CDRMDbSession:: |
|
4533 // |
|
4534 // ---------------------------------------------------------------------------- |
|
4535 // |
|
4536 void CDRMDbSession::GenerateIVL( TDes8& aIV ) |
|
4537 { |
|
4538 DRMLOG( _L( "CDRMDbSession::GenerateIVL" ) ); |
|
4539 __UHEAP_MARK; |
|
4540 |
|
4541 __ASSERT_DEBUG( aIV.MaxSize() >= KDCFKeySize, User::Invariant() ); |
|
4542 MDrmKeyStorage* storage = DrmKeyStorageNewL(); |
|
4543 TCleanupItem storageCleanup( DeleteObject, storage ); |
|
4544 CleanupStack::PushL(storageCleanup); |
|
4545 |
|
4546 storage->RandomDataGetL(aIV,KDCFKeySize); |
|
4547 CleanupStack::PopAndDestroy( storage ); |
|
4548 |
|
4549 DRMLOG(_L("random aIV:")); |
|
4550 DRMLOGHEX(aIV); |
|
4551 |
|
4552 |
|
4553 __UHEAP_MARKEND; |
|
4554 DRMLOG( _L( "CDRMDbSession::GenerateIVL ok" ) ); |
|
4555 } |
|
4556 |
|
4557 // ---------------------------------------------------------------------------- |
|
4558 // CDRMDbSession:: |
|
4559 // |
|
4560 // ---------------------------------------------------------------------------- |
|
4561 // |
|
4562 void CDRMDbSession::AsyncOperationDone() |
|
4563 { |
|
4564 DRMLOG( _L( "CDRMDbSession::AsyncOperationDone" ) ); |
|
4565 // All done. |
|
4566 delete iPendingRequest; |
|
4567 iPendingRequest = NULL; |
|
4568 } |
|
4569 |
|
4570 // ---------------------------------------------------------------------------- |
|
4571 // CDRMDbSession:: |
|
4572 // |
|
4573 // ---------------------------------------------------------------------------- |
|
4574 // |
|
4575 void CDRMDbSession::AsyncOperationDone( TFileName* aFileName ) |
|
4576 { |
|
4577 DRMLOG( _L( "CDRMDbSession::AsyncOperationDone" ) ); |
|
4578 // All done. |
|
4579 delete iPendingRequest; |
|
4580 iPendingRequest = NULL; |
|
4581 |
|
4582 iFileName = aFileName; |
|
4583 } |
|
4584 |
|
4585 |
|
4586 // ---------------------------------------------------------------------------- |
|
4587 // CDRMDbSession::SetAuthenticationSeedL |
|
4588 // Sets the authentication seed for a content ID. Requires that the REK and KEK |
|
4589 // have been set during a previous AddRecord operation |
|
4590 // ---------------------------------------------------------------------------- |
|
4591 // |
|
4592 void CDRMDbSession::SetAuthenticationSeedL( const RMessage2& aMessage ) |
|
4593 { |
|
4594 DRMLOG(_L("CDRMDbSession::SetAuthenticationSeedL")); |
|
4595 |
|
4596 __UHEAP_MARK; |
|
4597 SanitizeL( aMessage.GetDesLength(0)); |
|
4598 SanitizeL( aMessage.GetDesLength(1)); |
|
4599 |
|
4600 HBufC8* cid = HBufC8::NewLC(IPCGETDESLEN0); |
|
4601 HBufC8* wrappedSeed = HBufC8::NewLC(IPCGETDESLEN1); |
|
4602 HBufC8* seed = NULL; |
|
4603 |
|
4604 if (iRek.Length() == 0) |
|
4605 { |
|
4606 User::Leave(KErrNotReady); |
|
4607 } |
|
4608 |
|
4609 TPtr8 tmp(cid->Des()); |
|
4610 IPCREAD0L(tmp ); |
|
4611 TPtr8 tmp2(wrappedSeed->Des()); |
|
4612 IPCREAD1L(tmp2); |
|
4613 |
|
4614 seed = OmaCrypto::AesUnwrapL(iRek, *wrappedSeed); |
|
4615 CleanupStack::PushL(seed); |
|
4616 DRMDB.SetAuthenticationSeedL(*cid, *seed); |
|
4617 CleanupStack::PopAndDestroy(3); // seed, wrappedSeed, cid |
|
4618 __UHEAP_MARKEND; |
|
4619 aMessage.Complete(KErrNone); |
|
4620 } |
|
4621 |
|
4622 // ---------------------------------------------------------------------------- |
|
4623 // CDRMDbSession::GetAuthenticationSeedL |
|
4624 // Returns the authentication seed for a content ID |
|
4625 // ---------------------------------------------------------------------------- |
|
4626 // |
|
4627 void CDRMDbSession::GetAuthenticationSeedL( const RMessage2& aMessage ) |
|
4628 { |
|
4629 DRMLOG(_L("CDRMDbSession::GetAuthenticationSeedL")); |
|
4630 |
|
4631 __UHEAP_MARK; |
|
4632 HBufC8* cid = NULL; |
|
4633 HBufC8* seed = NULL; |
|
4634 |
|
4635 SanitizeL( aMessage.GetDesLength(0)); |
|
4636 cid = HBufC8::NewLC(IPCGETDESLEN0); |
|
4637 |
|
4638 TPtr8 tmp(cid->Des()); |
|
4639 IPCREAD0L(tmp); |
|
4640 User::LeaveIfError(VerifyCredentials(cid, NULL, EUnknown)); |
|
4641 seed = DRMDB.GetAuthenticationSeedL(*cid); |
|
4642 CleanupStack::PushL(seed); |
|
4643 |
|
4644 if( seed->Length() > aMessage.GetDesMaxLength(1) ) |
|
4645 { |
|
4646 User::Leave(KErrArgument); |
|
4647 } |
|
4648 |
|
4649 IPCWRITE1L(*seed); |
|
4650 CleanupStack::PopAndDestroy(2); // seed, cid |
|
4651 __UHEAP_MARKEND; |
|
4652 aMessage.Complete(KErrNone); |
|
4653 } |
|
4654 |
|
4655 // ---------------------------------------------------------------------------- |
|
4656 // CDRMDbSession::VerifyMacL |
|
4657 // Integrity protection for protecets ROs |
|
4658 // ---------------------------------------------------------------------------- |
|
4659 // |
|
4660 void CDRMDbSession::VerifyMacL( const RMessage2& aMessage ) |
|
4661 { |
|
4662 DRMLOG(_L("CDRMDbSession::VerifyMacL")); |
|
4663 |
|
4664 if( !iMac.Length() ) |
|
4665 { |
|
4666 User::Leave(KErrNotReady); |
|
4667 } |
|
4668 |
|
4669 __UHEAP_MARK; |
|
4670 |
|
4671 CHMAC* hMac = NULL; |
|
4672 CSHA1* sha = NULL; |
|
4673 TPtrC8 hmac_value( KNullDesC8 ); |
|
4674 TPtrC8 sha1_value( KNullDesC8 ); |
|
4675 HBufC8* signedInfo = NULL; |
|
4676 HBufC8* macValue = NULL; |
|
4677 TInt ret = KErrNone; |
|
4678 |
|
4679 signedInfo = HBufC8::NewLC(IPCGETDESLEN0); |
|
4680 TPtr8 signedInfoPtr(signedInfo->Des()); |
|
4681 macValue = HBufC8::NewLC(IPCGETDESLEN1); |
|
4682 TPtr8 macValuePtr(macValue->Des()); |
|
4683 |
|
4684 IPCREAD0L(signedInfoPtr); |
|
4685 IPCREAD1L(macValuePtr); |
|
4686 |
|
4687 DRMLOG(_L("Signed info:")); |
|
4688 DRMLOGHEX(signedInfoPtr); |
|
4689 DRMLOG(_L("MAC value:")); |
|
4690 DRMLOGHEX(macValuePtr); |
|
4691 |
|
4692 sha = CSHA1::NewL(); |
|
4693 CleanupStack::PushL( sha ); |
|
4694 hMac = CHMAC::NewL( iMac, sha ); |
|
4695 CleanupStack::Pop( sha ); // sha is now owned by hMac |
|
4696 CleanupStack::PushL( hMac ); |
|
4697 hMac->Update( signedInfoPtr ); |
|
4698 hmac_value.Set( hMac->Final() ); |
|
4699 |
|
4700 DRMLOG(_L("Calculated MAC value:")); |
|
4701 DRMLOGHEX(hmac_value); |
|
4702 if ( hmac_value.Compare( macValuePtr ) != 0 ) |
|
4703 { |
|
4704 // MAC validation failed |
|
4705 ret = KErrRightsServerMacFailed; |
|
4706 } |
|
4707 |
|
4708 CleanupStack::PopAndDestroy(3, signedInfo); // hMac, macValue, signedInfo |
|
4709 __UHEAP_MARKEND; |
|
4710 aMessage.Complete(ret); |
|
4711 } |
|
4712 |
|
4713 // ---------------------------------------------------------------------------- |
|
4714 // CDRMDbSession::GetSupportedIndividualsL |
|
4715 // ---------------------------------------------------------------------------- |
|
4716 // |
|
4717 void CDRMDbSession::GetSupportedIndividualsL( const RMessage2& aMessage ) |
|
4718 { |
|
4719 DRMLOG( _L( "CDRMDbSession::GetSupportedIndividualsL" ) ); |
|
4720 TPckgBuf< TInt > size( 0 ); |
|
4721 TInt stringSize = 0; |
|
4722 TInt offset = 0; |
|
4723 TUint8* ptr = 0; |
|
4724 |
|
4725 // Cleanup. |
|
4726 if ( iPreparedData ) |
|
4727 { |
|
4728 delete iPreparedData; |
|
4729 iPreparedData = NULL; |
|
4730 } |
|
4731 |
|
4732 for ( TInt i = 0; i < IMSI.Count(); i++ ) |
|
4733 { |
|
4734 stringSize += sizeof(TInt); |
|
4735 stringSize += IMSI[i]->Size(); |
|
4736 } |
|
4737 |
|
4738 |
|
4739 // If it's empty, just return right away |
|
4740 if( !stringSize ) |
|
4741 { |
|
4742 IPCWRITE0L( size ); |
|
4743 aMessage.Complete(KErrNone); |
|
4744 return; |
|
4745 } |
|
4746 |
|
4747 // Otherwise create a buffer and fill it: |
|
4748 iPreparedData = HBufC8::NewMaxL( stringSize ); |
|
4749 ptr = const_cast<TUint8*>( iPreparedData->Ptr() ); |
|
4750 |
|
4751 size() = stringSize; |
|
4752 |
|
4753 for( TInt i = 0; i < IMSI.Count(); i++ ) |
|
4754 { |
|
4755 // Write the size: |
|
4756 stringSize = IMSI[i]->Size(); |
|
4757 Mem::Copy(ptr+offset, &stringSize, sizeof(TInt)); |
|
4758 offset += sizeof(TInt); |
|
4759 |
|
4760 // Write the data: |
|
4761 Mem::Copy(ptr+offset, IMSI[i]->Ptr(), IMSI[i]->Size()); |
|
4762 offset += IMSI[i]->Size(); |
|
4763 } |
|
4764 IPCWRITE0L( size ); |
|
4765 |
|
4766 aMessage.Complete( KErrNone ); |
|
4767 } |
|
4768 |
|
4769 // ---------------------------------------------------------------------------- |
|
4770 // CDRMDbSession::StopWatchingL |
|
4771 // ---------------------------------------------------------------------------- |
|
4772 // |
|
4773 void CDRMDbSession::StopWatchingL( const RMessage2& aMessage ) |
|
4774 { |
|
4775 _LIT_SECURITY_POLICY_S0( sidCheck, KTrustedShutdownClient ); |
|
4776 if ( sidCheck.CheckPolicy( aMessage ) ) |
|
4777 { |
|
4778 SERVER->StopWatchingL(); |
|
4779 } |
|
4780 aMessage.Complete( KErrNone ); |
|
4781 } |
|
4782 |
|
4783 // ---------------------------------------------------------------------------- |
|
4784 // CDRMDbSession::DeleteAllowedL |
|
4785 // ---------------------------------------------------------------------------- |
|
4786 // |
|
4787 TBool CDRMDbSession::DeleteAllowedL( const TDesC8& aContentId ) |
|
4788 { |
|
4789 TBuf8< KMaxOmaV1CIDLength > URI; |
|
4790 |
|
4791 // Get the FL uri |
|
4792 GetFlURI( URI ); |
|
4793 |
|
4794 if( aContentId.Compare( URI ) && |
|
4795 aContentId.Compare( KDCMUri ) && |
|
4796 aContentId.Compare( KLDFUri ) ) |
|
4797 { |
|
4798 return ETrue; |
|
4799 } |
|
4800 return EFalse; |
|
4801 } |
|
4802 |
|
4803 // ---------------------------------------------------------------------------- |
|
4804 // CDRMDbSession::GetRandomDataL |
|
4805 // ---------------------------------------------------------------------------- |
|
4806 // |
|
4807 void CDRMDbSession::GetRandomDataL( const RMessage2& aMessage ) |
|
4808 { |
|
4809 DRMLOG(_L("CDRMDbSession::GetRandomDataL")); |
|
4810 |
|
4811 HBufC8* data = NULL; |
|
4812 SanitizeL( aMessage.GetDesMaxLength(0) ); |
|
4813 SanitizeL( aMessage.GetDesLength(0)); |
|
4814 |
|
4815 data = HBufC8::NewMaxLC(IPCGETDESLEN0); |
|
4816 TPtr8 ptr(data->Des()); |
|
4817 |
|
4818 MDrmKeyStorage* storage = DrmKeyStorageNewL(); |
|
4819 TCleanupItem storageCleanup( DeleteObject, storage ); |
|
4820 CleanupStack::PushL(storageCleanup); |
|
4821 storage->RandomDataGetL(ptr,ptr.Size()); |
|
4822 IPCWRITE0L(*data); |
|
4823 |
|
4824 CleanupStack::PopAndDestroy(2, data); |
|
4825 aMessage.Complete( KErrNone ); |
|
4826 } |
|
4827 |
|
4828 // ----------------------------------------------------------------------------- |
|
4829 // CDRMDbSession::GetMeteringDataL |
|
4830 // ----------------------------------------------------------------------------- |
|
4831 // |
|
4832 void CDRMDbSession::GetMeteringDataL( const RMessage2& aMessage ) |
|
4833 { |
|
4834 #ifndef RD_DRM_METERING |
|
4835 aMessage.Complete ( KErrNotSupported ); |
|
4836 #else |
|
4837 HBufC8* riId = NULL; |
|
4838 HBufC8* meteringData = NULL; |
|
4839 CDRMPointerArray<CDrmMeteringDbData>* meteringArray = |
|
4840 CDRMPointerArray<CDrmMeteringDbData>::NewLC(); |
|
4841 meteringArray->SetAutoCleanup( ETrue ); |
|
4842 |
|
4843 TInt size = 0; |
|
4844 TPtr8 data( NULL, 0 ); |
|
4845 TPckg<TInt> package( size ); |
|
4846 |
|
4847 SanitizeL( aMessage.GetDesLength(0)); |
|
4848 // Empty old data |
|
4849 delete iPreparedData; |
|
4850 iPreparedData = NULL; |
|
4851 |
|
4852 riId = HBufC8::NewLC( User::LeaveIfError( IPCGETDESLEN1 ) ); |
|
4853 data.Set( riId->Des() ); |
|
4854 IPCREAD1L( data ); |
|
4855 |
|
4856 if ( METERINGDB.GetL( *riId, *meteringArray ) ) |
|
4857 { |
|
4858 meteringData = CreateMeteringDataL( meteringArray ); |
|
4859 CleanupStack::PushL( meteringData ); |
|
4860 } |
|
4861 else |
|
4862 { |
|
4863 _LIT8( KEmptyMetering, "<rawMeteringReportData>\r\n</rawMeteringReportData>"); |
|
4864 meteringData = KEmptyMetering().AllocLC(); |
|
4865 } |
|
4866 DRMLOGHEX( *meteringData ); |
|
4867 size = meteringData->Size(); |
|
4868 iPreparedData = meteringData; |
|
4869 CleanupStack::Pop( meteringData ); |
|
4870 |
|
4871 IPCWRITE0L( package ); |
|
4872 CleanupStack::PopAndDestroy( 2 ); // riId, meteringArray |
|
4873 if ( !iPreparedData ) |
|
4874 { |
|
4875 aMessage.Complete( KErrNotFound ); |
|
4876 return; |
|
4877 } |
|
4878 aMessage.Complete( KErrNone ); |
|
4879 #endif |
|
4880 } |
|
4881 |
|
4882 // ----------------------------------------------------------------------------- |
|
4883 // CDRMDbSession::DeleteMeteringDataL |
|
4884 // ----------------------------------------------------------------------------- |
|
4885 // |
|
4886 void CDRMDbSession::DeleteMeteringDataL( const RMessage2& aMessage ) |
|
4887 { |
|
4888 #ifndef RD_DRM_METERING |
|
4889 aMessage.Complete ( KErrNotSupported ); |
|
4890 #else |
|
4891 // Metering supported |
|
4892 HBufC8* riId = NULL; |
|
4893 TPtr8 data( NULL, 0 ); |
|
4894 TBool meteringDataDeleted; |
|
4895 |
|
4896 riId = HBufC8::NewLC( User::LeaveIfError( IPCGETDESLEN0 ) ); |
|
4897 data.Set( riId->Des() ); |
|
4898 IPCREAD0L( data ); |
|
4899 meteringDataDeleted = METERINGDB.DeleteL( *riId ); |
|
4900 |
|
4901 if( meteringDataDeleted ) |
|
4902 { |
|
4903 DRMLOG( _L("CDRMDbSession::DeleteMeteringDataL -> some records were destroyed") ); |
|
4904 } |
|
4905 // Do we have to do something else? |
|
4906 CleanupStack::PopAndDestroy( riId ); |
|
4907 aMessage.Complete( KErrNone ); |
|
4908 #endif |
|
4909 } |
|
4910 // ----------------------------------------------------------------------------- |
|
4911 // CDRMDbSession::ConnectRoapClient() |
|
4912 // ----------------------------------------------------------------------------- |
|
4913 // |
|
4914 TInt CDRMDbSession::ConnectRoapClient() |
|
4915 { |
|
4916 if( iRoapClientConnected ) |
|
4917 { |
|
4918 return KErrNone; |
|
4919 } |
|
4920 TInt err( iRoapClient.Connect() ); |
|
4921 if ( !err ) |
|
4922 { |
|
4923 iRoapClientConnected = ETrue; |
|
4924 } |
|
4925 return err; |
|
4926 } |
|
4927 |
|
4928 // End of File |