1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 using System;
6 using System.Collections;
7 using System.Xml;
8 
9 namespace System.Security.Cryptography.Xml
10 {
11     public abstract class EncryptedReference
12     {
13         private string _uri;
14         private string _referenceType;
15         private TransformChain _transformChain;
16         internal XmlElement _cachedXml = null;
17 
EncryptedReference()18         protected EncryptedReference() : this(string.Empty, new TransformChain())
19         {
20         }
21 
EncryptedReference(string uri)22         protected EncryptedReference(string uri) : this(uri, new TransformChain())
23         {
24         }
25 
EncryptedReference(string uri, TransformChain transformChain)26         protected EncryptedReference(string uri, TransformChain transformChain)
27         {
28             TransformChain = transformChain;
29             Uri = uri;
30             _cachedXml = null;
31         }
32 
33         public string Uri
34         {
35             get { return _uri; }
36             set
37             {
38                 if (value == null)
39                     throw new ArgumentNullException(SR.Cryptography_Xml_UriRequired);
40                 _uri = value;
41                 _cachedXml = null;
42             }
43         }
44 
45         public TransformChain TransformChain
46         {
47             get
48             {
49                 if (_transformChain == null)
50                     _transformChain = new TransformChain();
51                 return _transformChain;
52             }
53             set
54             {
55                 _transformChain = value;
56                 _cachedXml = null;
57             }
58         }
59 
AddTransform(Transform transform)60         public void AddTransform(Transform transform)
61         {
62             TransformChain.Add(transform);
63         }
64 
65         protected string ReferenceType
66         {
67             get { return _referenceType; }
68             set
69             {
70                 _referenceType = value;
71                 _cachedXml = null;
72             }
73         }
74 
75         internal protected bool CacheValid
76         {
77             get
78             {
79                 return (_cachedXml != null);
80             }
81         }
82 
GetXml()83         public virtual XmlElement GetXml()
84         {
85             if (CacheValid) return _cachedXml;
86 
87             XmlDocument document = new XmlDocument();
88             document.PreserveWhitespace = true;
89             return GetXml(document);
90         }
91 
GetXml(XmlDocument document)92         internal XmlElement GetXml(XmlDocument document)
93         {
94             if (ReferenceType == null)
95                 throw new CryptographicException(SR.Cryptography_Xml_ReferenceTypeRequired);
96 
97             // Create the Reference
98             XmlElement referenceElement = document.CreateElement(ReferenceType, EncryptedXml.XmlEncNamespaceUrl);
99             if (!string.IsNullOrEmpty(_uri))
100                 referenceElement.SetAttribute("URI", _uri);
101 
102             // Add the transforms to the CipherReference
103             if (TransformChain.Count > 0)
104                 referenceElement.AppendChild(TransformChain.GetXml(document, SignedXml.XmlDsigNamespaceUrl));
105 
106             return referenceElement;
107         }
108 
LoadXml(XmlElement value)109         public virtual void LoadXml(XmlElement value)
110         {
111             if (value == null)
112                 throw new ArgumentNullException(nameof(value));
113 
114             ReferenceType = value.LocalName;
115             Uri = Utils.GetAttribute(value, "URI", EncryptedXml.XmlEncNamespaceUrl);
116 
117             // Transforms
118             XmlNamespaceManager nsm = new XmlNamespaceManager(value.OwnerDocument.NameTable);
119             nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl);
120             XmlNode transformsNode = value.SelectSingleNode("ds:Transforms", nsm);
121             if (transformsNode != null)
122                 TransformChain.LoadXml(transformsNode as XmlElement);
123 
124             // cache the Xml
125             _cachedXml = value;
126         }
127     }
128 }
129