//
// KeyInfoX509Data.cs - KeyInfoX509Data implementation for XML Signature
//
// Author:
// Sebastien Pouliot (spouliot@motus.com)
//
// (C) 2002 Motus Technologies Inc. (http://www.motus.com)
//
using System.Collections;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Xml;
namespace System.Security.Cryptography.Xml {
// FIXME: framework class isn't documented so compatibility isn't assured!
internal class IssuerSerial {
public string Issuer;
public string Serial;
public IssuerSerial (string issuer, string serial)
{
Issuer = issuer;
Serial = serial;
}
}
public class KeyInfoX509Data : KeyInfoClause {
protected byte[] x509crl;
protected ArrayList IssuerSerialList;
protected ArrayList SubjectKeyIdList;
protected ArrayList SubjectNameList;
protected ArrayList X509CertificateList;
public KeyInfoX509Data ()
{
IssuerSerialList = new ArrayList ();
SubjectKeyIdList = new ArrayList ();
SubjectNameList = new ArrayList ();
X509CertificateList = new ArrayList ();
}
public KeyInfoX509Data (byte[] rgbCert) : this ()
{
AddCertificate (new X509Certificate (rgbCert));
}
public KeyInfoX509Data (X509Certificate cert) : this ()
{
AddCertificate (cert);
}
public ArrayList Certificates {
get { return X509CertificateList; }
}
public byte[] CRL {
get { return x509crl; }
set { x509crl = value; }
}
public ArrayList IssuerSerials {
get { return IssuerSerialList; }
}
public ArrayList SubjectKeyIds {
get { return SubjectKeyIdList; }
}
public ArrayList SubjectNames {
get { return SubjectNameList; }
}
public void AddCertificate (X509Certificate certificate)
{
X509CertificateList.Add (certificate);
}
public void AddIssuerSerial (string issuerName, string serialNumber)
{
IssuerSerial isser = new IssuerSerial (issuerName, serialNumber);
IssuerSerialList.Add (isser);
}
public void AddSubjectKeyId (byte[] subjectKeyId)
{
SubjectKeyIdList.Add (subjectKeyId);
}
public void AddSubjectName (string subjectName)
{
SubjectNameList.Add (subjectName);
}
public override XmlElement GetXml ()
{
// sanity check
int count = IssuerSerialList.Count + SubjectKeyIdList.Count + SubjectNameList.Count + X509CertificateList.Count;
if ((x509crl == null) && (count == 0))
throw new CryptographicException ("value");
StringBuilder sb = new StringBuilder ();
sb.Append ("");
//
if (IssuerSerialList.Count > 0) {
sb.Append ("");
foreach (IssuerSerial iser in IssuerSerialList) {
sb.Append ("");
sb.Append (iser.Issuer);
sb.Append ("");
sb.Append ("");
sb.Append (iser.Serial);
sb.Append ("");
}
sb.Append ("");
}
//
if (SubjectKeyIdList.Count > 0) {
foreach (byte[] skid in SubjectKeyIdList) {
sb.Append ("");
sb.Append (Convert.ToBase64String (skid));
sb.Append ("");
}
}
//
if (SubjectNameList.Count > 0) {
foreach (string subject in SubjectNameList) {
sb.Append ("");
sb.Append (subject);
sb.Append ("");
}
}
//
if (X509CertificateList.Count > 0) {
foreach (X509Certificate x509 in X509CertificateList) {
sb.Append ("");
sb.Append (Convert.ToBase64String (x509.GetRawCertData ()));
sb.Append ("");
}
}
// only one
if (x509crl != null) {
sb.Append ("");
sb.Append (Convert.ToBase64String (x509crl));
sb.Append ("");
}
sb.Append ("");
XmlDocument doc = new XmlDocument ();
doc.LoadXml(sb.ToString ());
return doc.DocumentElement;
}
public override void LoadXml (XmlElement value)
{
if (value == null)
throw new ArgumentNullException ();
IssuerSerialList.Clear ();
SubjectKeyIdList.Clear ();
SubjectNameList.Clear ();
X509CertificateList.Clear ();
x509crl = null;
string ns = "http://www.w3.org/2000/09/xmldsig#";
if ((value.LocalName == "X509Data") && (value.NamespaceURI == ns)) {
XmlNodeList xnl = null;
//
xnl = value.GetElementsByTagName ("X509IssuerSerial", ns);
if (xnl != null) {
for (int i=0; i < xnl.Count; i++) {
XmlElement xel = (XmlElement) xnl[i];
XmlNodeList issuer = xel.GetElementsByTagName ("X509IssuerName", ns);
XmlNodeList serial = xel.GetElementsByTagName ("X509SerialNumber", ns);
AddIssuerSerial (issuer[0].InnerText, serial[0].InnerText);
}
}
//
xnl = value.GetElementsByTagName ("X509SKI", ns);
if (xnl != null) {
for (int i=0; i < xnl.Count; i++) {
byte[] skid = Convert.FromBase64String (xnl[i].InnerXml);
AddSubjectKeyId (skid);
}
}
//
xnl = value.GetElementsByTagName ("X509SubjectName", ns);
if (xnl != null) {
for (int i=0; i < xnl.Count; i++) {
AddSubjectName (xnl[i].InnerXml);
}
}
//
xnl = value.GetElementsByTagName ("X509Certificate", ns);
if (xnl != null) {
for (int i=0; i < xnl.Count; i++) {
byte[] cert = Convert.FromBase64String (xnl[i].InnerXml);
AddCertificate (new X509Certificate (cert));
}
}
// only one
xnl = value.GetElementsByTagName ("X509CRL", ns);
if ((xnl != null) && (xnl.Count > 0)) {
x509crl = Convert.FromBase64String (xnl[0].InnerXml);
}
}
else
throw new CryptographicException ("value");
}
}
}