// </ConfigureWidevineLicenseTempate>

        /// <summary>
        /// Configures FairPlay policy options.
        /// </summary>
        /// <returns></returns>
        // <ConfigureFairPlayPolicyOptions>
        private static ContentKeyPolicyFairPlayConfiguration ConfigureFairPlayPolicyOptions()
        {
            string askHex = "";
            string FairPlayPfxPassword = "";

            var appCert = new X509Certificate2("FairPlayPfxPath", FairPlayPfxPassword, X509KeyStorageFlags.Exportable);

            byte[] askBytes = Enumerable
                              .Range(0, askHex.Length)
                              .Where(x => x % 2 == 0)
                              .Select(x => Convert.ToByte(askHex.Substring(x, 2), 16))
                              .ToArray();

            ContentKeyPolicyFairPlayConfiguration fairPlayConfiguration =
                new ContentKeyPolicyFairPlayConfiguration
            {
                Ask         = askBytes,
                FairPlayPfx =
                    Convert.ToBase64String(appCert.Export(X509ContentType.Pfx, FairPlayPfxPassword)),
                FairPlayPfxPassword   = FairPlayPfxPassword,
                RentalAndLeaseKeyType =
                    ContentKeyPolicyFairPlayRentalAndLeaseKeyType
                    .PersistentUnlimited,
                RentalDuration = 2249
            };

            return(fairPlayConfiguration);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Configures FairPlay license template.
        /// </summary>
        /// <param name="askHex">The ASK hex string.</param>
        /// <param name="fairPlayPfxPath">The path of the PFX file.</param>
        /// <param name="fairPlayPfxPassword">The password for the PFX.</param>
        /// <returns>ContentKeyPolicyFairPlayConfiguration</returns>
        private static ContentKeyPolicyFairPlayConfiguration ConfigureFairPlayLicenseTemplate(string askHex, string fairPlayPfxPath,
                                                                                              string fairPlayPfxPassword)
        {
            byte[] askBytes = Enumerable
                              .Range(0, askHex.Length)
                              .Where(x => x % 2 == 0)
                              .Select(x => Convert.ToByte(askHex.Substring(x, 2), 16))
                              .ToArray();

            byte[] buf           = File.ReadAllBytes(fairPlayPfxPath);
            string appCertBase64 = Convert.ToBase64String(buf);
            ContentKeyPolicyFairPlayConfiguration objContentKeyPolicyPlayReadyConfiguration = new ContentKeyPolicyFairPlayConfiguration
            {
                Ask                        = askBytes,
                FairPlayPfx                = appCertBase64,
                FairPlayPfxPassword        = fairPlayPfxPassword,
                RentalAndLeaseKeyType      = ContentKeyPolicyFairPlayRentalAndLeaseKeyType.DualExpiry,
                RentalDuration             = 0,
                OfflineRentalConfiguration = new ContentKeyPolicyFairPlayOfflineRentalConfiguration()
                {
                    StorageDurationSeconds  = 300000,
                    PlaybackDurationSeconds = 500000
                }
            };

            return(objContentKeyPolicyPlayReadyConfiguration);
        }
        /// <summary>
        /// Create the content key policy that configures how the content key is delivered to end clients
        /// via the Key Delivery component of Azure Media Services.
        /// </summary>
        /// <param name="client">The Media Services client.</param>
        /// <param name="resourceGroupName">The name of the resource group within the Azure subscription.</param>
        /// <param name="accountName"> The Media Services account name.</param>
        /// <param name="contentKeyPolicyName">The name of the content key policy resource.</param>
        /// <returns></returns>
        private static async Task <ContentKeyPolicy> GetOrCreateContentKeyPolicyAsync(
            IAzureMediaServicesClient client,
            ConfigWrapper config,
            string contentKeyPolicyName)
        {
            // Call Media Services API to create or update the policy.

            Console.WriteLine("Creating or updating the content key policy...");

            ContentKeyPolicyOpenRestriction restriction = new();

            ContentKeyPolicyFairPlayConfiguration fairPlay = ConfigureFairPlayLicenseTemplate(config.AskHex, config.FairPlayPfxPath,
                                                                                              config.FairPlayPfxPassword);

            List <ContentKeyPolicyOption> options = new()
            {
                new ContentKeyPolicyOption()
                {
                    Configuration = fairPlay,
                    Restriction   = restriction
                }
            };

            Console.WriteLine("Creating or updating the content key policy...");
            ContentKeyPolicy policy = await client.ContentKeyPolicies.CreateOrUpdateAsync(config.ResourceGroup, config.AccountName, contentKeyPolicyName, options);

            return(policy);
        }
Exemplo n.º 4
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation($"AMS v3 Function - CreateContentKeyPolicy was triggered!");

            string  requestBody = new StreamReader(req.Body).ReadToEnd();
            dynamic data        = JsonConvert.DeserializeObject(requestBody);

            if (data.contentKeyPolicyName == null)
            {
                return(new BadRequestObjectResult("Please pass contentKeyPolicyName in the input object"));
            }
            string contentKeyPolicyName        = data.contentKeyPolicyName;
            string contentKeyPolicyDescription = null;

            if (data.contentKeyPolicyDescription == null)
            {
                contentKeyPolicyDescription = data.contentKeyPolicyDescription;
            }

            string mode = data.mode;

            if (mode != "simple" && mode != "advanced")
            {
                return(new BadRequestObjectResult("Please pass valid mode in the input object"));
            }

            //
            // Simple Mode
            //
            if (mode == "simple")
            {
                if (data.policyOptionName == null)
                {
                    return(new BadRequestObjectResult("Please pass policyOptionName in the input object"));
                }
                if (data.openRestriction == null)
                {
                    return(new BadRequestObjectResult("Please pass openRestriction in the input object"));
                }
                if (data.openRestriction == false)
                {
                    if (data.audience == null &&
                        data.issuer == null &&
                        data.tokenType == null &&
                        data.tokenKeyType == null &&
                        data.tokenKey == null)
                    {
                        return(new BadRequestObjectResult("Please pass required parameters for Token Restriction in the input object"));
                    }
                }
            }
            //
            // Advanced Mode
            //
            if (mode == "advanced")
            {
                if (data.contentKeyPolicyOptions == null)
                {
                    return(new BadRequestObjectResult("Please pass contentKeyPolicyOptions in the input object"));
                }
            }

            MediaServicesConfigWrapper amsconfig = new MediaServicesConfigWrapper();
            ContentKeyPolicy           policy    = null;

            JsonConverter[] jsonReaders =
            {
                new MediaServicesHelperJsonReader(),
                new MediaServicesHelperTimeSpanJsonConverter()
            };

            try
            {
                IAzureMediaServicesClient client = MediaServicesHelper.CreateMediaServicesClientAsync(amsconfig);

                policy = client.ContentKeyPolicies.Get(amsconfig.ResourceGroup, amsconfig.AccountName, contentKeyPolicyName);

                if (policy == null)
                {
                    List <ContentKeyPolicyOption> options = new List <ContentKeyPolicyOption>();

                    if (mode == "simple")
                    {
                        ContentKeyPolicyOption option = new ContentKeyPolicyOption();
                        option.Name = data.policyOptionName;

                        // Restrictions
                        if ((bool)data.openRestriction)
                        {
                            option.Restriction = new ContentKeyPolicyOpenRestriction();
                        }
                        else
                        {
                            ContentKeyPolicyTokenRestriction restriction = new ContentKeyPolicyTokenRestriction();
                            restriction.Audience = data.audience;
                            restriction.Issuer   = data.issuer;

                            string tokenType = data.tokenType;
                            switch (tokenType)
                            {
                            case "Jwt":
                                restriction.RestrictionTokenType = ContentKeyPolicyRestrictionTokenType.Jwt;
                                break;

                            case "Swt":
                                restriction.RestrictionTokenType = ContentKeyPolicyRestrictionTokenType.Swt;
                                break;

                            default:
                                return(new BadRequestObjectResult("Please pass valid tokenType in the input object"));
                            }

                            string tokenKeyType = data.tokenKeyType;
                            switch (tokenKeyType)
                            {
                            case "Symmetric":
                                restriction.PrimaryVerificationKey = new ContentKeyPolicySymmetricTokenKey(Convert.FromBase64String(data.tokenKey.ToString()));
                                break;

                            case "X509":
                                restriction.PrimaryVerificationKey = new ContentKeyPolicyX509CertificateTokenKey(Convert.FromBase64String(data.tokenKey.ToString()));
                                break;

                            case "RSA":
                                restriction.PrimaryVerificationKey = new ContentKeyPolicyRsaTokenKey();
                                break;

                            default:
                                return(new BadRequestObjectResult("Please pass valid tokenKeyType in the input object"));
                            }
                            if (data.tokenClaims != null)
                            {
                                restriction.RequiredClaims = new List <ContentKeyPolicyTokenClaim>();
                                String[] tokenClaims = data.tokenClaims.ToString().Split(';');
                                foreach (string tokenClaim in tokenClaims)
                                {
                                    String[] tokenClaimKVP = tokenClaim.Split('=');

                                    if (tokenClaimKVP.Length == 2)
                                    {
                                        restriction.RequiredClaims.Add(new ContentKeyPolicyTokenClaim(tokenClaimKVP[0], tokenClaimKVP[1] == "null" ? null : tokenClaimKVP[1]));
                                    }
                                    else if (tokenClaimKVP.Length == 1)
                                    {
                                        restriction.RequiredClaims.Add(new ContentKeyPolicyTokenClaim(tokenClaimKVP[0]));
                                    }
                                    else
                                    {
                                        return(new BadRequestObjectResult("Please pass valid tokenClaims in the input object"));
                                    }
                                }
                            }
                            if (data.openIdConnectDiscoveryDocument != null)
                            {
                                restriction.OpenIdConnectDiscoveryDocument = data.openIdConnectDiscoveryDocument;
                            }

                            option.Restriction = restriction;
                        }

                        // Configuration
                        string configurationType = data.configurationType;
                        switch (configurationType)
                        {
                        case "ClearKey":
                            option.Configuration = new ContentKeyPolicyClearKeyConfiguration();
                            break;

                        case "FairPlay":
                            ContentKeyPolicyFairPlayConfiguration configFairPlay = new ContentKeyPolicyFairPlayConfiguration();
                            configFairPlay.Ask                 = Convert.FromBase64String(data.fairPlayAsk);
                            configFairPlay.FairPlayPfx         = data.fairPlayPfx;
                            configFairPlay.FairPlayPfxPassword = data.fairPlayPfxPassword;
                            switch (data.faiPlayRentalAndLeaseKeyType)
                            {
                            case "Undefined":
                                configFairPlay.RentalAndLeaseKeyType = ContentKeyPolicyFairPlayRentalAndLeaseKeyType.Undefined;
                                break;

                            case "PersistentLimited":
                                configFairPlay.RentalAndLeaseKeyType = ContentKeyPolicyFairPlayRentalAndLeaseKeyType.PersistentLimited;
                                break;

                            case "PersistentUnlimited":
                                configFairPlay.RentalAndLeaseKeyType = ContentKeyPolicyFairPlayRentalAndLeaseKeyType.PersistentUnlimited;
                                break;

                            default:
                                return(new BadRequestObjectResult("Please pass valid faiPlayRentalAndLeaseKeyType in the input object"));
                            }
                            configFairPlay.RentalDuration = data.faiPlayRentalDuration;
                            break;

                        case "PlayReady":
                            ContentKeyPolicyPlayReadyConfiguration configPlayReady = new ContentKeyPolicyPlayReadyConfiguration();
                            configPlayReady.Licenses = JsonConvert.DeserializeObject <List <ContentKeyPolicyPlayReadyLicense> >(data.playReadyTemplates.ToString(), jsonReaders);
                            if (data.playReadyResponseCustomData != null)
                            {
                                configPlayReady.ResponseCustomData = data.playReadyResponseCustomData;
                            }
                            option.Configuration = configPlayReady;
                            break;

                        case "Widevine":
                            ContentKeyPolicyWidevineConfiguration configWideVine = JsonConvert.DeserializeObject <ContentKeyPolicyWidevineConfiguration>(data.widevineTemplate.ToString(), jsonReaders);
                            option.Configuration = configWideVine;
                            break;

                        default:
                            return(new BadRequestObjectResult("Please pass valid configurationType in the input object"));
                        }
                        options.Add(option);
                    }
                    else if (mode == "advanced")
                    {
                        options = JsonConvert.DeserializeObject <List <ContentKeyPolicyOption> >(data.contentKeyPolicyOptions.ToString(), jsonReaders);
                    }

                    foreach (ContentKeyPolicyOption o in options)
                    {
                        o.Validate();
                    }
                    policy = client.ContentKeyPolicies.CreateOrUpdate(amsconfig.ResourceGroup, amsconfig.AccountName, contentKeyPolicyName, options, contentKeyPolicyDescription);
                }
            }
            catch (ApiErrorException e)
            {
                log.LogError($"ERROR: AMS API call failed with error code: {e.Body.Error.Code} and message: {e.Body.Error.Message}");
                return(new BadRequestObjectResult("AMS API call error: " + e.Message + "\nError Code: " + e.Body.Error.Code + "\nMessage: " + e.Body.Error.Message));
            }
            catch (Exception e)
            {
                log.LogError($"ERROR: Exception with message: {e.Message}");
                return(new BadRequestObjectResult("Error: " + e.Message));
            }

            return((ActionResult) new OkObjectResult(new
            {
                policyId = policy.PolicyId
            }));
        }