KeyInfoX509Data.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. //
  2. // KeyInfoX509Data.cs - KeyInfoX509Data implementation for XML Signature
  3. //
  4. // Author:
  5. // Sebastien Pouliot ([email protected])
  6. // Atsushi Enomoto ([email protected])
  7. //
  8. // (C) 2002, 2003 Motus Technologies Inc. (http://www.motus.com)
  9. // (C) 2004 Novell Inc.
  10. //
  11. using System.Collections;
  12. using System.Security.Cryptography.X509Certificates;
  13. using System.Xml;
  14. namespace System.Security.Cryptography.Xml {
  15. // FIXME: framework class isn't documented so compatibility isn't assured!
  16. internal class IssuerSerial
  17. {
  18. public string Issuer;
  19. public string Serial;
  20. public IssuerSerial (string issuer, string serial)
  21. {
  22. Issuer = issuer;
  23. Serial = serial;
  24. }
  25. }
  26. public class KeyInfoX509Data : KeyInfoClause
  27. {
  28. private byte[] x509crl;
  29. private ArrayList IssuerSerialList;
  30. private ArrayList SubjectKeyIdList;
  31. private ArrayList SubjectNameList;
  32. private ArrayList X509CertificateList;
  33. public KeyInfoX509Data ()
  34. {
  35. IssuerSerialList = new ArrayList ();
  36. SubjectKeyIdList = new ArrayList ();
  37. SubjectNameList = new ArrayList ();
  38. X509CertificateList = new ArrayList ();
  39. }
  40. public KeyInfoX509Data (byte[] rgbCert) : this ()
  41. {
  42. AddCertificate (new X509Certificate (rgbCert));
  43. }
  44. public KeyInfoX509Data (X509Certificate cert) : this ()
  45. {
  46. AddCertificate (cert);
  47. }
  48. public ArrayList Certificates {
  49. get { return X509CertificateList.Count != 0 ? X509CertificateList : null; }
  50. }
  51. public byte[] CRL {
  52. get { return x509crl; }
  53. set { x509crl = value; }
  54. }
  55. public ArrayList IssuerSerials {
  56. get { return IssuerSerialList.Count != 0 ? IssuerSerialList : null; }
  57. }
  58. public ArrayList SubjectKeyIds {
  59. get { return SubjectKeyIdList.Count != 0 ? SubjectKeyIdList : null; }
  60. }
  61. public ArrayList SubjectNames {
  62. get { return SubjectNameList.Count != 0 ? SubjectNameList : null; }
  63. }
  64. public void AddCertificate (X509Certificate certificate)
  65. {
  66. X509CertificateList.Add (certificate);
  67. }
  68. public void AddIssuerSerial (string issuerName, string serialNumber)
  69. {
  70. IssuerSerial isser = new IssuerSerial (issuerName, serialNumber);
  71. IssuerSerialList.Add (isser);
  72. }
  73. public void AddSubjectKeyId (byte[] subjectKeyId)
  74. {
  75. SubjectKeyIdList.Add (subjectKeyId);
  76. }
  77. public void AddSubjectName (string subjectName)
  78. {
  79. SubjectNameList.Add (subjectName);
  80. }
  81. public override XmlElement GetXml ()
  82. {
  83. // sanity check
  84. int count = IssuerSerialList.Count + SubjectKeyIdList.Count + SubjectNameList.Count + X509CertificateList.Count;
  85. if ((x509crl == null) && (count == 0))
  86. throw new CryptographicException ("value");
  87. XmlDocument document = new XmlDocument ();
  88. XmlElement xel = document.CreateElement (XmlSignature.ElementNames.X509Data, XmlSignature.NamespaceURI);
  89. // FIXME: hack to match MS implementation
  90. xel.SetAttribute ("xmlns", XmlSignature.NamespaceURI);
  91. // <X509IssuerSerial>
  92. if (IssuerSerialList.Count > 0) {
  93. foreach (IssuerSerial iser in IssuerSerialList) {
  94. XmlElement isl = document.CreateElement (XmlSignature.ElementNames.X509IssuerSerial, XmlSignature.NamespaceURI);
  95. XmlElement xin = document.CreateElement (XmlSignature.ElementNames.X509IssuerName, XmlSignature.NamespaceURI);
  96. xin.InnerText = iser.Issuer;
  97. isl.AppendChild (xin);
  98. XmlElement xsn = document.CreateElement (XmlSignature.ElementNames.X509SerialNumber, XmlSignature.NamespaceURI);
  99. xsn.InnerText = iser.Serial;
  100. isl.AppendChild (xsn);
  101. xel.AppendChild (isl);
  102. }
  103. }
  104. // <X509SKI>
  105. if (SubjectKeyIdList.Count > 0) {
  106. foreach (byte[] skid in SubjectKeyIdList) {
  107. XmlElement ski = document.CreateElement (XmlSignature.ElementNames.X509SKI, XmlSignature.NamespaceURI);
  108. ski.InnerText = Convert.ToBase64String (skid);
  109. xel.AppendChild (ski);
  110. }
  111. }
  112. // <X509SubjectName>
  113. if (SubjectNameList.Count > 0) {
  114. foreach (string subject in SubjectNameList) {
  115. XmlElement sn = document.CreateElement (XmlSignature.ElementNames.X509SubjectName, XmlSignature.NamespaceURI);
  116. sn.InnerText = subject;
  117. xel.AppendChild (sn);
  118. }
  119. }
  120. // <X509Certificate>
  121. if (X509CertificateList.Count > 0) {
  122. foreach (X509Certificate x509 in X509CertificateList) {
  123. XmlElement cert = document.CreateElement (XmlSignature.ElementNames.X509Certificate, XmlSignature.NamespaceURI);
  124. cert.InnerText = Convert.ToBase64String (x509.GetRawCertData ());
  125. xel.AppendChild (cert);
  126. }
  127. }
  128. // only one <X509CRL>
  129. if (x509crl != null) {
  130. XmlElement crl = document.CreateElement (XmlSignature.ElementNames.X509CRL, XmlSignature.NamespaceURI);
  131. crl.InnerText = Convert.ToBase64String (x509crl);
  132. xel.AppendChild (crl);
  133. }
  134. return xel;
  135. }
  136. public override void LoadXml (XmlElement element)
  137. {
  138. if (element == null)
  139. throw new ArgumentNullException ("element");
  140. IssuerSerialList.Clear ();
  141. SubjectKeyIdList.Clear ();
  142. SubjectNameList.Clear ();
  143. X509CertificateList.Clear ();
  144. x509crl = null;
  145. if ((element.LocalName != XmlSignature.ElementNames.X509Data) || (element.NamespaceURI != XmlSignature.NamespaceURI))
  146. throw new CryptographicException ("element");
  147. XmlElement [] xnl = null;
  148. // <X509IssuerSerial>
  149. xnl = XmlSignature.GetChildElements (element, XmlSignature.ElementNames.X509IssuerSerial);
  150. if (xnl != null) {
  151. for (int i=0; i < xnl.Length; i++) {
  152. XmlElement xel = (XmlElement) xnl[i];
  153. XmlElement issuer = XmlSignature.GetChildElement (xel, XmlSignature.ElementNames.X509IssuerName, XmlSignature.NamespaceURI);
  154. XmlElement serial = XmlSignature.GetChildElement (xel, XmlSignature.ElementNames.X509SerialNumber, XmlSignature.NamespaceURI);
  155. AddIssuerSerial (issuer.InnerText, serial.InnerText);
  156. }
  157. }
  158. // <X509SKI>
  159. xnl = XmlSignature.GetChildElements (element, XmlSignature.ElementNames.X509SKI);
  160. if (xnl != null) {
  161. for (int i=0; i < xnl.Length; i++) {
  162. byte[] skid = Convert.FromBase64String (xnl[i].InnerXml);
  163. AddSubjectKeyId (skid);
  164. }
  165. }
  166. // <X509SubjectName>
  167. xnl = XmlSignature.GetChildElements (element, XmlSignature.ElementNames.X509SubjectName);
  168. if (xnl != null) {
  169. for (int i=0; i < xnl.Length; i++) {
  170. AddSubjectName (xnl[i].InnerXml);
  171. }
  172. }
  173. // <X509Certificate>
  174. xnl = XmlSignature.GetChildElements (element, XmlSignature.ElementNames.X509Certificate);
  175. if (xnl != null) {
  176. for (int i=0; i < xnl.Length; i++) {
  177. byte[] cert = Convert.FromBase64String (xnl[i].InnerXml);
  178. AddCertificate (new X509Certificate (cert));
  179. }
  180. }
  181. // only one <X509CRL>
  182. XmlElement x509el = XmlSignature.GetChildElement (element, XmlSignature.ElementNames.X509CRL, XmlSignature.NamespaceURI);
  183. if (x509el != null) {
  184. x509crl = Convert.FromBase64String (x509el.InnerXml);
  185. }
  186. }
  187. }
  188. }