namespace com.hitrust.Security.Certificates { using com.hitrust.Security; using System; using System.Collections; using System.Reflection; using System.Runtime.InteropServices; public class DistinguishedName { private ArrayList m_List; public DistinguishedName() { this.m_List = new ArrayList(); } internal DistinguishedName(CertificateNameInfo cni) : this() { this.Initialize(cni); } internal DistinguishedName(IntPtr input, int length) : this() { int size = 0; SspiProvider.CryptDecodeObject(0x10001, new IntPtr(20), input, length, 0, IntPtr.Zero, ref size); if (size <= 0) { throw new CertificateException("Unable to decode the name of the certificate."); } IntPtr buffer = Marshal.AllocHGlobal(size); if (SspiProvider.CryptDecodeObject(0x10001, new IntPtr(20), input, length, 0, buffer, ref size) == 0) { throw new CertificateException("Unable to decode the name of the certificate."); } try { CertificateNameInfo cni = (CertificateNameInfo) Marshal.PtrToStructure(buffer, typeof(CertificateNameInfo)); this.Initialize(cni); } catch (CertificateException ce) { throw ce; } catch (Exception e) { throw new CertificateException("Could not get the certificate distinguished name.", e); } finally { if (buffer != IntPtr.Zero) { Marshal.FreeHGlobal(buffer); } } } public int Add(NameAttribute attribute) { return this.m_List.Add(attribute); } public void Clear() { this.m_List.Clear(); } public bool Contains(NameAttribute value) { return this.m_List.Contains(value); } public int IndexOf(NameAttribute value) { return this.m_List.IndexOf(value); } private void Initialize(CertificateNameInfo cni) { if (cni.cRDN <= 0) { throw new CertificateException("Certificate does not have a subject relative distinguished name."); } for (int i = 0; i < cni.cRDN; i++) { RelativeDistinguishedName cr = (RelativeDistinguishedName) Marshal.PtrToStructure(new IntPtr(cni.rgRDN.ToInt64() + (i * Marshal.SizeOf(typeof(RelativeDistinguishedName)))), typeof(RelativeDistinguishedName)); for (int j = 0; j < cr.cRDNAttr; j++) { RdnAttribute cra = (RdnAttribute) Marshal.PtrToStructure(new IntPtr(cr.rgRDNAttr.ToInt64() + (j * Marshal.SizeOf(typeof(RdnAttribute)))), typeof(RdnAttribute)); this.m_List.Add(new NameAttribute(Marshal.PtrToStringAnsi(cra.pszObjId), Marshal.PtrToStringUni(cra.pbData))); } } } public void Insert(int index, NameAttribute value) { this.m_List.Insert(index, value); } public void Remove(NameAttribute value) { this.m_List.Remove(value); } public void RemoveAt(int index) { this.m_List.RemoveAt(index); } public int Count { get { return this.m_List.Count; } } public NameAttribute this[int index] { get { return (NameAttribute) this.m_List[index]; } set { this.m_List[index] = value; } } } }