/// <summary> /// This static Method builds a new instance of a SecureEnvironment for a given user that is already /// activated. If this method called with a user that isn't activated, and exception will be thrown. /// The user that is passed into the function must have a well defined authentication type /// AuthenticationType.Windows or AuthenticationType.Passport, all other Authentication /// types(AuthenticationType.WindowsPassport or AuthenticationType.Internal) are not allowed. /// </summary> public static SecureEnvironment Create(string applicationManifest, ContentUser user) { SecurityHelper.DemandRightsManagementPermission(); return(CriticalCreate(applicationManifest, user)); }
/// <summary> /// This method is responsible for tearing down secure environment that was built as a result of Init call. /// </summary> public void Dispose() { SecurityHelper.DemandRightsManagementPermission(); Dispose(true); GC.SuppressFinalize(this); }
/// <summary> /// This static method activates a user and creates a new instance of SecureEnvironment. /// The authentication type determines the type of user identity that will be activated. /// If Permanent Windows activation is requested then the default currently logged on /// Windows Account identity will be activated. If Temporary Windows activation requested /// then user will be prompted for Windows Domain credentials through a dialog, and the /// user identified through those credentials will be activated. /// In case of Passport authentication, a Passport authentication dialog will always /// appear regardless of temporary or permanent activation mode. The user that authenticatd /// through that Passport Authentication dialog will be activated. /// Regardless of Windows or Passport Authentication, all Temporary created activation will be /// destroyed when SecureEnvironment instance is Disposed or Finalized. /// </summary> public static SecureEnvironment Create(string applicationManifest, AuthenticationType authentication, UserActivationMode userActivationMode) { SecurityHelper.DemandRightsManagementPermission(); return(CriticalCreate(applicationManifest, authentication, userActivationMode)); }
/// <summary> /// 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. /// </summary> 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); }
/// <summary> /// This function returns a read only collection of the activated users. /// </summary> static public ReadOnlyCollection <ContentUser> GetActivatedUsers() { SecurityHelper.DemandRightsManagementPermission(); //build user with the default authentication type and a default name // neither name not authentication type is important in this case //ContentUser tempUser = new ContentUser(_defaultUserName, AuthenticationType.Windows); // Generic client session to enumerate user certificates using (ClientSession genericClientSession = ClientSession.DefaultUserClientSession(AuthenticationType.Windows)) { List <ContentUser> userList = new List <ContentUser>(); // if machine activation is not present we can return empty list right away if (genericClientSession.IsMachineActivated()) { int index = 0; while (true) { // we get a string which can be parsed to get the ID and type string userCertificate = genericClientSession.EnumerateLicense(EnumerateLicenseFlags.GroupIdentity, index); if (userCertificate == null) { break; } // we need to parse the information out of the string ContentUser user = ClientSession.ExtractUserFromCertificateChain(userCertificate); // User specific client session to check it's status using (ClientSession userClientSession = new ClientSession(user)) { if (userClientSession.IsUserActivated()) { userList.Add(user); } } index++; } } return(new ReadOnlyCollection <ContentUser>(userList)); } }
/// <summary> /// Removes activation for a given user. User must have Windows or Passport authnetication /// </summary> public static void RemoveActivatedUser(ContentUser user) { SecurityHelper.DemandRightsManagementPermission(); if (user == null) { throw new ArgumentNullException("user"); } // we only let specifically identifyed users to be used here if ((user.AuthenticationType != AuthenticationType.Windows) && (user.AuthenticationType != AuthenticationType.Passport)) { throw new ArgumentOutOfRangeException("user", SR.Get(SRID.OnlyPassportOrWindowsAuthenticatedUsersAreAllowed)); } // Generic client session to enumerate user certificates using (ClientSession userClientSession = new ClientSession(user)) { // Remove Licensor certificastes first List <string> userClientLicensorCertificateIds = userClientSession.EnumerateUsersCertificateIds(user, EnumerateLicenseFlags.ClientLicensor); // and now we can remove certificates that have been enumerated foreach (string licenseId in userClientLicensorCertificateIds) { userClientSession.DeleteLicense(licenseId); } // Remove User's identity certificastes second List <string> userGroupIdentityCertificateIds = userClientSession.EnumerateUsersCertificateIds(user, EnumerateLicenseFlags.GroupIdentity); // and now we can remove certificates that have been enumerated foreach (string licenseId in userGroupIdentityCertificateIds) { userClientSession.DeleteLicense(licenseId); } } }
/// <summary> /// This property verifies whether the current machine was prepared for consuming and producing RM protected content. /// If property returns true it could be used as an indication that Init function call will not result in a network transaction. /// </summary> public static bool IsUserActivated(ContentUser user) { SecurityHelper.DemandRightsManagementPermission(); if (user == null) { throw new ArgumentNullException("user"); } // we only let specifically identified users to be used here if ((user.AuthenticationType != AuthenticationType.Windows) && (user.AuthenticationType != AuthenticationType.Passport)) { throw new ArgumentOutOfRangeException("user", SR.Get(SRID.OnlyPassportOrWindowsAuthenticatedUsersAreAllowed)); } using (ClientSession userClientSession = new ClientSession(user)) { // if machine activation is not present we can return false right away return(userClientSession.IsMachineActivated() && userClientSession.IsUserActivated()); } }