KeyInfoX509Data.cs 5.8 KB

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