private KeyDatabase() { var keys = new Dictionary <Guid, byte[]>(); Keys = keys; var telemetry = new TelemetryClient(); var appDataPath = HttpContext.Current.Server.MapPath("~/App_Data"); telemetry.TrackTrace("Looking for keys in " + appDataPath); if (Directory.Exists(appDataPath)) { foreach (var cpixFilePath in Directory.GetFiles(appDataPath, "*.xml")) { var document = CpixDocument.Load(cpixFilePath); if (!document.ContentKeysAreReadable) { continue; } foreach (var key in document.ContentKeys) { keys[key.Id] = key.Value; } } } telemetry.TrackEvent("KeyDatabaseLoaded", null, new Dictionary <string, double> { { "KeyCount", keys.Count } }); }
public static void PopulateCollections(CpixDocument document) { document.Recipients.Add(new Recipient(Certificate3WithPublicKey)); document.Recipients.Add(new Recipient(Certificate4WithPublicKey)); var key1 = GenerateContentKey(); var key2 = GenerateContentKey(); document.ContentKeys.Add(key1); document.ContentKeys.Add(key2); AddUsageRule(document); AddUsageRule(document); document.DrmSystems.Add(new DrmSystem { SystemId = Guid.NewGuid(), KeyId = document.ContentKeys.First().Id, ContentProtectionData = "<pssh>Imaginary content protection data XML</pssh>" }); // Sanity check. foreach (var collection in document.EntityCollections) { if (collection.Count == 0) { throw new Exception("TestHelpers need update - not all collections got populated!"); } } }
public void RemoveRecipients_WithLoadedDocumentAndWrittenContentKeys_SucceedsAndDecryptsContentKeys() { // We start with some encrypted keys. var document = new CpixDocument(); document.ContentKeys.Add(TestHelpers.GenerateContentKey()); document.Recipients.Add(new Recipient(TestHelpers.Certificate3WithPublicKey)); // Load and decrypt keys. document = TestHelpers.Reload(document, new[] { TestHelpers.Certificate3WithPrivateKey }); // Re-add keys to mark them for processing. var keys = document.ContentKeys.ToArray(); document.ContentKeys.Clear(); foreach (var key in keys) { document.ContentKeys.Add(key); } // Remove recipients - we will output clear keys. document.Recipients.Clear(); document = TestHelpers.Reload(document); Assert.Empty(document.Recipients); Assert.True(document.ContentKeysAreReadable); }
public void ResolveContentKey_WithOneFilterTypeMatchOtherFilterTypeNonMatch_Fails() { var key = TestHelpers.GenerateContentKey(); var document = new CpixDocument(); document.ContentKeys.Add(key); document.UsageRules.Add(new UsageRule { KeyId = key.Id, // This rule requries the context to be both audio and video. Nothing should ever match it! AudioFilters = new[] { new AudioFilter() }, VideoFilters = new[] { new VideoFilter() } }); Assert.Throws <ContentKeyResolveException>(() => document.ResolveContentKey(new ContentKeyContext { Type = ContentKeyContextType.Video })); }
protected override void ProcessRecord() { if (!File.Exists(Path)) { throw new PSArgumentException("CPIX file not found: " + Path, "Path"); } var cpix = CpixDocument.Load(Path); if (!cpix.ContentKeysAreReadable) { throw new NotSupportedException("The content keys in the CPIX file are encrypted. This PowerShell command does not currently support decryption of encryted content keys."); } var communicationKey = Convert.FromBase64String(CommunicationKeyAsBase64); if (communicationKey.Length != 32) { throw new NotSupportedException("Communication key must be 256 bits long."); } foreach (var key in cpix.ContentKeys) { WriteVerbose("Adding key: " + key.Id); LicenseTokenLogic.AddKey(LicenseToken, key.Id, key.Value, communicationKey, KeyUsagePolicyName); } WriteObject(LicenseToken); }
public void Generate(Stream outputStream) { var document = new CpixDocument(); document.ContentKeys.Add(new ContentKey { Id = new Guid("bbe06060-1c26-4ed5-8ccd-ee03ddb2ffd9"), Value = Convert.FromBase64String("aTqer0SFxijnIoQLXGHYJg==") }); document.Recipients.Add(new Recipient(TestHelpers.Certificate1WithPublicKey)); document.SignedBy = TestHelpers.Certificate2WithPrivateKey; var buffer = new MemoryStream(); document.Save(buffer); var xml = new XmlDocument(); buffer.Position = 0; xml.Load(buffer); XmlHelpers.DeclareNamespace(xml.DocumentElement, "xxx", "http://example.com/this/makes/the/document/signature/invalid"); using (var writer = XmlWriter.Create(outputStream, new XmlWriterSettings { Encoding = Encoding.UTF8, CloseOutput = false })) { xml.Save(writer); } }
public void AddingSignature_OnEverythingInAlreadySignedEmptyDocument_Succeeds() { var document = new CpixDocument(); document.SignedBy = TestHelpers.Certificate1WithPrivateKey; foreach (var collection in document.EntityCollections) { collection.AddSignature(TestHelpers.Certificate1WithPrivateKey); } document = TestHelpers.Reload(document); // Mark the entire document for re-signing, making it editable. document.SignedBy = TestHelpers.Certificate1WithPrivateKey; foreach (var collection in document.EntityCollections) { collection.AddSignature(TestHelpers.Certificate2WithPrivateKey); } document = TestHelpers.Reload(document); foreach (var collection in document.EntityCollections) { Assert.Equal(2, collection.SignedBy.Count()); Assert.Contains(collection.SignedBy, c => c.Thumbprint == TestHelpers.Certificate1WithPrivateKey.Thumbprint); Assert.Contains(collection.SignedBy, c => c.Thumbprint == TestHelpers.Certificate2WithPrivateKey.Thumbprint); } }
public void ReplacingSignature_OnEverythingInEmptyDocument_Succeeds() { var document = new CpixDocument(); document.SignedBy = TestHelpers.Certificate1WithPrivateKey; foreach (var collection in document.EntityCollections) { collection.AddSignature(TestHelpers.Certificate1WithPrivateKey); } document = TestHelpers.Reload(document); document.SignedBy = TestHelpers.Certificate2WithPrivateKey; foreach (var collection in document.EntityCollections) { collection.RemoveAllSignatures(); collection.AddSignature(TestHelpers.Certificate2WithPrivateKey); } document = TestHelpers.Reload(document); foreach (var collection in document.EntityCollections) { Assert.Single(collection.SignedBy); Assert.Equal(TestHelpers.Certificate2WithPrivateKey.Thumbprint, collection.SignedBy.Single().Thumbprint); } Assert.Equal(TestHelpers.Certificate2WithPrivateKey.Thumbprint, document.SignedBy?.Thumbprint); }
public void Generate(Stream outputStream) { var document = new CpixDocument(); document.ContentKeys.Add(new ContentKey { Id = new Guid("40d02dd1-61a3-4787-a155-572325d47b80"), Value = Convert.FromBase64String("gPxt0PMwrHM4TdjwdQmhhQ==") }); document.ContentKeys.Add(new ContentKey { Id = new Guid("0a30ea4f-539d-4b02-94b2-2b3fba2576d3"), Value = Convert.FromBase64String("x/gaoS/fDi8BqGNIhkixwQ==") }); document.ContentKeys.Add(new ContentKey { Id = new Guid("9f7908fa-5d5c-4097-ba53-50edc2235fbc"), Value = Convert.FromBase64String("3iv9lYwafpe0uEmxDc6PSw==") }); document.ContentKeys.Add(new ContentKey { Id = new Guid("fac2cbf5-889c-412b-a385-04a29d409bdc"), Value = Convert.FromBase64String("1OZVZZoYFSU2X/7qT3sHwg==") }); document.Save(outputStream); }
public void AddingSignatures_ToEverythingInEmptyLoadedDocument_Succeeds() { var document = new CpixDocument(); document = TestHelpers.Reload(document); document.SignedBy = TestHelpers.Certificate1WithPrivateKey; foreach (var collection in document.EntityCollections) { collection.AddSignature(TestHelpers.Certificate1WithPrivateKey); collection.AddSignature(TestHelpers.Certificate2WithPrivateKey); } document = TestHelpers.Reload(document); foreach (var collection in document.EntityCollections) { Assert.Equal(2, collection.SignedBy.Count()); Assert.Contains(collection.SignedBy, c => c.Thumbprint == TestHelpers.Certificate1WithPrivateKey.Thumbprint); Assert.Contains(collection.SignedBy, c => c.Thumbprint == TestHelpers.Certificate2WithPrivateKey.Thumbprint); } Assert.Equal(TestHelpers.Certificate1WithPrivateKey.Thumbprint, document.SignedBy?.Thumbprint); }
private static void WritingCpixExample() { var document = new CpixDocument(); // Let's create a CPIX document with two content keys. document.ContentKeys.Add(new ContentKey { Id = Guid.NewGuid(), Value = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6 } }); document.ContentKeys.Add(new ContentKey { Id = Guid.NewGuid(), Value = new byte[] { 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5 } }); using (var myCertificateAndPrivateKey = new X509Certificate2("Cert1.pfx", "Cert1")) using (var recipientCertificate = new X509Certificate2("Cert2.cer")) { // Optional: we sign the list added elements to and also the document as a whole. document.ContentKeys.AddSignature(myCertificateAndPrivateKey); document.SignedBy = myCertificateAndPrivateKey; // Optional: the presence of recipients will automatically mark the content keys to be encrypted on save. document.Recipients.Add(new Recipient(recipientCertificate)); document.Save("cpix.xml"); } }
public void AddRecipient_WithWeakCertificate_Fails() { var document = new CpixDocument(); Assert.Throws <WeakCertificateException>(() => document.Recipients.Add(new Recipient(TestHelpers.WeakSha1CertificateWithPublicKey))); Assert.Throws <WeakCertificateException>(() => document.Recipients.Add(new Recipient(TestHelpers.WeakSmallKeyCertificateWithPublicKey))); }
public void SignCollection_WithWeakCertificate_Fails() { var document = new CpixDocument(); Assert.Throws <WeakCertificateException>(() => document.Recipients.AddSignature(TestHelpers.WeakSha1CertificateWithPrivateKey)); Assert.Throws <WeakCertificateException>(() => document.Recipients.AddSignature(TestHelpers.WeakSmallKeyCertificateWithPrivateKey)); }
public void SignDocument_WithWeakCertificate_Fails() { var document = new CpixDocument(); Assert.Throws <WeakCertificateException>(() => document.SignedBy = TestHelpers.WeakSha1CertificateWithPrivateKey); Assert.Throws <WeakCertificateException>(() => document.SignedBy = TestHelpers.WeakSmallKeyCertificateWithPrivateKey); }
public void Generate(Stream outputStream) { var document = new CpixDocument(); document.ContentKeys.Add(new ContentKey { Id = new Guid("bc365b99-0667-446f-b417-ff0398c9a4c4"), Value = Convert.FromBase64String("gMMdXMudvuGpYW5k3lzf/g==") }); document.ContentKeys.Add(new ContentKey { Id = new Guid("1e25f2a7-76a9-4570-bc1a-d8181800d529"), Value = Convert.FromBase64String("WUxnvQjGw28bA3cgW/1jfg==") }); document.ContentKeys.Add(new ContentKey { Id = new Guid("2e4e6c21-c0d7-4a1c-80af-bff3d7cc5270"), Value = Convert.FromBase64String("cCudMIPMQkak1l+oCVXT2A==") }); document.ContentKeys.Add(new ContentKey { Id = new Guid("8ad35bd4-53ab-437b-8f42-6e1ea8e2f0d8"), Value = Convert.FromBase64String("zqvOfAja51IUSRV385bvoA==") }); document.Recipients.Add(new Recipient(TestHelpers.Certificate1WithPublicKey)); document.Recipients.Add(new Recipient(TestHelpers.Certificate2WithPublicKey)); document.Recipients.Add(new Recipient(TestHelpers.Certificate3WithPublicKey)); document.Recipients.Add(new Recipient(TestHelpers.Certificate4WithPublicKey)); document.Save(outputStream); }
public void AddRecipient_WithLoadedDocumentAndWrittenContentKeys_SucceedsAndEncryptsContentKeys() { // We start with some clear keys. var document = new CpixDocument(); document.ContentKeys.Add(TestHelpers.GenerateContentKey()); document = TestHelpers.Reload(document); // Now we re-add keys to mark them for processing. var keys = document.ContentKeys.ToArray(); document.ContentKeys.Clear(); foreach (var key in keys) { document.ContentKeys.Add(key); } // This marks the keys as to be encrypted. document.Recipients.Add(new Recipient(TestHelpers.Certificate3WithPublicKey)); document = TestHelpers.Reload(document, new[] { TestHelpers.Certificate3WithPrivateKey }); Assert.Single(document.Recipients); Assert.True(document.ContentKeysAreReadable); }
public void RoundTrip_WithOneKeyEncryptedAndSigned_LoadsExpectedKeyAndDetectsIdentities() { var keyData = TestHelpers.GenerateKeyData(); var document = new CpixDocument(); document.ContentKeys.Add(new ContentKey { Id = keyData.Item1, Value = keyData.Item2 }); document.ContentKeys.AddSignature(TestHelpers.Certificate1WithPrivateKey); document.SignedBy = TestHelpers.Certificate1WithPrivateKey; document.Recipients.Add(new Recipient(TestHelpers.Certificate3WithPublicKey)); document = TestHelpers.Reload(document, new[] { TestHelpers.Certificate3WithPrivateKey }); Assert.Single(document.ContentKeys); Assert.NotNull(document.SignedBy); Assert.Single(document.ContentKeys.SignedBy); Assert.Single(document.Recipients); Assert.Equal(TestHelpers.Certificate1WithPrivateKey.Thumbprint, document.SignedBy.Thumbprint); Assert.Equal(TestHelpers.Certificate1WithPrivateKey.Thumbprint, document.ContentKeys.SignedBy.Single().Thumbprint); Assert.Equal(TestHelpers.Certificate3WithPrivateKey.Thumbprint, document.Recipients.Single().Certificate.Thumbprint); var key = document.ContentKeys.Single(); Assert.Equal(keyData.Item1, key.Id); Assert.Equal(keyData.Item2, key.Value); }
public void LoadDocument_WithXmlCommentsAddedAfterSigning_SuccessfullyValidatesSignature() { // The canonicalization we use excludes comments, so comments should have no effect on signature validity. var document = new CpixDocument(); FillDocumentWithData(document); document.Recipients.AddSignature(TestHelpers.Certificate4WithPrivateKey); document.ContentKeys.AddSignature(TestHelpers.Certificate4WithPrivateKey); document.UsageRules.AddSignature(TestHelpers.Certificate4WithPrivateKey); document.SignedBy = TestHelpers.Certificate3WithPrivateKey; var buffer = new MemoryStream(); document.Save(buffer); // Let's now sprinkle comments all over the place. var xmlDocument = new XmlDocument(); buffer.Position = 0; xmlDocument.Load(buffer); var namespaces = XmlHelpers.CreateCpixNamespaceManager(xmlDocument); AddCommentAsChild(xmlDocument.DocumentElement); AddCommentAsChild((XmlElement)xmlDocument.SelectSingleNode("/cpix:CPIX/cpix:DeliveryDataList", namespaces)); AddCommentAsChild((XmlElement)xmlDocument.SelectSingleNode("/cpix:CPIX/cpix:ContentKeyList", namespaces)); AddCommentAsChild((XmlElement)xmlDocument.SelectSingleNode("/cpix:CPIX/cpix:ContentKeyUsageRuleList", namespaces)); AddCommentAsChild((XmlElement)xmlDocument.SelectSingleNode("/cpix:CPIX/cpix:DeliveryDataList/cpix:DeliveryData", namespaces)); AddCommentAsChild((XmlElement)xmlDocument.SelectSingleNode("/cpix:CPIX/cpix:ContentKeyList/cpix:ContentKey", namespaces)); AddCommentAsChild((XmlElement)xmlDocument.SelectSingleNode("/cpix:CPIX/cpix:ContentKeyUsageRuleList/cpix:ContentKeyUsageRule", namespaces)); buffer.SetLength(0); using (var writer = XmlWriter.Create(buffer, new XmlWriterSettings { Encoding = Encoding.UTF8, CloseOutput = false, })) { xmlDocument.Save(writer); } buffer.Position = 0; document = CpixDocument.Load(buffer); Assert.NotNull(document.SignedBy); Assert.Single(document.Recipients.SignedBy); Assert.Single(document.ContentKeys.SignedBy); Assert.Single(document.UsageRules.SignedBy); // And, of course, the data should still be there. Assert.Equal(2, document.ContentKeys.Count); Assert.Equal(2, document.Recipients.Count); Assert.Equal(2, document.UsageRules.Count); }
public void RemoveContentKey_WithUnknownContentKey_Succeeds() { var contentKey = TestHelpers.GenerateContentKey(); var document = new CpixDocument(); document.ContentKeys.Remove(contentKey); }
public void Load_WithCpixContainingManyHlsSignalingDataElementsAndOneWithoutPlaylistAttribute_Fails() { const string CpixWithOneSignalingDataElementWithoutPlaylistAttribute = "<?xml version=\"1.0\" encoding=\"utf-8\"?><CPIX xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"urn:dashif:org:cpix\" xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\" xmlns:enc=\"http://www.w3.org/2001/04/xmlenc#\" xmlns:pskc=\"urn:ietf:params:xml:ns:keyprov:pskc\"><ContentKeyList><ContentKey kid=\"f8c80c25-690f-4736-8132-430e5c6994ce\"><Data><pskc:Secret><pskc:PlainValue>AQIDBAUGBwgJCgECAwQFBg==</pskc:PlainValue></pskc:Secret></Data></ContentKey></ContentKeyList><DRMSystemList><DRMSystem systemId=\"edef8ba9-79d6-4ace-a3c8-27dcd51d21ed\" kid=\"f8c80c25-690f-4736-8132-430e5c6994ce\"><HLSSignalingData playlist=\"master\">YWE=</HLSSignalingData><HLSSignalingData>YWE=</HLSSignalingData></DRMSystem></DRMSystemList></CPIX>"; var ex = Assert.Throws <InvalidCpixDataException>(() => CpixDocument.Load(new MemoryStream(Encoding.UTF8.GetBytes(CpixWithOneSignalingDataElementWithoutPlaylistAttribute)))); Assert.Contains("only one HLSSignalingData element", ex.Message); }
public void Load_WithCpixContainingMultipleDrmSystemsWithIdenticalSystemIdAndKeyId_Fails() { const string CpixWithInvalidDrmSystems = "<?xml version=\"1.0\" encoding=\"utf-8\"?><CPIX xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"urn:dashif:org:cpix\" xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\" xmlns:enc=\"http://www.w3.org/2001/04/xmlenc#\" xmlns:pskc=\"urn:ietf:params:xml:ns:keyprov:pskc\"><ContentKeyList><ContentKey kid=\"f8c80c25-690f-4736-8132-430e5c6994ce\"><Data><pskc:Secret><pskc:PlainValue>AQIDBAUGBwgJCgECAwQFBg==</pskc:PlainValue></pskc:Secret></Data></ContentKey></ContentKeyList><DRMSystemList><DRMSystem systemId=\"edef8ba9-79d6-4ace-a3c8-27dcd51d21ed\" kid=\"f8c80c25-690f-4736-8132-430e5c6994ce\"></DRMSystem><DRMSystem systemId=\"edef8ba9-79d6-4ace-a3c8-27dcd51d21ed\" kid=\"f8c80c25-690f-4736-8132-430e5c6994ce\"></DRMSystem></DRMSystemList></CPIX>"; var ex = Assert.Throws <InvalidCpixDataException>(() => CpixDocument.Load(new MemoryStream(Encoding.UTF8.GetBytes(CpixWithInvalidDrmSystems)))); Assert.Contains("multiple DRM system signaling entries", ex.Message); }
public void Load_WithCpixContainingDrmSystemElementThatReferencesNonExistentContentKey_Fails() { const string CpixWithDrmSystemReferencingNonExistentContentKey = "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48Q1BJWCB4bWxuczp4c2k9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hLWluc3RhbmNlIiB4bWxuczp4c2Q9Imh0dHA6Ly93d3cudzMub3JnLzIwMDEvWE1MU2NoZW1hIiB4bWxucz0idXJuOmRhc2hpZjpvcmc6Y3BpeCIgeG1sbnM6ZHM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvMDkveG1sZHNpZyMiIHhtbG5zOmVuYz0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxlbmMjIiB4bWxuczpwc2tjPSJ1cm46aWV0ZjpwYXJhbXM6eG1sOm5zOmtleXByb3Y6cHNrYyI+PENvbnRlbnRLZXlMaXN0PjxDb250ZW50S2V5IGtpZD0iZTVlMjE1YmMtYmMwZS00NzZkLTg0MmYtZmExMjQyMDQzMDIwIj48RGF0YT48cHNrYzpTZWNyZXQ+PHBza2M6UGxhaW5WYWx1ZT5meitmZnpLTldwbm84Ymt3UWM1V0FnPT08L3Bza2M6UGxhaW5WYWx1ZT48L3Bza2M6U2VjcmV0PjwvRGF0YT48L0NvbnRlbnRLZXk+PC9Db250ZW50S2V5TGlzdD48RFJNU3lzdGVtTGlzdD48RFJNU3lzdGVtIHN5c3RlbUlkPSJhYzRmMDc3Ny1jOTU0LTRjMjEtYjdiNC0xOWM2MTMxYTQyOGYiIGtpZD0iNTY5YjdlNTUtMDMxNy00NTg5LTg4YWEtYmI3OGRiODA2Zjg4Ij48Q29udGVudFByb3RlY3Rpb25EYXRhPlBIUmxjM1ErUEM5MFpYTjBQZz09PC9Db250ZW50UHJvdGVjdGlvbkRhdGE+PC9EUk1TeXN0ZW0+PC9EUk1TeXN0ZW1MaXN0PjwvQ1BJWD4="; var ex = Assert.Throws <InvalidCpixDataException>(() => CpixDocument.Load(new MemoryStream(Convert.FromBase64String(CpixWithDrmSystemReferencingNonExistentContentKey)))); Assert.Contains("keys referenced by DRM system", ex.Message); }
public static CpixDocument Reload(CpixDocument document, IReadOnlyCollection <X509Certificate2> decryptionCertificates = null) { var buffer = new MemoryStream(); document.Save(buffer); buffer.Position = 0; return(CpixDocument.Load(buffer, decryptionCertificates)); }
public void RemoveContentKey_WithNewWritableCollection_Succeeds() { var contentKey = TestHelpers.GenerateContentKey(); var document = new CpixDocument(); document.ContentKeys.Add(contentKey); document.ContentKeys.Remove(contentKey); }
public void Generate(Stream outputStream) { var document = new CpixDocument(); document.Recipients.Add(new Recipient(TestHelpers.Certificate3WithPublicKey)); document.Recipients.Add(new Recipient(TestHelpers.Certificate4WithPublicKey)); document.Save(outputStream); }
private static void FillDocumentWithData(CpixDocument document) { document.ContentKeys.Add(TestHelpers.GenerateContentKey()); document.ContentKeys.Add(TestHelpers.GenerateContentKey()); document.Recipients.Add(new Recipient(TestHelpers.Certificate3WithPublicKey)); document.Recipients.Add(new Recipient(TestHelpers.Certificate4WithPublicKey)); TestHelpers.AddUsageRule(document); TestHelpers.AddUsageRule(document); }
public void ResolveContentKey_WithNoRules_ThrowsException() { var key = TestHelpers.GenerateContentKey(); var document = new CpixDocument(); document.ContentKeys.Add(key); Assert.Throws <ContentKeyResolveImpossibleException>(() => document.ResolveContentKey(new ContentKeyContext())); }
public void Load_WithCpixContainingSingleHlsSignalingDataElementWithoutPlaylistAttribute_SucceedsWithDataInterpretedAsMediaPlaylistData() { const string CpixWithHlsSignalingDataWithoutPlaylistAttribute = "<?xml version=\"1.0\" encoding=\"utf-8\"?><CPIX xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"urn:dashif:org:cpix\" xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\" xmlns:enc=\"http://www.w3.org/2001/04/xmlenc#\" xmlns:pskc=\"urn:ietf:params:xml:ns:keyprov:pskc\"><ContentKeyList><ContentKey kid=\"f8c80c25-690f-4736-8132-430e5c6994ce\"><Data><pskc:Secret><pskc:PlainValue>AQIDBAUGBwgJCgECAwQFBg==</pskc:PlainValue></pskc:Secret></Data></ContentKey></ContentKeyList><DRMSystemList><DRMSystem systemId=\"edef8ba9-79d6-4ace-a3c8-27dcd51d21ed\" kid=\"f8c80c25-690f-4736-8132-430e5c6994ce\"><HLSSignalingData>YWE=</HLSSignalingData></DRMSystem></DRMSystemList></CPIX>"; var document = CpixDocument.Load(new MemoryStream(Encoding.UTF8.GetBytes(CpixWithHlsSignalingDataWithoutPlaylistAttribute))); var drmSystem = document.DrmSystems.First(); Assert.NotNull(drmSystem.HlsSignalingData.MediaPlaylistData); Assert.Null(drmSystem.HlsSignalingData.MasterPlaylistData); }
public void LoadDocument_WithUtf16EncodedInput_Succeeds() { // We ensure that some non-ASCII text survives the encoding/decoding/signing process intact. const string canary = "滆 柦柋牬 趉軨鄇 鶊鵱, 緳廞徲 鋑鋡髬 溮煡煟 綡蒚"; var document = new CpixDocument(); FillDocumentWithData(document); document.UsageRules.First().LabelFilters = new[] { new LabelFilter { Label = canary } }; document.Recipients.AddSignature(TestHelpers.Certificate4WithPrivateKey); document.ContentKeys.AddSignature(TestHelpers.Certificate4WithPrivateKey); document.UsageRules.AddSignature(TestHelpers.Certificate4WithPrivateKey); document.SignedBy = TestHelpers.Certificate3WithPrivateKey; var buffer = new MemoryStream(); document.Save(buffer); // Now we have a basic UTF-8 document in the buffer. Convert to UTF-16! // Using XmlDocument here to do it in a "smart" way with all the XML processing. var xmlDocument = new XmlDocument(); buffer.Position = 0; xmlDocument.Load(buffer); buffer.SetLength(0); using (var writer = XmlWriter.Create(buffer, new XmlWriterSettings { Encoding = Encoding.Unicode, CloseOutput = false, })) { xmlDocument.Save(writer); } buffer.Position = 0; // Okay, does it load? It should! document = CpixDocument.Load(buffer); Assert.Equal(2, document.ContentKeys.Count); Assert.Equal(2, document.Recipients.Count); Assert.Equal(2, document.UsageRules.Count); Assert.Equal(canary, document.UsageRules.First().LabelFilters.Single().Label); }
public void AddContentKey_WithLoadedEmptyDocument_Succeeds() { var document = new CpixDocument(); document = TestHelpers.Reload(document); document.ContentKeys.Add(TestHelpers.GenerateContentKey()); document = TestHelpers.Reload(document); Assert.Single(document.ContentKeys); }