protected override UsageRule DeserializeEntity(XmlElement element, XmlNamespaceManager namespaces) { var raw = XmlHelpers.Deserialize <UsageRuleElement>(element); raw.LoadTimeValidate(); var rule = new UsageRule { KeyId = raw.KeyId }; // This disables all usage rule processing, basically, and treats this particular rule as read-only. // The unknown filters will be preserved unless the rule is removed, just no rules from this document can be used. if (raw.UnknownFilters?.Any() == true) { rule.ContainsUnsupportedFilters = true; } if (raw.VideoFilters?.Length > 0) { rule.VideoFilters = raw.VideoFilters .Select(f => new VideoFilter { MinPixels = f.MinPixels, MaxPixels = f.MaxPixels, MinFramesPerSecond = f.MinFps, MaxFramesPerSecond = f.MaxFps, WideColorGamut = f.Wcg, HighDynamicRange = f.Hdr }) .ToList(); } if (raw.AudioFilters?.Length > 0) { rule.AudioFilters = raw.AudioFilters .Select(f => new AudioFilter { MinChannels = f.MinChannels, MaxChannels = f.MaxChannels }) .ToList(); } if (raw.BitrateFilters?.Length > 0) { rule.BitrateFilters = raw.BitrateFilters .Select(f => new BitrateFilter { MinBitrate = f.MinBitrate, MaxBitrate = f.MaxBitrate }) .ToList(); } if (raw.LabelFilters?.Length > 0) { rule.LabelFilters = raw.LabelFilters .Select(f => new LabelFilter { Label = f.Label }) .ToList(); } return(rule); }
protected override XmlElement SerializeEntity(XmlDocument document, XmlNamespaceManager namespaces, XmlElement container, Recipient entity) { var recipientRsa = entity.Certificate.GetRSAPublicKey(); // Ensure that we have the document-scoped cryptographic material available. if (Document.DocumentKey == null) { Document.GenerateKeys(); } var encryptedDocumentKey = recipientRsa.Encrypt(Document.DocumentKey, RSAEncryptionPadding.OaepSHA1); var encryptedMacKey = recipientRsa.Encrypt(Document.MacKey, RSAEncryptionPadding.OaepSHA1); var element = new DeliveryDataElement { DeliveryKey = new DeliveryKeyElement { X509Data = new X509Data { Certificate = entity.Certificate.GetRawCertData() } }, DocumentKey = new DocumentKeyElement { Algorithm = Constants.Aes256CbcAlgorithm, Data = new DataElement { Secret = new SecretDataElement { EncryptedValue = new EncryptedXmlValue { EncryptionMethod = new EncryptionMethodDeclaration { Algorithm = Constants.RsaOaepAlgorithm }, CipherData = new CipherDataContainer { CipherValue = encryptedDocumentKey } } } } }, MacMethod = new MacMethodElement { Algorithm = Constants.HmacSha512Algorithm, Key = new EncryptedXmlValue { EncryptionMethod = new EncryptionMethodDeclaration { Algorithm = Constants.RsaOaepAlgorithm }, CipherData = new CipherDataContainer { CipherValue = encryptedMacKey } } } }; return(XmlHelpers.AppendChildAndReuseNamespaces(element, container)); }
protected override XmlElement SerializeEntity(XmlDocument document, XmlNamespaceManager namespaces, XmlElement container, ContentKey entity) { var element = new ContentKeyElement { KeyId = entity.Id, ExplicitIv = entity.ExplicitIv, Data = new DataElement { Secret = new SecretDataElement() } }; if (Document.Recipients.Any()) { // We have to encrypt the key. Okay. Ensure we have the crypto values available. if (Document.DocumentKey == null) { Document.GenerateKeys(); } // Unique IV is generated for every content key. var iv = new byte[128 / 8]; using (var random = RandomNumberGenerator.Create()) random.GetBytes(iv); var aes = new AesManaged { BlockSize = 128, KeySize = 256, Key = Document.DocumentKey, Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7, IV = iv }; var mac = new HMACSHA512(Document.MacKey); using (var encryptor = aes.CreateEncryptor()) { var encryptedValue = encryptor.TransformFinalBlock(entity.Value, 0, entity.Value.Length); // NB! We prepend the IV to the value when saving an encrypted value to the document field. var fieldValue = iv.Concat(encryptedValue).ToArray(); element.Data.Secret.EncryptedValue = new EncryptedXmlValue { CipherData = new CipherDataContainer { CipherValue = fieldValue }, EncryptionMethod = new EncryptionMethodDeclaration { Algorithm = Constants.Aes256CbcAlgorithm } }; // Never not MAC. element.Data.Secret.ValueMAC = mac.ComputeHash(fieldValue); } } else { // We are saving the key in the clear. element.Data.Secret.PlainValue = entity.Value; } return(XmlHelpers.AppendChildAndReuseNamespaces(element, container)); }