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
- ExtendedProperty.cs
- Win32.cs
- RuntimeConfigLKG.cs
- RadioButton.cs
- InheritanceRules.cs
- HorizontalAlignConverter.cs
- ArrangedElement.cs
- KoreanLunisolarCalendar.cs
- RoleGroup.cs
- ListManagerBindingsCollection.cs
- SoapTypeAttribute.cs
- BatchStream.cs
- BitHelper.cs
- View.cs
- GridViewColumnCollectionChangedEventArgs.cs
- Queue.cs
- CryptoApi.cs
- FtpCachePolicyElement.cs
- SqlBulkCopy.cs
- FreeFormDragDropManager.cs
- Event.cs
- SchemaObjectWriter.cs
- FocusWithinProperty.cs
- DetailsViewCommandEventArgs.cs
- Material.cs
- GridViewEditEventArgs.cs
- EdmRelationshipRoleAttribute.cs
- DependentList.cs
- OdbcCommandBuilder.cs
- GreenMethods.cs
- PipelineModuleStepContainer.cs
- SingleKeyFrameCollection.cs
- DataGridViewTextBoxColumn.cs
- DesignerSerializerAttribute.cs
- ScrollProviderWrapper.cs
- PathFigure.cs
- DLinqColumnProvider.cs
- ListBoxItem.cs
- GeneralTransformGroup.cs
- SamlSubjectStatement.cs
- ManagedFilter.cs
- PageParserFilter.cs
- ConstructorNeedsTagAttribute.cs
- HwndSubclass.cs
- GlyphCache.cs
- WebPartTransformerAttribute.cs
- ForwardPositionQuery.cs
- HttpSessionStateBase.cs
- WS2007HttpBindingElement.cs
- Help.cs
- EdmComplexTypeAttribute.cs
- FixedSOMLineCollection.cs
- IncrementalCompileAnalyzer.cs
- TransformerInfoCollection.cs
- SqlParameterizer.cs
- RepeatBehaviorConverter.cs
- WindowsUserNameSecurityTokenAuthenticator.cs
- EntityProviderFactory.cs
- TagMapInfo.cs
- BCLDebug.cs
- uribuilder.cs
- ComponentChangingEvent.cs
- CommandDevice.cs
- _NestedMultipleAsyncResult.cs
- EdmScalarPropertyAttribute.cs
- SchemaCollectionCompiler.cs
- WebBrowserHelper.cs
- Condition.cs
- Vector3DKeyFrameCollection.cs
- XmlUTF8TextWriter.cs
- LongCountAggregationOperator.cs
- CompressedStack.cs
- PeerNearMe.cs
- MatrixUtil.cs
- StringWriter.cs
- SpeechRecognitionEngine.cs
- SizeAnimationClockResource.cs
- EnumValAlphaComparer.cs
- AnnotationComponentChooser.cs
- ColorConvertedBitmap.cs
- ReliabilityContractAttribute.cs
- SoapEnumAttribute.cs
- ExpressionDumper.cs
- SupportsPreviewControlAttribute.cs
- MaskedTextProvider.cs
- LicenseManager.cs
- GreenMethods.cs
- ImageMetadata.cs
- PtsHelper.cs
- PersistChildrenAttribute.cs
- FormViewRow.cs
- HandlerBase.cs
- _NegotiateClient.cs
- WebHeaderCollection.cs
- shaperfactoryquerycacheentry.cs
- RawStylusSystemGestureInputReport.cs
- MarkupCompiler.cs
- VectorCollectionConverter.cs
- CompositeFontFamily.cs
- SendingRequestEventArgs.cs