internal static int DRMCreateBoundLicense( SafeRightsManagementEnvironmentHandle environmentHandle, BoundLicenseParams boundLicenseParams, string licenseChain, out SafeRightsManagementHandle boundLicenseHandle, out uint errorLogHandle) { SecurityHelper.DemandRightsManagementPermission(); int res = UnsafeNativeMethods.DRMCreateBoundLicense( environmentHandle, boundLicenseParams, licenseChain, out boundLicenseHandle, out errorLogHandle); // on some platforms in the failure cases the out parameter is being created with the value 0 // in order to simplify error handling and Disposing of those handles we will just close them as // soon as we detect such case if ((boundLicenseHandle != null) && boundLicenseHandle.IsInvalid) { boundLicenseHandle.Dispose(); boundLicenseHandle = null; } return(res); }
internal static extern int DRMCreateBoundLicense( [In] SafeRightsManagementEnvironmentHandle environmentHandle, [In, MarshalAs(UnmanagedType.LPStruct)] BoundLicenseParams boundLicenseParams, [In, MarshalAs(UnmanagedType.LPWStr)] string licenseChain, [Out] out SafeRightsManagementHandle boundLicenseHandle, [Out, MarshalAs(UnmanagedType.U4)] out uint errorLogHandle);
// This function attempts to bind License to a given Identity // It will try to bind all rights One-by-one in order to eliminate // grants that may have been expired, so it will only bind The ones that are still valid private CryptoProvider BindUseLicense(string serializedUseLicense, List<RightNameExpirationInfoPair> unboundRightsList, BoundLicenseParams boundLicenseParams, out int theFirstHrFailureCode) { Debug.Assert(serializedUseLicense != null); Debug.Assert(unboundRightsList != null); Debug.Assert(boundLicenseParams != null); List<SafeRightsManagementHandle> successfullyBoundLicenseHandleList = new List<SafeRightsManagementHandle>(unboundRightsList.Count); List<RightNameExpirationInfoPair> successfullyBoundRightsList = new List<RightNameExpirationInfoPair>(unboundRightsList.Count); try { uint errorLogHandle; // we neeed to return the first failure code, that is the one that will communicate to the user int hr; theFirstHrFailureCode = 0; SafeRightsManagementHandle boundLicenseHandle; // first we are enumerating all rights one-by-one and preserving the ones that can be bound // we are going through the list of "recognised rights" foreach (RightNameExpirationInfoPair rightInfo in unboundRightsList) { boundLicenseParams.wszRightsRequested = rightInfo.RightName; boundLicenseHandle = null; errorLogHandle = 0; hr = SafeNativeMethods.DRMCreateBoundLicense( _envHandle, boundLicenseParams, serializedUseLicense, out boundLicenseHandle, out errorLogHandle); if (boundLicenseHandle != null && (hr == 0)) { // we got a successful bound let's copy the whole grant // the only thing that we need to substitute in the grant is the User identity // along with the original right name (prior to binding), as unmanaged SDK // messes up right names and their expiration // in case of multiple expiration dates and additional rights granted to an owner successfullyBoundLicenseHandleList.Add(boundLicenseHandle); successfullyBoundRightsList.Add(rightInfo); } // preserve the first encountered error code if ((theFirstHrFailureCode == 0) && (hr != 0)) { theFirstHrFailureCode = hr; } } // At this point we have a list of potential "Right" -candidates // if it is empty we can get out if (successfullyBoundLicenseHandleList.Count > 0) { ContentUser user = ExtractUserFromCertificateChain(boundLicenseParams.wszDefaultEnablingPrincipalCredentials); CryptoProvider cryptoProvider = new CryptoProvider(successfullyBoundLicenseHandleList, successfullyBoundRightsList, user); CryptoProviderList.Add(cryptoProvider); return cryptoProvider; } else { return null; } } catch { // In case of a failure we should clean up handle that have been accumulated // otherwise the list of handles is either empty or given to the CryptoProvider // to be taken care of foreach (SafeRightsManagementHandle handle in successfullyBoundLicenseHandleList) { handle.Dispose(); } throw; } }
internal CryptoProvider TryBindUseLicenseToAllIdentites(string serializedUseLicense) { CheckDisposed(); Invariant.Assert(serializedUseLicense != null); int hr = 0; int theFirstHrFailureCode = 0; /////////////////////////// // prepare bound license param structure /////////////////////////// //prepare for binding (enumerate unbound rights) string rightsGroupName; List<RightNameExpirationInfoPair> unboundRightsList = GetRightsInfoFromUseLicense(serializedUseLicense, out rightsGroupName); BoundLicenseParams boundLicenseParams = new BoundLicenseParams(); boundLicenseParams.uVersion = 0; boundLicenseParams.hEnablingPrincipal = 0; boundLicenseParams.hSecureStore = 0; boundLicenseParams.wszRightsGroup = rightsGroupName; string contentId; string contentIdType; GetContentIdFromLicense(serializedUseLicense, out contentId, out contentIdType); boundLicenseParams.DRMIDuVersion = 0; boundLicenseParams.DRMIDIdType = contentIdType; boundLicenseParams.DRMIDId = contentId; boundLicenseParams.cAuthenticatorCount = 0;//reserved.should be 0. boundLicenseParams.rghAuthenticators = IntPtr.Zero; string userCertificate = GetGroupIdentityCert(); boundLicenseParams.wszDefaultEnablingPrincipalCredentials = userCertificate; boundLicenseParams.dwFlags = 0; // let's try to bind this using currently provided user first CryptoProvider cryptoProvider = BindUseLicense(serializedUseLicense, unboundRightsList, boundLicenseParams, out hr); if (cryptoProvider != null) { return cryptoProvider; } // preserve the first encountered error code if ((theFirstHrFailureCode == 0) && (hr != 0)) { theFirstHrFailureCode = hr; } // now if the current user failed we can try to enumerate all the userr certificates // and go through them one-by-one int userCertIndex = 0; while (true) { userCertificate = EnumerateLicense(EnumerateLicenseFlags.GroupIdentity, userCertIndex); if (userCertificate == null) { // we have to enumerate all of the user certs . . . break; } userCertIndex++; boundLicenseParams.wszDefaultEnablingPrincipalCredentials = userCertificate; cryptoProvider = BindUseLicense(serializedUseLicense, unboundRightsList, boundLicenseParams, out hr); if (cryptoProvider != null) { return cryptoProvider; } // preserve the first encountered error code if ((theFirstHrFailureCode == 0) && (hr != 0)) { theFirstHrFailureCode = hr; } } // at this point we can only translate failure into some meaningfull exception Invariant.Assert(theFirstHrFailureCode != 0); // it must contain an error as a succesfull return above should take of non-failure cases Errors.ThrowOnErrorCode(theFirstHrFailureCode); return null; }
internal static int DRMCreateBoundLicense( SafeRightsManagementEnvironmentHandle environmentHandle, BoundLicenseParams boundLicenseParams, string licenseChain, out SafeRightsManagementHandle boundLicenseHandle, out uint errorLogHandle) { SecurityHelper.DemandRightsManagementPermission(); int res = UnsafeNativeMethods.DRMCreateBoundLicense( environmentHandle, boundLicenseParams, licenseChain, out boundLicenseHandle, out errorLogHandle); // on some platforms in the failure cases the out parameter is being created with the value 0 // in order to simplify error handling and Disposing of those handles we will just close them as // soon as we detect such case if ((boundLicenseHandle != null) && boundLicenseHandle.IsInvalid) { boundLicenseHandle.Dispose(); boundLicenseHandle = null; } return res; }