Issuing a License in a License Chain
Previous | Next |
Issuing a License in a License Chain
When issuing licenses for a license chain, the issuer might need to issue an entire license chain or only elements of the chain. So, the license issuer needs to know which license elements to issue.
The content header contains the uplink ID (the root key ID) in the license chain, which is also included in the license request. Use the WMRMChallenge.Uplinks property to retrieve this information from the license request. A WMRMUplinkCollection ** object is returned, and it contains a collection that corresponds to the elements in the license chain (item 0 is the leaf license, item 1 is the root license.) You can iterate through the collection and retrieve information into a WMRMUplink object, which provides the key ID and license state data for each license element. The license state data in the WMRMLicenseStateData object provides information about the licenses that are already present on the client computer, such as expiration dates and remaining play counts. Using this information, the license issuer can determine which elements in the license chain need to be reissued. For example, if the root license has expired but the leaf license is still valid, only a root license needs to be reissued.
When you issue a license from a license chain, you issue it almost as you would a simple license. The root license is bound to the computer, but the leaf license is bound to the root license by specifying the root key and key ID in the leaf license by using the WMRMLicGen.UplinkKey and WMRMLicGen.UplinkKid properties.
Additionally, rather than the 7-byte key used for simple or leaf licenses, the root licenses in a chain require a key of 8 bytes, which must be created using the WMRMKeys.GenerateKeyEx method.
Example Code
The following example is based on the sample page Simple.asp in the C:\WMSDK\WMRM10.1\samples folder, but this sample can issue a simple or a chained license depending on the license request.
<%@ LANGUAGE="VBScript"%> <% Response.Buffer = True Response.Expires = 0 Do On Error Resume Next '""""""""""""""""""""""""""""""""""""""""""""""""""""" ' Declare variables. '""""""""""""""""""""""""""""""""""""""""""""""""""""" Dim ChallengeObj ' WMRMChallenge object Dim ChainCollObj ' WMRMUplinkCollection object Dim ChainObj ' WMRMUplink object Dim LeafLicenseStateObj ' WMRMLicenseStateData object Dim RootLicenseStateObj ' WMRMLicenseStateData object Dim HeaderObj ' WMRMHeader object Dim KeyObj ' WMRMKeys object Dim RightsObj ' WMRMRights object Dim LicenseObj ' WMRMLicGen object Dim ResponseObj ' WMRMResponse object Dim RestrictObj ' WMRMRestrictions object Dim ContentServerPubKey ' Public key of the content server Dim Seed ' License key seed Dim Delivery ' Delivery flag Dim LicChain ' License chain flag Dim Silent ' Silent delivery flag Dim strLicenseRequested ' License request string Dim varClientInfo ' Client information Dim varHeader ' Content header Dim blnResult ' Signature verification Dim SimpleLeafKID ' Key ID of a simple license or leaf license Dim IndiVersion ' Security version of the DRM component Dim strRevinfo ' Revocation information string Dim ContainsRevinfo ' Flag for revocation information Dim strClientCRLs ' Supported revocation lists string Dim RootKID ' Key ID of the root license Dim RootCat ' License state data for root licenses Dim RCountArray ' Count array Dim RDateArray ' Date array Dim RStreamID ' Stream ID Dim RVague ' Vagueness Dim IssueRoot ' Root license flag Dim Rcounts ' Remaining counts Dim RstartDate ' Start date Dim RExpDate ' Expiration date Dim LeafCat ' License state data for leaf licenses Dim LCountArray ' Count array Dim LDateArray ' Date array Dim LStreamID ' Stream ID Dim LVague ' Vagueness Dim IssueLeaf ' Leaf license flag Dim Lcounts ' Remaining counts Dim LstartDate ' Start date Dim LExpDate ' Expiration date Dim SimpleLeafKey ' Key for the simple license or leaf license Dim SimpleLeafRights ' Rights string for the simple license or leaf license Dim SimpleLeafLicense ' License for the simple license or leaf license Dim RootKey ' Key for the root license Dim RootRights ' Rights string for the root license Dim RootLicense ' Root license Dim LicResponse ' License response '""""""""""""""""""""""""""""""""""""""""""""""""""""" ' Set variables. '""""""""""""""""""""""""""""""""""""""""""""""""""""" ContentServerPubKey = Application("contentserverpubkey") Seed = Application("seed") Delivery = "" LicChain = "" Silent = True '""""""""""""""""""""""""""""""""""""""""""""""""""""" ' Check the request for silent or non-silent delivery. '""""""""""""""""""""""""""""""""""""""""""""""""""""" If (Request.Form("nonsilent") <> "") Then Silent = False '""""""""""""""""""""""""""""""""""""""""""""""""""""" ' Retrieve the license request. Get the client information and content header. '""""""""""""""""""""""""""""""""""""""""""""""""""""" Set ChallengeObj = Server.CreateObject("WMRMObjs.WMRMchallenge") strLicenseRequested = Request.Form("challenge") ChallengeObj.Challenge = strLicenseRequested varClientInfo = ChallengeObj.ClientInfo varHeader = ChallengeObj.Header '""""""""""""""""""""""""""""""""""""""""""""""""""""" ' Check for revocation information. '""""""""""""""""""""""""""""""""""""""""""""""""""""" strRevinfo = ChallengeObj.RevInfo ContainsRevinfo = ChallengeObj.RevInfoPresent '""""""""""""""""""""""""""""""""""""""""""""""""""""" ' Put the content header into the header object. Retrieve ' the KID and required individualization version. '""""""""""""""""""""""""""""""""""""""""""""""""""""" Set HeaderObj = Server.CreateObject("WMRMObjs.WMRMheader") HeaderObj.Header = varHeader blnResult = HeaderObj.Verify(ContentServerPubKey) SimpleLeafKID = HeaderObj.KeyID IndiVersion = HeaderObj.IndividualizedVersion ' If IndividualizedVersion is not specified, an error ' might be set. '""""""""""""""""""""""""""""""""""""""""""""""""""""" ' If this is a chained license, retrieve the root license KID. '""""""""""""""""""""""""""""""""""""""""""""""""""""" Set ChainCollObj = ChallengeObj.Uplinks If (Err.Number = 0) Then ' Request for a license chain. LicChain = "chain" ' Get license state data and key ID for the root license. Set ChainObj = ChainCollObj.item(1) RootKID = ChainObj.KID ' Get license state data to determine whether to issue ' a root license. Set RootLicenseStateObj = ChainObj.LicenseState RootCat = cstr(RootLicenseStateObj.Category) Select Case RootCat case 0 ' The root license has no rights. IssueRoot = True case 1 ' The root license has unlimited play counts. IssueRoot = False case 2 ' The root license has remaining play counts. RCountArray = RootLicenseStateObj.Counts RCounts = cstr(RCountArray(0)) IssueRoot = False case 3 ' The root license has a start date. RDateArray = RootLicenseStateObj.Dates RStartDate = cstr(RDateArray(0)) IssueRoot = False case 4 ' The root license has an expiration date. RDateArray = RootLicenseStateObj.Dates RExpDate = cstr(RDateArray(0)) IssueRoot = False case 5 ' The root license has start and expiration dates. RDateArray = RootLicenseStateObj.Dates RStartDate = cstr(RDateArray(0)) RExpDate = cstr(RDateArray(1)) IssueRoot = False case 6 ' The root license has a start date and ' remaining play counts. RDateArray = RootLicenseStateObj.Dates RStartDate = cstr(RDateArray(0)) RCountArray = RootLicenseStateObj.Counts RCounts = cstr(RCountArray(0)) IssueRoot = False case 7 ' The root license has an expiration date and ' remaining play counts. RDateArray = RootLicenseStateObj.Dates RExpDate = cstr(RDateArray(0)) RCountArray = RootLicenseStateObj.Counts RCounts = cstr(RCountArray(0)) IssueRoot = False case 8 ' The root license has start and expiration ' dates, and remaining play counts. RDateArray = RootLicenseStateObj.Dates RStartDate = cstr(RDateArray(0)) RExpDate = cstr(RDateArray(1)) RCountArray = RootLicenseStateObj.Counts RCounts = cstr(RCountArray(0)) IssueRoot = False case 9 ' The root license expires after first use. IssueRoot = False End Select RStreamID = RootLicenseStateObj.StreamID ' This value is always 0. RVague = RootLicenseStateObj.Vagueness ' Get license state data to determine whether to issue ' a leaf license. Set ChainObj = ChainCollObj.item(0) Set LeafLicenseStateObj = ChainObj.LicenseState LeafCat = cstr(LeafLicenseStateObj.Category) Select Case LeafCat case 0 ' The leaf license has no rights. IssueLeaf = True case 1 ' The leaf license has unlimited play counts. IssueLeaf = False case 2 ' The leaf license has remaining play counts. LCountArray = LeafLicenseStateObj.Counts LCounts = cstr(LCountArray(0)) IssueLeaf = False case 3 ' The leaf license has a start date. LDateArray = LeafLicenseStateObj.Dates LStartDate = cstr(LDateArray(0)) IssueLeaf = False case 4 ' The leaf license has an expiration date. LDateArray = LeafLicenseStateObj.Dates LExpDate = cstr(LDateArray(0)) IssueLeaf = False case 5 ' The leaf license has start and expiration dates. LDateArray = LeafLicenseStateObj.Dates LStartDate = cstr(LDateArray(0)) LExpDate = cstr(LDateArray(1)) IssueLeaf = False case 6 ' The leaf license has a start date and ' remaining play counts. LDateArray = LeafLicenseStateObj.Dates LStartDate = cstr(LDateArray(0)) LCountArray = LeafLicenseStateObj.Counts LCounts = cstr(LCountArray(0)) IssueLeaf = False case 7 ' The leaf license has an expiration date and ' remaining play counts. LDateArray = LeafLicenseStateObj.Dates LExpDate = cstr(LDateArray(0)) LCountArray = LeafLicenseStateObj.Counts LCounts = cstr(LCountArray(0)) IssueLeaf = False case 8 ' The leaf license has start and expiration ' dates, and remaining play counts. LDateArray = LeafLicenseStateObj.Dates LStartDate = cstr(LDateArray(0)) LExpDate = cstr(LDateArray(1)) LCountArray = LeafLicenseStateObj.Counts LCounts = cstr(LCountArray(0)) IssueLeaf = False case 9 ' The root license expires after first use. IssueLeaf = False End Select LStreamID = LeafLicenseStateObj.StreamID ' This value is always 0. LVague = LeafLicenseStateObj.Vagueness Else ' An error indicates a request for a simple license. err.clear LicChain = "simple" End If '""""""""""""""""""""""""""""""""""""""""""""""""""""" ' Generate the keys. '""""""""""""""""""""""""""""""""""""""""""""""""""""" Set KeyObj = Server.CreateObject("WMRMObjs.WMRMkeys") KeyObj.KeyID = SimpleLeafKID KeyObj.Seed = Seed ' This is a key for either a simple license or a leaf license. SimpleLeafKey = KeyObj.GenerateKey() If (LicChain = "chain") Then ' Generate the 8-byte key for the root license. KeyObj.KeyID = RootKID RootKey = KeyObj.GenerateKeyEx(8) End If '""""""""""""""""""""""""""""""""""""""""""""""""""""" ' Get the certificate revocation lists that are supported by the client. '""""""""""""""""""""""""""""""""""""""""""""""""""""" strClientCRLs = LicGenObj.SupportedCRLS '""""""""""""""""""""""""""""""""""""""""""""""""""""" ' Set the rights. '""""""""""""""""""""""""""""""""""""""""""""""""""""" Set RightsObj = Server.CreateObject("WMRMObjs.WMRMRights") If (LicChain = "simple") Then ' Generate rights for a simple license. RightsObj.Playcount = 2 RightsObj.AllowCopy = True RightsObj.CopyCount = 5 RightsObj.AllowCollaborativePlay = False RightsObj.AllowBackupRestore = False RightsObj.AllowPlaylistBurn = True RightsObj.MaxPlaylistBurnCount = 5 RightsObj.PlaylistBurnTrackCount = 15 RightsObj.MinimumClientSDKSecurity = 3000 RightsObj.MinimumSecurityLevel = 1000 RightsObj.GracePeriod = 24 RightsObj.ExpirationDate = "#20051231Z#" RightsObj.DeleteOnClockRollback = False RightsObj.DisableOnClockRollback = True ' Set copy restrictions. Set RestrictObj = Server.CreateObject("WMRMObjs.WMRMRestrictions") Call RestrictObj.AddRestriction(6, 400) RightsObj.CopyRestrictions = RestrictObj.GetRestrictions If Err.Number = 0 Then SimpleLeafRights = RightsObj.GetAllRights End If Else ' Generate rights for a leaf license. RightsObj.AllowCopy = True RightsObj.CopyCount = 5 RightsObj.AllowCollaborativePlay = False RightsObj.AllowBackupRestore = False RightsObj.AllowPlaylistBurn = True RightsObj.MaxPlaylistBurnCount = 5 RightsObj.PlaylistBurnTrackCount = 15 RightsObj.GracePeriod = 24 RightsObj.MinimumClientSDKSecurity = 3000 RightsObj.MinimumSecurityLevel = 1000 ' Set copy restrictions. Set RestrictObj = Server.CreateObject("WMRMObjs.WMRMRestrictions") Call RestrictObj.AddRestriction(6, 400) RightsObj.CopyRestrictions = RestrictObj.GetRestrictions ' Get the rights string. If Err.Number = 0 Then SimpleLeafRights = RightsObj.GetAllRights End If ' Generate rights for a root license. RightsObj.Reset RightsObj.Playcount = 1 RightsObj.AllowCopy = True RightsObj.AllowPlaylistBurn = True RightsObj.AllowCollaborativePlay = False RightsObj.AllowBackupRestore = False RightsObj.ExpirationDate = "#20051231Z#" RightsObj.DeleteOnClockRollback = False RightsObj.DisableOnClockRollback = True ' Set copy restrictions. RightsObj.CopyRestrictions = RestrictObj.GetRestrictions ' Get the rights string. If Err.Number = 0 Then RootRights = RightsObj.GetAllRights End If End If '""""""""""""""""""""""""""""""""""""""""""""""""""""" ' Generate a simple license or leaf license. '""""""""""""""""""""""""""""""""""""""""""""""""""""" Set LicenseObj = Server.CreateObject("WMRMObjs.WMRMlicgen") LicenseObj.KeyID = SimpleLeafKID LicenseObj.SetKey "", SimpleLeafKey LicenseObj.Priority = 10 LicenseObj.Rights = SimpleLeafRights LicenseObj.ClientInfo = varClientInfo LicenseObj.BindToPubKey = ContentServerPubKey LicenseObj.Attribute("ContentDistributor") = "Distributor Name" LicenseObj.IndividualizedVersion = IndiVersion If (LicChain = "chain") Then ' Link to the root license. LicenseObj.UplinkKid = RootKID LicenseObj.UplinkKey = RootKey End If SimpleLeafLicense = LicenseObj.GetLicenseToDeliver() Delivery = "deliver" '""""""""""""""""""""""""""""""""""""""""""""""""""""" 'Generate a root license. '""""""""""""""""""""""""""""""""""""""""""""""""""""" If (LicChain = "chain") Then Set LicenseObj = Nothing Set LicenseObj = Server.CreateObject("WMRMObjs.WMRMlicgen") LicenseObj.KeyID = RootKID LicenseObj.SetKey "", RootKey LicenseObj.Priority = 10 LicenseObj.Rights = RootRights LicenseObj.ClientInfo = varClientInfo LicenseObj.BindToPubKey = ContentServerPubKey LicenseObj.Attribute("ContentDistributor") = "Distributor Name" LicenseObj.IndividualizedVersion = IndiVersion RootLicense = LicenseObj.GetLicenseToDeliver() End If Loop While False '""""""""""""""""""""""""""""""""""""""""""""""""""""" ' Send an error message or deliver the license. '""""""""""""""""""""""""""""""""""""""""""""""""""""" If (Delivery = "" and Err.Number <> 0) Then Response.Write "0x" + cstr(hex(err.number)) + " :" & Err.Description ElseIf (Delivery = "deliver") Then Set ResponseObj = Server.CreateObject("WMRMObjs.WMRMresponse") If (LicChain = "simple") or (IssueLeaf = True) Then ' Include a simple license or leaf license in the license response. Call ResponseObj.AddLicense("2.0.0.0", SimpleLeafLicense) End If If (IssueRoot = True) Then ' Include the root license in the license response. Call ResponseObj.AddLicense("2.0.0.0", RootLicense) End If Call ResponseObj.AddRevocationData(strRevinfo, strClientCRLs, ContainsRevinfo) If (Silent = True) Then LicResponse = ResponseObj.GetLicenseResponse() Response.Write LicResponse ElseIf (Silent = False) Then ' This replaces quotes to pass a value. ' ResponseObj.ReplaceQuotesWith = """""" ' For VBScript. ResponseObj.ReplaceQuotesWith = "\""" ' For JavaScript. LicResponse = ResponseObj.GetLicenseResponse() %> <!-- #include file="simple_ns.asp" --> <% End If End If ' Clear objects. Set ChallengeObj = Nothing Set ChainCollObj = Nothing Set ChainObj = Nothing Set LicenseStateObj = Nothing Set HeaderObj = Nothing Set KeyObj = Nothing Set RightsObj = Nothing Set LicenseObj = Nothing Set ResponseObj = Nothing %>
See Also
- Generating and Issuing Licenses
- How License Chaining Works
- Specifying a License Chain When Protecting Content
- WMRMHeader Object
- WMRMLicenseStateData
Previous | Next |