Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Base / System / Security / RightsManagement / CryptoProvider.cs / 1 / CryptoProvider.cs
//------------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
// Description: Crypto provider class which is a wrapper around unmanaged DRM SDK Bound License handle
// provides ability to Encryt/Decrypt protected content, and enumerate granted rights.
//
// History:
// 06/01/2005: IgorBel : Initial Implementation
//
//-----------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Security;
using System.Security.Permissions;
using System.Windows;
using System.Collections.ObjectModel;
using MS.Internal.Security.RightsManagement;
using MS.Internal;
using SecurityHelper=MS.Internal.WindowsBase.SecurityHelper;
namespace System.Security.RightsManagement
{
///
/// CryptoProvider class is built as a result of UseLicense.Bind call. This class represents a successful RightsManagement
/// Initialization, and as a result provides Encryption/Decryption services, and exposes list of Bound Grants, which are rights
/// that have been given by the publisher to the user, and were properly validated (expiration checks, secure environment, and so on)
///
///
/// Critical: This class expose access to methods that eventually do one or more of the the following
/// 1. call into unmanaged code
/// 2. affects state/data that will eventually cross over unmanaged code boundary
/// 3. Return some RM related information which is considered private
///
/// TreatAsSafe: This attrbiute automatically applied to all public entry points. All the public entry points have
/// Demands for RightsManagementPermission at entry to counter the possible attacks that do
/// not lead to the unamanged code directly(which is protected by another Demand there) but rather leave
/// some status/data behind which eventually might cross the unamanaged boundary.
///
[SecurityCritical(SecurityCriticalScope.Everything)]
public class CryptoProvider : IDisposable
{
//-----------------------------------------------------
//
// Public Methods
//
//-----------------------------------------------------
///
/// This method is responsible for tearing down crypto provider that was built as a result of UseLicense.Bind call.
///
~CryptoProvider()
{
Dispose(false);
}
///
/// This method is responsible for tearing down crypto provider that was built as a result of UseLicense.Bind call.
///
public void Dispose()
{
SecurityHelper.DemandRightsManagementPermission();
Dispose(true);
GC.SuppressFinalize(this);
}
///
/// This function encrypts clear text content.
/// An application is expected to create a padding scheme based on the value returned from
/// BlockSize property. BlockSize property should be used to determine the amount of extra
/// padding to be added to the clear text. The length, in bytes, of the buffer holding content to
/// be encrypted should be a multiple of the block cipher block size.
/// RMS system currently uses AES block cipher. All blocks are encrypted independently, so that 2 blocks
/// of identical clear text will produce identical results after encryption. An application
/// is encouraged to either compress data prior to encryption or create some other scheme to mitigate
/// threats potentially arising from independent block encryption.
///
public byte[] Encrypt(byte[] clearText)
{
SecurityHelper.DemandRightsManagementPermission();
CheckDisposed();
if (clearText == null)
{
throw new ArgumentNullException("clearText");
}
// validation of the proper size of the clearText is done by the unmanaged libraries
if (!CanEncrypt)
{
throw new RightsManagementException(RightsManagementFailureCode.EncryptionNotPermitted);
}
// first get the size
uint outputBufferSize=0;
byte[] outputBuffer = null;
int hr;
#if DEBUG
hr= SafeNativeMethods.DRMEncrypt(
EncryptorHandle,
0,
(uint)clearText.Length,
clearText,
ref outputBufferSize,
null);
Errors.ThrowOnErrorCode(hr);
// We do not expect Decryption to change the size of the buffer; otherwise it will break
// basic assumptions behind the encrypted compound file envelope format
Invariant.Assert(outputBufferSize == clearText.Length);
#else
outputBufferSize = (uint)clearText.Length;
#endif
outputBuffer = new byte[outputBufferSize];
// This will decrypt content
hr = SafeNativeMethods.DRMEncrypt(
EncryptorHandle,
0,
(uint)clearText.Length,
clearText,
ref outputBufferSize,
outputBuffer);
Errors.ThrowOnErrorCode(hr);
return outputBuffer;
}
///
/// This function decrypts cipher text content.
/// The length, in bytes, of the buffer holding content to be encrypted should be a multiple of the
/// block cipher block size.
///
public byte[] Decrypt(byte[] cryptoText)
{
SecurityHelper.DemandRightsManagementPermission();
CheckDisposed();
if (cryptoText == null)
{
throw new ArgumentNullException("cryptoText");
}
// validation of the proper size of the cryptoText is done by the unmanaged libraries
if (!CanDecrypt)
{
throw new RightsManagementException(RightsManagementFailureCode.RightNotGranted);
}
// first get the size
uint outputBufferSize=0;
byte[] outputBuffer = null;
int hr;
#if DEBUG
hr= SafeNativeMethods.DRMDecrypt(
DecryptorHandle,
0,
(uint)cryptoText.Length,
cryptoText,
ref outputBufferSize,
null);
Errors.ThrowOnErrorCode(hr);
// We do not expect Decryption changing the size of the buffer; otherwise it will break
// basic assumptions behind the encrypted compound file envelope format
Invariant.Assert(outputBufferSize == cryptoText.Length);
#else
outputBufferSize = (uint)cryptoText.Length;
#endif
outputBuffer = new byte[outputBufferSize];
// THis will decrypt content
hr = SafeNativeMethods.DRMDecrypt(
DecryptorHandle,
0,
(uint)cryptoText.Length,
cryptoText,
ref outputBufferSize,
outputBuffer);
Errors.ThrowOnErrorCode(hr);
return outputBuffer;
}
//------------------------------------------------------
//
// Protected Methods
//
//-----------------------------------------------------
///
/// Dispose(bool)
///
///
protected virtual void Dispose(bool disposing)
{
// close bound license handle which is a DRMHANDLE
// Encryptor and Decryptor handles as well
try
{
if (disposing)
{
if (_decryptorHandle != null && !_decryptorHandle.IsInvalid)
_decryptorHandle.Close();
if (_encryptorHandle != null && !_encryptorHandle.IsInvalid)
_encryptorHandle.Close();
if (_boundLicenseOwnerViewRightsHandle != null && !_boundLicenseOwnerViewRightsHandle.IsInvalid)
_boundLicenseOwnerViewRightsHandle.Close();
// dispose collection of the bound licenses that we have
if (_boundLicenseHandleList != null)
{
foreach(SafeRightsManagementHandle boundLicenseHandle in _boundLicenseHandleList)
{
if (boundLicenseHandle != null && !boundLicenseHandle.IsInvalid)
boundLicenseHandle.Close();
}
}
}
}
finally
{
_disposed = true;
_boundLicenseHandleList = null;
_boundLicenseOwnerViewRightsHandle = null;
_decryptorHandle = null;
_encryptorHandle = null;
}
}
//------------------------------------------------------
//
// Public Properties
//
//------------------------------------------------------
///
/// This is bock size of the cypther that is currently in use.
///
public int BlockSize
{
get
{
SecurityHelper.DemandRightsManagementPermission();
CheckDisposed();
if (_blockSize ==0)
{
_blockSize = QueryBlockSize();
}
return _blockSize;
}
}
///
/// This bollean indicates wheter Encrypt Decrypt calls can be made on buffers that are multiple of the BlockSize value.
/// If the value is false Encrypt Decrypt calls must be made on buffers of the size that is exactly equal to the BlockSize.
///
public bool CanMergeBlocks
{
get
{
SecurityHelper.DemandRightsManagementPermission();
CheckDisposed();
// convention is to return 1 for stream ciphers
// Stream ciphers (although currently not used) return 1.
// Block ciphers return size of the block that is always greater than 1.
// Comparing block size to 1 is a conventional way to differentiate stream and
// block ciphers. Block Ciphers can accept data chunks (for both encryption and decryption)
// that fall on the block boundary and are a multiple of the block cipher block size.
return (BlockSize > 1);
}
}
///
/// This is a read only property. It enable client application to enumerate list of rights that were
/// granted to the user, and also passed all the verification checks.
///
public ReadOnlyCollection BoundGrants
{
get
{
SecurityHelper.DemandRightsManagementPermission();
CheckDisposed();
if (_boundGrantReadOnlyCollection == null)
{
// we need to enumerate all the rights and keep the ones that we can translate into enum
// we ignore the rights that we can not translate for forward compatibility reasons
List grantList = new List(_boundRightsInfoList.Count);
foreach(RightNameExpirationInfoPair rightsInfo in _boundRightsInfoList)
{
Nullable contentRight = ClientSession.GetRightFromString(rightsInfo.RightName);
if (contentRight != null)
{
grantList.Add(new ContentGrant(_owner, contentRight.Value, rightsInfo.ValidFrom, rightsInfo.ValidUntil));
}
}
_boundGrantReadOnlyCollection = new ReadOnlyCollection (grantList);
}
return _boundGrantReadOnlyCollection;
}
}
///
/// Depending on the set of rights ggranted to the user he or she can do Encryption, Decryption or both.
/// this property checks whether user was granted rights to encrypt, which means that he or she was granted
/// either an Edit or an Owner right.
///
public bool CanEncrypt
{
get
{
SecurityHelper.DemandRightsManagementPermission();
CheckDisposed();
return (!EncryptorHandle.IsInvalid);
}
}
///
/// Depending on the set of rights granted to the user he or she can do Encryption, Decryption or both.
/// this property checks whether user was granted rights to decrypt. Decryption is given to a user if he or
/// she was able to successfully bind any right (View, Edit, Print, Owner, ....)
///
public bool CanDecrypt
{
get
{
SecurityHelper.DemandRightsManagementPermission();
CheckDisposed();
return (!DecryptorHandle.IsInvalid);
}
}
//-----------------------------------------------------
//
// Internal Constructor
//
//------------------------------------------------------
///
/// Constructor.
///
internal CryptoProvider(List boundLicenseHandleList,
List rightsInfoList,
ContentUser owner)
{
Invariant.Assert(boundLicenseHandleList != null);
Invariant.Assert(boundLicenseHandleList.Count > 0);
Invariant.Assert(rightsInfoList != null);
Invariant.Assert(rightsInfoList.Count > 0);
// we expect a match between lists of the Right Information and the bound license handles
// we will be mapping those lists based on indexes
Invariant.Assert(rightsInfoList.Count == boundLicenseHandleList.Count);
Invariant.Assert(owner != null);
_boundLicenseHandleList = boundLicenseHandleList;
_boundRightsInfoList = rightsInfoList;
_owner = owner;
}
//-----------------------------------------------------
//
// Internal Methods
//
//-----------------------------------------------------
internal UnsignedPublishLicense DecryptPublishLicense(string serializedPublishLicense)
{
Invariant.Assert(serializedPublishLicense != null);
if ((BoundLicenseOwnerViewRightsHandle == null ) || BoundLicenseOwnerViewRightsHandle.IsInvalid)
{
throw new RightsManagementException(RightsManagementFailureCode.RightNotGranted);
}
else
{
return new UnsignedPublishLicense(BoundLicenseOwnerViewRightsHandle, serializedPublishLicense);
}
}
//-----------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
///
/// Call this before accepting any API call
///
private void CheckDisposed()
{
if (_disposed)
throw new ObjectDisposedException(null, SR.Get(SRID.CryptoProviderDisposed));
}
private int QueryBlockSize()
{
uint attributeSize = 0;
byte[] dataBuffer = null;
uint encodingType;
int hr = SafeNativeMethods.DRMGetInfo(DecryptorHandle,
NativeConstants.QUERY_BLOCKSIZE,
out encodingType,
ref attributeSize,
null);
Errors.ThrowOnErrorCode(hr);
// it must return 4 bytes for block size
Invariant.Assert(attributeSize == 4);
dataBuffer = new byte[(int)attributeSize]; // this cast is safe based on the Invariant.Assert above.
hr = SafeNativeMethods.DRMGetInfo(DecryptorHandle,
NativeConstants.QUERY_BLOCKSIZE,
out encodingType,
ref attributeSize,
dataBuffer);
Errors.ThrowOnErrorCode(hr);
return BitConverter.ToInt32(dataBuffer,0);
}
//-----------------------------------------------------
//
// Private Properties
//
//------------------------------------------------------
private SafeRightsManagementHandle DecryptorHandle
{
get
{
if(!_decryptorHandleCalculated)
{
for(int i=0; i< _boundLicenseHandleList.Count; i++)
{
SafeRightsManagementHandle decryptorHandle = null;
int hr = SafeNativeMethods.DRMCreateEnablingBitsDecryptor(
_boundLicenseHandleList[i],
_boundRightsInfoList[i].RightName,
0,
null,
out decryptorHandle);
if (hr == 0)
{
Debug.Assert(decryptorHandle != null);
_decryptorHandle = decryptorHandle;
_decryptorHandleCalculated = true;
return _decryptorHandle;
}
}
_decryptorHandleCalculated = true; // if we got here it means we couldn't find anything; regardless
// we should still mark this calculation as complete
}
return _decryptorHandle;
}
}
private SafeRightsManagementHandle EncryptorHandle
{
get
{
if(!_encryptorHandleCalculated)
{
for(int i=0; i< _boundLicenseHandleList.Count; i++)
{
SafeRightsManagementHandle encryptorHandle = null;
int hr = SafeNativeMethods.DRMCreateEnablingBitsEncryptor(
_boundLicenseHandleList[i],
_boundRightsInfoList[i].RightName,
0,
null,
out encryptorHandle);
if (hr == 0)
{
Debug.Assert(encryptorHandle != null);
_encryptorHandle = encryptorHandle;
_encryptorHandleCalculated = true;
return _encryptorHandle;
}
}
_encryptorHandleCalculated = true; // if we got here it means we couldn't find anything; regardless
// we should still mark this calculation as complete
}
return _encryptorHandle;
}
}
private SafeRightsManagementHandle BoundLicenseOwnerViewRightsHandle
{
get
{
if(!_boundLicenseOwnerViewRightsHandleCalculated)
{
for(int i=0; i< _boundLicenseHandleList.Count; i++)
{
Nullable right =
ClientSession.GetRightFromString(_boundRightsInfoList[i].RightName);
if ((right != null)
&&
((right.Value == ContentRight.Owner) ||(right.Value== ContentRight.ViewRightsData)))
{
_boundLicenseOwnerViewRightsHandle = _boundLicenseHandleList[i];
_boundLicenseOwnerViewRightsHandleCalculated = true;
return _boundLicenseOwnerViewRightsHandle;
}
}
_boundLicenseOwnerViewRightsHandleCalculated = true; // if we got here it means we couldn't find anything; regardless
// we should still mark this calculation as complete
}
return _boundLicenseOwnerViewRightsHandle;
}
}
//------------------------------------------------------
//
// Private Fields
//
//-----------------------------------------------------
private int _blockSize;
private SafeRightsManagementHandle _decryptorHandle = SafeRightsManagementHandle.InvalidHandle;
private bool _decryptorHandleCalculated;
private SafeRightsManagementHandle _encryptorHandle = SafeRightsManagementHandle.InvalidHandle;
private bool _encryptorHandleCalculated;
private SafeRightsManagementHandle _boundLicenseOwnerViewRightsHandle = SafeRightsManagementHandle.InvalidHandle;
private bool _boundLicenseOwnerViewRightsHandleCalculated;
// if this is Invalid, we are disposed
private List _boundLicenseHandleList;
private List _boundRightsInfoList;
private ReadOnlyCollection _boundGrantReadOnlyCollection;
private ContentUser _owner;
private bool _disposed;
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
// Description: Crypto provider class which is a wrapper around unmanaged DRM SDK Bound License handle
// provides ability to Encryt/Decrypt protected content, and enumerate granted rights.
//
// History:
// 06/01/2005: IgorBel : Initial Implementation
//
//-----------------------------------------------------------------------------
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Security;
using System.Security.Permissions;
using System.Windows;
using System.Collections.ObjectModel;
using MS.Internal.Security.RightsManagement;
using MS.Internal;
using SecurityHelper=MS.Internal.WindowsBase.SecurityHelper;
namespace System.Security.RightsManagement
{
///
/// CryptoProvider class is built as a result of UseLicense.Bind call. This class represents a successful RightsManagement
/// Initialization, and as a result provides Encryption/Decryption services, and exposes list of Bound Grants, which are rights
/// that have been given by the publisher to the user, and were properly validated (expiration checks, secure environment, and so on)
///
///
/// Critical: This class expose access to methods that eventually do one or more of the the following
/// 1. call into unmanaged code
/// 2. affects state/data that will eventually cross over unmanaged code boundary
/// 3. Return some RM related information which is considered private
///
/// TreatAsSafe: This attrbiute automatically applied to all public entry points. All the public entry points have
/// Demands for RightsManagementPermission at entry to counter the possible attacks that do
/// not lead to the unamanged code directly(which is protected by another Demand there) but rather leave
/// some status/data behind which eventually might cross the unamanaged boundary.
///
[SecurityCritical(SecurityCriticalScope.Everything)]
public class CryptoProvider : IDisposable
{
//-----------------------------------------------------
//
// Public Methods
//
//-----------------------------------------------------
///
/// This method is responsible for tearing down crypto provider that was built as a result of UseLicense.Bind call.
///
~CryptoProvider()
{
Dispose(false);
}
///
/// This method is responsible for tearing down crypto provider that was built as a result of UseLicense.Bind call.
///
public void Dispose()
{
SecurityHelper.DemandRightsManagementPermission();
Dispose(true);
GC.SuppressFinalize(this);
}
///
/// This function encrypts clear text content.
/// An application is expected to create a padding scheme based on the value returned from
/// BlockSize property. BlockSize property should be used to determine the amount of extra
/// padding to be added to the clear text. The length, in bytes, of the buffer holding content to
/// be encrypted should be a multiple of the block cipher block size.
/// RMS system currently uses AES block cipher. All blocks are encrypted independently, so that 2 blocks
/// of identical clear text will produce identical results after encryption. An application
/// is encouraged to either compress data prior to encryption or create some other scheme to mitigate
/// threats potentially arising from independent block encryption.
///
public byte[] Encrypt(byte[] clearText)
{
SecurityHelper.DemandRightsManagementPermission();
CheckDisposed();
if (clearText == null)
{
throw new ArgumentNullException("clearText");
}
// validation of the proper size of the clearText is done by the unmanaged libraries
if (!CanEncrypt)
{
throw new RightsManagementException(RightsManagementFailureCode.EncryptionNotPermitted);
}
// first get the size
uint outputBufferSize=0;
byte[] outputBuffer = null;
int hr;
#if DEBUG
hr= SafeNativeMethods.DRMEncrypt(
EncryptorHandle,
0,
(uint)clearText.Length,
clearText,
ref outputBufferSize,
null);
Errors.ThrowOnErrorCode(hr);
// We do not expect Decryption to change the size of the buffer; otherwise it will break
// basic assumptions behind the encrypted compound file envelope format
Invariant.Assert(outputBufferSize == clearText.Length);
#else
outputBufferSize = (uint)clearText.Length;
#endif
outputBuffer = new byte[outputBufferSize];
// This will decrypt content
hr = SafeNativeMethods.DRMEncrypt(
EncryptorHandle,
0,
(uint)clearText.Length,
clearText,
ref outputBufferSize,
outputBuffer);
Errors.ThrowOnErrorCode(hr);
return outputBuffer;
}
///
/// This function decrypts cipher text content.
/// The length, in bytes, of the buffer holding content to be encrypted should be a multiple of the
/// block cipher block size.
///
public byte[] Decrypt(byte[] cryptoText)
{
SecurityHelper.DemandRightsManagementPermission();
CheckDisposed();
if (cryptoText == null)
{
throw new ArgumentNullException("cryptoText");
}
// validation of the proper size of the cryptoText is done by the unmanaged libraries
if (!CanDecrypt)
{
throw new RightsManagementException(RightsManagementFailureCode.RightNotGranted);
}
// first get the size
uint outputBufferSize=0;
byte[] outputBuffer = null;
int hr;
#if DEBUG
hr= SafeNativeMethods.DRMDecrypt(
DecryptorHandle,
0,
(uint)cryptoText.Length,
cryptoText,
ref outputBufferSize,
null);
Errors.ThrowOnErrorCode(hr);
// We do not expect Decryption changing the size of the buffer; otherwise it will break
// basic assumptions behind the encrypted compound file envelope format
Invariant.Assert(outputBufferSize == cryptoText.Length);
#else
outputBufferSize = (uint)cryptoText.Length;
#endif
outputBuffer = new byte[outputBufferSize];
// THis will decrypt content
hr = SafeNativeMethods.DRMDecrypt(
DecryptorHandle,
0,
(uint)cryptoText.Length,
cryptoText,
ref outputBufferSize,
outputBuffer);
Errors.ThrowOnErrorCode(hr);
return outputBuffer;
}
//------------------------------------------------------
//
// Protected Methods
//
//-----------------------------------------------------
///
/// Dispose(bool)
///
///
protected virtual void Dispose(bool disposing)
{
// close bound license handle which is a DRMHANDLE
// Encryptor and Decryptor handles as well
try
{
if (disposing)
{
if (_decryptorHandle != null && !_decryptorHandle.IsInvalid)
_decryptorHandle.Close();
if (_encryptorHandle != null && !_encryptorHandle.IsInvalid)
_encryptorHandle.Close();
if (_boundLicenseOwnerViewRightsHandle != null && !_boundLicenseOwnerViewRightsHandle.IsInvalid)
_boundLicenseOwnerViewRightsHandle.Close();
// dispose collection of the bound licenses that we have
if (_boundLicenseHandleList != null)
{
foreach(SafeRightsManagementHandle boundLicenseHandle in _boundLicenseHandleList)
{
if (boundLicenseHandle != null && !boundLicenseHandle.IsInvalid)
boundLicenseHandle.Close();
}
}
}
}
finally
{
_disposed = true;
_boundLicenseHandleList = null;
_boundLicenseOwnerViewRightsHandle = null;
_decryptorHandle = null;
_encryptorHandle = null;
}
}
//------------------------------------------------------
//
// Public Properties
//
//------------------------------------------------------
///
/// This is bock size of the cypther that is currently in use.
///
public int BlockSize
{
get
{
SecurityHelper.DemandRightsManagementPermission();
CheckDisposed();
if (_blockSize ==0)
{
_blockSize = QueryBlockSize();
}
return _blockSize;
}
}
///
/// This bollean indicates wheter Encrypt Decrypt calls can be made on buffers that are multiple of the BlockSize value.
/// If the value is false Encrypt Decrypt calls must be made on buffers of the size that is exactly equal to the BlockSize.
///
public bool CanMergeBlocks
{
get
{
SecurityHelper.DemandRightsManagementPermission();
CheckDisposed();
// convention is to return 1 for stream ciphers
// Stream ciphers (although currently not used) return 1.
// Block ciphers return size of the block that is always greater than 1.
// Comparing block size to 1 is a conventional way to differentiate stream and
// block ciphers. Block Ciphers can accept data chunks (for both encryption and decryption)
// that fall on the block boundary and are a multiple of the block cipher block size.
return (BlockSize > 1);
}
}
///
/// This is a read only property. It enable client application to enumerate list of rights that were
/// granted to the user, and also passed all the verification checks.
///
public ReadOnlyCollection BoundGrants
{
get
{
SecurityHelper.DemandRightsManagementPermission();
CheckDisposed();
if (_boundGrantReadOnlyCollection == null)
{
// we need to enumerate all the rights and keep the ones that we can translate into enum
// we ignore the rights that we can not translate for forward compatibility reasons
List grantList = new List(_boundRightsInfoList.Count);
foreach(RightNameExpirationInfoPair rightsInfo in _boundRightsInfoList)
{
Nullable contentRight = ClientSession.GetRightFromString(rightsInfo.RightName);
if (contentRight != null)
{
grantList.Add(new ContentGrant(_owner, contentRight.Value, rightsInfo.ValidFrom, rightsInfo.ValidUntil));
}
}
_boundGrantReadOnlyCollection = new ReadOnlyCollection (grantList);
}
return _boundGrantReadOnlyCollection;
}
}
///
/// Depending on the set of rights ggranted to the user he or she can do Encryption, Decryption or both.
/// this property checks whether user was granted rights to encrypt, which means that he or she was granted
/// either an Edit or an Owner right.
///
public bool CanEncrypt
{
get
{
SecurityHelper.DemandRightsManagementPermission();
CheckDisposed();
return (!EncryptorHandle.IsInvalid);
}
}
///
/// Depending on the set of rights granted to the user he or she can do Encryption, Decryption or both.
/// this property checks whether user was granted rights to decrypt. Decryption is given to a user if he or
/// she was able to successfully bind any right (View, Edit, Print, Owner, ....)
///
public bool CanDecrypt
{
get
{
SecurityHelper.DemandRightsManagementPermission();
CheckDisposed();
return (!DecryptorHandle.IsInvalid);
}
}
//-----------------------------------------------------
//
// Internal Constructor
//
//------------------------------------------------------
///
/// Constructor.
///
internal CryptoProvider(List boundLicenseHandleList,
List rightsInfoList,
ContentUser owner)
{
Invariant.Assert(boundLicenseHandleList != null);
Invariant.Assert(boundLicenseHandleList.Count > 0);
Invariant.Assert(rightsInfoList != null);
Invariant.Assert(rightsInfoList.Count > 0);
// we expect a match between lists of the Right Information and the bound license handles
// we will be mapping those lists based on indexes
Invariant.Assert(rightsInfoList.Count == boundLicenseHandleList.Count);
Invariant.Assert(owner != null);
_boundLicenseHandleList = boundLicenseHandleList;
_boundRightsInfoList = rightsInfoList;
_owner = owner;
}
//-----------------------------------------------------
//
// Internal Methods
//
//-----------------------------------------------------
internal UnsignedPublishLicense DecryptPublishLicense(string serializedPublishLicense)
{
Invariant.Assert(serializedPublishLicense != null);
if ((BoundLicenseOwnerViewRightsHandle == null ) || BoundLicenseOwnerViewRightsHandle.IsInvalid)
{
throw new RightsManagementException(RightsManagementFailureCode.RightNotGranted);
}
else
{
return new UnsignedPublishLicense(BoundLicenseOwnerViewRightsHandle, serializedPublishLicense);
}
}
//-----------------------------------------------------
//
// Private Methods
//
//------------------------------------------------------
///
/// Call this before accepting any API call
///
private void CheckDisposed()
{
if (_disposed)
throw new ObjectDisposedException(null, SR.Get(SRID.CryptoProviderDisposed));
}
private int QueryBlockSize()
{
uint attributeSize = 0;
byte[] dataBuffer = null;
uint encodingType;
int hr = SafeNativeMethods.DRMGetInfo(DecryptorHandle,
NativeConstants.QUERY_BLOCKSIZE,
out encodingType,
ref attributeSize,
null);
Errors.ThrowOnErrorCode(hr);
// it must return 4 bytes for block size
Invariant.Assert(attributeSize == 4);
dataBuffer = new byte[(int)attributeSize]; // this cast is safe based on the Invariant.Assert above.
hr = SafeNativeMethods.DRMGetInfo(DecryptorHandle,
NativeConstants.QUERY_BLOCKSIZE,
out encodingType,
ref attributeSize,
dataBuffer);
Errors.ThrowOnErrorCode(hr);
return BitConverter.ToInt32(dataBuffer,0);
}
//-----------------------------------------------------
//
// Private Properties
//
//------------------------------------------------------
private SafeRightsManagementHandle DecryptorHandle
{
get
{
if(!_decryptorHandleCalculated)
{
for(int i=0; i< _boundLicenseHandleList.Count; i++)
{
SafeRightsManagementHandle decryptorHandle = null;
int hr = SafeNativeMethods.DRMCreateEnablingBitsDecryptor(
_boundLicenseHandleList[i],
_boundRightsInfoList[i].RightName,
0,
null,
out decryptorHandle);
if (hr == 0)
{
Debug.Assert(decryptorHandle != null);
_decryptorHandle = decryptorHandle;
_decryptorHandleCalculated = true;
return _decryptorHandle;
}
}
_decryptorHandleCalculated = true; // if we got here it means we couldn't find anything; regardless
// we should still mark this calculation as complete
}
return _decryptorHandle;
}
}
private SafeRightsManagementHandle EncryptorHandle
{
get
{
if(!_encryptorHandleCalculated)
{
for(int i=0; i< _boundLicenseHandleList.Count; i++)
{
SafeRightsManagementHandle encryptorHandle = null;
int hr = SafeNativeMethods.DRMCreateEnablingBitsEncryptor(
_boundLicenseHandleList[i],
_boundRightsInfoList[i].RightName,
0,
null,
out encryptorHandle);
if (hr == 0)
{
Debug.Assert(encryptorHandle != null);
_encryptorHandle = encryptorHandle;
_encryptorHandleCalculated = true;
return _encryptorHandle;
}
}
_encryptorHandleCalculated = true; // if we got here it means we couldn't find anything; regardless
// we should still mark this calculation as complete
}
return _encryptorHandle;
}
}
private SafeRightsManagementHandle BoundLicenseOwnerViewRightsHandle
{
get
{
if(!_boundLicenseOwnerViewRightsHandleCalculated)
{
for(int i=0; i< _boundLicenseHandleList.Count; i++)
{
Nullable right =
ClientSession.GetRightFromString(_boundRightsInfoList[i].RightName);
if ((right != null)
&&
((right.Value == ContentRight.Owner) ||(right.Value== ContentRight.ViewRightsData)))
{
_boundLicenseOwnerViewRightsHandle = _boundLicenseHandleList[i];
_boundLicenseOwnerViewRightsHandleCalculated = true;
return _boundLicenseOwnerViewRightsHandle;
}
}
_boundLicenseOwnerViewRightsHandleCalculated = true; // if we got here it means we couldn't find anything; regardless
// we should still mark this calculation as complete
}
return _boundLicenseOwnerViewRightsHandle;
}
}
//------------------------------------------------------
//
// Private Fields
//
//-----------------------------------------------------
private int _blockSize;
private SafeRightsManagementHandle _decryptorHandle = SafeRightsManagementHandle.InvalidHandle;
private bool _decryptorHandleCalculated;
private SafeRightsManagementHandle _encryptorHandle = SafeRightsManagementHandle.InvalidHandle;
private bool _encryptorHandleCalculated;
private SafeRightsManagementHandle _boundLicenseOwnerViewRightsHandle = SafeRightsManagementHandle.InvalidHandle;
private bool _boundLicenseOwnerViewRightsHandleCalculated;
// if this is Invalid, we are disposed
private List _boundLicenseHandleList;
private List _boundRightsInfoList;
private ReadOnlyCollection _boundGrantReadOnlyCollection;
private ContentUser _owner;
private bool _disposed;
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- StrokeCollectionDefaultValueFactory.cs
- XPathItem.cs
- MouseEventArgs.cs
- Vector3DConverter.cs
- PassportAuthentication.cs
- StringValidatorAttribute.cs
- ByteStream.cs
- PasswordPropertyTextAttribute.cs
- NetworkCredential.cs
- BlockingCollection.cs
- RoleBoolean.cs
- EventLogStatus.cs
- ReliabilityContractAttribute.cs
- DrawingContextWalker.cs
- CancelEventArgs.cs
- PageFunction.cs
- PrivilegeNotHeldException.cs
- DataGridViewToolTip.cs
- LogStream.cs
- HttpException.cs
- ProfileGroupSettings.cs
- FormattedTextSymbols.cs
- RequestTimeoutManager.cs
- ExtendedPropertiesHandler.cs
- XmlEntityReference.cs
- JsonMessageEncoderFactory.cs
- BitmapCodecInfoInternal.cs
- DataSpaceManager.cs
- OlePropertyStructs.cs
- PageAsyncTaskManager.cs
- CounterCreationData.cs
- TargetParameterCountException.cs
- FormatterServices.cs
- IERequestCache.cs
- DateTimeOffset.cs
- _SSPIWrapper.cs
- _DisconnectOverlappedAsyncResult.cs
- DataGridCommandEventArgs.cs
- LinearGradientBrush.cs
- ByteAnimation.cs
- StorageBasedPackageProperties.cs
- SchemaLookupTable.cs
- PagerSettings.cs
- AnimationTimeline.cs
- GridViewRowPresenterBase.cs
- DbInsertCommandTree.cs
- XmlValueConverter.cs
- DecimalConstantAttribute.cs
- MatrixCamera.cs
- PackageRelationship.cs
- FunctionCommandText.cs
- WebPartConnection.cs
- WebPartMenuStyle.cs
- DataGridViewColumnCollection.cs
- GacUtil.cs
- OleDbConnectionFactory.cs
- FileUpload.cs
- FieldAccessException.cs
- MultiplexingFormatMapping.cs
- HealthMonitoringSectionHelper.cs
- GridViewHeaderRowPresenter.cs
- PathGeometry.cs
- Event.cs
- XmlWriterSettings.cs
- NativeMethods.cs
- EditingContext.cs
- Site.cs
- ApplicationInfo.cs
- BindingCollection.cs
- ConfigErrorGlyph.cs
- SystemIPInterfaceStatistics.cs
- UpdatePanelTriggerCollection.cs
- DataObjectFieldAttribute.cs
- ToolStripOverflow.cs
- SingleAnimationBase.cs
- SHA512.cs
- DoubleAnimationClockResource.cs
- ScriptControl.cs
- WorkflowExecutor.cs
- SqlRemoveConstantOrderBy.cs
- TypeLoader.cs
- EntitySqlQueryBuilder.cs
- ContainerUtilities.cs
- XPathBinder.cs
- SqlCacheDependencyDatabaseCollection.cs
- DiscoveryClientReferences.cs
- LinkArea.cs
- EntityReference.cs
- SecureEnvironment.cs
- SchemaNotation.cs
- HandlerBase.cs
- BackgroundWorker.cs
- SqlDataSourceConfigureFilterForm.cs
- MouseBinding.cs
- MdiWindowListStrip.cs
- StyleTypedPropertyAttribute.cs
- OleDbPropertySetGuid.cs
- Track.cs
- WindowsGraphics2.cs
- UrlRoutingHandler.cs