Code:
/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Base / System / Security / RightsManagement / CryptoProvider.cs / 1305600 / 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; using MS.Internal.WindowsBase; 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 ReadOnlyCollectionBoundGrants { 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(ListboundLicenseHandleList, 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++) { Nullableright = 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
- RemoteX509Token.cs
- InvokeSchedule.cs
- Sentence.cs
- Internal.cs
- CompilerGeneratedAttribute.cs
- ViewService.cs
- _DynamicWinsockMethods.cs
- PrintingPermission.cs
- Group.cs
- BitmapDownload.cs
- COM2FontConverter.cs
- TabItem.cs
- DataGridColumnCollection.cs
- SeekStoryboard.cs
- MediaCommands.cs
- RegexWorker.cs
- SrgsElement.cs
- RestHandlerFactory.cs
- NavigationWindowAutomationPeer.cs
- RijndaelManagedTransform.cs
- WebPartCatalogAddVerb.cs
- ExpandCollapseIsCheckedConverter.cs
- StandardBindingReliableSessionElement.cs
- XmlDocument.cs
- IndexerNameAttribute.cs
- DetailsViewUpdatedEventArgs.cs
- FunctionDescription.cs
- RepeatInfo.cs
- Permission.cs
- ComContractElementCollection.cs
- StaticExtension.cs
- wmiprovider.cs
- UIElementCollection.cs
- ErrorFormatterPage.cs
- BuildProviderCollection.cs
- ConnectionPoolManager.cs
- CodeSnippetTypeMember.cs
- Border.cs
- PassportAuthenticationEventArgs.cs
- TrueReadOnlyCollection.cs
- mediaeventargs.cs
- FlowDocumentView.cs
- CompositeFontInfo.cs
- TargetConverter.cs
- SafeBuffer.cs
- SiteMapDataSource.cs
- HttpHostedTransportConfiguration.cs
- EtwTrace.cs
- WebSysDescriptionAttribute.cs
- TempFiles.cs
- GroupBox.cs
- SHA1Managed.cs
- SafeNativeMethods.cs
- AnnotationResourceChangedEventArgs.cs
- PersonalizableAttribute.cs
- HtmlShimManager.cs
- CreateBookmarkScope.cs
- Vector3D.cs
- PseudoWebRequest.cs
- TypeUtils.cs
- ArglessEventHandlerProxy.cs
- FileSecurity.cs
- StreamGeometry.cs
- HttpVersion.cs
- TreeIterators.cs
- NameTable.cs
- TypeUtils.cs
- DataGridViewTextBoxCell.cs
- QueueProcessor.cs
- ServerIdentity.cs
- List.cs
- ChildTable.cs
- DbModificationCommandTree.cs
- EntityDataSourceStatementEditorForm.cs
- Options.cs
- SqlCrossApplyToCrossJoin.cs
- CopyOfAction.cs
- ApplicationInfo.cs
- UpdateRecord.cs
- storepermissionattribute.cs
- IERequestCache.cs
- ListParaClient.cs
- MouseButton.cs
- SQLInt16.cs
- SqlConnectionFactory.cs
- IResourceProvider.cs
- SimpleBitVector32.cs
- CheckBoxRenderer.cs
- TextCollapsingProperties.cs
- WebPartDeleteVerb.cs
- SRGSCompiler.cs
- OleDbDataAdapter.cs
- OleDbEnumerator.cs
- Module.cs
- MetadataArtifactLoaderXmlReaderWrapper.cs
- PresentationAppDomainManager.cs
- KeyManager.cs
- MergePropertyDescriptor.cs
- BezierSegment.cs
- ProcessHostConfigUtils.cs